目录
查看杂项设备驱动
系统有很多杂项设备,输入命令 cat /proc/misc 就可以查看到杂项设备驱动
杂项设备于字符设备的区别
- 杂项设备驱动属于字符设备的一种,可以自动生成设备节点
- 设备节点是指dev目录下的文件
- 杂项设备的主设备号是相同的,均为10,次设备号是不同的。主设备号相同就可以节省内核的资源
- 设备号,主要是计算机识别的一种方式,主设备号相同就被视为同一类的设备
- 主设备号,在linux系统中唯一,类似于手机的区号,都属于一个区域的
- 输入 cat /proc/devices 可以查看主设备号
- 次设备号,在linux系统中不唯一,类似于手机号码,区分个人
- 主设备号,在linux系统中唯一,类似于手机的区号,都属于一个区域的
- 设备号,主要是计算机识别的一种方式,主设备号相同就被视为同一类的设备
杂项设备相关结构体
miscdevice
可以在根目录下的include/linux/miscdevice.h中定义,这个结构体作用是描述这个设备
struct miscdevice{
int minor; //次设备号
const char *name; //设备节点的名字,也就是dev中的名字
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_DYNAMIC_MINOR,也在 miscdevice.h中,他会自动分配次设备号
file_operations
可以在根目录下的include/linux/fs.h中定义
里面有一个结构体成员都对应一个调用,后面会仔细讲,现在只用知道当对驱动进行读取read时,就会调用这个结构体中的read成员
注册/注销杂项设备
可以在根目录下的include/linux/fs.h中定义
extern int misc_register(struct miscdevice *misc);//注册
extern int misc_deregister(struct miscdevice *misc);//注销
注册杂项设备流程
- 填充描述结构体miscdevice,一般只需要填充前三个成员
- 填充文件操作集file_operations
- 向内核注册杂项设备并生成设备节点
模板
struct const file_operation xx_fops= {
.Owner = THIS_MODULE
......
};
struct miscdevice xx_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name ="xxx",
.fops =xx_fops
};
static int xxx_init()
{
int ret;
ret=misc_register(&xx_dev);
if(ret<0)
{
printk("misc register error\n");
return -1;
}
return 0;
}
void xxx_exit()
{
misc_deregister(&xx_dev);
}
- 填充xx_dev描述结构体,次设备号为宏定义,作用是自动分配,并配置设备节点的名称和文件操作集
- 填充文件操作集file_operations,只实现一个简单的成员
- xxx_init函数为入口,当驱动加载的时候就会调用这个函数,在函数中注册了杂项设备,判断其返回值,
- xxx_exit函数为出口,当驱动卸载的时候就会调用这个函数
实战 编写一个杂项设备驱动
- 新建一个misc.c文件
#include <linux/init.h> #include <linux/module.h> #include <linux/miscdevice.h> #include <linux/fs.h> struct const file_operation misc_fops = { .owner = THIS_MODULE }; struct miscdevice misc_dev = { .minor = MISC_DYNAMIC_MINOR,//动态分配 .name ="hellomisc",//设备节点名字 .fops =&misc_fops }; static int misc_init(void) { int ret; ret = misc_register(&misc_dev); if(ret<0) { printk("misc registe is error\n"); return -1; } printk("misc registe is success\n"); return 0; } static void misc_exit(void) { misc_deregister(&misc_dev); printk("misc goodbye"); } module_init(misc_init); module_exit(misc_exit); MODULE_LICENSE("GPL");
- 新建一个Makefile
obj-m +=misc.o KDIR:=自己的linux内核源码根目录路径 PWD?=$(shell pwd) all: make -C $(KDIR) M=$(PWD) modules
- 将上面两个文件放入一个hellomisc文件夹中
- 配置环境arm和交叉编译链
- 然后make编译出ko模块
- 将ko模块放到开发板上
- 加载ko模块,insmod misc.ko,就会打印misc registe is success
- 然后输入命令 ls /dev/h,会列出 /dev/hellomisc
- 然后卸载,rmnod misc,再输入ls /dev/h就消失了