嵌入式Linux设备驱动.ppt_第1页
嵌入式Linux设备驱动.ppt_第2页
嵌入式Linux设备驱动.ppt_第3页
嵌入式Linux设备驱动.ppt_第4页
嵌入式Linux设备驱动.ppt_第5页
已阅读5页,还剩37页未读 继续免费阅读

下载本文档

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

文档简介

三 嵌入式Linux设备驱动 1 嵌入式Linux设备驱动程序的基本原理2 如何编写嵌入式Linux设备驱动程序 1 嵌入式Linux设备驱动程序的基本原理 1 1概述1 2设备文件1 3设备驱动程序模块1 4设备驱动程序接口1 5设备驱动程序接口实现过程 1 1概述 设备驱动程序 是操作系统内核和机器硬件之间的接口它控制着设备的操作动作向应用程序提供一个可用的程序接口与设备互动可见 设备驱动程序为应用程序屏蔽了硬件的细节 这样在应用程序看来 硬件设备只是一个设备文件 应用程序可以像操作普通文件一样对硬件设备进行操作 因此在操作系统中起着不可缺少的作用 设备驱动程序结构图 各种设备驱动程序构成了它们所控制的硬件和操作系统内核之间的一个过渡层次 这个层次扎根于硬件 服务于内核 优点 1 极大的简化了内核的设计和应用它向外界提供了一个精心定义的接口 具体的工作将由各个设备去完成 而内核就不必亲自去与每一个设备打交道2 屏蔽了底层硬件 方便应用程序的编写 设备驱动程序 内核的一部分 的任务 1 对设备初始化和释放 2 把数据从内核传送到硬件和从硬件读取数据 3 读取应用程序传送给设备文件的数据和回送应用程序请求的数据 4 检测和处理设备出现的错误 驱动程序与应用程序的区别 1 应用程序 一般有一个main函数 从头到尾执行一个任务 驱动程序 它没有main函数 通过使用module init 初始化函数名 将初始化函数加入内核全局初始化函数列表中 在内核初始化时执行驱动的初始化函数 从而完成驱动的初始化和注册 之后驱动便停止等待被应用软件调用 驱动程序中有一个宏moudule exit 退出处理函数名 注册退出处理函数 它在驱动退出时被调用 2 应用程序 可以和GLIBC库连接 因此可以包含标准的头文件 比如 驱动程序 是不能使用标准C库的 因此不能调用所有的C库函数 比如输出打印函数只能使用内核的printk函数 包含的头文件只能是内核的头文件 比如 1 2设备文件 Linux设备驱动程 抽象了对硬件的处理 将所有外部设备看成是一类特殊文件 称之为 设备文件 每个设备文件对应有两个设备号 主设备号和次设备号 1 主设备号标识该设备的种类 也标识了该设备所使用的驱动程序 2 次设备号标识使用同一设备驱动程序的不同硬件设备 对于查看 dev目录下的设备的主次设备号可以使用如下命令 ls l dev 当应用程序对某个设备文件进行系统调时 Linux内核会根据该设备文件的设备类型和主设备号调用相应的驱动程序 从用户态进入到内核态 再由驱动程序判断该设备的次设备号 最终完成对相应硬件的操作 所有己经注册 即已加载了驱动程序 的硬件设备的主设备号可以从 proc devices文件中得到 内核函数mknod命令可以创建指定类型的设备文件 同时为其分配相应的主设备号和次设备号 mknod命令的语法 mknodnametypemajorminor其中 name 设备文件名major 主设备号minor 次设备号type 使用b或c b代表块设备 c代表字符设备 块设备与字符设备 Linux操作系统下有两类主要的设备文件 字符设备块设备 字符设备 所有能够像字节流一样访问的设备 字符设备是以字节为单位逐个进行I 0操作的设备 在对字符设备发出读写请求时 实际的硬件I 0紧接着就发生了 块设备 Linux的块设备通常是指诸如磁盘 内存 Flash等可以容纳文件系统的存储设备 块设备则是利用一块系统内存作为缓冲区 当用户进程对设备进行读写请求时 驱动程序先查看缓冲区中的内容 如果缓冲区中的数据能满足用户的要求就返回相应的数据 否则就调用相应的请求函数来进行实际的I 0操作 1 3设备驱动程序模块 Linux下的设备驱动程序可以按照两种方式进行编译 一种是直接静态编译成内核的一部分 一种是编译成可以动态加载的模块 静态编译缺点是 会增加内核的大小 要改动内核的源文件 不能动态地卸载 不利于调试 所以通常使用模块方式 从本质上来讲 模块也是内核的一部分 因为它不同于普通的应用程序 不能调用位于用户态下的C或者C 库函数 而只能调用Linux内核提供的函数 模块的加载和卸载方式 insmod完成模块的加载 rmmod命令完成模块的卸载具体实现是 init module cleanup module 具体的流程见1 5节 字符设备驱动程序动态连接图 1 4设备驱动程序接口 Linux中设备驱动程序接口是通过特定的数据结构 file operations 来完成的 其定义如下 结构体file operations在头文件linux fs h中定义的 structfile operations loff t llseek structfile loff t int ssize t read structfile char size t loff t ssize t write structfile conntchar sizet loff t int readdir structfile void filldir t unsignedint poll structfile structpoll table struct int ioctl structinode structfile unsignedintunsignedlong int mmap structfile structmareastruct int open structinode structfile int flush structfile int release structinode structfile int fsync structfile structentry int fasync intstructfile int int checkmediachange kdev tdev int revalidate kdev tdev int lock structfile int structf门e lock 在该数据结构里 指出了设备驱动程序所提供的入口点位置 下面讨论其中几个关键的入口点 llseek 对应着用户空间里的lseek 其作用是改变文件结构中的操作位置 显然只能用于可以随机存取的设备 2 read 进行读操作 其实际上就是把数据写到用户空间去 参数buf为存放读取结果的缓冲区 count为所要读取的数据长度 返回值为负表示读取操作发生错误 否则返回实际读取的字节数 3 write 进行写操作 与read类似 4 readdir 读取目录 对于设备文件来说 这个字段应该为NULL 它仅用于读且只对文件系统有用 5 poll 允许应用程序响应来自设备的给定事件 6 ioctl 驱动程序特殊控制入口点 进行读 写以外的其它操作 参数cmd为自定义的命令 它允许应用程序通过ioctl系统调用控制设备的行为或者从设备取得数据 7 open 是应用程序打开设备时将要调用的文件操作 返回0表示打开成功 返回负数表示失败 它对字符设备和块设备都有缺省实现 如果驱动程序没有提供open入口 则只要 dev driver文件存在就认为打开成功 8 release 在设备关闭时将调用的文件操作 file operations数据结构向Linux操作系统注册一组文件操作 这些文件操作定义了设备提供的特定功能 Linux设备驱动程序可以通过该数据结构向Linux操作系统内核报告自己代表的设备为应用程序提供了哪些功能 对于设备驱动程序而言 可以根据需要定义特定的操作接口 而用不着的则将其设置为NULL 1 5设备驱动程序接口实现过程 Linux的设备驱动程序接口实现过程大致可以分为如下几个部分 驱动程序的注册与注销 设备的打开与释放 设备的读写操作 设备的控制操作 中断处理 1 5 1驱动程序的注册与注销 字符设备的注册是通过内核函数 register chrdev 块设备的注册是通过内核函数 register blkdev register chrdev的调用语法 intregister chrdev unsignedintmajor constchar name structfile operations fops 该函数在失败时返回值是一个负数 成功则返回内核函数的主编号 第一个参数major 是驱动程序向内核注册的主设备编号 如果将其设置为0 则内核将给这个设备动态分配一个主设备编号 第二个参数name 只有一个用途一就是向 proc devices进行注册 这个名字将出现在那里 仅此而已 最后一个参数 最有意义 它定义了设备与外界交互的方法 特别是规定了哪些功能由它自己来负责完成 又有哪些功能需要由内核中的缺省函数来完成 设备的打开与释放 读写操作等都是通过file operations中对应的函数来实现 字符设备的注销是调用内核函数 unregister chrdev 块设备的注销是调用内核函数 unregister blkdev 通过注销 将模块从内核中卸载 1 5 2设备的打开与释放 打开设备 是通过调用file operations结构中的函数open 来完成的 它是驱动程序用来为后面的操作完成初始化准备工作的 在大部分驱动程序中 open 通常需要完成下列工作 1 检查设备相关错误 如设备尚未准备好等 2 如果是第一次打开 则初始化硬件设备 3 识别次设备号 如果有必要则更新读写操作的当前位置指针f ops file结构体中 4 分配和填写要放在file private data里的数据结构 5 使用计数增1 释放设备 是通过调用file operations结构中的函数release 来完成的 这个设备方法有时也被称为 close 它的作用正好与open 相反 通常要完成下列工作 1 使用计数减1 2 释放在file private data中分配的内存 3 如果使用计数为0 则关闭设备 1 5 3设备的读写操作 读和写方法都进行类似的任务 就是 从和到应用程序代码拷贝数据 因此 它们的原型相当相似 ssize tread structfile filp char user buff size tcount loff t offp ssize twrite structfile filp constchar user buff size tcount loff t offp 参数 filp是文件指针 count是请求传输数据的长度buffer是用户空间的数据缓冲区ppos是文件中进行操作的偏移量 类型为64位数 由于用户空间和内核空间的内存映射方式完全不同 所以不能使用象memcpy之类的函数 必须使用如下函数 unsignedlongcopy to user void to constvoid from unsignedlongcount unsignedlongcopy from user void to constvoid from unsignedlongcount Read的返回值返回值等于传递给read系统调用的count参数 表明请求的数据传输成功 2 返回值大于0 但小于传递给read系统调用的count参数 表明部分数据传输成功 根据设备的不同 导致这个问题的原因也不同 一般采取再次读取的方法 3 返回值 0 表示到达文件的末尾 4 返回值为负数 表示出现错误 并且指明是何种错误 错误号的定义参见 Write的返回值1 返回值等于传递给write系统调用的count参数 表明请求的数据传输成功 2 返回值大于0 但小于传递给write系统调用的count参数 表明部分数据传输成功 根据设备的不同 导致这个问题的原因也不同 一般采取再次读取的方法 3 返回值 0 表示没有写入任何数据 标准库在调用write时 出现这种情况会重复调用write 4 返回值为负数 表示出现错误 并且指明是何种错误 错误号的定义参见 1 5 4设备的控制操作 ioctl 什么是ioctl ioctl 是设备驱动程序中对设备的I O通道进行管理的函数 对I O通道进行管理 就是对设备的一些特性进行控制 例如串口的传输波特率 马达的转速等等 它的调用函数 用户空间 如下 intioctl intfd indcmd 其中 fd就是用户程序打开设备时使用open函数返回的文件标示符 cmd就是用户程序对设备的控制命令 后面的省略号 是一些补充参数 一般最多一个 有或没有是和cmd的意义相关的 ioctl方法 驱动程序中定义 ioctl方法原型为 int ioctl structinode inode structfile file unsignedintcmd unsignedlongarg inode和filp两个指针对应应用程序传递的文件描述符fd cmd不会被修改地传递给驱动程序 可选的参数arg则无论用户应用程序使用的是指针还是其他类型值 都以unsignedlong的形式传递给驱动 ioctl方法的命令编号确定 由于为了防止向不该控制的设备发出正确的命令 LINUX驱动的ioctl方法中的cmd参数推荐使用唯一编号 编号方法根据如下规则 编号分为4个字段 type 类型 也称为幻数 8位宽 幻数是一个字母 数据长度也是8 所以就用一个特定的字母来标明设备类型 这和用一个数字是一样的 只是更加利于记忆和理解 2 number 号码 顺序数 8位宽 设备类型 序列号 方向 数据尺寸 8bit 8bit 2bit 8 14bit 这些定义在中可以找到 这里还定义了一些用于构造命令号的宏 3 direction 方向 a IOC NONEb IOC READc IOC WRITE4 size 大小 数据大小 8 14bit 宽度与体系结构有关 在ARM上为14位 ioctl方法的返回值ioctl通常实现一个基于switch语句的各个命令的处理 对于用户程序传递了不合适的命名参数时 POSIX标准规定应返回 ENOTTY 返回 EINVAL是以前常见的方法 注1 不能使用与LINUX预定义命令相同的号码 因为这些命令号码会被内核sys ioctl函数识别 并且不再将命令

温馨提示

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

评论

0/150

提交评论