字符设备驱动的ioctl函数
用户空间的ioctl
#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);
/*
fd:文件描述符
cmd:控制命令
...:可选参数:插入*argp,具体内容依赖于cmd
*/
//使用例子,framerbuffer技术获取屏幕属性
ioctl(fd, FBIOGET_VSCREENINFO, &varInfo);
内核空间的ioctl
#include <asm/ioctl.c>
int (*ioctl) (struct inode *, struct file *, unsigned int cmd, unsigned long argv);
long (*unlocked_ioctl) (struct file *, unsigned int cmd, unsigned long argv);
long (*compat_ioctl) (struct file *, unsigned int cmd, unsigned long argv);
/*
inode file:文件描述符
cmd:由用户空间直接不经修改的传递给驱动程序
argv:可选参数:具体内容依赖于cmd
*/
用户空间的ioctl
会调用内核空间的ioctl
,内核空间中cmd
有具体的含义。
图片转自知乎,侵删。
分为4个字段:数据方向,数据大小,设备类型,命令编号
- dir(direction),ioctl 命令访问模式(数据传输方向),占据 2 bit,可以为 _IOC_NONE、_IOC_READ、_IOC_WRITE、_IOC_READ | _IOC_WRITE,分别指示了四种访问模式:无数据、读数据、写数据、读写数据;
- size,涉及到 ioctl 函数 第三个参数 arg ,占据 13bit 或者 14bit(体系相关,arm 架构一般为 14 位),指定了 arg 的数据类型及长度,如果在驱动的 ioctl 实现中不检查,通常可以忽略该参数;
- type(device type),设备类型,占据 8 bit,在一些文献中翻译为 “幻数” 或者 “魔数”,可以为任意 char 型字符,例如‘a’、’b’、’c’ 等等,其主要作用是使 ioctl 命令有唯一的设备标识;
- nr(number),命令编号/序数,占据 8 bit,可以为任意 unsigned char 型数据,取值范围 0~255,如果定义了多个 ioctl 命令,通常从 0 开始编号递增;
在驱动编程中通常使用宏定义制造出这个32位的cmd
或者反向解析
#include <asm/ioctl.h>
/* used to create numbers */
#define _IO(type,nr) _IOC(_IOC_NONE,(type)