新字符设备驱动实验

之前是老设备驱动,现在我们要用新字符驱动,据说更好更方便

新字符设备驱动原理

分配和释放设备号
如果没有指定设备号的话就使用如下函数来申请设备号:
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)
如果给定了设备的主设备号和次设备号就使用如下所示函数来注册设备号即可:
int register_chrdev_region(dev_t from, unsigned count, const char *name)
注销字符设备 之 后 要 释 放 掉 设 备 号 , 不 管 是 通 过 alloc_chrdev_region 函数还是
register_chrdev_region 函数申请的设备号,统一使用如下释放函数:
void unregister_chrdev_region(dev_t from, unsigned count)
新的字符设备注册方法
字符设备结构
Linux 中使用 cdev 结构体表示一个字符设备, cdev 结构体在 include/linux/cdev.h 文件中
的定义如下:
示例代码 42.1.2.1 cdev 结构体
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 };
cdev 中有两个重要的成员变量: ops dev ,这两个就是字符设备文件操作函数集合
file_operations 以及设备号 dev_t 。编写字符设备驱动之前需要定义一个 cdev 结构体变量,这个
变量就表示一个字符设备,如下所示:
struct cdev test_cdev;
cdev_init 函数
定义好 cdev 变量以后就要使用 cdev_init 函数对其进行初始化, cdev_init 函数原型如下:
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
cdev_add 函数
cdev_add 函数用于向 Linux 系统添加字符设备 (cdev 结构体变量 ) ,首先使用 cdev_init 函数
完成对 cdev 结构体变量的初始化,然后使用 cdev_add 函数向 Linux 系统添加这个字符设备。
cdev_add 函数原型如下:
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
cdev_del 函数
卸载驱动的时候一定要使用 cdev_del 函数从 Linux 内核中删除相应的字符设备, cdev_del
函数原型如下:
void cdev_del(struct cdev *p)

自动创建设备节点

当我们使用 modprobe 加载驱动程序以后还需要使用命令 “mknod ”手动创建设备节点。实现自动创建节点的功能后我们就可以只用modprode函数,然后系统会自己在/dev自动创建节点了。
mdev 机制
所以在嵌入式 Linux 中我们使用mdev 来实现设备节点文件的自动创建与删除,工作原理我们就不详细探讨了,我们重点来学习一下如何通过 mdev 来实现设备文件节点的自动创建与删除。
创建和删除类
自动创建设备节点的工作是在驱动程序的入口函数中完成的,一般在 cdev_add 函数后面添
加自动创建设备节点相关代码。首先要创建一个 class 类,class 是个结构体,
定义在文件 include/linux/device.h 里面。class_create 是类创建函数
卸载驱动程序的时候需要删除掉类,类删除函数为 class_destroy
创建设备
上一小节创建好类以后还不能实现自动创建设备节点,我们还需要在这个类下创建一个设
备。使用 device_create 函数在类下面创建设备。
device_create 是个可变参数函数,参数 class 就是设备要创建哪个类下面;参数 parent 是父
设备,一般为 NULL ,也就是没有父设备;参数 devt 是设备号;参数 drvdata 是设备可能会使用
的一些数据,一般为 NULL ;参数 fmt 是设备名字,如果设置 fmt=xxx 的话,就会生成 /dev/xxx
这个设备文件。返回值就是创建好的设备。
同样的,卸载驱动的时候需要删除掉创建的设备,设备删除函数为 device_destroy ,函数原
型如下:
void device_destroy(struct class *class, dev_t devt)
参考示例
在驱动入口函数里面创建类和设备,在驱动出口函数里面删除类和设备,参考示例如下:
示例代码 42.2.3.1 创建/删除类/设备参考代码
1 struct class * class ;
/*
*/
2 struct device * device ; /* 设备
*/
3 dev_t devid ;
/* 设备号 */
4
5 /* 驱动入口函数 */
6 static int __init led_init ( void )
7 {
8
/* 创建类 */
9
class = class_create ( THIS_MODULE , "xxx" );
10 /* 创建设备 */
11
device = device_create ( class , NULL , devid , NULL , "xxx" );
12
return 0 ;
13 }
14
15 /* 驱动出口函数 */
16 static void __exit led_exit ( void )
17 {
18
/* 删除设备 */
19
device_destroy ( newchrled . class , newchrled . devid );
20
/* 删除类 */
21
class_destroy ( newchrled . class );
22 }
23
24 module_init ( led_init );
25 module_exit ( led_exit );

设置文件私有数据

示例代码 42.3.2 设备结构体作为私有数据
/* 设备结构体 */
1 struct test_dev {
2
dev_t devid ; /* 设备号 */
3
struct cdev cdev ; /* cdev */
4
struct class * class ; /*
*/
5
struct device * device ; /* 设备
*/
6
int major ; /* 主设备号 */
7
int minor ; /* 次设备号 */
8 };
9
10 struct test_dev testdev ;
11
12 /* open 函数 */
13 static int test_open ( struct inode * inode , struct file * filp )
14 {
15
filp -> private_data = & testdev ; /* 设置私有数据 */
16
return 0 ;
17 }
open 函数里面设置好私有数据以后,在 write read close 等函数中直接读取 private_data
即可得到设备结构体。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值