转自:
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 函数" ioctl 函数是 Linux 驱动程序中对设备的 I/O 通道进行管理的函数,它可以控制设备的一些特性,例如串口的传输波特率、马达的转速等等。ioctl 函数的调用格式为 int ioctl(int fd, int cmd,...
ioctl 函数用法详解 ioctl 函数是一个系统调用函数...ioctl 函数是 Linux 系统中一个非常重要的系统调用函数,用于控制设备或文件描述符的参数。它可以用来执行各种设备操作,如获取或设置设备参数、执行设备命令等。
linux 系统 ioctl 使用示例 在 Linux 系统中,ioctl(Input/Output Control)是一种系统调用,用于控制和管理设备文件的输入/输出操作。ioctl 函数可以用来设置或获取设备文件的属性、控制设备的行为、执行特殊的 I...
"Linux下的ioctl函数详解" Linux操作系统中,ioctl函数是一个非常重要的概念,它是设备驱动程序中对设备的I/O通道进行管理的函数。下面,我们将详细讨论ioctl函数的定义、必要性、实现方式、cmd参数的生成等方面。 ...
### ioctl函数详解:深入理解设备控制的核心机制 在Linux系统编程中,`ioctl`函数扮演着设备控制的关键角色。本文将全面解析`ioctl`函数的工作原理、如何在内核模块中实现以及其在用户空间与内核空间通信中的重要性...
在 Linux 系统中,ioctl 函数的原型为 `int ioctl(int fd, int request, ...);`,其中 `fd` 是要控制的文件描述符,`request` 是要执行的操作码,参数 `...` 是依赖于 `request` 的参数。 在 Linux 系统中,ioctl ...
ioctl函数在Linux操作系统中扮演着重要的角色,它是设备驱动程序和应用程序之间进行通信的主要机制之一。这个函数允许用户空间的应用程序对设备进行控制操作,比如配置硬件参数、获取设备状态等,而不仅仅是简单的...
ioctl系统调用流程是一个复杂的过程,涉及到系统调用框架、系统调用号、系统调用表、DoSyscall函数、sys_ioctl函数等多个方面。但是,通过对每个组件的详细分析,我们可以更好地理解ioctl系统调用流程的工作原理。
ioctl函数的原型如下所示: ```c int ioctl(int __fd, unsigned long int __request, ...); ``` - `__fd`:代表文件描述符,通常是在调用open或类似函数时获得的。 - `__request`:这是一个无符号长整型参数,用于...
### Linux系统文件分析ioctl.c&stat.c程序 #### 一、引言 随着计算机技术的发展,操作系统作为连接用户与硬件的重要桥梁,在计算机科学领域占据着举足轻重的地位。Linux作为一种广泛使用的开源操作系统,因其高度...
"Linux系统下RS-485串行通信程序设计" 本文简要介绍了在Linux操作系统下RS-485多点串行通信程序设计的实现方法。首先,文章概述了Linux操作系统的特点,包括高效、健壮、安全和自由等特征,并且具有跨平台的特性,...
在Linux内核中,ioctl函数主要在`<linux/ioctl.h>`头文件中定义。 1. **ioctl命令定义** 每个ioctl命令都有一个唯一的命令标识符,由三个参数组合而成:主设备号、次设备号和命令代码。命令标识符通常定义为`#...
在Linux内核开发中,`ioctl`(Input/Output Control)是用于设备驱动程序与用户空间应用程序之间通信的一种机制。`unlocked_ioctl`是Linux 3.16版本引入的一个新特性,它改进了传统的`ioctl`调用,提高了并发性能和...
总结来说,这两个示例展示了如何利用`ioctl`系统调用在Linux下获取网络接口的配置信息并检查物理连接状态。这些基础知识对于进行网络编程和系统级调试非常重要,特别是对于需要与硬件交互或者处理网络设备问题的...
本文将介绍通过ioctl函数实现获取Linux系统的IP地址和MAC地址的方法。ioctl函数是一个Unix中的少有的几个“家族类”复杂函数,它可以用于获取系统的所有接口列表、接口地址、接口标志、广播地址、子网掩码等信息。 ...
### Linux设备驱动常用函数详解 #### 一、概述 Linux设备驱动是操作系统与硬件设备之间的桥梁,负责管理和控制硬件资源。对于Linux驱动开发者而言,掌握常用接口函数是基础且重要的一步。本文档将深入探讨Linux ...
文章将从理论基础出发,介绍Linux设备文件的基本概念、系统调用机制以及如何通过ioctl函数获取系统当前的时间日期信息。 ### Linux 设备文件概述 在Linux操作系统中,所有硬件设备都被抽象成文件的形式,即设备...
在Linux系统中,IIC(Inter-Integrated Circuit)是一种常用于设备间短距离通信的串行接口,尤其在嵌入式系统中应用广泛。本文将深入探讨两种在Linux应用层进行IIC操作的方法:通过read和write函数以及通过构建i2c_...
在ubuntu18.04系统;利用V4L2采集两个usb摄像头数据,在QT上控件显示两个采集的视频流。可以同时采集两个相机。 在QT下调用V4L2的库函数来实现采集视频流。并且把采集到的视频流在控件上显示出来。 相机输出格式...
Linux中的`ioctl`函数是一个非常重要的系统调用,主要用于设备驱动程序和其他系统组件之间的通信。在计算机科学,尤其是操作系统和网络编程领域,`ioctl`在Linux环境下被广泛使用,允许程序控制和查询设备状态,包括...