崔阳
摘 要:针对64位Windows操作系统对HID设备与主机应用程序的通讯造成的新问题,首先简要介绍了Windows环境下HID设备的性能特点和通讯机制,以此为基础提出一个面向64位Windows的HID设备通讯接口,并在Wave Panel上进行了编程实验。结果证明该接口的通用性较强,能够较好地实现64位Windows下HID设备与主机应用程序的通讯功能。
关键词:HID;通讯接口;中断传输;64位Windows
中图分类号:TP319 文献标识码:A
Abstract:To solve the new problems of communication between human interface devices (HID) and the computer applications caused by 64-bit Windows,characteristics and the communication mechanism of HID in Windows environment are introduced first,based on which a communication interface for 64-bit Windows is designed and programmed on Wave Panel.Results show that communication function in 64-bit Windows environment can be better achieved through the interface.
Keywords:HID;communication interface;interrupt transmission;64-bit Windows
1 引言(Introduction)
HID(Human Interface Device,人机接口设备)是一类低速USB设备,具有使用方便、响应迅速、成本低廉等优点。典型的有键盘、鼠标、游戏杆等。
HID设备研发和使用中面临的重要问题之一是设备与主机应用程序的通讯。Windows 7的发布标志着Windows操作系统开始从32位向64位过渡,因此有必要对64位Windows环境下HID设备通讯程序的一些新问题进行研究。
2 HID设备的性能特点(Performance characteristics of HID)
HID设备虽然也属于USB设备,但还具备一些自身特点,主要有:
(1)单次传输的数据量小,且以设备状态信息和控制信息为主。单次传输数据通常在8字节到1024字节。数据存储在报表(Report)结构内[1]。
(2)使用轮询方式。HID设备会在一个设定的时间间隔内检测一次设备,若发现设备状态有变化则会生成输入报表,并发送到主机[2]。
(3)多数采用中断方式通讯。这种方式适用于周期性、延迟低的数据[3],符合HID设备的应用特点。
3 HID设备的通讯过程(Communication process of HID)
Windows 98及之后的各版本Windows已包含HID驱动程序[4,5],应用程序可直接调用相关API函数实现HID设备的通讯。该过程可分为以下四个模块:
(1)设备识别和打开。一台主机有可能同时连接多台HID设备,因此在通讯前必须确定要进行通讯的设备并打开。HID设备以厂商ID(VID)、产品ID(PID)和产品版本号(PVN)三项属性值作为其唯一标识[6]。
(2)读报表。读报表是指HID设备向主机输入数据。对以中断方式发送数据的HID设备而言,应用程序需要创建一个异步调用的读报表线程。同时为减轻系统负载,该线程在HID设备没有向主机输入数据时应阻塞。当有数据输入时恢复运行,将输入数据保存在缓冲区中,并进行解析。之后线程将再次阻塞。读报表线程在应用程序运行结束前将一直存在。
(3)写报表。写报表是指主机向HID设备输出数据。但该功能不是必需的,视HID设备而定[7]。写报表线程比较简单,只须将要输出的数据先复制到一个缓冲区内,然后输出到HID设备即可。数据通常是一些控制信息和状态信息[8]。
(4)设备关闭。当主机与HID设备的通讯结束后必须将HID设备关闭。
4 64位Windows环境中HID设备通讯模式 (Communication mode of HID in 64-bit Windows environment)
通过上述讨论,Windows环境下HID设备的识别和打开主要是通过调用API函数实现的。但64位Windows操作系统不支持这些API函数,也没有提供相应的API函数。因此必须对设备识别与打开模块的功能进行分解。思路是将涉及API函数的设备识别功能与设备打开功能相分离,并在32位环境下将前者编译为可执行程序,供后者在64位环境下调用。因此,应将设备识别与打开模块再细分为设备识别和设备打开两个独立的功能模块。
4.1 设备识别
HID设备识别模块主要是通过调用相关的API函数对主机各USB接口上连接的设备进行三项属性值对比,完全符合的即为当前要打开的HID设备。用到的API函数主要有HidD_GetHidGuid()、SetupDiGetClassDevs()、SetupDiEnumDeviceInterfaces()、SetupDiGetDeviceInterfaceDetail()、HidD_GetAttributes()、SetupDiDestroyDeviceInfoList()等。
4.2 设备打开
设备打开模块的功能相对简单,只需首先从外部文件中获取设备识别模块中保存的HID设备路径,再调用ReadFile()以带读写访问设置的异步方式将设备打开,并返回设备句柄即可。
4.3 通讯接口的设计和实验
以上述讨论为基础,设计一个实用的HID设备通讯接口,起名为CHidComm64。该接口包括:
(1)DWORD变量VID、PID和PVN:保存HID设备的三项属性值。
(2)UCHAR类型数组ReadBuffer和WriteBuffer:分别表示HID设备的输入报表和输出报表。
(3)UCHAR类型数组DevicePath,表示HID设备路径。
(4)ReadReportThread()和WriteReportThread():用于创建读报表线程和写报表线程,当HID设备没有向主机输入数据时,线程被阻塞;当有数据输入时,线程恢复运行,这样就可以降低系统负载、提高运行效率。
(5)成员函数SearchDevice()、OpenDevice()、CloseDevice()函数:分别实现HID设备识别、打开和关闭。
在连接不同的HID设备时,只需要重新设置VID、PID和PVN值以及ReadBuffer、WriteBuffer的长度,不用对HID设备识别、打开、读写报表等功能进行修改,从而提高接口的通用性。
实验以视频色彩编辑软件专用HID设备Wave Panel为平台,编程语言为C++,编译环境为64位Windows 7操作系统下的Visual Studio 2010。Wave Panel有按键、解码器和二维跟踪球三种控制器,每40ms对所有控制器轮询一次。若任何一个控制器的状态在期间发生变化,就会生成输入报表发送给主机。同时Wave Panel的液晶屏也可以显示主机的状态信息。
图1是主机应用程序调用CHidComm64接口实现与Wave Panel通讯的界面。应用程序以十六进制形式将Wave Panel发送的数据显示在界面上,同时显示控制器状态变化的情况。
5 结论(Conclusion)
64位Windows操作系统不再支持原有的HID设备通讯API函数,因此有必要对HID设备与主机的通讯流程做出改进。所设计的CHidComm64通讯接口将HID设备识别与设备打开功能相分离,从而能够较好地实现在64位Windows环境下的通讯功能。今后的工作将主要研究对该接口功能的完善方面。
参考文献(References)
[1] Device Class Definition for Human Interface [EB/OL]. http://www.usb.org/developers/devclass_docs/HID1_11.pdf.
[2] 胡晓军,张爱成.USB接口开发技术[M].陕西:西安电子科技大学出版社,2005.
[3] 蔡欣荣.基于ARM的HID类自定义功能键盘研究与实现[J].工业控制计算机,2011,24(5):14-18.
[4] 王恒升,匡洋,彭宏道.USBHID类设备小驱动程序开发[J].控制工程,2010,17(6):815-819.
[5] 时向卫,李峥,张少武.Win2000/XP下USB设备驱动程序研究与设计[J].计算机工程与设计,2008,29(21):5562-5565.
[6] Jan AXELSON.USB开发大全(第4版)[M].北京:人民邮电出版社,2011.
[7] 刘力,等.基于HID类的USB人机接口设计[J].计算机工程与科学,2003,25(3):82-85.
[8] 王继刚,等.虚拟化环境下的USB设备访问方法[J].计算机应用,2011,31(5):1439-1442.
作者简介:
崔 阳(1979-),男,博士,讲师.研究领域:知识工程与知识发现.