Linux MISC杂项设备驱动
前言:
misc的意思是混合的杂项的,所以misc设备驱动也叫做杂项设备驱动,当开发板上某个设备没有办法分类的时候,就可以使用misc设备驱动。他的注册和使用比较简单,所以比较适用于功能简单的设备。所以它通常嵌套在 platform 总线驱动中,配合总线驱动达 到更复杂,多功能的效果。杂项设备是字符设备的一种,杂项设备可以自动生成设备节点。
回顾几个概念:
1、设备结点:
进入内核的dev目录下,如图所示:
系统里也有很多杂项设备:cat /proc/misc
2、杂项设备的优点
杂项设备比字符设备编写简单,所有的misc设备驱动的主设备号都是10,不同的设备使用不同的从设备号。主设备号相同就可以节省内核资源,子啊内核中大概可以找到两百多处使用miscdevice框架的驱动。
3、主设备号和次设备号的概念
设备号包含主设备号和次设备号,设备号是计算机识别设备的一种方式,主设备号相同就被视作同一类设备,主设备号在Linux系统里面是唯一的,次设备号是不是唯一的。
主设备号可以使用"cat /proc/devices"进行查看
上图中对应的紫色数字就是每个设备的主设备号,可以看到misc的主设备号是10 。
misc 设备用miscdevicea结构体进行表示,miscdevice结构体的定义在内核源码中的具体定义在include/linux/miscdevice.h 中,
struct miscdevice {
int minor; //次设备号
const char *name; //设备结点名字
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设备的miscdevice结构体的时候,需要我们指定minor,name和fops这个三个成员变量。当minor表示次设备号需要用户设备,在Linux啮合中有些预定义misc设备的次设备号,定义在include/linux/miscdevice.h 文件中。
我们设备子设备的时候要注意不要重复使用其他子设备的设备号。可以从这些预定义中选择一个也可以自己定义,name就是misc设备的名字,在设备注册成功的时候会在/dev目录下自动生成一根名为name的设备文件。fops就是这个misc设备的操作集合。
注册杂项设备的通用思路和方法:
1、创建驱动文件出入口函数,规则等
2、填充miscdevice这个结构体
3、填充file_operations这个结构体
4、注册杂项设备并生成设备结构点
实验测试
使用misc设备驱动编写最简单的杂项设备的驱动。
编写驱动程序示例:
创建驱动程序结构:
添加头文件:
填充 miscdevice 结构体
上述代码第二行的minor为MISC_DYNAMIC_MINOR,miscdevice核心层会自动找一个空闲的次设备号,否则用minor指定次设备号。第三行的name是要在dev目录下边显示出来的字符。
填充file_openration结构体
全部代码:
#include <linux/init.h>
#include <linux/module.h>
/*注册杂项设备头文件*/
#include <linux/miscdevice.h>
/*注册设备节点的文件结构体*/
#include <linux/fs.h>
struct miscdevice misc_dev =
{
.minor = MISC_DYNAMIC_MINOR,
.name = "misc_test",
.fops = &misc_fops,
};
struct file_operations misc_fops={
.owner = THIS_MODULE
};
static int misc_init(void)
{
int ret ;
ret = misc_register(&misc_dev);//注册杂项设备
if(ret<0)
printk("misc register error \n");
printk("misc registe is succeed \n");
return 0;
}
static void misc_exit(void)
{
misc_deregister(&misc_dev);//注销杂项设备
printk("misc byb \n");;
}
module_init(misc_init);
module_exit(misc_exit);
MODULE_LICENSE("GPL");
编译安装测试(据不同开发板情况来定)
运行测试如果dev目录下有"misc_test"则说明注册成功