diff --git a/README.md b/README.md new file mode 100644 index 0000000..a11285e --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +## USB-HID + +> 参考:[玩转USB HID系列:Linux下使用C语言和libusb开发USB HID_hid c++ usb linux-CSDN博客](https://blog.csdn.net/whstudio123/article/details/104348736) + +#### 1、使用用途 + +​ USB-HID是USB的人体学输入设备(USB Human Input Device),这是一种免驱动的USB通信方式,适合用于数据量较小的通信,例如机器人硬件驱动的控制、外置IMU、VR手柄类设备。这个仓库主要用于解决STM32和Linux、windows的通信问题。 + +​ 一般来说,STM32最常用的是采用串口通信,但是串口有可能存在驱动不兼容、相同串口插入主机后分不清的问题。所以,部分情况采用USB-HID能够解决串口驱动问题和相同串口干扰问题。 + +#### 2、代码编译 + +##### 2.1 windows + +##### 2.2 Linux + +##### 2.2.1 环境要求 + +```shell +sudo apt-get install libusb-1.0-0 +``` + +##### 2.2.2 样例和编译 + +​ usb_test_show.cpp : 显示各个连接到主机的usb信息 + +```shell +# firefly RK3588已经集成libusb 1.0 +gcc usb_test_show.cpp -o hid_test_show -lusb-1.0 +# 运行 +sudo ./hid_test_show +``` + +​ usb_test_show.cpp :读取USB信息(IMU设备DEMO)并显示 + +```shell +gcc usb_read_data.cpp -o hid -lusb-1.0 +# 执行 +sudo ./hid +``` + diff --git a/readme b/readme deleted file mode 100644 index 63d8acb..0000000 --- a/readme +++ /dev/null @@ -1,5 +0,0 @@ -usb-hid -1. build the sample read usb-hid device gcc usb_test_show.cpp -o hid_test_show -lusb-1.0, this is have been test in -rk3588 and read Tracker sucessful. -2. build cmd gcc usb_read_data.cpp -o hid -lusb-1.0 and run "sudo ./hid" or you will cannot open dev - diff --git a/usb_read_data.cpp b/usb_read_data.cpp index e43276d..d6432cd 100644 --- a/usb_read_data.cpp +++ b/usb_read_data.cpp @@ -1,108 +1,128 @@ +/******************** (C) COPYRIGHT 2024 UPBot*********************************** +* File Name : usb_read_data.cpp +* Current Version : V1.0 +* Author : UPBot Group +* Date of Issued : 2024.04.11 +* Comments : UWB USB-HID驱动 +********************************************************************************/ #include #include #include #include -static void print_devs(libusb_device **devs) -{ - libusb_device *dev; - int i = 0; - - while ((dev = devs[i++]) != NULL) { - struct libusb_device_descriptor desc; - int r = libusb_get_device_descriptor(dev, &desc); - if (r < 0) { - fprintf(stderr, "failed to get device descriptor"); - return; - } - - printf("%04x:%04x (bus %d, device %d)\n", - desc.idVendor, desc.idProduct, - libusb_get_bus_number(dev), libusb_get_device_address(dev)); - } -} + +/**--------------------------------------------------------------------- +* Function : print_devs +* Description : 列举usb设备信息,和ls usb功能差不多 +* Date : 2024/04/11 zhanli +*---------------------------------------------------------------------**/ +static void print_devs(libusb_device **devs) +{ + libusb_device *dev; + int i = 0; + + while ((dev = devs[i++]) != NULL) + { + struct libusb_device_descriptor desc; + int r = libusb_get_device_descriptor(dev, &desc); + if (r < 0) + { + fprintf(stderr, "Failed to get device descriptor."); + return; + } + + printf("USB Dev VID = %04x,PID = %04x (Bus %d, Device %d)\n", + desc.idVendor, desc.idProduct, + libusb_get_bus_number(dev), libusb_get_device_address(dev)); + } +} int main() { int r; ssize_t cnt; - libusb_device_handle *dev_handle; //a device handle - libusb_device **devs; //devices - //libusb_context **ctx=NULL; - r=libusb_init(NULL); //init 初始化libusb - if(r<0) { - printf("failed to init libusb\n"); - return 1; - } - cnt = libusb_get_device_list(NULL,&devs); //获取设备列表 - if (cnt < 0) { - printf("failed to get device list\n"); - return 1; - } - //print_devs(devs); - dev_handle = libusb_open_device_with_vid_pid(NULL, 0x2833, 0x0002); - if(dev_handle == NULL){ + libusb_device_handle *dev_handle; // a device handle + libusb_device **devs; // devices + // libusb_context **ctx=NULL; + // 初始化libusb + r = libusb_init(NULL); + if (r < 0) + { + printf("failed to init libusb\n"); + return 1; + } + // 获取设备列表 + cnt = libusb_get_device_list(NULL, &devs); + if (cnt < 0) + { + printf("failed to get device list\n"); + return 1; + } + // 打印usb设备信息 + // print_devs(devs); + dev_handle = libusb_open_device_with_vid_pid(NULL, 0x2833, 0x0002); + if (dev_handle == NULL) + { printf("Cannot open device\n"); return 1; - }else + }else{ printf("Device Opened\n"); + } + + // free the list, unref the devices in it + libusb_free_device_list(devs, 1); - libusb_free_device_list(devs, 1); //free the list, unref the devices in it - - if(libusb_kernel_driver_active(dev_handle, 0) == 1) { //find out if kernel driver is attached + if (libusb_kernel_driver_active(dev_handle, 0) == 1) + { // find out if kernel driver is attached printf("Kernel Driver Active\n"); - if(libusb_detach_kernel_driver(dev_handle, 0) == 0) //detach it + if (libusb_detach_kernel_driver(dev_handle, 0) == 0) // detach it printf("Kernel Driver Detached!\n"); } - r = libusb_claim_interface(dev_handle, 0); //claim interface 0 (the first) of device (mine had jsut 1) - if(r < 0) { + // claim interface 0 (the first) of device (mine had jsut 1) + r = libusb_claim_interface(dev_handle, 0); + if (r < 0){ printf("Cannot Claim Interface\n"); return 1; } printf("Claimed Interface\n"); - sleep(1); - unsigned char data[2]; + sleep(1); - unsigned char tmp_char[64]; - data[0]=0x02;data[1]=0x64; + unsigned char data[64]; int transferred; - int actual; //used to find out how many bytes were written - while(1){ - //r = libusb_interrupt_transfer(dev_handle, (0x01 | LIBUSB_ENDPOINT_OUT), data, 2, &actual, 0); //my device's out endpoint was 1, found with trial- the device had 2 endpoints: 2 and 129 - //if(r == 0 && actual == 2) //we wrote the 2 bytes successfully - //printf("Writing Successful\n"); - //else - // printf("Write Error\n"); - - //r = libusb_interrupt_transfer(dev_handle, (0x01 | LIBUSB_ENDPOINT_IN),tmp_char,64,&actual, 1000);//pay attion - - r = libusb_bulk_transfer(dev_handle, (0x01 | LIBUSB_ENDPOINT_IN), tmp_char, 64, &transferred,1000); - if(r == 0 && actual == 64) //we read the 64 bytes successfully + // 用于实际判断传输的数据长度 + int actual; + while (1) + { + + r = libusb_bulk_transfer(dev_handle, (0x01 | LIBUSB_ENDPOINT_IN), data, 64, &transferred, 1000); + if (r == 0 && actual == 64) // we read the 64 bytes successfully printf("Read Successful\n"); else printf("Read Error\n"); - printf("%i,%i\n",r,actual); + printf("%i,%i\n", r, actual); - int16_t mx = *(int16_t *)(tmp_char+56); - int16_t my = *(int16_t *)(tmp_char+58); - int16_t mz = *(int16_t *)(tmp_char+60); - printf("mag:%d,%d,%d\n",mx,my,mz); - usleep(1000*500); - //printf("%s","\033[1H\033[2J");//clear display - - } - - r = libusb_release_interface(dev_handle, 0); //release the claimed interface - if(r!=0) { + // 解析GeekIMU的磁力计信息 + int16_t mx = *(int16_t *)(data + 56); + int16_t my = *(int16_t *)(data + 58); + int16_t mz = *(int16_t *)(data + 60); + printf("mag:%d,%d,%d\n", mx, my, mz); + // 睡眠延时100ms + usleep(1000 * 100); + // 清屏 + // printf("%s","\033[1H\033[2J");//clear display + } + // 释放 the claimed interface + r = libusb_release_interface(dev_handle, 0); + if (r != 0) + { printf("Cannot Release Interface\n"); return 1; } printf("Released Interface\n"); + // 关闭设备 + libusb_close(dev_handle); + // 结束时调用 + libusb_exit(NULL); - libusb_close(dev_handle); //close the device we opened - libusb_exit(NULL); //needs to be called to end the - return 0; -} - - +} \ No newline at end of file