一、 什么是ioctl

ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数如下:

  int ioctl(int fd, ind cmd, …);

其中fd就是用户程序打开设备时使用open函数返回的文件标示符,cmd就是用户程序对设备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,有或没有是和cmd的意义相关的,如果有的话,第三个参数总是一个指针,但指针的类型依赖于request参数。

ioctl函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支持,用户就可以在用户程序中使用ioctl函数控制设备的I/O通道。

二、 ioctl的必要性 
如果不用ioctl的话,也可以实现对设备I/O通道的控制,但那是蛮拧了。例如,我们可以在驱动程序中实现write的时候检查一下是否有特殊约定的数 据流通过,如果有的话,那么后面就跟着控制命令(一般在socket编程中常常这样做)。但是如果这样做的话,会导致代码分工不明,程序结构混乱,程序员 自己也会头昏眼花的。所以,我们就使用ioctl来实现控制的功能。要记住,用户程序所作的只是通过命令码(cmd)告诉驱动程序它想做什么,至于怎么解释这些命令和怎么实现这些命令,这都是驱动程序要做的事情。

三、 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控制都是通过这一部分的代码实现的。

转载于:https://www.cnblogs.com/Lxk0825/p/10216662.html

Linux下ioctl函数理解相关推荐

  1. linux下system函数的深入理解

    这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数中调用的命令也都一切正常.就没理这个bug,以为 ...

  2. linux驱动---ioctl函数解析

    转自(39条消息) linux驱动---ioctl函数解析_那可真是太开心了的博客-CSDN博客_linux驱动ioctl 参考:ioctl,unlocked_ioctl 处理方法-阿里云开发者社区 ...

  3. linux下syscall函数,SYS_gettid,SYS_tgkill

    出处:http://blog.chinaunix.net/uid-28458801-id-4630215.html linux下syscall函数,SYS_gettid,SYS_tgkill 2014 ...

  4. Linux下curses函数库的详细介绍

    Linux下curses函数库的详细介绍 curses库介绍 安装 curses库函数介绍 初始化和重置函数 管理屏幕的函数 输出到屏幕 从屏幕读取 清除屏幕 移动光标 字符属性 管理键盘的函数 键盘 ...

  5. linux下readlink函数详解

    linux下readlink函数详解 相关函数: stat, lstat, symlink 表头文件: #include <unistd.h> 定义函数:int  readlink(con ...

  6. linux 纪元时间转换,[转]Linux下时间函数time gettimeofday

    Linux下时间函数time & gettimeofday UNIX及Linux的时间系统是由「新纪元时间」Epoch开始计算起,单位为秒.Epoch是指定为1970年1月1日凌晨零点零分零秒 ...

  7. Linux下connect函数 阻塞 与 非阻塞 问题

    一.概述 linux系统下,connect函数是阻塞的,阻塞时间的长度与系统相关.而如果把套接字设置成非阻塞,调用connect函数时会报错Operation now in progress,且err ...

  8. Linux下select函数实现的聊天服务器

    转载: http://blog.csdn.net/microtong/article/details/4989902 Linux下select函数实现的聊天服务器  佟强 http://blog.cs ...

  9. LINUX下poll函数用法

    LINUX下poll函数用法 文章目录 LINUX下poll函数用法 一.函数介绍 二.使用 1. 一.函数介绍 int poll(struct pollfd *fds, nfds_t nfds, i ...

最新文章

  1. matlab中如何输出,将文本信息显示到屏幕上的输出流
  2. Ubuntu中配置SSH服务
  3. 如何写出安全的API接口
  4. 计算机网络之数据链路层:10、CSMA协议-随机访问介质访问控制
  5. System.Runtime.InteropServices.COMException 检索COM类工厂中CLSID{xxxxxxxxx}的组件时失败解决方法...
  6. 《Java程序设计》第四次学习总结
  7. 研究预测2022年全球VoLTE市场规模达348亿美元
  8. 关于新建android项目时 appcompat_v7报错问题的一点总结
  9. Pandas+Pyecharts | 医院药品销售数据可视化
  10. 网易云音乐获取音频链接(爬虫)破解params参数
  11. 博士一篇SCI三区即可入职该高校,配偶是硕士的,直接给事业编!还有45万安家费…...
  12. Linux下套接字详解(八)----select模式下服务器(非阻塞,单进程+多进程+多线程)
  13. C语言函数之经典例题
  14. html5小游戏猴子爬树源码,猴子爬树小班教案
  15. Showwindow及参数介绍
  16. MySQL数据库对象
  17. 【剑桥摄影协会】针对摄影的显示器校准
  18. 4.unity UI ScrollRect 无限滚动条(最详细)
  19. 剖析加载RAID驱动的步骤(BIOS RAIDKEY点子)
  20. PHP学生成绩管理,使用MySQL数据库,界面简洁,适合当做学生期末课设作业,有数据库和PHP文件源码,没有使用任何框架,都是使用简单的PHP代码

热门文章

  1. python os详解
  2. 树莓派 4G模块 PPP 拨号 NDIS 拨号
  3. 容器的主要目的是什么,Wise2C睿云智合的实战
  4. 这些科技大佬们的星座你知道吗
  5. SQLSERVER之快速掌握T-SQL语句
  6. Spring Aop pointcut expression表达式解析
  7. Visual Studio 2015编译wxWidgets
  8. window启动过程讲解--PPT截图[张银奎]
  9. [Java] 蓝桥杯ALGO-100 算法训练 整除问题
  10. [Java] 1001. 害死人不偿命的(3n+1)猜想 (15)-PAT乙级