欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 美景 > 十四、(正点原子)Linux MISC驱动

十四、(正点原子)Linux MISC驱动

2024/10/24 11:12:25 来源:https://blog.csdn.net/Tofu_Cabbage/article/details/140474333  浏览:    关键词:十四、(正点原子)Linux MISC驱动

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

一、MISC设备驱动

        随着 Linux字符设备驱动的不断增加,设备号变得越来越紧张,尤其是主设备号。所以在MISC驱动中所有的 MISC 设备驱动的主设备号都为 10,不同的设备使用不同的从设备号。
        MISC 设备会自动创建 cdev,不需要像我们以前那样手动创建,因此采用 MISC 设备驱动可以简化字符设备驱动的编写。

        在MISC中,使用struct miscdevice结构体来表示一个设备,我们需要向 Linux 注册一个 struct miscdevice 设备,内容如下:

定义在文件 include/linux/miscdevice.h 中struct miscdevice  {int minor;                             /* 次设备号 */const char *name;                      /* MISC设备名字 */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;
};

         定义一个 MISC 设备(struct miscdevice 类型)以后我们需要设置 minorname fops 这三个成员变量。 minor 表示子设备号, MISC 设备的主设备号为 10,这个是固定的,需要用户指定子设备号, Linux 系统已经预定义了一些 MISC 设备的子设备号,这些预定义的子设备号如下所示:

定义在include/linux/miscdevice.h 文件中#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 MISC_DYNAMIC_MINOR	    255    /* 动态自己分配 */

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

        name 就是此 MISC 设备名字,当此设备注册成功以后就会在/dev 目录下生成一个名为 name的设备文件。 fops 就是字符设备的操作集合, MISC 设备驱动最终是需要使用用户提供的 fops操作集合。

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

定义在include/linux/miscdevice.h 文件中extern int misc_register(struct miscdevice *misc);

        misc:要注册的MISC设备。 

        返回值:负数,失败;0,成功。

        以前创建字符设备时,需要调用一堆的函数去注册设备号,初始化字符设备,添加字符设备等等步骤如下所示:

传统的创建设备过程alloc_chrdev_region();       /* 申请设备号 */
cdev_init();                 /* 初始化 cdev */
cdev_add();                  /* 添加 cdev */
class_create();              /* 创建类 */
device_create();             /* 创建设备 */

        但是在MISC设备驱动中,其实也是一个字符设备,使用misc_register 函数就能够自动完成以前字符设备创建的功能。同理,在注销字符设备时候我们也需要调用一堆函数将前面创建的一些结构体给释放掉比如:


/* 注销设备号 */
unregister_chrdev_region(dtsled.devid, DTSLED_CNT);/* 注销LED字符设备 */
cdev_del(&dtsled.cdev);/* 删除设备 */
device_destroy(dtsled.class, dtsled.devid);/* 删除类 */
class_destroy(dtsled.class);

        当我们使用的时MISC设备时,就只需要调用 misc_deregister 函数就可以注销设备驱动,函数原型如下:

定义在include/linux/miscdevice.h 文件中extern int misc_deregister(struct miscdevice *misc);

        misc:要注销的MISC设备。

        返回值:负数,失败;0,成功。

二、MISC设备驱动示例代码

        


/* 设备操作函数 */
struct file_operations xxx_fops = {.owner = THIS_MODULE,
};/* MISC 设备结构体 */
struct miscdevice xxx_miscdev = {.minor = 255,    /* 前面有定义 */.name = "xxx",.fops = &xxx_fops,
};/* flatform 驱动的 probe 函数,当驱动与设备匹配以后此函数就会执行 */
int xxx_probe(struct platform_device *dev)
{。。。。misc_register(&xxx_miscdev);return 0;
}/* remove函数,移除 platform 驱动的时候此函数会执行 */
int xxx_remove(struct platform_device *dev)
{。。。/* 注销 misc 设备驱动 */misc_deregister(&xxx_miscdev);return 0;
}/* 匹配列表 */
const struct of_device_id beep_of_match[] = {{ .compatible = "xxx" },     /* 要与设备树的compatible属性一致 */{ /* Sentinel */ }
};/* 驱动设备结构体 */
struct platform_driver xxx_driver = {.driver = {.name = "xxx",                  /* 驱动名字 */.of_match_table = xxx_of_match,  /* 设备树匹配表 */},.probe = xxx_probe,.remove = xxx_remove,};/* 驱动入口函数 */
static int __init xxx_init(void)
{return platform_driver_register(&xxx_driver);
}/* 驱动出口函数 */
static void __exit xxx_exit(void)
{platform_driver_unregister(&xxx_driver);
}module_init(xxx_init);
module_exit(xxx_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhangxueguo");

        当我们驱动加载成功后,在/sys/class/misc这个目录下可以看到一个struct platform_driver->driver->name名字的设备,如果MISC设备与驱动像匹配以后,就会在dev/下生成的一个struct miscdevice->name设备驱动文件。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com