欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    嵌入式系统驱动开发.ppt

    • 资源ID:6158796       资源大小:814.50KB        全文页数:133页
    • 资源格式: PPT        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    嵌入式系统驱动开发.ppt

    设备驱动程序Device Drivers,嵌入式系统,设备驱动程序和内核接口,Linux内核必须能够用标准的方式和设备驱动程序交互。每一类的设备驱动程序:字符、块和网络,都提供了通用的接口供内核在需要请求它们的服务的时候使用。这些通用的接口意味着内核可以完全相同地看待通常是非常不同的设备和它们的设备驱动程序。例如,SCSI和IDE磁盘的行为非常不同,但是Linux内核对它们使用相同的接口。,Linux非常地动态,每一次Linux内核启动,它都可能遇到不同的物理设备从而需要不同的设备驱动程序。Linux允许你在建立内核时通过配置脚本,将设备驱动程序包含在内核中。,在系统启动时,这些设备驱动程序初始化,此时它们可能没有发现自己可以控制的任何硬件。其它驱动程序可以在需要的时候作为内核模块加载。,为了处理设备驱动程序的这种动态特性,设备驱动程序要在它们初始化时向内核登记。Linux维护已经登记的设备驱动程序列表,作为和它们接口的一部分。这些列表包括了例程指针和支持这一类设备的接口信息。,字符设备,字符设备,Linux中最简单的设备,可以象文件一样访问。应用程序使用标准系统调用打开、读、写和关闭字符设备,完全把它们作为普通文件一样对待。甚至正在被PPP守护进程使用,用于将一个Linux系统连接到网上的modem,也被看作一个普通文件。当字符设备初始化时,它的设备驱动程序向Linux内核登记,在chrdevs向量表增加一个device_struct数据结构条目。这个设备的主设备标识符(例如对于tty设备是4),用作这个向量表的索引。一个设备的主设备标识符是固定的。Chrdevs向量表中的每一个条目,即一个device_struct数据结构,包括两个元素:一个是指向登记的设备驱动程序名字的指针;另一个是指向一组文件操作的指针。这组文件操作本身位于这个设备的字符设备驱动程序中,每一个都处理一个特定的文件操作,比如打开、读、写和关闭。/proc/devices中字符设备的内容来自chrdevs向量表,当代表一个字符设备(例如/dev/cua0)的字符特殊文件打开时,内核必须做一些事情,从而去调用正确的字符设备驱动程序的文件操作例程。和普通文件或目录一样,每一个设备特殊文件都用VFS I节点表达。这个字符特殊文件的VFS inode(实际上所有的设备特殊文件)包含有设备的major和minor标识符。这个VFS I节点由底层的文件系统(例如EXT2)创建,其信息是在查找这个设备特殊文件时,由实际的文件系统提供的。,每一个VFS I节点都关联着一组文件操作,它们依赖于I节点所代表的文件系统对象的不同而不同。不管代表一个字符特殊文件的VFS I节点什么时候创建,它的文件操作都被设置成字符设备的缺省操作。实际上只有一种文件操作:open操作。当一个应用程序打开这个字符特殊文件时,通用的open文件操作使用设备的主设备标识符作为chrdevs向量表中的索引,取出这种特殊设备的文件操作块。它也建立描述这个字符特殊文件的file数据结构,让它的文件操作指针指向设备驱动程序中的相应操作。然后应用程序所有的文件系统操作都被映射到字符设备的文件操作。,Linux设备驱动程序及开发,Linux设备驱动程序概述,Linux设备驱动程序是处理或操作硬件控制器的软件,被集成在内核中,是常驻内存的低级硬件处理程序的共享库,设备驱动程序是系统对设备的抽象管理与控制。Linux允许设备驱动程序作为内核可加载模块实现,即除了可以在系统启动时进行注册外,还可以在启动后进行加载注册。,操作系统的目标之一是向用户掩盖系统硬件设备的特殊性。例如,虚拟文件系统呈现给用户一个统一的文件系统视图,而和底层的物理设备无关。,CPU不是系统中唯一的智能设备,每一个物理设备都由它自己的硬件控制器。键盘、鼠标和串行口由SuperIO芯片控制,IDE磁盘由IDE控制器控制,SCSI磁盘由SCSI控制器控制,等等。,每一个硬件控制器都由自己的控制和状态寄存器(CSR),而且不同的设备有不同的寄存器。CSR用于启动和停止设备,初始化设备和诊断它的问题。管理这些硬件控制器的代码不是放在每一个应用程序里边,而是放在Linux内核。这些处理或者管理硬件控制器的软件叫做设备驱动程序。,本质上,Linux内核的设备驱动程序是特权的、驻留在内存的、低级硬件控制例程的共享库。正是Linux的设备驱动程序处理它们所管理的设备的特性。,Linux的一个基本特点是它抽象了对设备的处理。所有的硬件设备都象常规文件一样看待:它们可以使用和操作文件相同的、标准的系统调用来打开、关闭和读写。,系统中的每一个设备都用一个设备特殊文件代表。例如系统中第一个IDE硬盘用/dev/hda表示。对于块(磁盘)和字符设备,这些设备特殊文件用mknod命令创建,并使用主(major)和次(minor)设备编号来描述设备。,Linux支持三种类型的硬件设备:字符、块和网络。,Linux有许多不同的设备驱动程序,它们都具有一些一般的属性:Kernel code Kenel interfaces Kernel mechanisms and services Loadable Configurable Dynamic,Kernel code 设备驱动程序和内核中的其它代码相似,是kenel的一部分,如果发生错误,可能严重损害系统。一个粗劣的驱动程序甚至可能摧毁系统,可能破坏文件系统,丢失数据。,Kenel interfaces 设备驱动程序必须向Linux内核或者它所在的子系统提供一个标准的接口。例如,终端驱动程序向Linux内核提供了一个文件I/O接口,而SCSI设备驱动程序向SCSI子系统提供了SCSI设备接口,接着,向内核提供了文件I/O和buffer cache的接口。,Kernel mechanisms and services 设备驱动程序使用标准的内核服务,例如内存分配、中断转发和等待队列来完成工作。,Loadable 大多数的Linux设备驱动程序,可以在需要的时候作为内核模块加载,在不再需要的时候卸载。这使得内核对于系统资源非常具有适应性和效率。,Configurable Linux设备驱动程序可以建立在内核。至于哪些设备建立到内核,可以在内核编译的时候配置。,Dynamic 在系统启动,每一个设备启动程序初始化的时候,它会查找它管理的硬件设备。如果一个设备驱动程序所控制的设备不存在并没有关系。这时这个设备驱动程序只是多余的,占用很少的系统内存,而不会产生危害。,Linux驱动程序开发,建立嵌入式Linux平台,移植和编写驱动程序往往是最具挑战的工作驱动程序的开发周期一般较长,对产品的面世时间有着重要影响驱动程序质量的好坏,直接关系到系统工作效能和稳定性,对项目的成败起着关键作用,设备驱动程序主要功能,设备驱动程序主要完成如下功能:检测设备和初始化设备使设备投入运行和退出服务从设备接收数据并提交给内核从内核接收数据送到设备检测和处理设备错误,Linux设备驱动程序分类,Linux中所有设备被抽象出来,都看成文件 设备的读写和普通文件一样 Linux系统的设备分为如下三类:字符设备(char device)块设备(block device)网络设备(network device)字符设备是指存取时没有缓存的设备块设备的读写都有缓存来支持,且块设备必须能够随机存取(random access)网络设备在Linux里做专门的处理,Linux设备驱动程序分类,网络设备在Linux里做专门的处理Linux的网络系统主要是基于BSD unix的socket 机制。在系统和驱动程序之间定义有专门的数据结构(sk_buff)进行数据的传递系统里支持对发送数据和接收数据的缓存,提供流量控制机制,提供对多协议的支持,Linux设备驱动程序分类,典型的字符设备包括鼠标,键盘,串行口等块设备主要包括硬盘、软盘设备、CD-ROM等一个文件系统要安装进入操作系统必须在块设备上,Linux驱动程序介绍,嵌入式Linux驱动已经支持的设备门类齐全,已成为其相对其他嵌入式操作系统的一大优势工业控制常用的串口,并口人机输入设备如鼠标、键盘,触摸屏彩色、黑白液晶显示输出网络的完善支持,包括tcp/ip,udp,firewall,WLAN,ip forwarding,ipsec,vpnUsb的全面支持,包括usb硬盘、u盘,usb摄像头支持丰富的文件系统,包括FAT32,NTFS,嵌入式设备框图,驱动程序的功用,1、驱动程序直接操控硬件收发通讯数据读写存储介质,比如flash或硬盘操作输出设备和执行机构,例如打印,开关门禁等,驱动程序的功用(续),2、驱动程序提供软件访问硬件的机制应用软件通过驱动程序安全高效的访问硬件驱动程序文件可以方便的提供访问权限控制驱动程序作为一个隔离的中间层软件,将底 层细节隐藏起来,提高了软件的可移植性,访问Linux设备驱动的方法,设备提供dev文件系统节点和proc文 件系统节点应用程序通过dev文件节点访问驱动 程序应用程序通过proc文件节点可以查 询设备驱动的信息,驱动程序位置,驱动程序位于drivers目录下通常驱动程序占kernel代码的50%Linux设备驱动程序在Linux的内核源代码中占有很大的比例,源代码的长度日益增加,主要是驱动程序的增加。在Linux内核的不断升级过程中,驱动程序的结构还是相对稳定。在到的变动里,驱动程序的编写做了一些改变,但是从的驱动到的移植只需做少量的工作。,Linux驱动程序的特点,嵌入式Linux驱动程序需求多样嵌入式设备硬件各异嵌入式计算平台往往资源有限,比如处理速度、存储器容量、总线带宽、电池容量等通常要求短的开发周期、压力大开发驱动程序需要丰富的专业知识,包括 硬件和软件知识,嵌入式Linux驱动程序特点,嵌入式系统硬件更新速度加快国际上大的嵌入式芯片提供商如Intel、Samsung、Freescale、TI、ST每年都有大量新品推出新的芯片功能总是需要相应的驱动程序支持,Linux驱动开发流程,熟悉设备的特性 确定设备驱动程序类别 编写测试用例 搜集可重用的代码 编写自己的驱动程序代码 编码、调试、测试,Linux驱动程序的开发环境,本机编译调试开发环境配置简单无需网络环境适用于配置较高的x86机器主机+目标机主机可以自由选择Linux主机和目标机通过网络共享文件系统内核崩溃不会影响主机,Linux驱动程序的开发环境(续),主机+目标机环境包括主机运行的工具链cross gcc+glibc+gdb,如果是windows主机还要有cygwin仿真环境主机运行远程服务,常用的有tftp用来传送内 核映像、initrd,NFS用来共享文件系统目标机运行ssh或telnet等远程登陆服务,用来 调试驱动程序,Linux驱动程序的加载方式,驱动程序直接编译入内核驱动程序在内核启动时就已经在内存中可以保留专用存储器空间驱动程序以模块形式存储在文件系 统里,需要时动态载入内核驱动程序按需加载,不用时节省内存驱动程序相对独立于内核,升级灵活,Linux驱动程序模块加载,Linux驱动程序开发的任务,规划硬件资源的使用分离硬件相关和硬件无关的代码划分驱动程序的抽象层次移植驱动程序到新的平台,Linux驱动程序开发的任务,规划硬件资源的使用CPU时间片分配中断处理系统存储器空间映射,Linux驱动程序开发的任务,分离硬件相关和硬件无关的代码划分驱动程序的抽象层次,Linux驱动程序开发的任务,移植驱动程序到新的平台,设备驱动程序的代码,驱动程序的注册与注销register_chrdev()register_blkdev()设备的打开与释放open()release()设备的读写操作read()write()设备的控制操作ioctl(),设备驱动的加载,使用模块的方式动态加载驱动int func_init(void)Makefile:insmod xx.olsmodrmmod xx.o将驱动静态编译到内核里面 int _init func_init(void)Makefile:启动时自动加载,内核模块,模块是内核的一部分,但是并没有被编译到内核里去。它们被分别编译和连接成目标文件。用命令insmod插入一个模块到内核中,用命令rmmod卸载一个模块 在Linux内核中,以下内容一般编译成模块:大多数的驱动程序。包括SCSI设备,CD-ROM,网络设备,不常用的字符设备,如打印机等。大多数文件系统,理论上除了根文件系统不能是模块,其他文件系统都可以是模块。一些内核支持的不常用的可执行文件格式,如binfmt_misc。,驱动源代码,驱动源代码,驱动源代码,驱动源代码,驱动源代码,编译驱动程序,应用程序,编译应用程序,背景知识:Linux设备管理,主要内容,概述驱动程序基础中断处理辅助函数设备驱动程序模块编程基础字符设备块设备网络设备,概述,输入输出子系统:下层:设备驱动程序 上层:设备无关部分,设备管理总体结构示意,用户程序,系统调用接口,文件系统,高速缓存,字符设备,块设备,驱动程序,硬件设备,输入输出系统层次结构,用户进程,设备无关软件,设备驱动程序,设备服务子程序,中断处理程序,硬件,I/O请求,I/O应答,进行I/O调用;格式化I/O命名、保护、阻塞、缓冲、分配建立设备寄存器、检测状态I/O结束时,唤醒设备服务子程序执行I/O操作,驱动程序基础命名空间,并行设备:lp软盘:fdSCSI盘:sdIDE硬盘:hda1,hda2,hdb等网络设备:ethn,slipn,pppn等在写驱动程序的时候,需要给函数名加上选择的前缀来避免任何混淆。如:foo_read(),foo_write()等。,驱动程序基础内存分配,函数kmalloc()内存以2的幂大小的块分配 有一个优先级参数宏kfree()和函数kfree_s()kfree()调用kfree_s(),和free()一样工作可以直接调用kfree_s(),但是需要知道释放内存块的大小,驱动程序基础设备分类,字符设备:不使用缓冲区,顺序读写foo_read()&foo_write()块设备:需要使用缓冲区,随机读写策略规程网络设备采用了特殊的处理方法。,驱动程序基础设备号,主设备号&次设备号主设备号相同的设备使用相同的驱动程序次设备号区分具体设备的实例命令:ls l/dev/had*,驱动程序基础DMA方式,用于传送大规模的数据PC机上的ISA DMA控制器8条DMA通道。每条通道联系着一个16位地址寄存器和16位计数器DMA直接访问物理内存DMA通道不能被共享。一些设备拥有固定的DMA通道。Struct dma_chan结构:每个通道拥有一个此结构两个域:指向该通道拥有者的字符串指针 指示该通道是否已分配的标志,驱动程序基础睡眠唤醒机制,TASK_INTERRUPTIBLE TASK_UNITERUPTIBLE,决定于睡眠是否能够被系统调用一类的事情打断。一般来说,如果设备比较慢、可以被无限阻塞,包括终端、网络设备或伪设备,睡眠应该是可中断的 _sleep_on()Struct wait_queuestruct task_struct*task;struct wait_queue*next;,驱动程序基础设备文件,Struct file结构include/linux/fs.h增加一个设备时需要用mknod命令为该设备创建一个inode,驱动程序基础file_operations,lseek():转到所需的偏移。struct inode*inode 指向此设备inode结构的指针。Struct file*file 指向此设备的文件结构的指针。Off_t offset 要转移到的相对origin指示的基准的偏移地址。Int origin 0=采用相对于绝对地址0(开始)的偏移量。1=采用相对于当前位置的偏移量。2=采用相对于末尾的偏移量。Lseek()在出错是返回出错码 errno,否则返回lseek操作以后的绝对地址(=0)。,read()和write()struct inode*inode:指向代表要访问的设备的特殊文件的指针。sturct file*file:指向该设备的文件结构的指针。Char*buf:一个读写的字符缓冲区。位于用户空间内存中,可以用get_fs*(),put_fs*()和memcpy*fs()访问。Int count:缓冲区中读或写的字符的计数。它是buf的大小,也是知道怎样到达buf的末尾的手段,因为buf是没有保证以NULL结尾的。,Select()struct inode*inode:指向该设备的inode结构的指针。Struct file*file:指向设备的文件结构的指针。Int sel_type:可以执行的选择类型 SEL_IN read SEL_OUT write SEL_EX exception Select_table*wait 如果设备没有准备好,调用select_wait(),并且返回0。如果设备准备好,返回1。,ioctl()函数:处理ioctl调用。结构:首先差错检查,然后用一个大的switch语句来处理所有可能的ioct。参数:Struct inode*inode Struct file*file Unsigned int cmd:ioctl命令。一般用于做case语句的switch参数。Unsigned int arg 这是此命令的参数,由用户定义。返回:出错返回-error。其他情况下返回由用户定义。,mmap()函数Struct inode*inode Struct file*file Unsigned long addr 需要映射进入的主存开始地址。Size_t len 需要映射的存储空间长度。Int prot 下面中的一个:PROT_READ 可以读的区域。PROT_WRITE 可写的区域 PROT_EXEC 可执行的区域 PROT_NONE 不可访问的区域 Unsigned long off 需要映射的文件偏移地址。这个地址将被映射到addr。,open()和release()函数 Struct inode*inode 指向此设备的inode结构的指针。Struct file*file 指向此设备的文件结构的指针。Open()在设备特殊文件打开时调用。是用来保证一致性的策略机制。Release()只在进程关闭它打开的最后一个文件描述子的时候调用?,init()函数内核第一次启动时调用:在正确的位置调用init():字符设备drivers/char/mem.c中的chr_dev_init()把file_operation注册到VFS中:对于字符设备register_chrdev()打印关于设备的信息,并且报告找到的硬件 printk(),模块编程基础,模块的基本概念:可以动态的加载到内核中成为kernel的一部分;加载后可以访问内核的数据结构;用户空间的程序或进程可以通过某个模块和内核交互。module在需要的时可通过符号表(symbol table)使用核心资源。而且module一般需要调用核心的资源,所以必须注意module的版本和核心的版本的相配问题。一般在module的装入过程中检查module的版本信息。,模块之间的函数调用 内核可以使用其它模块或内核的函数,也可以export一些函数供其他模块或内核使用。模块栈:如果模块A使用了模块B的函数,那么B必须在A之前加载,否则加载A的命令不成功。模块可以使用的函数:自身定义;其他module提供;内核提供命令ksyms a:列出已经加载的模块的函数或变量。Symbol table:记录module导出的函数或变量。所有声明为global的函数或变量都意味着被导出,可以被其他模块使用。,模块编程基础常用命令,lsmod 把现在 kernel 中已经安装的modules 列出来insmod 把某个 module 安装到 kernel 中。rmmod 把某个没在用的 module 从kerne中卸载。depmod 制造 module dependency file,以告诉将来的 insmod 要去哪儿找modules 来安装。这个 dependency file放在/lib/modules/当前kernel版本/modules.dep。,设备驱动程序框架接口,Linux设备驱动程序与外界的接口 1.设备驱动程序与操作系统内核的接口,通过file_operations(include/linux/fs.h)完成。2.驱动程序与系统引导的接口,初始化设备。3.驱动程序与设备的接口。与具体设备相关。,驱动程序框架功能,驱动程序的注册与注销设备的打开与释放设备的读写操作设备的控制操作设备的中断和轮询处理,注册与注销,注册和注销函数:register_*dev()unregister_*dev()/include/linux/fs.h所谓注册就是在内核的chrdevs或blkdevs中添加一项。struct device_struct const char*name;struct file_operations*fops;相同主设备号的fops元素内容相同。,打开与释放,打开设备:open()检查与设备有关的错误,如未准备好。如果是首次打开,则初始化设备。确定次设备号,根据需要可更新设备的f_op。如果需要,分配且设置文件中的private_data。递增设备使用的计数器。如果只允许一个进程使用设备,则需要设忙标志。,释放设备:release()递减设备使用的计数器 释放设备文件中的私有数据所占空间 如果是独占设备,则要清除忙标志,使其他进程可以使用 如果是最后一个释放,则关闭设备,设备的读写操作,字符设备:foo_read()和foo_write()块设备 block_read和block_write()策略规程,不需要在驱动程序中实现。通过缓冲区读写,只在数据不在缓冲区时才真正执行数据传输,通过request_fn()完成。struct blk_dev_struct struct request,设备的控制,ioctl()一般做法是:首先差错检查,然后用一个大的switch语句(可能是内嵌的)来处理所有可能的ioctl命令。返回:出错返回-erro 其他情况由用户定义,字符设备驱动程序,数据结构注册与注销轮询和中断 对应驱动程序的“三个接口”。,添加一个简单的字符设备,确定主设备号编写file_operations中的函数以及中断处理函数。编写初始化函数foo_init()在chr_dev_init()中添加调用和返回初始化函数的代码。修改drivers/char/Makefile;假设我们把所以必要的函数写foo.c中,则在“L_OBJS:=tty_io.o n_tty.o console.o”行把“foo.o”加到其中。,将该设备私有的*.c,*.h复制到目录drivers/char下。用命令:make clean;make dep;make zImage重新编译内核。用mknod命令在目录/dev下建立相应主设备号的用于读写的特殊文件 mknod命令:建立设备特殊文件 格式:mknod 文件名 类型 主设备号 次设备号 类型:c或b,代表字符设备或块设备,块设备驱动程序,数据结构注册与注销读写请求及其处理增加一个块设备的方法和字符设备差不多。块设备不需要编写file_operations结构里的read和write函数,但是也需要read和write在request中调用。需要有请求处理函数,以及中断处理函数。,

    注意事项

    本文(嵌入式系统驱动开发.ppt)为本站会员(小飞机)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开