字符设备驱动(1)

1、对于驱动的理解和解释

(1)、字符设备和块设备都可以体现为“一切都是文件”的思想,可以使用open()、read()、write()、close()等函数进行访问。

(2)、驱动的编写要体现“驱动融合入内核中的思想”,其实就是驱动必须遵循内核提供的接口规范进行编写,即驱动对硬件操作的函数,和内核系统调用函数之间有映射关系。当应用程序中系统调用open()、read()、write()等函数调用时,内核找到驱动对应的映射函数进行对硬件的操作。

2、工作流程

模块加载时,自己定义一个结构体,在这个结构体中,调用内核cdev结构体,然后用内核提供“一组函数”对设备进行申请、注册。

3、编写字符驱动的步骤

(1)、认识内核提供2个结构体:cdev 和 file_operations

struct cdev

{

struct module *owner; //所属模块

struct file_operation *ops;//文件操作结构体

dev_t dev;//设备号

}

struct file_operations

{

struct module *owner;

函数指针;

.......

}

(2)、自己编写file_operations结构体中成员函数的具体实现

一般为 xxx_read()、xxx_write()、xxx_close()等。

(3)、自己定义一个file_operations实例,将具体成员函数的入口地址付给函数指针

struct file_operations xxx_ops

{

.owner = This_module;

.read = xxx_read;

.write = xxx_write;

.close = xxx_close;

......

}

4、字符驱动模块加载和卸载模板

认识:内核中提供了用于操作cdev结构体的一组函数,这组函数是:

void cdev_init(struct cdev *,struct file_operations *);

struct cdev *cdev_alloc(void);

void cdev_put(struct cdev *p);

int cdev_add(struct cdev *,dev_t,unsigned);

void cdev_del(struct cdev *);

 

// 设备结构体(自己定义的)

struct xxx_dev_t

{

struct cdev cdev;

....

}

// 设备驱动模块加载函数

static int __init xxx_init(void)

{

....

cdev_init(&xxx_dev.cdev,&xxx_fops);// 初始化cdev,将自己定义的结构体指针和内核结构体指针关联起来(这样子,内核就指向驱动的xxx_open等函数了)

xxx_dev.cdev.owner = THIS_MODULE;

if(xxx_major)

{

register_chrdev_region(xxx_dev_no,1,DEV_NAME);

}

else

{

alloc_chrdev_region(&xxx_dev_no,0,1,DEV_NAME);

}

ret = cdev_add(&xxx_dev.cdev,xxx_dev_no,1);//注册设备

......

}

// 设备驱动模块卸载函数

static void __exit xxx_exit(void)

{

unregister_chrdev_region(xxx_dev_no,1);//释放占用的设备号

cdev_del(&xxx_dev.cdev);//注销设备

.....

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值