Linux 2.6内核中包含了HID驱动,能够自动把USB Key等HID外设识别成“/dev/hiddev0”之类的设备。但是该驱动没有实现write接口,因此无法象Windows平台那样使用 ReadFile和WriteFile来读写HID设备,而只能使用ioctl接口。
      网上有各种各样读写HID设备的源代码例子,有的是通过HIDIOCSUSAGE和HIDIOCGUSAGE来每次收发4个字节,适合鼠标、键盘之类数据传输量小的设备;有的是通过HIDIOCSUSAGES和HIDIOCGUSAGES来连续接收和发送多个字节,适合USB Key一类的设备。
      在上一篇日志(已删除)中,介绍了如何利用《USB and PIC: quick guide to an USB HID framework》一文提供的方法与USB Key进行通信(先发送HIDIOCSUSAGES和HIDIOCSREPORT进行写操作,再发送HIDIOCGREPORT和HIDIOCGUSAGES进行读操作,从而完成一次通信过程)。但是经过好友测试,发现该方法不论是在PC机上,还是在Cavium Octeon 52XX开发板上均存在问题,读出的数据始终是第一次通信的结果,除非在每次通信之前都发送HIDIOCINITREPORT控制码,但这又会造成相当长时间的阻塞。
      进一步的测试表明,如果按照HIDIOCGUCODE、HIDIOCSUSAGES、HIDIOCSREPORT、HIDIOCGUCODE、HIDIOCGUSAGES的顺序发送控制码,那么可以每次都读出正确数据。不过该方法虽然在PC机上只需400毫秒延时,但是在Octeon开发板上仍会长时间阻塞在usbhid_wait_io函数那里。
      无奈之下,我只好根据Cavium SDK自带的Linux内核源码中的usb_skeleton.c写了一个USB设备驱动程序,试图通过直接读写USB端点来完成通信过程。以下是在开发和调试过程中需要注意的几个问题:
      首先,必须卸载Linux内核自带的HID驱动,否则它会自动“接管”新插入的USB Key,导致我们自己编写的驱动程序找不到设备。对于开发板,可以在编译内核时去掉HID相关的选项;对于PC机上已经安装好的Linux,我也不知道该怎么卸载其中的HID驱动。
      其次,端点类型。在usb_skeleton.c中是通过bulk端点来访问USB设备的,而USB Key作为HID设备,一般只有0号控制端点和一个中断输入端点(例如3号)。对于中断端点,可以用usb_interrupt_msg(其实就是usb_bulk_msg)函数进行访问;对于控制端点,则稍微麻烦一些,因为除了数据,还需要构造一个8字节的setup包。有关setup包的详细结构,可以参考USB和HID规范。获取setup包具体数值最简单的方法,就是在Windows环境下用BusHound观察USB Key的通信过程。
      最后,关于Report ID。在Windows环境下通过ReadFile和WriteFile访问HID设备时,必须在数据开头附加1字节的Report ID(一般为0)。在Linux环境下,如果使用HID驱动的ioctl接口,那么需要在hiddev_usage_ref结构中指定Report ID;如果使用自己编写的USB驱动程序,则不需要考虑Report ID,直接发送数据就得了。
      经过测试,利用自己编写的驱动程序,可以在Octeon开发板上正确读写HID类型的USB Key,而且读写之间的时间间隔也可以缩短至50毫秒。

