没有合适的资源?快使用搜索试试~ 我知道了~
1.当驱动程序需要给定主设备号时,使用函数来注册设备号: 2.驱动程序不需要指定主设备号时,使用函数: 3.注销设备号只要使用同一个函数: 1. /* 字符设备
资源详情
资源评论
资源推荐
2 字符设备的新写法
2.1 设备号管理
在上一章中的实验中,设备号直接在驱动代码中写死了。这样做会带来很多麻烦:
①编译驱动代码前,必须要先查看目标系统中设备号的占用情况;
②更换设备后原先驱动中写死的设备号就可能已被占用;
③原先的驱动注册函数 register_chrdev()输入参数中仅有主设备号而没有次设备号,这
意味着一个设备就会占用所有的次设备号,十分浪费。
针对这些问题,Linux 内核提出了新的字符设备注册方法,并由内核来管理设备号。新
增两个设备号注册函数。
1.当驱动程序需要给定主设备号时,使用函数来注册设备号:
int register_chrdev_region(dev_t from, unsigned count, const char *name)
输入参数说明:
from:需要申请的起始设备号,dev_t 类型,它取代了原先的主设备号和次设备号,在
需要指定主次设备号的情况下,可以通过方法 from=MKDEV(major, minor);来获取他的值。
count:需要申请设备号的个数,一般只要申请一个。
name:设备名。
示例:
1. int major = 200; //主设备号指定为 200
2. int minor = 0; //次设备号为 0
3. dev_t devid = MKDEV(major, minor); //通过主次设备号获得设备号
4. /* 向内核注册设备号 */
5. register_chrdev_region(devid, 1, "xxx-dev");
2.驱动程序不需要指定主设备号时,使用函数:
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char
*name)
输入参数说明:
dev:设备号指针,不指定主次设备号的情况下,设备号由内核分配,因此传入指针来
获取设备号,注册成功后可以通过方法 major = MAJOR(*dev); 和 minor = MINOR(*dev);分别
获取主次设备号,如果不需要用到主次设备号,不获取也可以。
baseminor:次设备号起始地址。
count:需要申请设备号的个数,一般只要申请一个。
name:设备名。
示例:
1. dev_t devid; //设备号
2. /* 申请设备号 */
3. alloc_chrdev_region(&devid, 0, 1, "xxx-dev");
3.注销设备号只要使用同一个函数:
void unregister_chrdev_region(dev_t from, unsigned count)
输入参数含义以注册函数一致。
示例:
1. dev_t devid; //设备号
2. /* 申请设备号 */
3. alloc_chrdev_region(&devid, 0, 1, " xxx-dev");
4. /* 注销设备号 */
5. unregister_chrdev_region(devid, 1);
2.2 新的注册方法
上面提到过注册函数 register_chrdev()存在问题。和新的设备号管理方式相对应,现在
摒弃 register_chrdev(),使用一套新的方法来来注册字符设备。
2.2.1 字符设备数据结构
使用 cdev 结构体来定来定义一个字符设备,他定义在 include/linux/cdev.h 中,具体如
下:
1. struct cdev {
2. struct kobject kobj;
3. struct module *owner;
4. const struct file_operations *ops;
5. struct list_head list;
6. dev_t dev;
7. unsigned int count;
8. };
重要成员变量:
owner:一般设置为 THIS_MODULE;
ops:设备操作函数指针;
dev:设备号。
2.2.2 cdev 结构体初始化
cdev 结构体变量定义后需要用 cdev_init()函数初始化,函数原型为:
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
cdev:字符设备结构体指针;
fops:设备操作函数集合结构体指针。
使用示例:
1. /* 字符设备 */
2. struct cdev ax_cdev = {
3. .owner = THIS_MODULE,
4. };
5.
6. /* 设备操作函数 */
7. static struct file_operations ax_fops = {
8. .owner = THIS_MODULE,
9. .open……
10. };
11.
12. /* ax_cdev 变量初始化 */
13. cdev_init(&ax_cdev, &ax_fops);
2.2.3 新的注册和注销函数
初始化字符结构体变量后,便可以使用这个变量来向 Linux 系统注册字符设备。使用新
的注册函数 cdev_add,原型为:
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
p:上面初始化后的字符设备结构体变量;
dev:设备号;
count:需要添加的设备数量。
注册函数变了,注销卸载函数也一样,不再使用 unregister_chrdev()函数,改用 cdev_del()
函数,原型:
void cdev_del(struct cdev *p)
输入参数即为字符设备结构体变量。
结合上设备号,补充一下 2.2.2 中的示例:
1. /* 字符设备 */
2. struct cdev ax_cdev = {
3. .owner = THIS_MODULE,
4. };
5.
6. /* 设备操作函数 */
7. static struct file_operations ax_fops = {
8. .owner = THIS_MODULE,
9. .open……
10. };
11.
12. /* 设备号 */
13. cdev_t devid;
14. /* 申请设备号 */
15. alloc_chrdev_region(&devid, 0, 1, " xxx-dev");
16.
剩余11页未读,继续阅读
Friday永不为奴
- 粉丝: 12
- 资源: 317
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 西安市地铁预测数据西安市地铁预测数据西安市地铁预测数据
- 测绘专业的 水准网平差算例 用基于MATLAB语言实现的.rar
- 基于matlab的水准网平差程序基于matlab的水准网平差程序
- 基于matlab实现的,实现分布式电源接入对配电网电压,网损影响仿真,并以IEEE33节点为例说明 代码可直接运行.rar
- 解决HC32F460的PC14输出电平异常问题
- 基于matlab实现的PCB缺陷检测 印刷电路预处理 印刷电路图像的配准 缺陷的识别与判断.rar
- 基于matlab实现的本程序是基于机器视觉的零件缺陷检测,主要是对热轧钢缺陷的检测.rar
- 基于matlab实现的编写的水准平差,还有一个实例.rar
- 基于matlab实现的编写的水准网平差程序,由测量数据可计算水准网平差结果,得到不错的水准网数据.rar
- 呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0