书签 分享 收藏 举报 版权申诉 / 37
上传文档赚钱

类型嵌入式系统设计-李秀娟-课件-第8章.pptx

  • 上传人(卖家):三亚风情
  • 文档编号:2775161
  • 上传时间:2022-05-25
  • 格式:PPTX
  • 页数:37
  • 大小:905.02KB
  • 【下载声明】
    1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
    2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
    3. 本页资料《嵌入式系统设计-李秀娟-课件-第8章.pptx》由用户(三亚风情)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
    4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
    5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    嵌入式 系统 设计 李秀娟 课件
    资源描述:

    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 & = 0 x80) /GPF70 x80) /GPF7输出

    15、输出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 x40) /GPF6输出输出1 1# define LED4_OF

    16、F()(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 file_operationsfile_operations

    17、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 4、LEDLED驱动程序的读写函数实现驱动程序的读写函数实现

    18、在本例中,在本例中,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 count; return count; /-WRITE-/-

    19、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( (structstruct inodeinode * * inodeinode

    20、, , 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(); / 点亮点亮LED2LED2udelayudelay(0 x500000); /(0 x500

    21、000); /延时延时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 x500000udelay(0 x500000); /); /延时延时LE

    22、D2_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: default: printkprintk (LED (LED co

    23、ntrol: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_openGPIO_LED_open( (structstruct in

    24、odeinode * * 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 , , structstruct file file * * file)

    25、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; /GPFCON = 0 x55aa; /设置端口为设置端口为I/OI/O

    26、输出模式输出模式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); );if (ret)if (ret) printkprintk(fail

    27、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; / / 调用函数调用函数GPIO_LED_CTL_initGPIO_LED_

    28、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_MAJOR, (GPIO_LED_MAJOR, GPIO_LED_CTL); /GP

    29、IO_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操作中传送固定大小的数操作中传送固定大小的数据块,可以随机访问设备中所存放的块。据块,可以随机访问设备中所存放的块。v所有对块设备的读写操作都是通过

    30、调用所有对块设备的读写操作都是通过调用generic_file_readgeneric_file_read ( ) ( )和和generic_file_writegeneric_file_write ( ) ( ) 函数实现函数实现 。 268.2.3 8.2.3 网络设备驱动程序设计网络设备驱动程序设计网络设备的驱动程序接口函数网络设备的驱动程序接口函数 :1. 1.初始化(初始化(initializeinitialize):主要完成检测设备、配置和):主要完成检测设备、配置和初始化硬件初始化硬件 、申请资源等。申请资源等。 2. 2. 打开(打开(openopen):网络设备被激活的时候调

    31、用):网络设备被激活的时候调用 。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:主设备号;:主设备号; namename:设备名称:设备名称; ; fops: fops: 指向

    33、文件操作表的一个指针。指向文件操作表的一个指针。v如果如果major=0major=0,系统自动分配一个主设备号。,系统自动分配一个主设备号。 v注册成功返回注册成功返回0 0,否则返回负值。,否则返回负值。 v 取消注册的函数为取消注册的函数为unregister_chrdevunregister_chrdev( register_chrdevregister_chrdev(unsigned (unsigned intint major, const char major, const char * * name name) 282 2块设备驱动程序的注册块设备驱动程序的注册 v注册函数:注

    34、册函数: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:指向具体设备操作的指针。:指向具体设备操作的指针。v如果如果major=0major=0,系统自动分配一

    35、个主设备号。,系统自动分配一个主设备号。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卸载设备:卸载设备: unre

    36、gister_netdevunregister_netdev( (structstruct device device * *) ) 函数函数 308.2.5 8.2.5 设备驱动程序的编译设备驱动程序的编译v在在LinuxLinux下要运行驱动程序需要用下要运行驱动程序需要用MakefileMakefile文件进行文件进行编译,编译,MakefileMakefile 文件定义了一系列的编译规则。文件定义了一系列的编译规则。318.2.68.2.6驱动程序的加载驱动程序的加载v动态加载:动态加载: 动态加载在系统启动后,用动态加载在系统启动后,用insmodinsmod命令把驱动程命令把驱动程

    37、序添加上去,在不需要的时候用序添加上去,在不需要的时候用rmmodrmmod命令来卸命令来卸载载 。v静态加载:静态加载: 静态加载就是把驱动程序直接编译到内核里,系统静态加载就是把驱动程序直接编译到内核里,系统启动后可以直接调用。启动后可以直接调用。 328.2.7 8.2.7 驱动程序的调用驱动程序的调用 在嵌入式系统中应用程序对驱动程序的调用实质就是在嵌入式系统中应用程序对驱动程序的调用实质就是使用数据结构使用数据结构structstruct file_operationsfile_operations中成员函数的指针中成员函数的指针 。这个结构的每一个成员函数的名字都对应着一个系这个结

    38、构的每一个成员函数的名字都对应着一个系统调用统调用 。用户进程利用系统调用在对设备文件进行。用户进程利用系统调用在对设备文件进行诸如读写诸如读写read/writeread/write操作时,首先通过设备文件的主操作时,首先通过设备文件的主设备号找到相应的设备驱动程序,然后再读取这个设备号找到相应的设备驱动程序,然后再读取这个数据结构相应的函数指针,接着把控制权交给该函数据结构相应的函数指针,接着把控制权交给该函数。数。 338.3 8.3 驱动程序开发的常见问题驱动程序开发的常见问题驱动程序开发过程中主要考虑三个方面。驱动程序开发过程中主要考虑三个方面。v提供尽量多的选项给用户;提供尽量多的

    39、选项给用户;v提高驱动程序的速度和效率;提高驱动程序的速度和效率;v尽量使驱动程序简单,使之易于维护。尽量使驱动程序简单,使之易于维护。34比较常见的问题有比较常见的问题有 v阻塞型阻塞型IO的处理:的处理: readread函数调用时会出现当前没有数据可读,但马上函数调用时会出现当前没有数据可读,但马上就会有数据到达的情况,这时采用睡眠并等待数就会有数据到达的情况,这时采用睡眠并等待数据的方式,这就是阻塞型据的方式,这就是阻塞型IOIO。 解决阻塞型解决阻塞型IO IO ,一般采用进程睡眠、唤醒,在阻,一般采用进程睡眠、唤醒,在阻塞的情况查看是否有数据等方式。塞的情况查看是否有数据等方式。 35v并发访问与数据保护并发访问与数据保护 当应用程序使用多线程操作时,需要数据共享使用,在驱动程序中可以使用循环缓冲区并且避免使用共享变量。v中断处理中断处理 在使用请求中断函数时,如果有几个设备共享同一个中断的话,申请时要指明共享方式 。v网络驱动程序中对硬件发送忙时的处理网络驱动程序中对硬件发送忙时的处理 在Linux系统中网络设备驱动程序一般不做数据缓存,不能发送的数据都要通知系统发送不成功,所以必须要有一个机制在硬件不忙时及时通知系统接着发送后续剩余的数据。 3637

    展开阅读全文
    提示  163文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:嵌入式系统设计-李秀娟-课件-第8章.pptx
    链接地址:https://www.163wenku.com/p-2775161.html

    Copyright@ 2017-2037 Www.163WenKu.Com  网站版权所有  |  资源地图   
    IPC备案号:蜀ICP备2021032737号  | 川公网安备 51099002000191号


    侵权投诉QQ:3464097650  资料上传QQ:3464097650
       


    【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。

    163文库