版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1.字符设备驱动编写流程8.2 字符设备驱动编程1按模块化设计,一个典型的Linux设备驱动程序应包含哪几部分?在Linux操作系统中如何实现一个驱动程序的开发?设备驱动程序通常包含中断处理程序和设备服务子程序两部分。一个典型的Linux设备驱动程序应包含以下几部分代码:设备服务子程序(驱动程序模块的注册与注销函数、设备的打开、关闭、读、写及需要的其他操作函数)设备的中断服务程序。在Linux操作系统中实现一个驱动程序的开发,必须按照如下步骤进行:设备或模块的初始化;实现该文件操作接口;注册设备中断;编写中断服务程序;文件读写操作。22.重要数据结构 驱动程序中最重要的三个结构:inode 文
2、件file 文件描述符 I/O操作函数8.2 字符设备驱动编程3struct loff_t (*llseek) (struct file *, loff_t, int);ssize_t (*read) (struct file *filp, char *buff, size_t count, loff_t *offp);ssize_t (*write) (struct file *filp, const char *buff, size_t count, loff_t *offp);int (*readdir) (struct file *, void *, filldir_t);unsign
3、ed int (*poll) (struct file *, struct poll_table_struct *);int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);int (*mmap) (struct file *, struct vm_area_struct *);int (*open) (struct inode *, struct file *);int (*flush) (struct file *);int (*release) (struct inode *, struct fi
4、le *);int (*fsync) (struct file *, struct dentry *);int (*fasync) (int, struct file *, int);int (*check_media_change) (kdev_t dev);int (*revalidate) (kdev_t dev);int (*lock) (struct file *, int, struct *);4mode_t f_mode;/*标识文件是否可读或可写,FMODE_READ或FMODE_WRITE*/dev_t f_rdev; /* 用于/dev/tty */off_t f_pos;
5、 /* 当前文件位移 */unsigned short f_flags; /* 文件标志,如O_RDONLY、O_NONBLOCK和O_SYNC */unsigned short f_count; /* 打开的文件数目 */unsigned short f_reada;struct inode *f_inode; /*指向inode的结构指针 */struct *f_op;/* 文件索引指针 */;struct file 5struct inodedev_t i_rdev,表示设备文件对应的设备号。structcdev *i_cdev,成员指向cdev设备。除了从dev_t得到主设备号和次设备
6、号外,这里还可以使用imajor()和iminor()函数从i_rdev中得到主设备号和次设备号。imajor()函数在内部调用MAJOR宏,如下代码所示。staticinlineunsignedimajor(conststructinode*inode) returnMAJOR(inode-i_rdev);/*从inode-i_rdev中提取主设备号*/ 同样,iminor()函数在内部调用MINOR宏,如下代码所示。staticinlineunsignediminor(conststructinode*inode) returnMINOR(inode-i_rdev);/*从inode-i_
7、rdev中提取次设备号*/ 68.2.3设备驱动程序主要组成1.早期版本的字符设备注册register_chrdev() 8.2 字符设备驱动编程78.2.3设备驱动程序主要组成1.早期版本的字符设备注册unregister_chrdev() 8.2 字符设备驱动编程88.2.3设备驱动程序主要组成2.设备号相关函数获取设备号MAJOR(dev_t dev); /*获得主设备号*/MINOR(dev_t dev); /*获得次设备号*/MKDEV(int major, int minor);设备注册于注销8.2 字符设备驱动编程98.2.3设备驱动程序主要组成2.设备号相关函数获取设备号MAJ
8、OR(dev_t dev); /*获得主设备号*/MINOR(dev_t dev); /*获得次设备号*/MKDEV(int major, int minor);设备注册于注销8.2 字符设备驱动编程108.2.3设备驱动程序主要组成3.新版本设备注册8.2 字符设备驱动编程11举例structtest_fops=read:read_test,write:write_test,open:open_test,release:release_test,;unsignedinttest_major=254;/设备号intresult;result=register_chrdev(test_major
9、,test,&test_fops);if(resultprivate_data的数据结构。检查设备特定的错误(诸如设备未就绪或类似的硬件问题)。8.2 字符设备驱动编程138.2.3设备驱动程序主要组成5.释放设备int (*release) (struct inode *, struct file *); 释放设备的主要操作:释放打开设备时系统所分配的内存空间(包括filp-private_data指向的内存空间)。在最后一次关闭设备(使用close()系统调用)时,才会真正释放设备(执行release()函数)。即在打开计数等于0时的close()系统调用才会真正进行设备的释放操作。8.2
10、 字符设备驱动编程14模块计数的实现Linux 2.4内核MOD_INC_USE_COUNTMOD_DEC_USE_COUNTLinux 2.6内核try_module_get(&module)int try_module_get(struct module *module);该函数用于增加模块使用计数;若返回为0,表示调用失败,希望使用的模块没有被加载或正在被卸载中。module_put (&module)void module_put(struct module *module);该函数用于减少模块使用计数。15举例linux2.4staticintopen_test(structinod
11、e*inode,structfile*file)MOD_INC_USE_COUNT;return0;staticintrelease_test(structinode*inode,structfile*file)MOD_DEC_USE_COUNT;return0;16举例linux2.6static void _exit module_close(void) len=0; printk(KERN_ALERTUnloading.n); unregister_chrdev_region(MKDEV(DP_MAJOR,DP_MINOR),10); cdev_del(chardev); 178.2.3
12、设备驱动程序主要组成6.读写设备 read()和write()函数 8.2 字符设备驱动编程188.2.3设备驱动程序主要组成6.读写设备 copy_to_user()和copy_from_user() 8.2 字符设备驱动编程19举例char*str_test;/存放内存空间的指针unsignedintcount_driver;/当前内存中拥有的数据的字节数constunsignedintcount_driver_max=255;/容量的最大值static ssize_t write_test(struct file * char *buf,size_t count,loff_t *t)in
13、t result;if(count0)if(count_driver=count)if(result=copy_to_user(buf,str_test,count)!=0)read_num=count;elseread_num=0;elseif(result=copy_to_user(buf,str_test,count_driver)!=0)read_num=count_driver;elseread_num=0;elseread_num=0;return read_num;218.2.3设备驱动程序主要组成7.ioctl 大部分设备除了读写操作,还需要硬件配置和控制(例如,设置串口设备的
14、波特率)等很多其他操作。在字符设备驱动中ioctl函数接口给用户提供对设备的非读写操作机制。8.2 字符设备驱动编程228.2.3设备驱动程序主要组成8.获取内存kmalloc()/kfree()kmalloc语法格式:8.2 字符设备驱动编程238.2.3设备驱动程序主要组成if(str_test=(char*)kmalloc(256,GFP_KERNEL)=NULL)/申请256字节的内存空间printk(kmallocerrorn);return-1;8.2 字符设备驱动编程241.什么是GPIO接口?其主要作用? GPIO接口就是通用输入输出(General Purpose Input
15、/Output) 主要作用是传送需并行交互的信息,或者是开关量信号。 2.内核模块的编程和普通应用程序的编程有哪些区别? 主要区别为:(1)因为内核模块运行在内核态,所以包含的头文件是内核程序相关的头文件,而普通程序则包含的是glibc的头文件(2)模块程序没有main函数,而是通过init_module函数在加载后初始化。(3)模块程序内可直接调用内核函数,而普通程序则只能通过系统调用使用内核函数。(4)普通用户程序可运行多次,而内核函数通常则只能加载1次。253.Linux中的设备可以分为哪几类,各有何特点? Linux中的设备可以分为三类:字符设备、块设备和网络设备。各自的特点是:字符设
16、备是指数据处理以字节为单位按顺序进行的设备,它没有缓冲区,不支持随机读写。在对字符设备发出读/写请求时,实际的硬件I/O一般就紧接着发生了。块设备是指那些在输入/输出时数据处理以块为单位的设备,它一般都采用了缓存技术,支持数据的随机读写。网络设备面向的上一层不是文件系统层而是网络协议层,设备节点只有在系统正确初始化网络控制器之后才能建立。内核和网络设备驱动程序间的通信,与字符设备驱动程序、块设备驱动程序与内核间的通信也是完全不一样的。在Linux中,整个网络接口驱动程序的框架可分为四层,从上到下分别为协议接口层、网络设备接口层、提供实际功能的设备驱动功能层、以及网络设备和网络媒介层。26驱动模
17、块编写测试步骤编写模块代码编译代码 gcc 加载模块insmod 查看设备号/proc/device映射为设备文件 mknod /dev/fs c 254 0编写测试代码生成可执行测试文件运行测试27#include#include#include#include#include#include#include#include#includeMODULE_LICENSE(GPL);unsignedinttest_major=254;/设备号char*str_test;/存放内存空间的指针unsignedintcount_driver;/当前内存中拥有的数据的字节数constunsignedin
18、tcount_driver_max=255;/容量的最大值structtest_fops=read:read_test,write:write_test,open:open_test,release:release_test,;28模块初始化函数为staticinttest_init_module(void) intresult;result=register_chrdev(test_major,test,&test_fops);if(result0) printk(KERN_INFOtest:cantgetmajornumbern);returnresult;printk(registero
19、kn);if(str_test=(char*)kmalloc(256,GFP_KERNEL)=NULL)/申请256字节的内存空间printk(kmallocerrorn);return-1;Elseprintk(kamllocsuccess!n);count_driver=0;return0; 29open和close的实现, 只是一个计数功能:staticintopen_test(structinode*inode,structfile*file)MOD_INC_USE_COUNT;return0;staticintrelease_test(structinode*inode,struct
20、file*file)MOD_DEC_USE_COUNT;return0;30Write函数的实现static ssize_t write_test(struct file * char *buf,size_t count,loff_t *t)int result;if(count0)if(count_driver=count)if(result=copy_to_user(buf,str_test,count)=0)read_num=count;elseread_num=0;elseif(result=copy_to_user(buf,str_test,count_driver)=0)read_num=count_driver;elseread_num=0;elseread_num=0;return read_num;32gcc-DMODULE-D_KERNEL_-I/usr/src/linux-2.4.20/include-ctest.cinsmod test.omknod /dev/test c 254 0c表示字符设备,254为主设备号,0为次设备号。33Test_w.c#include#include#include#includeint main(void)int i;in
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年新型钢构材料采购与施工劳务分包合同范本
- 二零二五年全新微商佣金分成合同范本下载3篇
- 2025年度汽车租赁合同电子版范本8篇
- 2025年度短视频拍摄制作合同样本4篇
- 二零二五年度历史文化街区风貌改造合同4篇
- 二零二五年度殡仪馆鲜花礼仪用品采购及配送合同3篇
- 2025年度农药市场准入许可申请代理服务合同3篇
- 2025版环保型建筑材料供应与施工合同4篇
- 二零二五年度木门行业品牌推广采购合同3篇
- 二零二五年度城乡汽车租赁及售后服务合同
- (正式版)SJT 11449-2024 集中空调电子计费信息系统工程技术规范
- 广州绿色金融发展现状及对策的研究
- 《近现代史》义和团运动
- 人教版四年级上册加减乘除四则混合运算300题及答案
- 合成生物学技术在生物制药中的应用
- 消化系统疾病的负性情绪与心理护理
- 高考语文文学类阅读分类训练:戏剧类(含答案)
- 协会监事会工作报告大全(12篇)
- 灰坝施工组织设计
- WS-T 813-2023 手术部位标识标准
- 同意更改小孩名字协议书
评论
0/150
提交评论