




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第第8 8章章 设备驱动程序开发设备驱动程序开发 驱动激励硬件设备开启,驱动激励硬件设备开启,赋予硬件设备能量赋予硬件设备能量 1本章内容28 8.1 .1 设备驱动概述设备驱动概述18.2 8.2 设备驱动程序的开发过程设备驱动程序的开发过程2 8.3 8.3 驱动程序开发的常见问题驱动程序开发的常见问题3目的和要求目的和要求v了解驱动程序的功能了解驱动程序的功能v理解驱动程序开发过程理解驱动程序开发过程v掌握各类设备驱动程序设计方法掌握各类设备驱动程序设计方法v掌握驱动程序开发过程中的常见问题掌握驱动程序开发过程中的常见问题v掌握直流电机驱动程序设计实例掌握直流电机驱动程序设计实例 38.
2、1 8.1 设备驱动概述设备驱动概述主要完成以下的功能主要完成以下的功能:v(1 1)对设备初始化和释放;)对设备初始化和释放;v(2 2)把操作数据从内核传送到硬件和从硬)把操作数据从内核传送到硬件和从硬 件读取数据;件读取数据;v(3 3)读取应用程序传送给硬件设备的数据)读取应用程序传送给硬件设备的数据 和回送应用程序请求的数据;和回送应用程序请求的数据;v(4 4)检测和处理硬件设备出现的错误。)检测和处理硬件设备出现的错误。48.1.1 8.1.1 驱动程序和应用程序的区别驱动程序和应用程序的区别v设备驱动程序就工作在设备驱动程序就工作在“内核空间内核空间” ; ;应用程序则应用程序
3、则是在是在“用户空间用户空间”中运行中运行 。v驱动程序的优先级高于应用程序。驱动程序的优先级高于应用程序。 v驱动程序可以对硬件进行直接访问和对内存的访驱动程序可以对硬件进行直接访问和对内存的访问。应用程序则不能。问。应用程序则不能。5应用程序与驱动程序的关系图 6 Linux Linux的设备管理的设备管理 v字符设备(字符设备(Character DeviceCharacter Device) v块设备(块设备(Block DeviceBlock Device) v网络设备驱动(网络设备驱动(Network interfaceNetwork interface) 7字符设备字符设备 vL
4、inuxLinux下的字符设备接口支持面向字符的下的字符设备接口支持面向字符的I/OI/O操作,操作,是以字节为单位顺序读写;是以字节为单位顺序读写; v字符设备无需缓存且被直接读写字符设备无需缓存且被直接读写 ;v字符设备可以访问字符设备可以访问/dev/dev目录下的文件系统节点目录下的文件系统节点 8字符设备驱动程序示意图字符设备驱动程序示意图 9块设备块设备 vLinuxLinux系统下的块设备是指对信息存取以系统下的块设备是指对信息存取以“块块”为单为单位位 ;v块设备对于块设备对于I/OI/O请求有对应的缓冲区,块设备具有随请求有对应的缓冲区,块设备具有随机访问特性;机访问特性;v
5、块设备和字符设备一样也是通过块设备和字符设备一样也是通过/dev/dev目录下的文件目录下的文件系统节点被访问的;系统节点被访问的;v块驱动程序除了给内核提供和字符设备驱动程序一块驱动程序除了给内核提供和字符设备驱动程序一样的接口以外,还提供了专门面向块设备的接口样的接口以外,还提供了专门面向块设备的接口 ;v块设备的接口还必须支持挂装块设备的接口还必须支持挂装(mount)(mount)文件系统。文件系统。 10 块设备驱动程序数据结构示意图块设备驱动程序数据结构示意图 11网络设备驱动网络设备驱动 网络驱动的体系结构包括网络协议接口层、网网络驱动的体系结构包括网络协议接口层、网络设备接口层
6、、网络驱动接口层和设备媒介层。络设备接口层、网络驱动接口层和设备媒介层。 12网络驱动的体系结构网络驱动的体系结构 138.2 8.2 设备驱动程序的开发过程设备驱动程序的开发过程v8.2.1 8.2.1 字符设备驱动程序的设计字符设备驱动程序的设计 驱动程序的接口流程图驱动程序的接口流程图 14LinuxLinux为所有的设备文件都提供了统一的操作函数接为所有的设备文件都提供了统一的操作函数接口,具体操作方法是使用数据结构口,具体操作方法是使用数据结构structstruct file_operationsfile_operations。 structstruct file_operatio
7、nsfile_operations structstruct module module * *owner;owner;loff_tloff_t ( (* *llseekllseek) () (structstruct file file * *, , loff_tloff_t, , intint); );ssize_tssize_t ( (* *read) (read) (structstruct file file * *, char , char * *, , size_tsize_t, , loff_tloff_t * *); );ssize_tssize_t ( (* *write)
8、 (write) (structstruct file file * *, const char , const char * *, , size_tsize_t, , loff_tloff_t * *); );intint ( (* *readdirreaddir) () (structstruct file file * *, void , void * *, , filldir_tfilldir_t); );unsigned unsigned intint ( (* *poll) (poll) (structstruct file file * *, , structstruct pol
9、l_table_structpoll_table_struct * *); );intint ( (* *ioctlioctl) () (structstruct inodeinode * *, , structstruct file file * *, unsigned , unsigned intint, unsigned , unsigned long);long);intint ( (* *mmapmmap) () (structstruct file file * *, , structstruct vm_area_structvm_area_struct * *); );intin
10、t ( (* *open) (open) (structstruct inodeinode * *, , structstruct file file * *); ); ;15 在嵌入式系统的开发中,我们一般仅仅实现其中在嵌入式系统的开发中,我们一般仅仅实现其中几个接口函数:几个接口函数:readread、writewrite、ioctlioctl、openopen、releaserelease,就可以完成应用系统需要的功能。就可以完成应用系统需要的功能。vopenopen接口接口 Open Open 接口提供给驱动程序初始化设备的能力,接口提供给驱动程序初始化设备的能力,从而为以后的设备操作
11、做好准备。从而为以后的设备操作做好准备。vreleaserelease接口接口 与与 openopen函数相反函数相反 ; ;vread read 和和write write 接口接口 read read 函数完成将数据从内核拷贝到应用程序空间,函数完成将数据从内核拷贝到应用程序空间,writewrite函数则相反,将数据从应用程序空间拷贝到函数则相反,将数据从应用程序空间拷贝到内核。内核。 16vioctlioctl 接口接口 ioctlioctl 接口主要用于对设备进行读写之外的其他控接口主要用于对设备进行读写之外的其他控制。制。 例:LED驱动程序: S3C2410上的4个LED指示灯由
12、4个I/O端口控制,他们分别是GPF4GPF7,当GPF4GPF7分别输出低电平时候,LED指示灯亮,输出高电平的时候,LED指示灯灭 171 1、LEDLED驱动需要的头文件驱动需要的头文件 # include # include / /配置头文件配置头文件# include # include / /内核头文件内核头文件# include # include / /用户定义模块初始函数需引用户定义模块初始函数需引用的头文件用的头文件# include # include / /模块加载的头文件模块加载的头文件# include # include / /延时头文件延时头文件 # inclu
13、de # include # include # include / /用户的硬件配置文件用户的硬件配置文件# include # include 182 2、LEDLED驱动需要的宏定义驱动需要的宏定义 # define GPIO_LED_MAJOR 220 /# define GPIO_LED_MAJOR 220 /定义主设备号定义主设备号/声明声明4 4个个LEDLED灯的灯的I/OI/O端口;端口; GPFDAT GPFDAT 是端口是端口F F的数据寄存的数据寄存器器# define LED1_ON()(GPFDAT & = # define LED1_ON()(GPFDAT
14、 & = 0 x10) /GPF40 x10) /GPF4输出输出0 0# define LED2_ON()(GPFDAT & = # define LED2_ON()(GPFDAT & = 0 x20) /GPF50 x20) /GPF5输出输出0 0# define LED3_ON()(GPFDAT & = # define LED3_ON()(GPFDAT & = 0 x40) /GPF60 x40) /GPF6输出输出0 0# define LED4_ON()(GPFDAT & = # define LED4_ON()(GPFDAT &a
15、mp; = 0 x80) /GPF70 x80) /GPF7输出输出0 0# define LED1_OFF()(GPFDAT | = 0 x10) /GPF4# define LED1_OFF()(GPFDAT | = 0 x10) /GPF4输出输出1 1# define LED2_OFF()(GPFDAT | = 0 x20) /GPF5# define LED2_OFF()(GPFDAT | = 0 x20) /GPF5输出输出1 1# define LED3_OFF()(GPFDAT | = 0 x40) /GPF6# define LED3_OFF()(GPFDAT | = 0 x
16、40) /GPF6输出输出1 1# define LED4_OFF()(GPFDAT | = 0 x80) /GPF7# define LED4_OFF()(GPFDAT | = 0 x80) /GPF7输出输出1 1/定义定义LEDLED灯的状态灯的状态# define LED_ON 0 /# define LED_ON 0 /低电平点亮低电平点亮LEDLED# define LED_OFF 1 /# define LED_OFF 1 /高电平熄灭高电平熄灭LEDLED193 3、file_operationsfile_operations 结构体的设计结构体的设计 structstruct
17、 file_operationsfile_operations GPIO_LED_ctl_opsGPIO_LED_ctl_ops= open: open: GPIO_LED_openGPIO_LED_open, read: read: GPIO_LED_readGPIO_LED_read, , write: write: GPIO_LED_writeGPIO_LED_write, , ioctlioctl: : GPIO_LED_ioctlGPIO_LED_ioctl, , release: release: GPIO_LED_releaseGPIO_LED_release, , ; ;204
18、 4、LEDLED驱动程序的读写函数实现驱动程序的读写函数实现 在本例中,在本例中,LEDLED的读写操作不做任何操作,可以的读写操作不做任何操作,可以省略。本例仅给出了读写操作函数的框架。省略。本例仅给出了读写操作函数的框架。/-READ-/-READ-ssize_tssize_t GPIO_LED_readGPIO_LED_read( (structstruct file file * * file ,char file ,char * * bufbuf , , size_tsize_t count, count, loff_tloff_t * * f_opsf_ops) ) return
19、 count; return count; /-WRITE-/-WRITE-ssize_tssize_t GPIO_LED_writeGPIO_LED_write( (structstruct file file * * file ,const char file ,const char * * bufbuf , , size_tsize_t count, count, loff_tloff_t * * f_opsf_ops) ) return count; return count; 21ssize_tssize_t GPIO_LED_ioctlGPIO_LED_ioctl( (struct
20、struct inodeinode * * inodeinode, , structstruct file file * * file,unsignedfile,unsigned intint cmd,longcmd,long data) data) Switch ( Switch (cmdcmd) ) case LED_ON: case LED_ON: LED1_ON(); / LED1_ON(); / 点亮点亮LED1LED1udelayudelay(0 x500000); /(0 x500000); /延时延时LED2_ON(); / LED2_ON(); / 点亮点亮LED2LED2u
21、delayudelay(0 x500000); /(0 x500000); /延时延时LED3_ON(); / LED3_ON(); / 点亮点亮LED3LED3udelayudelay(0 x500000); /(0 x500000); /延时延时LED4_ON(); / LED4_ON(); / 点亮点亮LED4LED4udelayudelay(0 x500000); /(0 x500000); /延时延时break;break; case LED_OFF: case LED_OFF:LED1_OFF(); / LED1LED1_OFF(); / LED1灭灭 udelay(0 x5000
22、00udelay(0 x500000); /); /延时延时LED2_OFF(); / LED2LED2_OFF(); / LED2灭灭udelayudelay(0 x500000); /(0 x500000); /延时延时LED3_OFF(); / LED3LED3_OFF(); / LED3灭灭udelayudelay(0 x500000); /(0 x500000); /延时延时LED4_OFF(); / LED4LED4_OFF(); / LED4灭灭udelayudelay(0 x500000); /(0 x500000); /延时延时break;break; default: de
23、fault: printkprintk (LED (LED control:nocontrol:no cmdcmd run.n ); run.n ); return -1;return -1; return 0; return 0; 5 5、LEDLED驱动程序驱动程序ioctlioctl控制模块的控制模块的实现:对设备实现:对设备I/OI/O控制操作控制操作 226 6、驱动程序的、驱动程序的open()open()、close()close()函数:函数:设备文件的打开、关闭操作。设备文件的打开、关闭操作。 /-OPEN-/-OPEN-Ssize_tSsize_t GPIO_LED_ope
24、nGPIO_LED_open( (structstruct inodeinode * * inodeinode , , structstruct file file * * file) file) MOD_INC_USE_COUNT; / MOD_INC_USE_COUNT; /模块数量增模块数量增1 1 return 0; return 0; /-RELEASE/CLOSE-/-RELEASE/CLOSE-Ssize_tSsize_t GPIO_LED_releaseGPIO_LED_release( (structstruct inodeinode * * inodeinode , , s
25、tructstruct file file * * file) file) MOD_DEC_USE_COUNT; / MOD_DEC_USE_COUNT; /模块数量减模块数量减1 1 return 0; return 0; 237 7、驱动程序的、驱动程序的initinit、exitexit函数:函数:模块加载功能的函数实现模块加载功能的函数实现 /-INIT-/-INIT-static static intint GPIO_LED_CTL_initGPIO_LED_CTL_init(void)(void) intint ret=0; ret=0;GPFCON = 0 x55aa; /GPF
26、CON = 0 x55aa; /设置端口为设置端口为I/OI/O输出模式输出模式GPFUP = 0 xff; / GPFUP = 0 xff; / 关闭上拉功能关闭上拉功能GPFDAT = 0 xff; / GPFDAT = 0 xff; / 初始值为高电平熄灭初始值为高电平熄灭LEDLED灯灯/注册设备注册设备ret=ret=register_chrdevregister_chrdev(GPIO_LED_MAJOR, GPIO_LED_CTL, (GPIO_LED_MAJOR, GPIO_LED_CTL, & &GPIO_LED_ctl_opsGPIO_LED_ctl_ops
27、); );if (ret)if (ret) printkprintk(fail to register!n );(fail to register!n ); return -1; return -1; printkprintk(success to register!n );(success to register!n );return 0;return 0; 24static static intint _init S3C2410_GPIO_LED_CTL_init(void) _init S3C2410_GPIO_LED_CTL_init(void) intint ret=0; ret=0
28、; / / 调用函数调用函数GPIO_LED_CTL_initGPIO_LED_CTL_init() () ret= ret= GPIO_LED_CTL_initGPIO_LED_CTL_init();(); if (ret) return -1; if (ret) return -1; return 0; return 0; static void _exit static void _exit cleanup_GPIO_LED_ctlcleanup_GPIO_LED_ctl(void)(void) unregister_chrdevunregister_chrdev(GPIO_LED_MA
29、JOR, (GPIO_LED_MAJOR, GPIO_LED_CTL); /GPIO_LED_CTL); /注销注销LEDLED设备设备 module_initmodule_init(S3C2410_GPIO_LED_init);(S3C2410_GPIO_LED_init);module_exitmodule_exit( (cleanup_GPIO_LED_ctlcleanup_GPIO_LED_ctl); ); 258.2.2 8.2.2 块设备驱动程序设计块设备驱动程序设计 v块设备可以在一次块设备可以在一次I/OI/O操作中传送固定大小的数操作中传送固定大小的数据块,可以随机访问设备中
30、所存放的块。据块,可以随机访问设备中所存放的块。v所有对块设备的读写操作都是通过调用所有对块设备的读写操作都是通过调用generic_file_readgeneric_file_read ( ) ( )和和generic_file_writegeneric_file_write ( ) ( ) 函数实现函数实现 。 268.2.3 8.2.3 网络设备驱动程序设计网络设备驱动程序设计网络设备的驱动程序接口函数网络设备的驱动程序接口函数 :1. 1.初始化(初始化(initializeinitialize):主要完成检测设备、配置和):主要完成检测设备、配置和初始化硬件初始化硬件 、申请资源等。
31、申请资源等。 2. 2. 打开(打开(openopen):网络设备被激活的时候调用):网络设备被激活的时候调用 。3. 3. 关闭(关闭(closeclose):释放资源以减少系统负担):释放资源以减少系统负担 。4. 4. 发送(发送(hard_start_xmithard_start_xmit) 5. 5. 接收(接收(receptionreception)6. 6. 硬件帧头硬件帧头( (hard_headerhard_header) ) 7. 7. 地址解析(地址解析(xarpxarp) 8. 8. 参数设置和统计数据参数设置和统计数据278.2.4 8.2.4 驱动程序的注册驱动程序
32、的注册 设备驱动程序的注册和取消注册应分别在模块设备驱动程序的注册和取消注册应分别在模块的初始化函数和析构函数中完成。的初始化函数和析构函数中完成。1 1字符设备驱动程序的注册字符设备驱动程序的注册v 注册函数:注册函数: register_chrdevregister_chrdev(unsigned (unsigned intint major, const major, const char char * * name, name, structstruct file_operationsfile_operations * *fops) fops) major major:主设备号;:主设
33、备号; namename:设备名称:设备名称; ; fops: fops: 指向文件操作表的一个指针。指向文件操作表的一个指针。v如果如果major=0major=0,系统自动分配一个主设备号。,系统自动分配一个主设备号。 v注册成功返回注册成功返回0 0,否则返回负值。,否则返回负值。 v 取消注册的函数为取消注册的函数为unregister_chrdevunregister_chrdev( register_chrdevregister_chrdev(unsigned (unsigned intint major, const char major, const char * * name
34、 name) 282 2块设备驱动程序的注册块设备驱动程序的注册 v注册函数:注册函数:register_blkdevregister_blkdev(unsigned (unsigned intint major, const major, const char char * * name, name, structstruct block_device_operationsblock_device_operations * *bdopsbdops) ) major major:主设备号;:主设备号; name name :设备名称;:设备名称; bdopsbdops:指向具体设备操作的指针。
35、:指向具体设备操作的指针。v如果如果major=0major=0,系统自动分配一个主设备号。,系统自动分配一个主设备号。v注册成功返回注册成功返回0 0,否则返回负值。,否则返回负值。 v删除块注册函数:删除块注册函数: unregister_blkdevunregister_blkdev(unsigned (unsigned intint major, const char major, const char * * name name)293 3网络设备驱动程序注册网络设备驱动程序注册v注册函数:注册函数:register_netdevregister_netdev( (structstruct device device * *) )v卸载设备:卸载设备: unregister_netdevunregister_netdev( (structstruct device device * *) ) 函数函数 308.2.5 8.2.5 设备驱动程序的编译设备驱动程序的编译v在在LinuxLinux下要运行驱动程序需要用下要运行驱动程序需要用MakefileMakefile文件进行文件进行编译,编译,MakefileMakefile 文件定义了一系列的编译规则。文件定义了一系列的编译规则。318.2.68.2.6驱动程序的加载驱动程序的加载v动态
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 如何让年度工作计划更具吸引力
- 智能仓库建设工作总结计划
- 水利水电工程发展战略试题及答案
- 工程投资过程中的数据可视化技术试题及答案
- 水利水电工程创新技术与试题及答案
- 工程经济官方指导试题及答案
- 市政工程知识运用试题及答案
- 行政管理中经济法的实务应用试题及答案
- 市政工程相关法规试题及答案
- 2025年国家电网招聘之经济学类题库练习试卷B卷附答案
- 泌尿系结石的护理课件
- T∕ZZB 2733-2022 贯流式蒸汽发生器
- 飞行区培训题库
- 项目部周例会制度
- 战略管理教学ppt课件(完整版)
- 云南锂电池项目可行性研究报告
- 体育科研方法试卷试题答案
- 《国家电网公司十八项电网反事故措施(试行)》实施细则
- 中国民主同盟入盟申请表(样表)
- 国家标准色卡电子版(WORD版图片)
- 《呼吸机的使用管理》PPT课件.ppt
评论
0/150
提交评论