1. 介绍
考虑到字符设备驱动编写过程中 init 函数要完成申请主设备号、创建一个类、创建设备节点,还有 exit 函数中做相反的操作的繁琐步骤,使用混杂设备来替代是个很好的选择。
混杂设备,之所以叫混杂设备就是为了将杂乱的设备包含进来,可以是 普通的字符设备,也可以是 i2c设备,还可以是 lcd 设备。混杂设备共享一个主设备号 10,根据次设备号的不同,对应不同的 file_operation 结构体,混杂设备的 API 在 driver/char/misc.c 中。混杂设备的本质依然是字符设备。
2. 函数和结构体
表征一个混杂设备的结构体 miscdevice
struct miscdevice {
int minor;
const char *name;
const struct file_operations *fops;
struct list_head list;
struct device *parent;
struct device *this_device;
};
其中 minor (次设备号)如果是MISC_DYNAMIC_MINOR 这个宏,表示次设备号由系统自动分配。
混杂设备的 API
int misc_register(struct miscdevice * misc);
int misc_deregister(struct miscdevice *misc);
3. 使用
顺着按键驱动的脉络,我们用混杂设备来修改 platform 架构的按键驱动,那篇文章的地址:
http://blog.youkuaiyun.com/qqliyunpeng/article/details/52873411
具体要做的更改如下:
diff -u .. ..
--- /home/zyl/wor_lip/test/embedded/key_platform/dri/key_dri.c2016-10-20 15:18:03.924439170 +0800
+++ key_dri.c2016-10-20 17:06:55.015790780 +0800
@@ -18,6 +18,7 @@
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/platform_device.h>
+#include <linux/miscdevice.h>
#define DEVICE_NAME "jz2440_button_drv"
@@ -45,9 +46,6 @@
struct jz2440_key_t *key_tablep;
struct jz2440_key_platform *key_platformp;
-static struct class *button_drv_class;
-int major;
-
unsigned int key_pressed;
unsigned int key_pressed_middle_flag;
@@ -203,25 +201,17 @@
.poll = jz2440_button_drv_poll,
};
+struct miscdevice button_misc = {
+ .minor = 0,
+ .name = DEVICE_NAME,
+ .fops = &button_drv_fops,
+};
+
int button_drv_init(void)
{
platform_driver_register(&jz2440_key_dri);
- /* auto choice major */
- major = register_chrdev(0, DEVICE_NAME, &button_drv_fops);
- if (major < 0)
- {
- printk("jz2440 button driver can't register major number!\n");
- return major;
- }
-
- button_drv_class = class_create(THIS_MODULE, DEVICE_NAME);
- if (IS_ERR(button_drv_class))
- {
- printk("error, fail to init button_drv_class");
- return -1;
- }
- device_create(button_drv_class, NULL, MKDEV(major, 0), NULL, DEVICE_NAME);
+ misc_register(&button_misc);
printk("BUTTON_DRV initialized! \n");
@@ -232,10 +222,7 @@
{
platform_driver_unregister(&jz2440_key_dri);
- device_destroy(button_drv_class, MKDEV(major, 0)); //删掉设备节点
- class_destroy(button_drv_class); //注销类
-
- unregister_chrdev(major, DEVICE_NAME); //卸载驱动
+ misc_deregister(&button_misc);
printk("exit is finished.\n");
}
看看是不是减少了很多的代码呀!。