易方数码笔缺省是一个标准的USB HID设备(Mouse),在 Android 平板电脑上接入时,基于USB Mouse 形式输出的笔迹精度不够,为此,我们将其切换至hiddev设备类型,通过发送相关命令来获得笔输出的原始坐标信息,这样精度就大大提升了。
基于USB HID协议,除可实现为普通的输入设备外,也可用作为有自定义通讯功能的设备。事实上,当前Linux 内核中已提供了这两种HID事件的接口,即输入子系统和hiddev接口(具体请参见linux内核根目录下的Documentation/hid/hiddev.txt文档)。
为使用hiddev设备,我们只需在配置内核时要打开hiddev选项,这样就可以编写应用级代码来读取笔的原始坐标信息了。hiddev驱动是一个字符型驱动,其访问节点一般为/dev/usb/hiddev[0~15],在应用程序中打开这个设备节点后,即可调用hiddev API来与hiddev设备进行通讯。
hiddev API有两个调用接口,read和ioctl调用。read只用于获取hiddev设备的状态变化,而主机与设备间进行数据交换是通过ioctl调用来实现的,写数据时传入ioctl的命令字为HDIOCSREPORT,读数据时则传入HDIOCGREPORT,传送的数据封装在report中,每个report分成多个filed,而每个filed又有多个usage。
访问数码笔时,我们要向设备发命令数据来通知设备切换输出模式(输出原始坐标信息),同时,我们也要实时地读取出数据笔输出的原始坐标信息。
1. 打开设备
int digitalpen_open(void)
{
int index;
int fd;
char hid_dev_node[50];
struct hiddev_devinfo dinfo;
for(index = 0; index < 15; index ++) {
sprintf(hid_dev_node, "/dev/usb/hiddev%d", index);
fd = open(hid_dev_node, O_RDONLY);
if(fd > 0) {
memset(&dinfo, 0, sizeof(dinfo));
ioctl(fd, HIDIOCGDEVINFO, &dinfo);
if( (dinfo.vendor == 0x0e20) && (dinfo.product == 0x0101))
break;
close(fd);
fd = -1;
}
}
return fd;
}
打开函数中通过对USB的VID和PID信息来确认所打开的设备是否为数码笔(可通过以下命令查到设备的VID和PID)。如打开成功,返回的是数码笔设备的文件描述符。