一、MISC 驱动简介

MISC 驱动其实就是最简单的字符设备驱动,所有的 MISC 设备驱动的主设备号都为 10,不同的设备使用不同的从设备号。
MISC 设备会自动创建 cdev,不需要像我们以前那样手动创建,因此采用 MISC 设备驱动可以简化字符设备驱动的编写。
我们只需要向 Linux 注册一个 miscdevice 设备, miscdevice是一个结构体定义在文件 include/linux/miscdevice.h 中,内容如下:

struct miscdevice  {int minor;const char *name;const struct file_operations *fops;struct list_head list;struct device *parent;struct device *this_device;const struct attribute_group **groups;const char *nodename;umode_t mode;
};

miscdevice 结构体中的name 就是此 MISC 设备名字,当此设备注册成功以后就会在/dev 目录下生成一个名为 name的设备文件(后面驱动实例我们会看到这一点)。 fops 就是字符设备的操作集合, MISC 设备驱动最终是需要使用用户提供的 fops操作集合。

当设置好 miscdevice 以后就需要使用 misc_register 函数向系统中注册一个 MISC 设备,此函数原型如下:
int misc_register(struct miscdevice * misc)

MISC 设备的主设备号为 10,这个是固定的,需要用户指定子设备号, Linux 系统已经预定义了一些 MISC 设备的子设备号,这些预定义的子设备号定义在include/linux/miscdevice.h 文件中,如下所示:

/**  These allocations are managed by device@lanana.org. If you use an* entry that is not in assigned your entry may well be moved and* reassigned, or set dynamic if a fixed value is not justified.*/#define PSMOUSE_MINOR        1
#define MS_BUSMOUSE_MINOR   2   /* unused */
#define ATIXL_BUSMOUSE_MINOR    3   /* unused */
/*#define AMIGAMOUSE_MINOR  4   FIXME OBSOLETE */
#define ATARIMOUSE_MINOR    5   /* unused */
#define SUN_MOUSE_MINOR     6   /* unused */
#define APOLLO_MOUSE_MINOR  7   /* unused */
#define PC110PAD_MINOR      9   /* unused */
/*#define ADB_MOUSE_MINOR   10  FIXME OBSOLETE */
#define WATCHDOG_MINOR      130 /* Watchdog timer     */
#define TEMP_MINOR      131 /* Temperature Sensor */
#define RTC_MINOR       135
#define EFI_RTC_MINOR       136 /* EFI Time services */
#define VHCI_MINOR      137
#define SUN_OPENPROM_MINOR  139
#define DMAPI_MINOR     140 /* unused */
#define NVRAM_MINOR     144
#define SGI_MMTIMER     153
#define STORE_QUEUE_MINOR   155 /* unused */
#define I2O_MINOR       166
#define MICROCODE_MINOR     184
#define VFIO_MINOR      196
#define TUN_MINOR       200
#define CUSE_MINOR      203
#define MWAVE_MINOR     219 /* ACP/Mwave Modem */
#define MPT_MINOR       220
#define MPT2SAS_MINOR       221
#define MPT3SAS_MINOR       222
#define UINPUT_MINOR        223
#define MISC_MCELOG_MINOR   227
#define HPET_MINOR      228
#define FUSE_MINOR      229
#define KVM_MINOR       232
#define BTRFS_MINOR     234
#define AUTOFS_MINOR        235
#define MAPPER_CTRL_MINOR   236
#define LOOP_CTRL_MINOR     237
#define VHOST_NET_MINOR     238
#define UHID_MINOR      239
#define USERIO_MINOR        240
#define MISC_DYNAMIC_MINOR  255

字符设备驱动中我们常常会使用如下几个函数完成设备创建过程:

1 alloc_chrdev_region(); /* 申请设备号 */
2 cdev_init(); /* 初始化 cdev */
3 cdev_add(); /* 添加 cdev */
4 class_create(); /* 创建类 */
5 device_create(); /* 创建设备 */

现在我们可以直接使用 misc_register 一个函数来完成上面代码中的这些步骤。

二、MISC驱动实例

