ioctl系统调用

什么是ioctl
设备的IO通道进行管理的函数。对设备的一些特性进行控制,传输波特率,马达转速。


在用户空间,函数原型:
int ioctl(int fd, int cmd, ...) \\...可选参数:插入 *argp,是cmd命令所需参数,至多指定一个参数,也可以不指定。该参数要么是一个指针,要么是一个整数。
fd是用户程序打开设备时使用open函数返回的文件标识符,cmd是用户程序对设备的控制命令,后面的补充参数,就可以把几个数据捆绑成一个结构,然后传递结构的指针强制转换。
ioctl 函数是文件结构中的一个属性分量,驱动提供支持,就可以用户程序中使用ioctl函数来控制设备的IO通道。

必要性
write函数中检查一下是否有特殊约定的数据流通过,后面跟着控制命令。这样程序结构混乱,代码分工不明。用户程序所做的只通过 命令码(ioctl) 告诉驱动想做什么,解释命令和实现命令,驱动程序要做的。

实现
ioctl中命令码 是唯一联系用户程序命令和驱动程序支持的途径。一定要做到命令和设备是一一对应。linux核心定义一个命令码:
设备类型 (8it) 序列号(8bit) 方向(2bit) 数据尺寸(8-14bit)


一个命令就变成了一个整数形式的命令码,不直观的原因Linux Kernel提供了一些宏。“幻数”是一个字母,数据长度也是8,用一个特定的字母来标明设备类型,和用一个数字是一样的,更加利于记忆和理解。
cmd 参数再用户程序端由一些宏根据设备类型、序列号、传送方向、数据尺寸等生成,这个整数通过系统调用传递到内核中的驱动程序,再由驱动程序解码宏从这个整数中得到设备的类型、序列号、传送方向、数据尺寸等信息。


小结

理解cmd命令码 怎么在用户程序里生成并在驱动程序里解析,主要工作量在 switch结构中






这些宏都定义在<asm/ioctl.h>头文件中(<asm-generic.h>)
驱动ioctl方法

int (*ioctl)(struct inode *inode, struct file *flip, unsigned int cmd, unsigned long arg);

内核提供了一些宏来帮助定义
_IO(type, nr)  
_IOR(type, nr, size)
_IOW(type, nr, size)
_IOWR(type, nr, size)

相对的,Linux内核提供了相应的宏来从ioctl来解析相应的域值
_IOC_DIR(nr)
_IOC_TYPE(nr)
_IOC_NR(nr)
_IOC_SIZE(nr)


一般使用,先指定各个IOCTL命令的顺序编号(从0开始),然后根据环境使用这些宏自动生成IOCTL命令号
ioctl函数使用,如果命令参数是一个指针,指向的地址是用户空间的虚拟地址,内核空间无法使用,用于在内核空间访问用户空间的数据,定义在 <asm/uaccess.h>

unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n);
unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n);
  //copy_from_user 和 coyp_to_user 一般用于复杂的或大数据交换。

对于简单的数据类型,如int或char,内核提供简单宏(x是内核地址,ptr是用户空间地址)

#define get_user(x,ptr)
#define put_user(x,ptr)







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值