- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
字符设备驱动程序的扩展操作
第5章 字符设备驱动程序的扩展操作
在关于字符设备驱动程序的那一章中,我们构建了一个完整的设备驱动程序,从中用户可以读也可以写。但实际一个驱动程序通常会提供比同步read和write更多的功能。现在如果出了什么毛病,我已经配备了调试工具,我们可以大胆的实验并实现新操作。
通过补充设备读写操作的功能之一就是控制硬件,最常用的通过设备驱动程序完成控制动作的方法就是实现ioctl方法。另一种方法是检查写到设备中的数据流,使用特殊序列做为控制命令。尽管有时也使用后者,但应该尽量避免这样使用。不过稍后我们还是会在本章的“非ioctl设备控制”一节中介绍这项技术。
正如我在前一章中所猜想的,ioctl系统调用为驱动程序执行“命令”提供了一个设备相关的入口点。与read和其他方法不同,ioctl是设备相关的,它允许应用程序访问被驱动硬件的特殊功能――配置设备以及进入或退出操作模式。这些“控制操作”通常无法通过read/write文件操作完成。例如,你向串口写的所有数据都通过串口发送出去了,你无法通过写设备改变波特率。这就是ioctl所要做的:控制I/O通道。
实际设备(与scull不同)的另一个重要功能是,读或写的数据需要同其他硬件交互,需要某些同步机制。阻塞型I/O和异步触发的概念将满足这些需求,本章将通过一个改写的scull设备介绍这些内容。驱动程序利用不同进程间的交互产生异步事件。与最初的scull相同,你无需特殊硬件来测试驱动程序是否可以工作。直到第8章“硬件管理”我才会真正去与硬件打交道。
ioctl
在用户空间内调用ioctl函数的原型大致如下:
int ioctl(int fd, int cmd, ...);
由于使用了一连串的“.”的缘故,该原型在Unix系统调用列表之中非常突出,这些点代表可变数目参数。但是在实际系统中,系统调用实际上不会有可变数目个参数。因为用户程序只能通过第2章“编写和运行模块”的“用户空间和内核空间”一节中介绍的硬件“门”才能访问内核,系统调用必须有精确定义的参数个数。因此,ioctl的第3个参数事实上只是一个可选参数,这里用点只是为了在编译时防止编译器进行类型检查。第3个参数的具体情况与要完成的控制命令(第2个参数)有关。某些命令不需要参数,某些需要一个整数做参数,而某些则需要一个指针做参数。使用指针通常是可以用来向ioctl传递任意数目数据;设备可以从用户空间接收任意大小的数据。
系统调用的参数根据方法的声明传递给驱动程序方法:
int (*ioctl) (struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg)
inode和filp指针是根据应用程序传递的文件描述符fd计算而得的,与read和write的用法一致。参数cmd不经修改地传递给驱动程序,可选的arg参数无论是指针还是整数值,它都以unsigned long的形式传递给驱动程序。如果调用程序没有传递第3个参数,驱动程序所接收的arg没有任何意义。
由于附加参数的类型检查被关闭了,如果非法参数传递给ioctl,编译器无法向你报警,程序员在运行前是无法注意这个错误的。这是我所见到的ioctl语义方面的唯一一个问题。
如你所想,大多数ioctl实现都包括一个switch语句来根据cmd参数选择正确的操作。不同的命令对应不同的数值,为了简化代码我们通常会使用符号名代替数值。这些符号名都是在预处理中赋值的。不同的驱动程序通常会在它们的头文件中声明这些符号;scull就在scull.h中声明了这些符号。
选择ioctl命令
在编写ioctl代码之前,你需要选择对应不同命令的命令号。遗憾的是,简单地从1开始选择号码是不能奏效的。
为了防止对错误的设备使用正确的命令,命令号应该在系统范围内是唯一的。这种失配并不是不很容易发生,程序可能发现自己正在对象FIFO和kmouse这类非串口输入流修改波特率。如果每一个ioctl命令都是唯一的,应用程序就会获得一个EINVAL错误,而不是无意间成功地完成了操作。
为了达到唯一性的目的,每一个命令号都应该由多个位字段组成。Linux的第一版使用了一个16位整数:高8位是与设备相关的“幻”数,低8位是一个序列号码,在设备内是唯一的。这是因为,用Linus的话说,他有点“无头绪”,后来才接收了一个更好的位字段分割方案。遗憾的是,很少有驱动程序使用新的约定,这就挫伤了程序员使用新约定的热情。在我的源码中,为了发掘这种约定都提供了那些功能,同时防止被其他开发人员当成异教徒而禁止,我使用了新的定义命令的方法。
为了给我的驱动程序选择ioctl号,你应该首先看看include/asm/ioctl.h和Documentation/io
您可能关注的文档
最近下载
- 中学地理学科课程标准与教材研究教学大纲.pdf VIP
- 中建X局各类建筑工程技术经济指标.docx VIP
- 我们的手上有多少细菌?.doc VIP
- 第一单元 观察物体 大单元教学设计2025数学人教版三年级上册(新教材).pdf
- 年东北财经大学国际商学院(校本部) 联招联考项目招生指南.pdf VIP
- 驾驶员安全生产操作规程 - 生产安全.docx VIP
- 公务员(国考)之行政职业能力测验题库附答案(基础题)收藏.docx VIP
- 全册部编版六年级上册全册道德与法治教学课件.pptx
- 第二章-空气流动压力及阻力.pptx VIP
- 2025年全国农产品质量安全检测技能竞赛理论知识考试题库(含答案.docx VIP
文档评论(0)