《《字符设备驱动程序》》
《设备控制理论》
<作用>
大部分驱动除了对外部设备提供读和写的基本功能以外,还需要对设备进行控制。
<应用程序接口>
在用户空间使用ioctl()系统调用来控制设备。
函数原型:
int ioctl (int fd,unsigned long cmd,........)
参数分析:
fd:要控制的设备描述符
cmd:要发送的命令
.......:第三个是可选参数,存在与否依赖于控制命令(第二个参数)
<驱动控制方法>
当程序使用ioctl() 函数后,驱动成程序的响应函数:
1)2.6.36 内核之前:
long (*ioctl)(struct inode* node ,struct file *filep,unsigned int cmd ,unsigned long arg)
2)2.6.36 内核之后
long (*unlock_ioctl)(struct file *filep,unsigned int cmd ,unsigned long arg)
《设备控制实现》
<定义命令>
命令从其实质而言就是一长串整数,为了让着长传整数具有更好的可读性,通常会把这个整数分成几段:类型(8位),序号,参数传递方向,参数长度
Type(类型/幻数):表明是属于那种设备的命令
Number(序号):用来区分同一设备的不同命令
Direction(方向):参数传递方向,可能的值有(_IOC_NONE()没有数据传输,_IOC_READ/_IOC_WRITE(向设备写入参数))
Size:参数长度
如果用传统的方法拼接命令字,比较麻烦,linux系统提供了相应的函数。
_IO(type,nr) :不带参数的命令
_IOR(type,nr,dataype):从设备中读参数的命令
_IOW(type,nr,datatype):往设备写参数的命令
例:
#define MEM_MAGIC ‘m’
#define MEM_SET -IOW(MEM_MAGIC ,0,int)
注意:为什么类型/幻术是一个字符?因为对类型的要求是一个8位的数据,字符数据就是一个8位的数据,这样使用比较方便。
<实现设备方法>
unlocked_iotcl() 函数的实现通常是根据执行的cmd 使用switch 语句。但是当命令不能匹配任何设备所支持的命令时,返回 _EINVAL
编程模型:
switch cmd
case cmd1:
//执行相应操作
case cmd2:
//执行相应操作
case cmd2:
//执行相应操作
case cmd3:
//执行相应操作
default:
return _EINVAL
<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">