字符设备控制

字符设备控制

在用户空间,使用ioctl系统调用来控制设备,原型如下:

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

ioctl驱动方法有和用户空间版本不用的原型

         int(*ioctl)(struct inode *inode,struct file *filp,unsigned int cmd,unsigned longarg)

         structfile:在Linux系统中,每一个打开的文件,在内核中都会关联一个struct file ,它由内核在打开文件时创建,在文件关闭后释放。

         structinode:每一个存在于文件系统里面的文件都会关联一个inode结构,该结构主要用来记录文件物理上的信息。

ioctl实现

1、  定义命令

2、  实现命令

定义命令

         命令实质是一个整数,通常分为几个段:类型(8位)、序号,参数传递方向,参数长度。

         Type(类型):表明这是属于哪个设备的命令。

         Number(序号):用来区分同一设备的不同命令。

         Direction(参数传递方向):可能的值_IOC_NONE,_IO_READ,_IO_WRITE。

         Size:参数长度

        

         Linux系统提供了下面的宏来帮助定义命令:

         _IO(type,nr):不带参数的命令

_IOR(type ,nr ,datatype):从驱动中读数据

_IOW(type ,nr ,datatype):写数据到驱动

_IOWR(type ,nr ,datatype):双向传送,tyoe和number成员作为参数被传递

例:#defineMEM_IOC_MAGIC ‘m’ //定义幻数

#define MEM_IOCSET

_IOW(MEM_IOC_MAGIC, 0, int)

#define MEM_IOCGQSET

_IOR(MEM_IOC_MAGIC, 1, int)

实现命令

         实现命令包括如下3个技术环节

1、  返回值

2、  参数使用

3、  命令操作

代码示例

 

/*IO操作*/

int memdev_ioctl(struct inode *inode,struct file *filp,

                 unsigned int cmd, unsignedlong arg)

{

 

   int err = 0;

   int ret = 0;

    intioarg = 0;

   

   /* 检测命令的有效性 */

   if (_IOC_TYPE(cmd) != MEMDEV_IOC_MAGIC)

       return -EINVAL;

   if (_IOC_NR(cmd) > MEMDEV_IOC_MAXNR)

       return -EINVAL;

 

   /* 根据命令类型,检测参数空间是否可以访问 */

   if (_IOC_DIR(cmd) & _IOC_READ)

       err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));

   else if (_IOC_DIR(cmd) & _IOC_WRITE)

       err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));

   if (err)

       return -EFAULT;

 

   /* 根据命令,执行相应的操作 */

   switch(cmd) {

 

     /* 打印当前设备信息 */

     case MEMDEV_IOCPRINT:

          printk("<--- CMDMEMDEV_IOCPRINT Done--->\n\n");

       break;

     

     /* 获取参数 */

     case MEMDEV_IOCGETDATA:

       ioarg = 1101;

       ret = __put_user(ioarg, (int *)arg);

       break;

     

     /* 设置参数 */

     case MEMDEV_IOCSETDATA:

       ret = __get_user(ioarg, (int *)arg);

       printk("<--- In Kernel MEMDEV_IOCSETDATA ioarg = %d--->\n\n",ioarg);

       break;

 

     default: 

       return -EINVAL;

    }

   return ret;

 

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值