标签:
20150226 IMX257 混杂设备miscdevice驱动程序
2015-02-26 16:00 李海沿
在Linux驱动中把无法归类的五花八门的设备定义为混杂设备(用miscdevice结构体表述)。miscdevice共享一个主设备号MISC_MAJOR(即10),但次设备号不同。 所有的miscdevice设备形成了一个链表,对设备访问时内核根据次设备号查找对应的miscdevice设备,然后调用其file_operations结构中注册的文件操作接口进行操作。 在内核中用struct miscdevice表示miscdevice设备,然后调用其file_operations结构中注册的文件操作接口进行操作。miscdevice的API实现在drivers/char/misc.c中。
一、混杂设备介绍
1. miscdevice结构体
struct miscdevice { int minor; //次设备号 const char *name; //设备的名称 const struct file_operations *fops; //文件操作 struct list_head list; //misc_list的链表头 struct device *parent; //父设备(Linux设备模型中的东东了,哈哈) struct device *this_device; //当前设备,是device_create的返回值,下边会看到 }; |
2. misc子系统初始化函数
|
下边是register_chrdev函数的实现:
|
来看看这个设备的操作函数的集合:
|
可以看到这里只有一个打开函数,用户打开miscdevice设备是通过主设备号对应的打开函数,在这个函数中找到次设备号对应的相应的具体设备的open函数。它的实现如下:
|
3. misc子注册函数
并且会自动生成设备节点
|
misc_register:
匹配次设备号->找到一个没有占用的次设备号(如果需要动态分配的话)->计算设号->创建设备文-
miscdevice结构体添加到misc_list链表中。
4. misc子卸载函数
|
misc_deregister:
从mist_list中删除miscdevice->删除设备文件->位图位清零。
二、代码分析
1. 包含头文件:
#include <linux/miscdevice.h>
2. 定义混杂设备结构体以及实现相关的file_operation函数
3. 最后分别在init函数和exit函数中卸载
4. 编译测试
我们使用 ll /dev/key_misc 查看 其 设备的详细信息 可以发现其主设备号为10 次设备号110
然后 cat /proc/misc 查看当前混杂设备列表,发现我们的key_misc 110 当然还设有gpio dma等都使用混杂设备
本文部分知识点摘自 http://tomhibolu.iteye.com/blog/1214940
附驱动程序代码:
1 /****************************** 2 misc device 3 *****************************/ 4 #include <linux/module.h> 5 #include <linux/init.h> 6 #include <linux/kernel.h> 7 #include <linux/delay.h> 8 #include <linux/types.h> 9 #include <linux/ioctl.h> 10 #include <linux/gpio.h> 11 #include <linux/fs.h> 12 #include <linux/device.h> 13 #include <linux/miscdevice.h> 14 15 #define Driver_NAME "key_misc" 16 #define Driver_minor 110 17 18 /* 应用程序对设备文件/dev/key_query执行open(...)时, 19 * 就会调用key_open函数*/ 20 static int key_open(struct inode *inode, struct file *file){ 21 printk("<0>function open!\n"); 22 return 0; 23 } 24 static int key_read(struct file *filp, char __user *buff, size_t count, loff_t *offp){ 25 printk("<0>function read!\n"); 26 return 0; 27 } 28 static ssize_t key_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos){ 29 printk("<0>function write!\n"); 30 return 1; 31 } 32 33 /* 这个结构是字符设备驱动程序的核心 34 * 当应用程序操作设备文件时所调用的open、read、write等函数, 35 * 最终会调用这个结构中指定的对应函数 36 */ 37 static struct file_operations key_fops = { 38 .owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */ 39 .open = key_open, 40 .read = key_read, 41 .write = key_write, 42 }; 43 44 /*混杂设备结构体*/ 45 static struct miscdevice key_misc = { 46 .minor = Driver_minor, //次设备号 47 .name = Driver_NAME, //混杂设备名字 48 .fops = &key_fops, //操作指针 49 }; 50 51 /* 52 * 执行insmod命令时就会调用这个函数 53 */ 54 static int __init key_init(void) 55 { 56 printk("<0>\nHello,this is %s module!\n\n",Driver_NAME); 57 58 misc_register(&key_misc); 59 return 0; 60 } 61 62 /* 63 * 执行rmmod命令时就会调用这个函数 64 */ 65 static void __exit key_exit(void) 66 { 67 printk("<0>\nGoodbye,%s!\n\n",Driver_NAME); 68 69 misc_register(&key_misc); 70 } 71 72 /* 这两行指定驱动程序的初始化函数和卸载函数 */ 73 module_init(key_init); 74 module_exit(key_exit); 75 76 /* 描述驱动程序的一些信息,不是必须的 */ 77 MODULE_AUTHOR("Lover雪"); 78 MODULE_VERSION("0.1.0"); 79 MODULE_DESCRIPTION("IMX257 key Driver"); 80 MODULE_LICENSE("GPL");
20150226 IMX257 混杂设备miscdevice驱动程序
标签:
原文地址:http://www.cnblogs.com/lihaiyan/p/4301579.html