分类: 嵌入式
2009-11-20 14:41:09
编写驱动程序中ioctl的步骤:
31-30 | 29-16 | 15-8 | 7-0 |
direction(2bits) | size(14bits) | type(8bits) | number(8bits) |
新的符号都定义在linux/ioctl.h : 中。
_IO
(
type
,
nr
)
/*
没有参数的命令
*/
_IOR
(
type
,
nr
,
datatype
)
/*
从驱动中读数据
*/
_IOW
(
type
,
nr
,
datatype
)
/*
写数据
*/
_IOWR
(
type
,
nr
,
datatype
)
/*
双向传送
*/
/*type
和
number
成员作为参数被传递
,
并且
size
成员通过应用
sizeof
到
datatype
参数而得到
*/
在使用switch之前,对cmd进行有效检验,如果检验无效返回:-ENOTTY
以及通过函数access_ok验证指向用户空间的地址是否合法,不合法返回:-EINVAL
int err = 0, tmp;
int retval = 0;
/*
* extract the type and number bitfields, and don't decode
* wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()
*/
if (_IOC_TYPE(cmd) != SCULL_IOC_MAGIC) return -ENOTTY;
if (_IOC_NR(cmd) > SCULL_IOC_MAXNR) return -ENOTTY;
/*
* the direction is a bitmask, and VERIFY_WRITE catches R/W
* transfers. `Type' is user-oriented, while
* access_ok is kernel-oriented, so the concept of "read" and
* "write" is reversed
*/
if (_IOC_DIR(cmd) & _IOC_READ)
err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
else if (_IOC_DIR(cmd) & _IOC_WRITE)
err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
if (err) return -EFAULT;
接下来就要根据不同的设备对各种命令进行实现.
*******************************************************
文件头有:
// get_user __get_user copy_from_user