device_num++; /* 找到的设备数 */ } } }
return device_num; /* 返回设备数量 */ }
注:在新版本的libusb中,usb_get_busses就能不用了 ,这个函数是返回系统上的usb总线链表句柄 这里我们直接用usb_busses变量,这个变量在usb.h中被定义为外部变量 所以能直接写成这样: struct usb_bus *bus;
for (bus = usb_busses; bus; bus = bus->next) { struct usb_device *dev;
for (dev = bus->devices; dev; dev = dev->next) { /* 这里添加设备的初始化代码 */ } }
3.2 打开设备
假设我们定义的打开设备的函数名是device_open,
/* 使用hid驱动打开设备 */ int Device_Open() {
int handle;
/* 传统HID驱动调用,通过open打开设备文件就可 */ handle = open(“hiddev0”, O_RDONLY); }
/* 使用libusb打开驱动 */
int Device_Open() {
/* LIBUSB 驱动打开设备,这里写的是伪代码,不确保代码有用 */ struct usb_device* udev;
usb_dev_handle* device_handle;
/* 当找到设备后,通过usb_open打开设备,这里的函数就相当open 函数 */ device_handle = usb_open(udev);
}
3.3 读写设备和操作设备
假设我们的设备使用控制传输方式,至于批处理传输和中断传输限于篇幅这里不介绍 我们这里定义三个函数,Device_Write, Device_Read, Device_Report Device_Report 功能发送接收函数 Device_Write 功能写数据 Device_Read 功能读数据
Device_Write和Device_Read调用Device_Report发送写的信息和读的信息,研发者根据发送的命令协议来设计,我们这里只简单实现发送数据的函数。
假设我们要给设备发送72字节的数据,头8个字节是报告头,是我们定义的和设备相关的规则,后64位是数据。
HID驱动的实现(这里只是用代码来有助理解,代码是伪代码)
int Device_Report(int fd, unsigned char *buffer72) {
int ret; /* 保存ioctl函数的返回值 */ int index;
unsigned char send_data[72]; /* 发送的数据 */ unsigned char recv_data[72]; /* 接收的数据 */
struct hiddev_usage_ref uref; /* hid驱动定义的数据包 */ struct hiddev_report_info rinfo; /* hid驱动定义的
memset(send_data, 0, sizeof(send_data)); memset(recv_data, 0, sizeof(recv_data));
memcpy(send_data, buffer72, 72);
/* 这在发送数据之前必须调用的,初始化设备 */ ret = ioctl(fd, HIDIOCINITREPORT, 0); if( ret !=0) {
return NOT_OPENED_DEVICE;/* NOT_OPENED_DEVICE 属于自己定义宏 */ }
/* HID设备每次传输一个字节的数据包 */ for(index = 0; index /* 设置发送数据的状态 */
uref.report_type = HID_REPORT_TYPE_FEATURE; uref.report_id = HID_REPORT_ID_FIRST; uref.usage_index = index;
uref.field_index = 0;
uref.value = send_data[index]; ioctl(fd, HIDIOCGUCODE, &uref); ret=ioctl(fd, HIDIOCSUSAGE, &uref); if(ret != 0 ){
return UNKNOWN_ERROR; } }
/* 发送数据 */
rinfo.report_type = HID_REPORT_TYPE_FEATURE; rinfo.report_id = HID_REPORT_ID_FIRST; rinfo.num_fields = 1;
ret=ioctl(fd, HIDIOCSREPORT, &rinfo); /* 发送数据 */ if(ret != 0) {
return WRITE_REPORT; }
/* 接受数据 */
ret = ioctl(fd, HIDIOCINITREPORT, 0); for(index = 0; index
uref.report_type = HID_REPORT_TYPE_FEATURE; uref.report_id = HID_REPORT_ID_FIRST; uref.usage_index = index; uref.field_index = 0;
ioctl(fd, HIDIOCGUCODE, &uref); ret = ioctl(fd, HIDIOCGUSAGE, &uref); if(ret != 0 ) {
return UNKNOWN_ERROR; }
recv_data[index] = uref.value; }
memcpy(buffer72, recv_data, 72);
return SUCCESS; }
libusb驱动的实现
int Device_Report(int fd, unsigned char *buffer72) {
/* 定义设备句柄 */
usb_dev_handle* Device_handle;
/* save the data of send and receive */ unsigned char send_data[72]; unsigned char recv_data[72];
int send_len; int recv_len;
/* 数据置空 */
memset(send_data, 0 , sizeof(send_data)); memset(recv_data, 0 , sizeof(recv_data));
/* 这里的g_list是全局的数据变量,里面能存储相关设备的所需信息,当然我们 也能从函数形参中传输进来,设备的信息在打开设备时初始化,我们将在后面的总结中周详描述一下 */ Device_handle = (usb_dev_handle*)(g_list[fd].device_handle); if (Device_handle == NULL) { return NOT_OPENED_DEVICE; }
/* 这个函数前面已说过,在操作设备前是必须调用的, 0是指用默认的设备 */ usb_claim_interface(Device_handle, 0);
/* 发送数据,所用到的宏定义在usb.h能找到,我列出来大家看一下 #define USB_ENDPOINT_OUT 0x00 #define USB_TYPE_CLASS (0x01 #define USB_RECIP_INTERFACE 0x01
#define HID_REPORT_SET 0x09 */ send_len = usb_control_msg(Device_handle,
USB_ENDPOINT_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE, HID_REPORT_SET, 0x300, 0,
send_data, 72, USB_TIMEOUT);
/* 发送数据有错误 */ if (send_len
return WRITE_REPORT; }
if (send_len != 72) { return send_len; }
相关推荐: