IOCTL 高级字符设备驱动程序(国嵌笔记)

高级字符设备驱动程序
1.ioctl设备控制 
大部分驱动程序除了需要具备读写设备的能力外,还需具备对硬件控制的能力。
例如:要求设备报告错误信息,改变波特率等,通常通过ioctl来实现
2.用户使用方法
int ioctl(int fd,unsigned long cmd,···)
函数中的省略部分代表这是一个可选参数,存在与否依赖于控制命令(第二个参数)是否涉及到与设备的数据交互。
 驱动ioctl方法
int(*ioctl)(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
cmd参数从用户空间传下来,可选参数arg以一个unsigned long的形式传递,不管他是一个整数或一个指针。如果cmd命令不涉及数据传输,则第三个参数arg的值无任何意义。
设备方法(在file_operations中的函数都叫做设备方法)
3.实现ioctl
1.定义命令
2.实现命令


1.定义命令(32位)
为了防止对错误的设备使用正确的命令,命令号应该在系统范围内是唯一的。ioctl命令编码被划分为几个位段,include/asm/ioctl.h中定义了这些位字段。
类型(幻数),序号,传递方向,参数的大小
Documentation/ioctl-number.txt文件中罗列了在内核中已经使用的幻数。
<linux/ioctl.h>
type:幻数,表明那个设备的命令,在参考ioctl-number.txt之后选出,8位宽。
number:序号,表明设备命令中的第几个,8位宽。
direction:数据传递的方向,可能的值是_IOC_NONE(没有数据传输),_IOC_READ,_IOC_WRITE.数据传送是从应用程序的观点来看待,_IOC_READ意思是从设备读。
size:用户数据的大小。(13/14位宽,视处理器而定)
内核提供了下列宏用来帮助定义命令
_IO(type,nr)
没有参数命令
_IOR(type,nr,datatype)
从驱动中读
_IOW(type,nr,datatype)
写数据到驱动
_IOWR(type,nr,datatype)
双向传送,type和number(nr)成员作为参数传递

范例:
#define MEM_IOC_MAGIC 'm'
#define MEM_IOCSET
_IOW(MEM_IOC_MAGIC,0,int)
#define MEM_IOCGQSET
_IOW(MEM_IOC_MAGIC,1,int)
2.命令实现(ioctl函数实现)
1.返回值2.参数使用3.命令操作
1.返回值:通常根据命令执行一个switch语句,但是当命令不能匹配时,返回-EINVAL(“非法参数”)
2.参数:如果是一个整数,可以直接使用。如果是指针,我们必须确保这个用户地址是有效的,因此使用前需要进行正确的检查。
参数检测:
  不许要检测的函数
copy_from_user,copy_to_user,get_user,put_user
  需要检测的函数
__get_user,__put_user
使用int access_ok(int type,const void *addr,unsigned long size)
第一个参数表示是读用户内存还是写用户内存。addr是要检测的用户地址,size是操作长度。返回1(存取没问题)0(存取有问题),如果该函数返回失败,则ioctl应当返回-EFAULT
例子:
if(_IOC_DIR(cmd)&_IOC_READ)//从命令中取出方向与给定的方向进行判断
err=!access_ok(VERIFY_WRITE,(void __user*)arg,_IOC_SIZE(cmd))
//_IOC_READ对应VERIFY_WRITE,从内核读取来写到用户数据区中
else if(_IOC_DIR(cmd)&_IOC_WRITE)
err=!access_ok(VERIFY_READ,(void __user*)arg,_IOC_SIZE(cmd))
if(err)
return -EFAULT

3.命令操作
switch(cmd)
{
case MEM_IOCSQUANTUM:
retval=__get_user(scull_quantum,(int*)arg);
break;
`````
default:
return -EINVAL;

}
具体的代码进行分析
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值