字符设备驱动——申请、创建、应用

上传人:安**** 文档编号:201855340 上传时间:2021-10-12 格式:DOCX 页数:9 大小:299.30KB
返回 下载 相关 举报
字符设备驱动——申请、创建、应用_第1页
第1页 / 共9页
字符设备驱动——申请、创建、应用_第2页
第2页 / 共9页
字符设备驱动——申请、创建、应用_第3页
第3页 / 共9页
字符设备驱动——申请、创建、应用_第4页
第4页 / 共9页
字符设备驱动——申请、创建、应用_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《字符设备驱动——申请、创建、应用》由会员分享,可在线阅读,更多相关《字符设备驱动——申请、创建、应用(9页珍藏版)》请在金锄头文库上搜索。

1、1、申请设备号/ 1、注册获取设备号/ 2、初始化设备/ 3、操作设备 file_operations open release read write ioctl/ 4、两个宏定义 module_init module_exit / 5、注册设备号 register_chrdev_region/ 6、cdev_init 初始化字符设备/ 7、cdev_add 添加字符设备到系统1)向系统申请主设备号int register_chrdev(unsigned int major, const char * name, const struct file_operations * fops)/参数:

2、/1、major:主设备号/ 设备号(32bitdev_t)=主设备号(高12bit) + 次设备号(低20bit)/ 主设备号:表示一类设备(如:camera)/ 次设备号: 表示一类设备中某一个(如:前置camera/后置camera)/ 0 -动态分配 ; 250 - 给定整数,静态指定/2、name: 描述设备信息,可自定义/ 在目录/proc/devices列举出了所有的已经注册的设备/3、fops: 文件操作对象/ 提供open, read,write/返回值:成功-0,失败-负数2)释放设备号void unregister_chrdev(unsigned int major, c

3、onst char * name)3)例:主设备号的申请chr_drv.c加载驱动前:加载驱动后:2、创建设备节点1)手动创建缺点/dev/目录中文件都是在内存中,断电后/dev/文件就会消失 mknod /dev/设备名 类型 主设备号 次设备号 (主设备号要和驱动中申请的主设备号保持一致) 比如: mknod /dev/chr0 c 250 0 eg: rootfarsight drv_module# ls /dev/chr0 -l crw-r-r- 1 0 0 250, 0 Jan 1 00:33 /dev/chr02)自动创建通过udev/mdev机制struct class *cla

4、ss_create(owner, name)/创建一个类/参数:/1、owner:THIS_MODULE/2、name :字符串名字,自定义/返回:/ 返回一个class指针创建一个设备文件:/创建一个设备文件struct device *device_create(struct class * class, struct device * parent, dev_t devt, void * drvdata, const char * fmt,.)/参数:/1、class结构体,class_create调用之后的返回值/2、表示父亲,一般直接填NULL/3、设备号类型 dev_t/4、私有数

5、据,一般直接填NULL/5/6、表示可变参数,字符串,表示设备节点名字设备号类型:dev_t devt #define MAJOR(dev) (unsigned int) (dev) MINORBITS) /获取主设备号 #define MINOR(dev) (unsigned int) (dev) & MINORMASK) /获取次设备号 #define MKDEV(ma,mi) (ma) MINORBITS) | (mi) /生成设备号销毁设备文件:void device_destroy(devcls, MKDEV(dev_major, 0);/参数:/1、class结构体,class_c

6、reate调用之后到返回值/2、设备号类型 dev_tvoid class_destroy(devcls);/参数:class结构体,class_create调用之后到返回值3)示例:chr_drv.c3、实现文件IO接口-fops1)驱动中实现文件io操作接口:struct file_operations 1 struct file_operations 2 struct module *owner; 3 loff_t (*llseek) (struct file *, loff_t, int); 4 ssize_t (*read) (struct file *, char _user *,

7、 size_t, loff_t *); 5 ssize_t (*write) (struct file *, const char _user *, size_t, loff_t *); 6 ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t); 7 ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); 8 int (*iterate) (struct file *, st

8、ruct dir_context *); 9 unsigned int (*poll) (struct file *, struct poll_table_struct *);10 long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);11 long (*compat_ioctl) (struct file *, unsigned int, unsigned long);12 int (*mmap) (struct file *, struct vm_area_struct *);13 int (*open) (

9、struct inode *, struct file *);14 .16 long (*fallocate)(struct file *file, int mode, loff_t offset, loff_t len);17 int (*show_fdinfo)(struct seq_file *m, struct file *f);18 ; /函数指针的集合,其实就是接口,我们写驱动到时候需要去实现19 20 const struct file_operations my_fops = 21 .open = chr_drv_open,22 .read = chr_drv_read,23

10、.write = chr_drv_write,24 .release = chr_drv_close,25 ;示例:chr_drv1.c实现了底层的fops成员函数,再实现应用程序的调用2)应用程序调用文件IO控制驱动 :open、read.chr_drv1.cchr_test.cMakefile测试结果;4、应用程序控制驱动应用程序要控制驱动,就涉及用户空间与内核空间的数据交互,如何实现?通过以下函数:1)copy_to_user1 /将数据从内核空间拷贝到用户空间,一般是在驱动中chr_drv_read()用2 int copy_to_user(void _user * to, const

11、 void * from, unsigned long n)3 /参数:4 /1:应用驱动中的一个buffer5 /2:内核空间到一个buffer6 /3:个数7 /返回值:大于0,表示出错,剩下多少个没有拷贝成功等于0,表示正确2)copy_from_user1 /将数据从用户空间拷贝到内核空间,一般是在驱动中chr_drv_write()用2 int copy_from_user(void * to, const void _user * from, unsigned long n)3 /参数:4 /1:内核驱动中的一个buffer5 /2:应用空间到一个buffer6 /3:个数示例:c

12、hr_drv1.cchr_test.c测试:5、驱动程序控制外设之前我们了解了应用程序如何与内核空间进行数据交互,那么内核驱动与外设间的控制是怎么样的?写过裸机程序的都知道,可以通过修改外设对应的控制寄存器来控制外设,即向寄存器的地址写入数据,这个地址就是物理地址,且物理地址是已知的,有硬件设计决定。在内核中,同样也是操作地址控制外设,但是内核中的地址,是经过MMU映射后的虚拟地址,而且CPU通常并没有为这些已知的外设I/O内存资源的物理地址预定义虚拟地址范围,驱动程序并不能直接通过物理地址访问I/O内存资源,而必须将它们映射到核心虚地址空间内,然后才能根据映射所得到的核心虚地址范围,通过访内

13、指令访问这些I/O内存资源。Linux在io.h头文件中声明了函数ioremap(),用来将I/O内存资源的物理地址映射到核心虚地址空间中ioremap的函数如下:1 /映射虚拟地址2 void *ioremap(cookie, size)3 /参数:4 /1、cookie:物理地址5 /2、size:长度(连续映射一定长度的地址空间)6 /返回值:虚拟地址解除映射:1 /去映射-解除映射2 void iounmap(void _iomem *addr)3 /参数:映射后的虚拟地址实例:通过驱动控制LED灯LED GPX2_7 GPX2CON 0x11000C40 GPX2DAT 0x11000C44 将0x11000c40映射为虚拟地址chr_drv1.cchr_test.c测试:执行app后,可以看到LED等以一秒的间隔亮灭

展开阅读全文
相关资源
相关搜索

当前位置:首页 > IT计算机/网络 > 计算机应用/办公自动化

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号