在Linux 2.6环境下读写HID设备(USB Key)相关推荐

  1. Linux创建线程读取双口数据,linux环境下读写一次双口ram尽然要十几个毫秒。(附驱动代码)...

    linux环境下读写一次双口ram尽然要十几个毫秒.(附驱动代码) 我用的双口ram是IDT70V28,手册上说的读写时间应该是几个纳秒,我写了个linux驱动,然后做测试,发现读写一次的时间尽然是十 ...

  2. linux下dds软件,【数据库】Linux 单实例环境下实现Oracle数据库和DDS软件的开机自动重启...

    Linux 单实例环境下实现Oracle数据库和DDS软件的开机自动重启1.修改/etc/oratab# vi /etc/orataboradb:/opt/ora10/product/10.2 首页 ...

  3. Linux无桌面环境下,实现USB的自动挂载/卸载

    Linux无桌面环境下,实现USB的自动挂载/卸载 1.gnome桌面环境如何实现USB的自动挂载 2.udev 3.单个设备自动挂载/卸载 4.usbmount工具实现自动挂载卸载 linux无桌面 ...

  4. Linux服务器docker环境下Jasper Report报错

    Linux服务器docker环境下Jasper Report报错 Jasperreports模板制作方法在网上都有很多教程,可以自行探索一下 我用的模板参考:https://blog.csdn.net ...

  5. Hadoop2.6.0+Linux Centos7+idea环境下:MapReduce二度好友推荐案例

    目录 一.问题描述 二.intellij idea中编写代码+打包项目 三.xftp中上传jar包到Linux 四.hadoop中准备输入数据+运行jar包+查看输出结果 一.问题描述 使用MapRe ...

  6. 浅析单一冗余校验RAID缺陷--云存储环境下IP存储设备组建策略

    浅析单一冗余校验RAID缺陷--云存储环境下IP存储设备组建策略 前面的话 摘要 一.当前常见阵列组建模式及云存储环境下IP存储设备特点 1.只求容量及读写性能的RAID0: 2.为了数据安全宁可牺牲 ...

  7. windows下学习linux,在Windows环境下学习Linux命令行的几种方法

    Linux高手通常将Windows工作平台的人鄙视得一无是处, 其实这完全没有必要.请不要装. 对于想进军linux的人来说, 学好linux命令行无疑是最基本的东西. 本文讲述如何在Windows环 ...

  8. linux环境下调试嵌入式设备时出现Aborted、segmentation fault、卡死的问题以及关于指针使用的一点想法

    linux环境下调试一些嵌入式设备时出现Aborted.segmentation fault.卡死的问题,这些问题可能的原因为: 1.Aborted的问题,例如: # ./logUtils0322 [ ...

  9. linux开发 stc_Linux环境下搭建STC单片机平台的指南

    Linux 环境下的头文件定义 编译文件以及转换bin文件等 操作系统:Ubuntu16.04 单片机:STC89C52RC 所需工具: 1.编辑器 - vim 2.编译器 - sdcc 3.转换程序 ...

最新文章

  1. 京东数科宣布机房巡检AI机器人落地金融机构数据中心
  2. oracle 最低要求吗,神谕Oracle配置要求高吗?最低及推荐配置一览
  3. python和C语言分别实现插入排序
  4. 终于等到你!阿里正式向 Apache Flink 贡献 Blink 源码
  5. 测试必备:if条件测试( if-else语句、if-elif-else语句、多个elif代码块、省略else代码块、测试多个条件)
  6. Linux基础(13)文本查找利器find的使用方法
  7. Gazebo Ros入门
  8. 解决Oracle 11g在用EXP导出时,空表不能导出
  9. 无穷分数java_java – 如何NaN和无穷大的浮动或双倍存储在内存?
  10. Red5流媒体服务器初探——Red5服务器的搭建
  11. AD 中快速查找隐藏NC元器件方法
  12. cobar mysql_cobar mysql 高可用
  13. django-查询语句(一)
  14. 嵌入式软件工程师是前端还是后端_软件开发工程师与嵌入式软件工程师有区别吗...
  15. python计算排列组合
  16. ndk编译 toolchains/llvm/prebuilt/windows-x86_64/bin/clang++.exe
  17. R语言——ggplot2的绘图逻辑
  18. Promise is a promise
  19. google学术无法访问
  20. matlab函数merge_MATLAB数据合并方法

热门文章

  1. 生成包含IR的CFG-小例子
  2. 如何查看Linux内核输出的调试信息
  3. C++——程序员的逼格神器-github
  4. java web——servlet+jsp实现前后台交互
  5. 关于 本地仓库有jar包,但idea找不到的问题
  6. 头一批升级鸿蒙的手机,来了!这些手机将升级鸿蒙系统
  7. 无线传感器网络及其安全问题
  8. Android Senor Framework (五) SensorManager
  9. position属性的四种取值用法
  10. soft nproc 与 soft nofile