Linux内核的ioctl函数学习

我这里说的ioctl函数是在驱动程序里的,由于我不知道还有没有别的场合用到了ioctl, 因此就规定了咱们讨论的范围。为何要写篇文章呢,是由于我前一阵子被ioctl给搞混了,这几天才弄明白它,因而在这里清理一下头脑。 1、 什么是ioctl。 ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数以下: int ioctl(int fd, ind cmd, …); 其中fd就是用户程序打开设备时使用open函数返回的文件标示符,cmd就是用户程序对设备的控制命令,至于后面的省略号,那是一些补充参数,通常最多一个,有或没有是和cmd的意义相关的。 ioctl函数是文件结构中的一个属性份量,就是说若是你的驱动程序提供了对ioctl的支持,用户就能够在用户程序中使用ioctl函数控制设备的I/O通道。 2、 ioctl的必要性 若是不用ioctl的话,也能够实现对设备I/O通道的控制,但那就是蛮拧了。例如,咱们能够在驱动程序中实现write的时候检查一下是否有特殊约定的数据流经过,若是有的话,那么后面就跟着控制命令(通常在socket编程中经常这样作)。可是若是这样作的话,会致使代码分工不明,程序结构混乱,程序员本身也会头昏眼花的。 因此,咱们就使用ioctl来实现控制的功能。要记住,用户程序所做的只是经过命令码告诉驱动程序它想作什么,至于怎么解释这些命令和怎么实现这些命令,这都是驱动程序要作的事情。 3、 ioctl如何实现 这是一个很麻烦的问题,我是能省则省。要说清楚它,没有四五千字是不行的,因此我这里是不可能把它说得很是清楚了,不过若是有读者对用户程序怎么和驱动程序联系起来感兴趣的话,能够看我前一阵子写的《write的奥秘》。读者只要把write换成ioctl,就知道用户程序的ioctl是怎么和驱动程序中的ioctl实现联系在一块儿的了。 我这里说一个大概思路,由于我以为《Linux设备驱动程序》这本书已经说的很是清楚了,可是得化一些时间来看。 在驱动程序中实现的ioctl函数体内,其实是有一个switch{case}结构,每个case对应一个命令码,作出一些相应的操做。怎么实现这些操做,这是每个程序员本身的事情,由于设备都是特定的,这里也无法说。关键在于怎么样组织命令码,由于在ioctl中命令码是惟一联系用户程序命令和驱动程序支持的途径。 命令码的组织是有一些讲究的,由于咱们必定要作到命令和设备是一一对应的,这样才不会将正确的命令发给错误的设备,或者是把错误的命令发给正确的设备,或者是把错误的命令发给错误的设备。这些错误都会致使不可预料的事情发生,而当程序员发现了这些奇怪的事情的时候,再来调试程序查找错误,那将是很是困难的事情。 因此在Linux核心中是这样定义一个命令码的: ____________________________________ | 设备类型 | 序列号 | 方向 |数据尺寸| |----------|--------|------|--------| | 8 bit | 8 bit |2 bit |8~14 bit| |----------|--------|------|--------| 这样一来,一个命令就变成了一个整数形式的命令码。可是命令码很是的不直观,因此Linux Kernel中提供了一些宏,这些宏可根据便于理解的字符串生成命令码,或者是从命令码获得一些用户能够理解的字符串以标明这个命令对应的设备类型、设备序列号、数据传送方向和数据传输尺寸。 这些宏我就不在这里解释了,具体的形式请读者察看Linux核心源代码中的和,文件里给除了这些宏完整的定义。这里我只多说一个地方,那就是"幻数"。 幻数是一个字母,数据长度也是8,因此就用一个特定的字母来标明设备类型,这和用一个数字是同样的,只是更加利于记忆和理解。就是这样,再没有更复杂的了。 更多的说了也没有,读者仍是看一看源代码吧,推荐各位阅读《Linux 设备驱动程序》所带源代码中的short一例,由于它比较短小,功能比较简单,能够看明白ioctl的功能和细节。 4、 cmd参数如何得出 这里确实要说一说,cmd参数在用户程序端由一些宏根据设备类型、序列号、传送方向、数据尺寸等生成,这个整数经过系统调用传递到内核中的驱动程序,再由驱动程序使用解码宏从这个整数中获得设备的类型、序列号、传送方向、数据尺寸等信息,而后经过switch{case}结构进行相应的操做。 要透彻理解,只能是经过阅读源代码,我这篇文章实际上只是一个引子。Cmd参数的组织仍是比较复杂的,我认为要搞熟它仍是得花很多时间的,可是这是值得的,驱动程序中最难的是对中断的理解。 5、 小结 ioctl其实没有什么很难的东西须要理解,关键是理解cmd命令码是怎么在用户程序里生成并在驱动程序里解析的,程序员最主要的工做量在switch{case}结构中,由于对设备的I/O控制都是经过这一部分的代码实现的。 程序员

本文转自:http://blog.csdn.net/jerrygj/article/details/6533194 编程

相关文章
相关标签/搜索