这个驱动代码是由之前写过的一个led点灯代码改造而来,我们主要看下一led_gpio_probe() 函数中misc_register() 的使用,它简化了我们创建设备所需要的一系列步骤。

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>static struct gpio_desc *led_gpio;#define MISCLED_NAME "miscled" /* 名字 */
#define MISCLED_MINOR 145static int led_drv_open(struct inode *node, struct file *file)
{printk(KERN_INFO "%s %s line is %d \r\n", __FILE__, __FUNCTION__, __LINE__);gpiod_direction_output(led_gpio, 0);return 0;
}static int led_drv_read(struct file *file, char __user *buf, size_t size, loff_t *offset)
{int status = 0;int result = 0;printk(KERN_INFO "%s %s line is %d \r\n", __FILE__, __FUNCTION__, __LINE__);status = gpiod_get_value(led_gpio);result = copy_to_user(buf, &status, 1);return 1;
}static int led_drv_write(struct file *file, const char __user *buf, size_t size, loff_t *offset)
{int result;char status;printk(KERN_INFO "%s %s line is %d \r\n", __FILE__, __FUNCTION__, __LINE__);result = copy_from_user(&status, buf, 1);gpiod_set_value(led_gpio, status);return 1;
}static int led_drv_release(struct inode *node, struct file *file)
{printk(KERN_INFO "%s %s line is %d \r\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}
/*面朝大海0902*/
static struct file_operations led_drv =
{.owner = THIS_MODULE,.open  = led_drv_open,.read  = led_drv_read,.write = led_drv_write,.release = led_drv_release,
};/* MISC 设备结构体 */
static struct miscdevice led_miscdev = {.minor = MISCLED_MINOR,
.name = MISCLED_NAME,
.fops = &led_drv,
};static int led_gpio_probe(struct platform_device *pdev)
{int ret =0;printk(KERN_INFO "%s %s line is %d \r\n", __FILE__, __FUNCTION__, __LINE__);led_gpio = gpiod_get(&pdev->dev, "led", 0);if(IS_ERR(led_gpio)){printk(KERN_ERR "gpiod_get is err\r\n");return -1;}ret = misc_register(&led_miscdev);if(ret < 0){printk("misc device register failed!\r\n");return -EFAULT;}return 0;
}
/*面朝大海0902*/
static int led_gpio_remove(struct platform_device *pdev)
{printk(KERN_INFO "%s %s line is %d \r\n", __FILE__, __FUNCTION__, __LINE__);misc_deregister(&led_miscdev);gpiod_put(led_gpio);return 0;
}
static const struct of_device_id my_led[] =
{{.compatible = "my,led_driver"},{},
};static struct platform_driver led_gpio_driver =
{.probe  = led_gpio_probe,.remove = led_gpio_remove,.driver = {.name = "led_gpio",.of_match_table = my_led,},
};static int __init led_init(void)
{int result;printk(KERN_INFO "%s %s line is %d \r\n", __FILE__, __FUNCTION__, __LINE__);result = platform_driver_register(&led_gpio_driver);return result;
}static void __exit led_exit(void)
{printk(KERN_INFO "%s %s line is %d \r\n", __FILE__, __FUNCTION__, __LINE__);platform_driver_unregister(&led_gpio_driver);
}module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
/*面朝大海0902*/

驱动加载并且与设备中的device匹配之后,我们在/dev目录下面看到一个名为"miscled"的设备,主设备号为10,此设备号为145,与我们代码设置的一致。

三、MISC实例测试

编写一个简单的测试程序,write()和read()设备节点,进而触发驱动fops文件操作函数。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>/** ./ledtest /dev/miscled on* ./ledtest /dev/miscled off*/
int main(int argc, char **argv)
{int fd;char status;/* 1. 判断参数 */if (argc != 3) {printf("Usage: %s <dev> <on | off>\n", argv[0]);return -1;}/* 2. 打开文件 */fd = open(argv[1], O_RDWR | O_NONBLOCK);if (fd == -1){printf("can not open file %s\n", argv[1]);return -1;}/* 3. 写文件 */if (0 == strcmp(argv[2], "on")){status = 1;write(fd, &status, 1);}else{status = 0;write(fd, &status, 1);}read(fd, &status, 1);printf("status is %d\n", status);close(fd);return 0;
}

在开发板上进行测试,打印如下:

[root@Joy:/dev]# /mnt/misc_test /dev/miscled on
[ 1133.332943] /home/book/code/test/misc_drv.c led_drv_open line is 27
[ 1133.340139] /home/book/code/test/misc_drv.c led_drv_write line is 46
[ 1133.352154] /home/book/code/test/misc_drv.c led_drv_read line is 36
status is 1
[ 1133.360455] /home/book/code/test/misc_drv.c led_drv_release line is 54[root@Joy:/dev]# /mnt/misc_test /dev/miscled off
[ 1146.420773] /home/book/code/test/misc_drv.c led_drv_open line is 27
[ 1146.428629] /home/book/code/test/misc_drv.c led_drv_write line is 46
[ 1146.436893] /home/book/code/test/misc_drv.c led_drv_read line is 36
status is 0
[ 1146.445773] /home/book/code/test/misc_drv.c led_drv_release line is 54
/*面朝大海0902*/

可以看到fops对应的操作函数得到执行,比起普通的字符设备驱动MISC更加精简一些。
/面朝大海0902/

Linux---MISC杂项驱动相关推荐

  1. platform框架--Linux MISC杂项框架--Linux INPUT子系统框架--串行集成电路总线I2C设备驱动框架--串行外设接口SPI 设备驱动框架---通用异步收发器UART驱动框架

    platform框架 input. pinctrl. gpio 子系统都是 Linux 内核针对某一类设备而创建的框架, input子系统是管理输入的子系统 pinctrl 子系统重点是设置 PIN( ...

  2. 嵌入式linux MISC设备驱动

    misc 的意思是混合.杂项的,因此 MISC 驱动也叫做杂项驱动,也就是当我们板子上的某 些外设无法进行分类的时候就可以使用 MISC 驱动.MISC 驱动其实就是最简单的字符设备驱 动,通常嵌套在 ...

  3. linux MISC设备驱动

    系列文章 I.MX6ULL 手册查找使用方法 实战点亮LED(寄存器版) I.MX6ULL 手册查找使用方法 实战点亮LED(固件库版本) linux 字符设备驱动实战 linux LED设备驱动文件 ...

  4. Linux MISC 驱动实验

    目录 MISC 设备驱动简介 硬件原理图分析 实验程序编写 修改设备树 beep 驱动程序编写 编写测试APP 运行测试 编译驱动程序和测试APP 运行测试 misc 的意思是混合.杂项的,因此MIS ...

  5. linux MISC 驱动模型分析

    linux MISC 驱动模型分析 阅读led驱动程序的代码的时候,没有发现ldd3中提到的各种字符设备注册函数,而是发现了一个misc_register函数,这说明led设备是作为杂项设备出现在内核 ...

  6. linux 杂项设备,浅谈 MISC杂项设备

    在虚拟机的 Ubuntu 系统上,如下图所示,使用命令"cat /proc/misc",可以查看到 PC 机 Ubuntu 系统的杂项设备. 启动开发板,在超级终端中输入命令&qu ...

  7. 韦东山 IMX6ULL和正点原子_正点原子Linux第五十七章Linux MISC驱动实验

    1)资料下载:点击资料即可下载 2)对正点原子Linux感兴趣的同学可以加群讨论:935446741 3)关注正点原子公众号,获取最新资料更新 第五十七章Linux MISC驱动实验 misc的意思是 ...

  8. Linux MISC 驱动实验-基于正点原子IMX6ULL开发板

    misc 的意思是混合.杂项的,因此 MISC 驱动也叫做杂项驱动,也就是当我们板子上的某些外设无法进行分类的时候就可以使用 MISC 驱动.MISC 驱动其实就是最简单的字符设备驱动,通常嵌套在 p ...

  9. Linux 驱动开发 四十六:Linux MISC驱动实验

    misc 的意思是混合.杂项的,因此MISC 驱动也叫做杂项驱动,也就是当我们板子上的某些外设无法进行分类的时候就可以使用 MISC 驱动. MISC 驱动其实就是最简单的字符设备驱动,通常嵌套在 p ...

  10. Misc杂项设备驱动框架

    Misc杂项设备驱动框架 由于设备号比较紧张,所以一些不相关的设备可以使用同一个主设备号,不同的次设备号.主设备号通常是10. 杂项设备结构体 struct miscdevice {int minor ...

最新文章

  1. 求n!中含有质因子p的个数
  2. (JAVA学习笔记) 关于方法的递归-阶乘方法演示
  3. .Net下几种日志管理方法
  4. 南科大计算机系实力a,五大竞赛学科A+高校排行榜发布!北大实力碾压,科大赶超清华...
  5. xshell进入桌面_Xshell怎么远程桌面连接Linux系统
  6. 如果番茄花园在美国...
  7. 装逼神器,5 行 Python 代码 实现一键批量扣图,你get到了吗
  8. 【GYM-100889 D】Dicy Numbers【数学推导求解】
  9. DEM数据如何生成高程点
  10. VMware虚拟机安装WIN7操作系统
  11. 企业海量数据搜索服务器架构图
  12. 微信小程序的在线学习每日签到打卡 项目源码介绍
  13. 上海自来水来自海上,一文掌握这类字符串的验证!
  14. BiliBili视频下载
  15. [必看]身份证复印件的正确用法
  16. 好用的电脑备份软件推荐
  17. ElementUi Carousel 走马灯,自定义el-carousel箭头左右切换
  18. 保姆级给电脑分盘,和合并两个盘
  19. 交叉编译-16:live555交叉编译(Windows和君正平台)
  20. 进程调度算法FCFS和RR

热门文章

  1. cpu渲染测试软件,CPU多核渲染大比拼 Corona 引擎测试
  2. 记录安卓开发工程师的面试题
  3. EmbedRank论文解读
  4. B端产品实战课读书笔记05:第四章需求调研
  5. matlab 图像 高通滤波器,基于matlab数字图像处理之高通滤波器
  6. 1、脑电基本原理及其经典成分
  7. android基于gpuimage和photoview的图片编辑(滤镜,饱和度,裁剪)
  8. openwrt 使用ipv6上网
  9. TapTap玩家评论——从爬虫到情感分析:APP爬虫、数据清洗、Pyecharts可视化、Word2Vec建模、LSTM建模
  10. 中睿天下Coremail联合发布《2022年第三季度企业邮箱安全报告》