嵌入式系统设计-李秀娟-课件-第8章.pptx_第1页
嵌入式系统设计-李秀娟-课件-第8章.pptx_第2页
嵌入式系统设计-李秀娟-课件-第8章.pptx_第3页
嵌入式系统设计-李秀娟-课件-第8章.pptx_第4页
嵌入式系统设计-李秀娟-课件-第8章.pptx_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第8章设备驱动程序开发,驱动激励硬件设备开启,赋予硬件设备能量,1,本章内容,2,8.1设备驱动概述,1,8.2设备驱动程序的开发过程,2,8.3驱动程序开发的常见问题,3,目的和要求,了解驱动程序的功能理解驱动程序开发过程掌握各类设备驱动程序设计方法掌握驱动程序开发过程中的常见问题掌握直流电机驱动程序设计实例,3,8.1设备驱动概述,主要完成以下的功能:(1)对设备初始化和释放;(2)把操作数据从内核传送到硬件和从硬件读取数据;(3)读取应用程序传送给硬件设备的数据和回送应用程序请求的数据;(4)检测和处理硬件设备出现的错误。,4,8.1.1驱动程序和应用程序的区别,设备驱动程序就工作在“内核空间”;应用程序则是在“用户空间”中运行。驱动程序的优先级高于应用程序。驱动程序可以对硬件进行直接访问和对内存的访问。应用程序则不能。,5,应用程序与驱动程序的关系图,6,Linux的设备管理,字符设备(CharacterDevice)块设备(BlockDevice)网络设备驱动(Networkinterface),7,字符设备,Linux下的字符设备接口支持面向字符的I/O操作,是以字节为单位顺序读写;字符设备无需缓存且被直接读写;字符设备可以访问/dev目录下的文件系统节点,8,字符设备驱动程序示意图,9,块设备,Linux系统下的块设备是指对信息存取以“块”为单位;块设备对于I/O请求有对应的缓冲区,块设备具有随机访问特性;块设备和字符设备一样也是通过/dev目录下的文件系统节点被访问的;块驱动程序除了给内核提供和字符设备驱动程序一样的接口以外,还提供了专门面向块设备的接口;块设备的接口还必须支持挂装(mount)文件系统。,10,块设备驱动程序数据结构示意图,11,网络设备驱动,网络驱动的体系结构包括网络协议接口层、网络设备接口层、网络驱动接口层和设备媒介层。,12,网络驱动的体系结构,13,8.2设备驱动程序的开发过程,8.2.1字符设备驱动程序的设计,驱动程序的接口流程图,14,Linux为所有的设备文件都提供了统一的操作函数接口,具体操作方法是使用数据结构structfile_operations。,structfile_operationsstructmodule*owner;loff_t(*llseek)(structfile*,loff_t,int);ssize_t(*read)(structfile*,char*,size_t,loff_t*);ssize_t(*write)(structfile*,constchar*,size_t,loff_t*);int(*readdir)(structfile*,void*,filldir_t);unsignedint(*poll)(structfile*,structpoll_table_struct*);int(*ioctl)(structinode*,structfile*,unsignedint,unsignedlong);int(*mmap)(structfile*,structvm_area_struct*);int(*open)(structinode*,structfile*);,15,在嵌入式系统的开发中,我们一般仅仅实现其中几个接口函数:read、write、ioctl、open、release,就可以完成应用系统需要的功能。open接口Open接口提供给驱动程序初始化设备的能力,从而为以后的设备操作做好准备。release接口与open函数相反;read和write接口read函数完成将数据从内核拷贝到应用程序空间,write函数则相反,将数据从应用程序空间拷贝到内核。,16,ioctl接口ioctl接口主要用于对设备进行读写之外的其他控制。,例:LED驱动程序:S3C2410上的4个LED指示灯由4个I/O端口控制,他们分别是GPF4GPF7,当GPF4GPF7分别输出低电平时候,LED指示灯亮,输出高电平的时候,LED指示灯灭,17,1、LED驱动需要的头文件#include/配置头文件#include/内核头文件#include/用户定义模块初始函数需引用的头文件#include/模块加载的头文件#include/延时头文件#include#include/用户的硬件配置文件#include,18,2、LED驱动需要的宏定义#defineGPIO_LED_MAJOR220/定义主设备号/声明4个LED灯的I/O端口;GPFDAT是端口F的数据寄存器#defineLED1_ON()(GPFDAT,20,4、LED驱动程序的读写函数实现在本例中,LED的读写操作不做任何操作,可以省略。本例仅给出了读写操作函数的框架。/-READ-ssize_tGPIO_LED_read(structfile*file,char*buf,size_tcount,loff_t*f_ops)returncount;/-WRITE-ssize_tGPIO_LED_write(structfile*file,constchar*buf,size_tcount,loff_t*f_ops)returncount;,21,ssize_tGPIO_LED_ioctl(structinode*inode,structfile*file,unsignedintcmd,longdata)Switch(cmd)caseLED_ON:LED1_ON();/点亮LED1udelay(0 x500000);/延时LED2_ON();/点亮LED2udelay(0 x500000);/延时LED3_ON();/点亮LED3udelay(0 x500000);/延时LED4_ON();/点亮LED4udelay(0 x500000);/延时break;caseLED_OFF:,LED1_OFF();/LED1灭udelay(0 x500000);/延时LED2_OFF();/LED2灭udelay(0 x500000);/延时LED3_OFF();/LED3灭udelay(0 x500000);/延时LED4_OFF();/LED4灭udelay(0 x500000);/延时break;default:printk(LEDcontrol:nocmdrun.n);return-1;return0;,5、LED驱动程序ioctl控制模块的实现:对设备I/O控制操作,22,6、驱动程序的open()、close()函数:设备文件的打开、关闭操作。/-OPEN-Ssize_tGPIO_LED_open(structinode*inode,structfile*file)MOD_INC_USE_COUNT;/模块数量增1return0;/-RELEASE/CLOSE-Ssize_tGPIO_LED_release(structinode*inode,structfile*file)MOD_DEC_USE_COUNT;/模块数量减1return0;,23,7、驱动程序的init、exit函数:模块加载功能的函数实现/-INIT-staticintGPIO_LED_CTL_init(void)intret=0;GPFCON=0 x55aa;/设置端口为I/O输出模式GPFUP=0 xff;/关闭上拉功能GPFDAT=0 xff;/初始值为高电平熄灭LED灯/注册设备ret=register_chrdev(GPIO_LED_MAJOR,GPIO_LED_CTL,24,staticint_initS3C2410_GPIO_LED_CTL_init(void)intret=0;/调用函数GPIO_LED_CTL_init()ret=GPIO_LED_CTL_init();if(ret)return-1;return0;staticvoid_exitcleanup_GPIO_LED_ctl(void)unregister_chrdev(GPIO_LED_MAJOR,GPIO_LED_CTL);/注销LED设备module_init(S3C2410_GPIO_LED_init);module_exit(cleanup_GPIO_LED_ctl);,25,8.2.2块设备驱动程序设计,块设备可以在一次I/O操作中传送固定大小的数据块,可以随机访问设备中所存放的块。所有对块设备的读写操作都是通过调用generic_file_read()和generic_file_write()函数实现。,26,8.2.3网络设备驱动程序设计,网络设备的驱动程序接口函数:1.初始化(initialize):主要完成检测设备、配置和初始化硬件、申请资源等。2.打开(open):网络设备被激活的时候调用。3.关闭(close):释放资源以减少系统负担。4.发送(hard_start_xmit)5.接收(reception)6.硬件帧头(hard_header)7.地址解析(xarp)8.参数设置和统计数据,27,8.2.4驱动程序的注册,设备驱动程序的注册和取消注册应分别在模块的初始化函数和析构函数中完成。1字符设备驱动程序的注册注册函数:register_chrdev(unsignedintmajor,constchar*name,structfile_operations*fops)major:主设备号;name:设备名称;fops:指向文件操作表的一个指针。如果major=0,系统自动分配一个主设备号。注册成功返回0,否则返回负值。取消注册的函数为unregister_chrdev(register_chrdev(unsignedintmajor,constchar*name),28,2块设备驱动程序的注册,注册函数:register_blkdev(unsignedintmajor,constchar*name,structblock_device_operations*bdops)major:主设备号;name:设备名称;bdops:指向具体设备操作的指针。如果major=0,系统自动分配一个主设备号。注册成功返回0,否则返回负值。删除块注册函数:unregister_blkdev(unsignedintmajor,constchar*name),29,3网络设备驱动程序注册,注册函数:register_netdev(structdevice*)卸载设备:unregister_netdev(structdevice*)函数,30,8.2.5设备驱动程序的编译,在Linux下要运行驱动程序需要用Makefile文件进行编译,Makefile文件定义了一系列的编译规则。,31,8.2.6驱动程序的加载,动态加载:动态加载在系统启动后,用insmod命令把驱动程序添加上去,在不需要的时候用rmmod命令来卸载。静态加载:静态加载就是把驱动程序直接编译到内核里,系统启动后可以直接调用。,32,8.2.7驱动程序的调用,在嵌入式系统中应用程序对驱动程序的调用实质就是使用数据结构structfile_operations中成员函数的指针。这个结构的每一个成员函数的名字都对应着一个系统调用。用户进程利用系统调用在对设备文件进行诸如读写read/write操作时,首先通过设备文件的主设备号找到相应的设备驱动程序,然后再读取这个数据结构相应的函数指针,接着把控制权交给该函数。,33,8.3驱动程序开发的常见问题,驱动程序开发过程中主要考虑三个方面。提供尽量多的选项给用户;提高驱动程序的速度和效率;尽量使驱动程序简单,使之易于维护。,34,比较常见的问题有,阻塞型IO的处理:read函数调用时会出现当前没有数据可读,但马上就会有数据到达的情况,这时采用睡眠并等待数据的方式,这就是阻塞型

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论