杂项设备也是在嵌入式系统中用嘚比较多的一种设备驱动在 Linux 内核的include/linux目录下有Miscdevice.h文件,要把自己定义的misc device从设备定义在这里其实是因为这些字符设备不符合预先确定的字符設备范畴,所有这些设备采用主编号10 一起归于misc
也就是说,misc设备其实也就是特殊的字符设备可自动生成设备节点。
使用register_chrdev(LED_MAJOR,DEVICE_NAME,&dev_fops)注册字符设备驱動程序时如果有多个设 备使用该函数注册驱动程序,LED_MAJOR不能相同否则几个设备都无法注册(我已验证)。如果模块使用该方式注册并且 LED_MAJOR为0(自動分配主设备号 )使用insmod命令加载模块时会在终端显示分配的主设备号和次设备号,在/dev目录下建立该节点比如 设备leds,如果加载该模块时分配的主设备号和次设备号为253和0则建立节点:mknod leds c 253
阅读led驱动程序的代码的时候,没有发现ldd3中提到的各种字符设备注册函数而是发现了一个misc_register函数,这说明led设备是作为杂项设备出现在内核中的在内核中,misc杂项设备驱动接口是对一些字符设备的简单封装他们共享一个主设备号,有鈈同的次设备号共享一个open调用,其他的操作函数在打开后运用linux驱动程序的方法重载进行装载
这个结构体是misc设备基本的结构体,在注册misc設备的时候必须要声明并初始化一个这样的结构体但其中一般只需填充name minor fops字段就可以了。下面就是led驱动程序中初始化miscdevice的代码:
misc也是作为一個模块被加载到内核的只不过是静态模块。这个函数是misc静态模块加载时的初始化函数//udev创建设备节点使用
可以看出,这个初始化函数朂主要的功能就是注册字符设备 ,所用的注册接口是2.4内核的register_chrdev它注册了主设备号为MISC_MAJOR,次设备号为0-255的256个设备并且创建了一个misc类。
可以看出这个函数首先遍历misc_list链表,查找所用的次设备号是否已经被注册防止冲突。如果是动态次设备号则分配一个然后调用MKDEV生成设备号,从这里可以看出所有的misc设备共享一个主设备号MISC_MAJOR,然后调用device_create生荿设备文件。最后加入到misc_list链表中
关于device_create,class_create 作用: class_create函数在misc.c中的模块初始化中被调用现在一起说一下。这两个函数看起来很陌生没有在ldd3中發现过,看源代码的时候发现class_create会调用底层组件__class_regsiter()是说明它是注册一个类而device_create是创建一个设备,他是创建设备的便捷实现调用了device_register函数他们都提供给linux设备模型使用,从linux内核2.6的某个版本之后devfs不复存在,udev成为devfs的替代相比devfs,udev有很多优势
这样就创建了一个类和设备,模块被加载时udev daemon就会自动在/dev下创建my_device设备文件节点。这样就省去了自己创建设备文件的麻烦这样也有助于动态设备的管理。
杂项设备作为字符设备的封裝为字符设备提供的简单的编程接口,如果编写新的字符驱动可以考虑使用杂项设备接口,方便简单只需要初始化一个miscdevice的结构,调鼡misc_register就可以了系统最多有255个杂项设备,因为杂项设备模块自己占用了一个次设备号可以发现,mini2440很多字符设备都是以杂项设备注册到内核嘚如mini2440_buttons,mini2440_adc,mini2440_pwm等。