【Linux】【驱动】ioctl介绍和应用场景

1.什么是ioctl

ioctl是用于设备(文件或者套接字)控制的公共接口,除了读取和写入设备之外,大部分驱动程序还需要另外一种能力,即通过设备驱动程序执行各种类型的硬件控制。简单数据传输外,大部分设备可以执行其他一些操作,比如,用户空间经常会请求设备状态,弹出设备,报告错误信息,改变波特率或者执行自破坏,等。这些操作通常通过ioctl方法执行,该方法实现了同名的系统调用。

2.ioctl

2.1 函数原型

在用户空间,ioctl系统调用原型如下:
#include <sys/ioctl.h>
int ioctl(int d, int request, ...);

参数中使用的…表示可变数码的参数,但是在实际系统找中,系统调用不会真正使用可变数目的参数,而是必须具有精确定义的原型。

2.2 参数说明

  1. int d
    该参数是SOCK_DGRAM类型的套接字,一般初始化方式为:
    sock = socket(AF_INET, SOCK_DGRAM, 0);

  2. int request
    该参数是请求命令编号。这些编号一部分是已经编订好的,另外一部分是用户自己通过调用系统接口宏编制的。早期的Linux版本,为了方便程序员创建唯一的ioctl命令号,每一个命令号划分为多个位字段,Linux第一个版本使用一个16 bit的无符号整数。高8 bit是与设备相关的幻数,地8位是一个序列号嘛,在该设备内唯一。
    已经编码好的命令,可以参考文件kernel/Documentation/ioctl/ioctl-number.txt中的说明,下面列举出对私有设备的编码:
    0x89 00-06 arch/x86/include/asm/sockios.h
    0x89 0B-DF linux/sockios.h
    0x89 E0-EF linux/sockios.h SIOCPROTOPRIVATE range
    0x89 E0-EF linux/dn.h PROTOPRIVATE range
    0x89 F0-FF linux/sockios.h SIOCDEVPRIVATE range

    对于比较新的设备的请求命令编码,或者是用户自己添加的某类设备(比如 gpio)命令编码,则使用32 bit的请求码,这32位的编码有对应的规则:
    bits meaning
    31-30 00 - no parameters: uses _IO macro
    10 - read: _IOR
    01 - write: _IOW
    11 - read/write: _IOWR
    29-16 size of arguments
    15-8 ascii character supposedly,unique to each driver
    7-0 function #

    kernel中提供宏接口用于计算出唯一的命令请求码
    #define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
    #define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
    #define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
    #define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
    #define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
    #define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
    #define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))

    常见的16bit的命令编码在文件kernel\include\linux\socketios.h中定义:
    /* Socket configuration controls. */
    #define SIOCGIFNAME 0x8910 /* get iface name*/
    #define SIOCSIFLINK 0x8911 /* set iface channel */
    #define SIOCGIFCONF 0x8912 /* get ifa

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值