5. ioctl() 函数解析

解析完 open、close、read、write 四个函数后,终于到我们的 ioctl() 函数了一、 什么是ioctl

ioctl是设备驱动程序中对设备的IO通道进行管理的函数。所谓对IO通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率,马达的转速等。

函数名: ioctl

功 能: 控制I/O设备

用 法: int ioctl(int handle, int cmd,[int *argdx, int argcx]);

参数:fd是用户程序打开设备时使用open函数返回的文件标示符,cmd是用户程序对设备的控制命令,后面是一些补充参数,一般最多一个,这个参数的有无和cmd的意义相关。

include/asm/ioctl.h中定义的宏的注释:

二、ioctl的必要性

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

三、 ioctl如何实现

在驱动程序中实现的ioctl函数体内,实际上是有一个switch{case}结构,每一个case对应一个命令码,做出一些相应的操作。怎么实现这些操作,这是每一个程序员自己的事情。因为设备都是特定的,这里也没法说。关键在于怎样组织命令码,因为在ioctl中命令码是唯一联系用户程序命令和驱动程序支持的途径。

命令码的组织是有一些讲究的,因为我们一定要做到命令和设备是一一对应的,这样才不会将正确的命令发给错误的设备,或者是把错误的命令发给正确的设备,或者是把错误的命令发给错误的设备。这些错误都会导致不可预料的事情发生,而当程序员发现了这些奇怪的事情的时候,再来调试程序查找错误,那将是非常困难的事情。所以在Linux核心中是这样定义一个命令码的:

这样一来,一个命令就变成了一个整数形式的命令码;但是命令码非常的不直观,所以Linux Kernel中提供了一些宏。这些宏可根据便于理解的字符串生成命令码,或者是从命令码得到一些用户可以理解的字符串以标明这个命令对应的设备类型、设备序列号、数据传送方向和数据传输尺寸。

比如上面展现的:

我们在前面PWM驱动程序中也定义了命令宏:

这里必须要提一下的,就是"幻数"MAGIC_NUMBER, "幻数"是一个字母,数据长度也是8,用一个特定的字母来标明设备类型,这和用一个数字是一样的,只是更加利于记忆和理解。

四、 cmd参数如何得出

这里确实要说一说,cmd参数在用户程序端由一些宏根据设备类型、序列号、传送方向、数据尺寸等生成,这个整数通过系统调用传递到内核中的驱动程序,再由驱动程序使用解码宏从这个整数中得到设备的类型、序列号、传送方向、数据尺寸等信息,然后通过switch{case}结构进行相应的操作。实例时刻,当然只是部分代码:https://blog.csdn.net/zqixiao_09/article/details/50859302

原文地址:https://www.cnblogs.com/Ocean-Star/p/9249899.html

时间: 2024-10-01 17:29:58

5. ioctl() 函数解析的相关文章

(笔记)Linux下的ioctl()函数详解

我这里说的ioctl函数是指驱动程序里的,因为我不知道还有没有别的场合用到了它,所以就规定了我们讨论的范围.写这篇文章是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑. 一. 什么是ioctl      ioctl是设备驱动程序中对设备的I/O通道进行管理的函数.所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率.马达的转速等等.它的调用个数如下:  int ioctl(int fd, ind cmd, …):      其中fd是用户程序

【转】Linux内核的ioctl函数学习

来源:Linux公社  http://www.linuxidc.com/Linux/2007-12/9623.htm 我这里说的ioctl函数是在驱动程序里的,因为我不知道还有没有别的场合用到了ioctl, 所以就规定了我们讨论的范围.为什么要写篇文章呢,是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑. 一. 什么是ioctl. ioctl是设备驱动程序中对设备的I/O通道进行管理的函数.所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率

Linux下的ioctl()函数详解

我这里说的ioctl函数是指驱动程序里的,因为我不知道还有没有别的场合用到了它,所以就规定了我们讨论的范围.写这篇文章是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑. 一. 什么是ioctl     ioctl是设备驱动程序中对设备的I/O通道进行管理的函数.所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率.马达的转速等等.它的调用个数如下: int ioctl(int fd, ind cmd, -):     其中fd是用户程序打开设

Linux下ioctl函数理解

一. 什么是ioctl ioctl是设备驱动程序中对设备的I/O通道进行管理的函数.所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率.马达的转速等等.它的调用个数如下: int ioctl(int fd, ind cmd, -): 其中fd就是用户程序打开设备时使用open函数返回的文件标示符,cmd就是用户程序对设备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,有或没有是和cmd的意义相关的,如果有的话,第三个参数总是一个指针,但指针的类型依赖于re

AngularJS指令中的compile与link函数解析

AngularJS指令中的compile与link函数解析 通常大家在使用ng中的指令的时候,用的链接函数最多的是link属性,下面这篇文章将告诉大家complie,pre-link,post-link的用法与区别. 原文地址 angularjs里的指令非常神奇,允许你创建非常语义化以及高度重用的组件,可以理解为web components的先驱者. 网上已经有很多介绍怎么使用指令的文章以及相关书籍,相互比较的话,很少有介绍compile与link的区别,更别说pre-link与post-lin

ngx_http_process_request_headers函数解析

ngx_http_process_request_headers函数被ngx_http_process_request_line函数调用,将请求头逐个放到r->headers_in.headers结构体中.由于不确定请求中一共有多少个header,所以这个函数主要功能也是在for(;;){}循环中完成,一下所有的代码都是在上述循环内部的.主要代码和解析如下: 判断是否超时,如果超时,报错并结束请求.    if (rev->timedout) {        ngx_log_error(NG

IOCTL函数用法

http://blog.163.com/he_junwei/blog/static/19793764620152510533753/ http://blog.csdn.net/styyzxjq2009/article/details/8023501 .ioctl的实现 一.ioctl的简介: 虽然在文件操作结构体"struct file_operations"中有很多对应的设备操作函数,但是有些命令是实在找不到对应的操作函数.如CD-ROM的驱动,想要一个弹出光驱的操作,这种操作并不是

iOS 基础函数解析 - Foundation Functions Reference

Foundation Functions Reference Framework Foundation/Foundation.h Declared in NSBundle.h NSByteOrder.h NSDecimal.h NSException.h NSObjCRuntime.h NSObject.h NSPathUtilities.h NSRange.h NSZone.h Overview This chapter describes the functions and function

第3章 文件I/O(4)_dup、dup2、fcntl和ioctl函数

5. 其它I/O系统调用 (1)dup和dup2函数 头文件 #include<unistd.h> 函数 int dup(int oldfd); int dup2(int oldfd, int newfd); 返回值 若成功返回新文件描述符,出错返回-1 功能 文件描述符的复制(将oldfd复制给newfd) 参数 old:原先的文件描述符 newfd: 新文件描述符 备注 (1)由dup返回的新文件描述符一定是当前可用文件描述符中最小数值. (2)用dup2则可以用newfd参数指定新描述符