正点原子-驱动开发-新字符设备驱动实验

字符设备驱动开发重点是使用register_chrdev函数注册字符设备,当不用设备时使用unregister_chrdev函数注销字符设备,驱动模块加载成功后还需要手动mknod创建设备节点。

register_chrdev和unregister_chrdev这两个函数是老版本内核驱动使用的函数,现在新的字符设备驱动已经不再使用这两个函数,而是使用linux内核推荐的新字符设备驱动API函数。

新字符设备驱动原理

分配和释放设备号

如果没有指定设备号,向内核申请设备号

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)
// from是要申请的起始设备号, count是要申请的数量,name 是设备名字

不管是通过alloc_chrdev_region还是register_chrdev_region申请的设备号,释放设备号统一使用如下函数

void unregister_chrdev_region(dev_t from, unsigned count)

新字符设备驱动,设备号分配示例代码如下:

int major;                 /* 主设备号 */ 
int minor;                 /* 次设备号 */ 
dev_t devid;                 /* 设备号 */ 
if (major) {                                     /* 定义了主设备号 */ 
    devid = MKDEV(major, 0);                     /* 大部分驱动次设备号都选择0 */ 
    register_chrdev_region(devid, 1, "test"); 
} else {                                         /* 没有定义设备号 */ 
    alloc_chrdev_region(&devid, 0, 1, "test");     /* 申请设备号 */ 
    major = MAJOR(devid);                         /* 获取分配号的主设备号 */ 
    minor = MINOR(devid);                         /* 获取分配号的次设备号 */ 
}

unregister_chrdev_region(devid, 1);             /* 注销设备号 */

新的字符设备注册方法

在 Linux中使用 中使用 cdev结构体表示一个字符设备, cdev结构体在 结构体在 include/linux/cdev.h文件中的定义如下:

struct cdev { 
    struct kobject kobj; 
    struct module *owner; 
    const struct file_operations *ops;     // 设备操作函数集合
    struct list_head list; 
    dev_t dev;                             // 字符设备名称
    unsigned int count; 
};

编写字符设备驱动前,需要定义一个cdev的结构体变量:

struct cdev test_cdev;

cdev_init函数

void cdev_init(struct cdev *cdev, const struct file_operations *fops)
// 初始化test_cdev结构体变量
struct cdev test_cdev; 
/* 设备操作函数 */ 
static struct file_operations test_fops = { 
    .owner = THIS_MODULE, 
    /* 其他具体的初始项 */ 
}; 
testcdev.owner = THIS_MODULE; 
cdev_init(&test_cdev, &test_fops); /* 初始化cdev结构体变量 */

cdev_add函数

先使用cdev_init函数对cdev结构体变量进行初始化,然后使用cdev_add函数向Linux系统添加这个字符设备。

int cdev_add(struct cdev *p, dev_t dev, unsigned count)
// p 为执行cdev结构体的指针,dev为设备号,count是要添加的设备数量
struct cdev testcdev; 
/* 设备操作函数 */ 
static struct file_operations test_fops = { 
    .owner = THIS_MODULE, 
    /* 其他具体的初始项 */ 
}; 
testcdev.owner = THIS_MODULE; 
cdev_init(&testcdev, &test_fops); /* 初始化cdev结构体变量 */ 
cdev_add(&testcdev, devid, 1); /* 添加字符设备 */

以上就是新的注册字符设备代码段,Linux内核中大量的字符设备驱动都是采用这种方法向Linux内核添加字符设备的。

cdev_del函数

卸载驱动的时候一定要使用cdev_del函数从Linux内核中删除相应的字符设备。

void cdev_del(struct cdev *p)
// p 就是要删除的字符设备结构体指针

cdev_del(&testcdev); /* 删除cdev */

cdev_del和 unregister_chrdev_region这两个函数合起来的功能相当于unregister_chrdev函数

自动创建设备节点

modprobe加载驱动程序后,还需要使用命令mknod手动创建设备节点。现在可以在驱动中自动创建节点,使用modprobe加载驱动成功后会自动在/dev目录下创建对应的设备文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值