`

linux系统下的ioctl函数

阅读更多
转自:http://www.sudu.cn/info/html/edu/20080102/282377.html


我这里说的ioctl函数是在驱动程序里的,因为我不知道还有没有别的场合用到了ioctl,
      所以就规定了我们讨论的范围。为什么要写篇文章呢,是因为我前一阵子被ioctl给搞混
      了,这几天才弄明白它,于是在这里清理一下头脑。
     
      一、 什么是ioctl。
      ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就
      是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数
      如下:
      int ioctl(int fd, ind cmd, …);
      其中fd就是用户程序打开设备时使用open函数返回的文件标示符,cmd就是用户程序对设
      备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,有或没有是和
      cmd的意义相关的。
      ioctl函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支
      持,用户就可以在用户程序中使用ioctl函数控制设备的I/O通道。
     
      二、 ioctl的必要性
      如果不用ioctl的话,也可以实现对设备I/O通道的控制,但那就是蛮拧了。例如,我们可
      以在驱动程序中实现write的时候检查一下是否有特殊约定的数据流通过,如果有的话,
      那么后面就跟着控制命令(一般在socket编程中常常这样做)。但是如果这样做的话,会
      导致代码分工不明,程序结构混乱,程序员自己也会头昏眼花的。
      所以,我们就使用ioctl来实现控制的功能。要记住,用户程序所作的只是通过命令码告
      诉驱动程序它想做什么,至于怎么解释这些命令和怎么实现这些命令,这都是驱动程序要
      做的事情。
     
      三、 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的功能和细
      节。

      四、 cmd参数如何得出
      这里确实要说一说,cmd参数在用户程序端由一些宏根据设备类型、序列号、传送方向、
      数据尺寸等生成,这个整数通过系统调用传递到内核中的驱动程序,再由驱动程序使用解
      码宏从这个整数中得到设备的类型、序列号、传送方向、数据尺寸等信息,然后通过
      switch{case}结构进行相应的操作。
      要透彻理解,只能是通过阅读源代码,我这篇文章实际上只是一个引子。Cmd参数的组织
      还是比较复杂的,我认为要搞熟它还是得花不少时间的,但是这是值得的,驱动程序中最
      难的是对中断的理解。

      五、 小结
      ioctl其实没有什么很难的东西需要理解,关键是理解cmd命令码是怎么在用户程序里生成
      并在驱动程序里解析的,程序员最主要的工作量在switch{case}结构中,因为对设备的
      I/O控制都是通过这一部分的代码实现的。

      参考资料:
      1.《Linux 设备驱动程序》,鲁宾尼著,中国电力出版社。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/17Array28/showart_525854.html
分享到:
评论

相关推荐

    linux下ioctl函数

    linux下ioctl函数,这里说的ioctl函数是在驱动程序里的

    linux系统ioctl使用示例

    程序1:检测接口的 inet_addr,netmask,broad_addr 程序2:检查接口的物理连接是否正常 程序3:更简单一点测试物理连接 程序4:调节音量

    linux下ioctl函数 (2).docx

    ...

    ioctl命令详解

    详细阐述Linux下驱动开发的ioctl函数的使用和注意事项

    ioctl好文章,推荐给大家

    ioctl 好文章,推荐给大家,是大家很快理解ioctl的作用,函数名: ioctl 功 能: 控制I/O设备 用 法: int ioctl(int handle, int cmd,[int *argdx, int argcx]); include/asm/ioctl.h中定义的宏的注释: #define _IOC_...

    ubuntu18.04 在QT下调用V4L2的ioctl函数来实现采集视频流 把采集到的视频流在控件上显示出来 同时采集两个相机

    在ubuntu18.04系统;利用V4L2采集两个usb摄像头数据,在QT上控件显示两个采集的视频流。可以同时采集两个相机。 在QT下调用V4L2的库函数来实现采集视频流。并且把采集到的视频流在控件上显示出来。 相机输出格式...

    Linux操作系统的声音设备编程实例解析

    Linux下常用的声音设备是内部扬声器和声卡,它们都对应/dev目录下的一个或多个设备文件,我们象打开普通文件一样打开它们,用ioctl()函数设置一些参数,然后对这些打开的特殊文件进写操作。由于这些文件不是普通的...

    Linux声音设备编程实例.rar_audio linux_ioctl_linux 声卡_声卡_声音 比对

    一般说来,我们常用的声音设备是内部扬声器和声卡,它们都对应/dev目录下的一个或多个设备文件,我们象打开普通文件一样打开它们,用ioctl()函数设置一些参数,然后对这些打开的特殊文件进写操作。

    linux下基于V4L2/Qt的usb摄像头采集显示程序

    linux下基于V4L2/Qt的usb摄像头采集显示程序 Qt工程, 测试使用的是Qt5.6.0 可以正常使用, 采集usb摄像头的图像并显示, 可以正常配置摄像头像素

    linux操作系统培训资料.pptx

    如果我们想控制串口的速率、校验位、码位的长度,我们只需要调用ioctl函数,然后传入相应的数据就可以了。 linux操作系统培训资料全文共28页,当前为第8页。 Linux文件管理 Linux系统中使用的文件类型 目前linux...

    Linux操作系统的声音设备编程实例

    一般说来,我们常用的声音设备是内部扬声器和声卡,它们都对应/dev目录下的一个或多个设备文件,我们象打开普通文件一样打开它们,用ioctl()函数设置一些参数,然后对这些打开的特殊文件进写操作。由于这些文件...

    linux无线网卡信号强度测定

    通过调用linux本身的ioctl函数,输出无线网卡信号强度,单位为dbm

    linux网络编程-宋敬彬-part3

    3.1 Linux下的文件系统 61 3.1.1 Linux下文件的内涵 61 3.1.2 文件系统的创建 62 3.1.3 挂接文件系统 64 3.1.4 索引节点inode 65 3.1.5 普通文件 66 3.1.6 设备文件 66 3.1.7 虚拟文件系统VFS 68 ...

    矩阵键盘通过ioctl控制上传

    模拟按键功能的调用采用了标准Linux的ioctl模型。设计函数包括open、read、ioctl、close等标准操作。应用接口开发时,应包含定义为input_event的变量。例:struct input_event button_event。 本驱动程序的字符设备...

    linux网络编程-宋敬彬-part2

    3.1 Linux下的文件系统 61 3.1.1 Linux下文件的内涵 61 3.1.2 文件系统的创建 62 3.1.3 挂接文件系统 64 3.1.4 索引节点inode 65 3.1.5 普通文件 66 3.1.6 设备文件 66 3.1.7 虚拟文件系统VFS 68 ...

    rtl8188gu无线网卡驱动linux

    linux的rtl8188gu无线网卡驱动,可以解决8188gu芯片在linux无法识别的问题。解压后使用make命令

    步进电机QT源代码

    3,完善你的controlMachine函数,在函数中实现:读取Edit中变量的值,放在你的新变量中,使用Linux系统函数open打开设备文件,调用::ioctl函数(在QT中直接调用系统函数前边得加::两个冒号),使用ioctl传入参数,然后...

    IIC Linux 应用层的两种操作方式

    一种是使用read and write的方式读写。一种是使用构造i2c_msg结构体的方式并利用ioctl的方式读写

    linux rtc驱动

    详细介绍linux rtc驱动的编写思路,以及测试程序介绍

    通过Qt界面控制步进电机的启停

    3,完善你的controlMachine函数,在函数中实现:读取Edit中变量的值,放在你的新变量中,使用Linux系统函数open打开设备文件,调用::ioctl函数(在QT中直接调用系统函数前边得加::两个冒号),使用ioctl传入参数,然后...

Global site tag (gtag.js) - Google Analytics