免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1829 | 回复: 0
打印 上一主题 下一主题

linux ioctl函数及其驱动和应用程序注意事项 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-11-09 11:37 |只看该作者 |倒序浏览
关于IOCTL驱动的编写方法LDD这本书确实写的比较明白了,在这呢我就简单的做一个介绍。这里我主要描述自己编写IOCTL驱动时所遇到的问题及其原因。
    驱动里的ioctl函数主要实现不用read,write函数的与用户空间的简单数据交互及无参数的命令控制。那么我们如何实现这几种功能的IOCTL函数呢?ioctl驱动中以SWITCH{case A,case B}结构以实现对不同命令的响应,首先我们要对我们要使用的“A”,“B”命令定义一个整个操作系统内唯一的标识,同时这个标识又能够表明我们的操作类型及传递参数的类型(如果需要的话)。linux系统的每一个命令号被分为多个位字段,这些位字段包括type,number,direction,size,分别表示幻数(与设备相关的一个字母,以避免与内核冲突),序数(命令编号),方向位(以用户空间为参照的读,写和无数据传输),size(传递参数类型)。内核中/include/asm/ioctl.h,/Documentation/ioctl-number.txt两个文件表明了我们应该如何定义ioctl命令编号及自定义的幻数,。
    看起来构造IOTCL命令这么复杂,庆幸的是内核已经为我们编写了构造命令编号的宏命令。_IO(type,nr),_IOR(type,nr,datatype),_IOW(type,nr,datatype)。它们在包含的中有定义,所以在我们的驱动中应包含这个头文件。其中_IO()用做无参数的命令编号,_IOR()用做从驱动中读取数据的命令编号,_IOW()用做写入数据命令。 LDD中用:define SCULL_IOC_MAGIC 'k' ,define SCULL_IOCSQUANTUM _IOW(SCULL_IOC_MAGIC,1,int)表示SCULL_IOCSQUANTUM命令编号为向驱动中写数据,命令编号为1,传送参数类型为int。
这里把我所写的部分代码贴出来:
驱动程序部分代码:
#define MOTOR_MAGIC  'k'
#define SET_PULSE _IOW(MOTOR_MAGIC,  1,int)
  .
  .
  static int motor_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
{      int data=0;
      int retval;
      switch (cmd) {
      case SET_PULSE:
              if (copy_from_user(&data, (int *)arg, sizeof(int)))
               return -EFAULT;
             .
             .
             .
}
   
应用程序部分代码:   
    #define MOTOR_MAGIC  'k'
    #define SET_PULSE _IOW(MOTOR_MAGIC,  1,int)
    int pulse,fileno;
    fileno = open("/tmp/usb",O_RDWR);
    if (fileno == -1) {
        printf("open device key error!\n");
        return 0;
    }
       .
       .
       printf("Please input the pulse:\n"
       scanf("%d",pulse);  
       if(ioctl(fileno,SET_PULSE,pulse)<0){
          perror("ioctl error");
          exit(1);
       }      
        .
        .
  这里我们一定要注意的是data 和pulse的数据类型一定要与SET_PULSE _IOW(MOTOR_MAGIC,  1,int)中定义的int类型严格一致,即使是unsigned int 和int类型之间也是有很大差别的,我就是因为设定了unsigned int类型的data和pulse却使用SET_PULSE _IOW(MOTOR_MAGIC,  1,int)搞了我两三天才搞明白。 再有就是ioctl函数的声明一定要与 static int motor_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg);相一致,我刚开始就是定义错了,也是搞了我好长时间才明白。因为内核非常的相信你,它不会检查你的IOTCL定义有没有问题,它只负责把你的IOCTL函数映射到驱动的ioctl操作上。其中inode和filp对应应用程序传递的文件描述符,这和传递给open方法的参数一样,参数cmd 由用户空间不经修改的传递给驱动程序,可选的arg参数无论用户空间传递的是指针还是值,它都以unsigned long的形式传递给驱动程序。
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/74510/showart_1388498.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP