- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第18章 设备驱动程序的编写
Linux应用与开发典型实例精讲 配套教材: 《Linux应用与开发典型实例精讲》 邱铁、于玉龙、徐子川编著. 清华大学出版社. 2010.5 Email: openlinux21@ 第18章 设备驱动程序的编写 学习本章要达到的目标: 1. 了解Linux下设备驱动程序的原理; 2.学习Linux2.6.30内核下设备驱动程序编写方法; 3. 掌握用模块方式设计和加载驱动程序的方法; 4. 学会如何通过配置编译内核,将驱动添加进内核。 18.1 Linux驱动程序 设备驱动程序是为相应的硬件提供给应用程序的一组标准化接口 应用程序通过标准化系统调用,进入Linux内核状态后,由内核调用相应的设备驱动程序实现对实际硬件设备的读、写、控制等操作。 18.1.1 驱动程序分类 1.字符设备 字符设备包括那些使数据成为数据流的设备,一般不使用缓存技术。 典型的字符设备有串行接口和音频设备等 。 18.1.1 驱动程序分类 2.块设备 块设备是可寻址的以块为单位访问的设备,一般使用缓存技术。 磁盘驱动器和光盘驱动器都是块设备,它们内部的文件指针可以指向设备内部的任何位置。 3.网络接口 网络接口是一个数据的中转站,每一个网络任务都经过一个网络接口形成,能够和其他主机进行数据交换。 典型的网络接口有网卡设备。 4.总线设备 总线接口与上面的设备类型是有区别的,因为它们都有自己的协议和标准时序,在设计驱动时要与设备的标准严格对应。 I2C、 AMBA、PCI等总线 18.1.2 驱动程序开发的注意事项 对于驱动程序开发不仅要遵守内核编程规则,而且要遵循以下规则: 名字空间。 在linux设备驱动程序开发时,要注意自己所定义的标号不要与全局内核名字空间中的命名发生冲突。 设备号。 在linux内核下的设备都有一定的编号形式,一般由主设备号和次设备号组成。 主设备号用来表明这是哪一种设备 次设备号表明这是哪一个具体的设备 18.1.3设备目录 设备都以文件的形式存放在/dev目录下,通过以下命令我们可以看到详细的信息。 ls –l /dev 设备详细清单 字符设备用c来标识,块设备用b标识。 第一列为设备文件权限; 第二列为链接数即使用该设备的用户数; 第三列当前用户; 第四列为用户组; 第五列为设备号,分为主设备号和次设备号; 最后一列为设备名称。 18.2 Linux驱动数据结构分析 Linux驱动核心结构体 设备的内核操作函数 18.2 .1Linux驱动核心结构体 设备驱动程序也需要将自己的功能映射成为文件操作,而这个映射在Linux中通过一个结构struct file_operations来完成。 2.6.30内核中的file_operations结构体(路径inux-2.6.30/include/linux/fs.h)所有可能的函数,但是一个驱动程序中并不是必须完成所有函数的映射,可以有选择的进行使用。 struct module *owner; 这个域是用来设置指向“拥有”该结构的模块指针,内核使用该指针维护模块的使用计数。 ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); read 调用用来从设备中读数据,需要提供字符串指针。从设备中读取数据时,成功返回所读取的字节数,read 等于NULL 时,将导致调用失败,并返回-EINVAL。 ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); write调用用来向字符设备写数据,需要提供所写指针内容。当向设备写入数据时,成功返回实际写入的字节数,write 等于NULL 时,将导致调用失败,并返回-EINVAL。 int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); ioctl域用来设置控制设备的方式,这提供用户程序对设备执行特定的命令的方法,例如控制光盘的弹出。需要提供符合设备预先定义的命令字。调用成功返回非负值。 int (*open) (struct inode *, struct file *); open调用用来打开设备,并初始化设备,准备进行操作。如果该方法没有实现,系统调用open也会是成功的 ,但驱动程序得不到任何打开设备的通知。在实现中,可以给出一定的提示信息。 int (*release) (struct inode *, struct file *); release调用用来关闭设备,释放设备资源。当且仅
文档评论(0)