您当前的位置: 首页 >  驱动开发

耐心的小黑

暂无认证

  • 2浏览

    0关注

    323博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

linux驱动开发学习笔记二十二:MISC驱动

耐心的小黑 发布时间:2020-05-10 14:23:51 ,浏览量:2

一、简介

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

所有的 MISC 设备驱动的主设备号都为 10,不同的设备使用不同的从设备号。随着 Linux字符设备驱动的不断增加,设备号变得越来越紧张,尤其是主设备号,MISC 设备驱动就用于解决此问题。MISC 设备会自动创建 cdev,不需要像我们以前那样手动创建,因此采用MISC 设备驱动可以简化字符设备驱动的编写。我们需要向 Linux 注册一个 miscdevice 设备,miscdevice是一个结构体,定义在文件 include/linux/miscdevice.h 中,内容如下:

57 struct miscdevice {
58 		int minor; /* 子设备号 */
59 		const char *name; /* 设备名字 */ 
60 		const struct file_operations *fops; /* 设备操作集 */
61 		struct list_head list;
62 		struct device *parent;
63 		struct device *this_device;
64 		const struct attribute_group **groups;
65 		const char *nodename;
66 		umode_t mode;
67 };

定义一个 MISC 设备(miscdevice 类型)以后我们需要设置 minor、name 和 fops 这三个成员变量。

  • minor 表示子设备号,MISC 设备的主设备号为 10,这个是固定的,需要用户指定子设备号,Linux 系统已经预定义了一些 MISC 设备的子设备号,这些预定义的子设备号定义在include/linux/miscdevice.h 文件中,如下所示:
13 #define PSMOUSE_MINOR 1
14 #define MS_BUSMOUSE_MINOR 2 /* unused */
15 #define ATIXL_BUSMOUSE_MINOR 3 /* unused */
16 /*#define AMIGAMOUSE_MINOR 4 FIXME OBSOLETE */
17 #define ATARIMOUSE_MINOR 5 /* unused */
18 #define SUN_MOUSE_MINOR 6 /* unused */
......
52 #define MISC_DYNAMIC_MINOR 255

我们在使用的时候可以从这些预定义的子设备号中挑选一个,当然也可以自己定义,只要这个子设备号没有被其他设备使用接口。

  • name 就是此 MISC 设备名字,当此设备注册成功以后就会在/dev 目录下生成一个名为 name的设备文件。

  • fops 就是字符设备的操作集合,MISC 设备驱动最终是需要使用用户提供的 fops操作集合。

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

函数参数和返回值含义如下: misc:要注册的 MISC 设备。 返回值:负数,失败;0,成功。

以前我们需要自己调用一堆的函数去创建设备,现在我们可以直接使用 misc_register 一个函数来完成这些步骤。

  • 当我们卸载设备驱动模块的时候需要调用 misc_deregister 函数来注销掉 MISC 设备,函数原型如下:
int misc_deregister(struct miscdevice *misc)

函数参数和返回值含义如下: misc:要注销的 MISC 设备。 返回值:负数,失败;0,成功。

三、实例(伪代码)
29 #define MISCBEEP_NAME "miscbeep" /* 名字 */
30 #define MISCBEEP_MINOR 144 /* 子设备号 */
31 #define BEEPOFF 0 /* 关蜂鸣器 */
32 #define BEEPON 1 /* 开蜂鸣器 */
33 
34 /* miscbeep 设备结构体 */
35 struct miscbeep_dev{
36 		dev_t devid; /* 设备号 */
37 		struct cdev cdev; /* cdev */
38 		struct class *class; /* 类 */
39 		struct device *device; /* 设备 */
40 		struct device_node *nd; /* 设备节点 */
41 		int beep_gpio; /* beep 所使用的 GPIO 编号 */
42 };
43
44 struct miscbeep_dev miscbeep; /* beep 设备 */

53 static int miscbeep_open(struct inode *inode, struct file *filp)
54 {
55     ..............
56 		return 0;
57 }
 static ssize_t miscbeep_write(struct file *filp,
                               const char __user *buf, 
                               size_t cnt, loff_t *offt)
{
      ....................
      return 0;
}
89 /* 设备操作函数 */
90 static struct file_operations miscbeep_fops = {
91 		.owner = THIS_MODULE,
92 		.open = miscbeep_open,
93 		.write = miscbeep_write,
94 };
95 
96 /* MISC 设备结构体 */
97 static struct miscdevice beep_miscdev = {
98 		.minor = MISCBEEP_MINOR,
99 		.name = MISCBEEP_NAME,
100 	.fops = &miscbeep_fops,
101 };
109 static int miscbeep_probe(struct platform_device *dev)
110 {
       /*
       获取设备节点
       获取节点中的某个属性
       等等一些操作
       */
       ................
135 /* 一般情况下会注册对应的字符设备,但是这里我们使用 MISC 设备
136 * 所以我们不需要自己注册字符设备驱动,只需要注册 misc 设备驱动即可
137 */
138 		ret = misc_register(&beep_miscdev);
139 		if(ret             
关注
打赏
1640088279
查看更多评论
0.0441s