本文主要是介绍Linux内核驱动字符设备-linux 2.6设备驱动模型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
和misc杂项设备以及早期经典设备模型比较,有如下的特征:
1. 安装后, 不会自动创建/dev/设备文件节点, 需要手动使用 mknod 命令创建。可以使用设备类的方法自动创建设备节点。
2. 调用一个 cdev_add 注册后, 指定数量的次号被占用完了。 数量可以自己指定,一个主设备可以使用
cdev_add 函数注册多次。
3. 设备号使用前需要先申请: register_chrdev_region--静态分配,或 alloc_chrdev_region--动态分配设备号
函数申请。
设备模型的核心结构:
struct cdev {struct kobject kobj;struct module *owner;const struct file_operations *ops; /* 设备文件操作方法 */struct list_head list;dev_t dev; /* 32 位设备号:包含主和次 */unsigned int count; /*占用多少个连续的次设备号 */
};
ops: 文件操作方法指针
dev: 起始设备号(包含主设备号和次设备号), dev_t 实际上是一个 u32 类型
count: 本设备要占用次设备号的数量(连续的), 从 dev 中的的次设备号开始。
编写一个linux2.6字符设备的驱动步骤:
模块的初始化函数:
1. 申请设备号
2. 分配 cdev 结构空间
3. 初始化 cdev 结构
4. 注册已经初始化好的 cdev 结构
模块卸载函数:
1. 注销 cdev 结构
2. 释放 cdev 结构空间
3. 释放设备号
设备号:
使用 dev_t 来表示一个设备号, dev_t 实际上是一个 u32 类型。 其中高 12 位是主设备号,低 20 位是次
设备号。
主设备号: dev_t 高 12 位, 2^12=4K (10 是给杂项设备使用)
次设备号: dev_t 低 20 位, 2^20=1M
合成设备号:
MKDEV(ma,mi): ma: 主设备号; mi: 次设备号
分解设备号:
MAJOR(dev) :从设备号 dev 中分解出主设备号
MINOR(dev) :从设备号 dev 中分解出次设备号
内核中定义:
#define MINORBITS20
#define MINORMASK ((1U << MINORBITS) - 1)
#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))
设备号注册函数:
静态设备号注册函数:
int register_chrdev_region(dev_t from, /* 起始设备号(主、次)*/
unsigned count, /* 连续的次设备号数量*/
const char *name) /* 设备名,不需要和/dev/的设备文件名相同*/
头文件: #include <linux/fs.h>
功能: 注册一个设备号范围
参数: from: 起始设备号(主、次)
count: 连续的次设备号数量
name: 设备名,不需要和/dev/的设备文件名相同
返回值: 0:成功;失败:返回负数
动态设备号注册函数:
这篇关于Linux内核驱动字符设备-linux 2.6设备驱动模型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!