设备操作函数 2> ioctl

2140阅读 0评论2015-06-10 lsxuan驱动
分类:嵌入式

0> 目标:

通过虚拟led设备实验,学习用户态ioctl()与驱动unlocked_ioctl( )之间的关系,忽略中间流程。

ioctlio control
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

1> 用户空间:

int ioctl(int fd, int cmd, ...);

@fd:文件描述符

@cmd:命令,只是个数字,看成是用户态与客户态的暗号,内核建议了这个暗号的组织。

@... : 这只写一个参数或不写,...的妙处:可以传任何类型的参数,学会这招。

2> kernel:

long unlocked_ioctl (struct file *filep, unsigned int cmd, unsigned long arg);

@filep:

@cmd: 等于用户态cmd

@arg:等于用户态<...>传的值, 可看出用户态<...>只能写一个参数。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

补充:看看内核怎么设计暗号的:

创建命令:


点击(此处)折叠或打开

  1. "/linux-3.5/include/asm-generic/ioctl.h"

  2. #define _IOC_NRBITS 8

  3. #define _IOC_TYPEBITS 8

  4. # define _IOC_SIZEBITS 14

  5. # define _IOC_DIRBITS 2


  6. #define _IOC_NRSHIFT 0

  7. #define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) //8

  8. #define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) // 16

  9. #define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) //30


  10. #define     _IOC(dir, type, nr, size) \

  11.             (((dir) << _IOC_DIRSHIFT) | \ 30

  12.             ((type) << _IOC_TYPESHIFT) | \ 8

  13.             ((nr) << _IOC_NRSHIFT) | \ 0

  14.             ((size) << _IOC_SIZESHIFT)) 16

direction31:30

size29:16

Type[15:8]

Number[7:0]

数据传输方向2

数据大小14

幻数8

顺序编号8

……………………………………………………………………………………………………

# define _IOC_NONE 0U //无传输方向

#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

解析密令:

#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)

//((1<<8)-1) = 0x ff = 0b 1111_1111 赞一个,这招不能不学!!

#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)

//(cmd >> 0)& 0xff 就是number的值,


大牛:

http://www.cnblogs.com/geneil/archive/2011/12/04/2275372.html

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
实例源码:
app.txt
ioctl.txt
ledioctl.txt
Makefile.txt







上一篇:driver: Linux设备模型之input子系统详解
下一篇:设备操作函数 3> poll