国嵌内核驱动进阶班-7-1(Ioctl设备控制)

ioctl 

控制设备

除了读写设备之外,其他功能的实现需要ioctl。如串口的波特率的设定。


 

用户空间:

ioctl的应用

  • api 

int ioctl(int fd, unsigned long cmd, ...)

fd 文件描述符

cmd 发送的命令

...依赖cmd命令


 

内核空间

  • api 

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

  inode 文件的物理信息(如文件的设备编号)

  flip 表示打开文件

  cmd 来自于用户空间的cmd

      arg 

  •  内核驱动的实现
    • 定义命令

include/asm/ioctl.h

类型(幻数)8

序号 8 传送方向 参数大小
设备(Document/ioctl-number.txt 记录已经使用的幻数) 指定设备的第几个命令

_IOC_NONE

_IOC_READ(从设备读)

_IOC_WRITE(向设备写)

用户数据的大小

13到14位

 

内核提供定义命令的宏

 _IO(type,nr)         没有参数的命令

_IOR(type,nr,datetype)    从设备读取数据

_IOW(type,nr,datetype)   向设备中写数据

_IOWR(type,nr,datetype)   向设备读写数据


_IOC_TYPE(cmd)  从命令中取得幻数(幻数type决定设备)

_IOC_NR(cmd)     从命令中取得命令的个数

_IOC_DIR(cmd)    从命令取得direction

 

例子

#define MEM_IOC_MAGIC 'm'

#define MEM_IOCSET  _LOW(MEM_IOC_MAGIC, 0, int)

#define MEM_IOCGQSET  _LOR(MEM_IOC_MAGIC, 1, int) 

    • 实现命令

1. ioctl 返回值

  EINVAL=-1“非法参数”

2. ioctl参数

  arg 指针的检测

        ※ 用户空间指针,不可以直接使用。

 

  不需要检测:

  copy_from_user

  copy_to_user

  get_user

  put_user

   需要检测:

  __get_user

  __put_user

  

  检测函数:

  int access_ok(int type, )

  type :VERIFY_WRITE VERIFY_READ

  

if (__IOC_DIR(cmd) & _IOC_READ)
err = !access_ok(VERIFY_WRITE, (void __user*)args, _IOC_SIZE(cmd));

else if (__IOC_DIR(cmd) & _IOC_WRITE)
er r = !access_ok(VERIFY_READ, (void __user*)args, _IOC_SIZE(cmd));

if (err)
erturn -EFAULT;

3. 命令的实现

switch(cmd)

{

  case MEM_IOCSQUANTUM:

  break;

        case MEM_IOCSQUANTUM:

        break;

        default:

  return -EINVAL;

}

  

 

 

3. 

posted @ 2015-06-02 23:46  renhl  阅读(229)  评论(0编辑  收藏  举报