我在网上看到人们可以使用 CubeIde 生成的 USB 自定义 hid 类,并且他们获得了良好的传输速度。
同样在过去,我曾使用 STM32(F103RE/L462RE) 和用于自定义 HID 和 KeilIDE 的较旧的 usblib。我将它与 ac# 应用程序一起使用,它可以非常快地读取和写入数据(只需几秒钟即可传输一些最大 3kb 的数据块)。
现在使用相同的处理器和带有最新 usb 自定义 hid 库的 CUBEIDE,相同的传输平均需要 1 分 30 秒。
在 PC 端使用旧库从 stm32 读取数据时,我使用了 hid.dll 中的 HidD_Ge tinputReport 方法。对于较新的 usb hid 库,我必须使用 ReadFile(overlaped),因为 HidD_GetInputReport 不工作。
这是一个非常显着的差异,所以我认为我没有正确使用新的 USB CUSTOM HID 库。
这是我到目前为止所做的:
- 该项目使用 freertos v2.0 一些 IO/ADC 转换器/USART2/DMA(usart 和 adc)和一些定时器。
1.我正在使用CUBEIDE
2.我把USB中断优先级设置为0。
3. 我将 CUSTOM_HID_FS_BINTERVAL 设置为 1。
4. 将 CUSTOM_HID_OUTREPORT_BUF_SIZE 设置为 2 或 64。(使用 2 和 64 字节进行测试 - 对于 64 字节,读取文件 (stm32->pc) 失败的频率更高)
5. 更新了报告描述符和输入/输出端点大小(64 字节/2 字节)
6. USB 传输的工作原理如下:PC 发送一个请求,stm32 处理它并创建一个回复,PC 必须读取这个回复然后发送一个新的请求等等。
下面是STM32读写的代码(c/c++语言)
- //====================================================================================
- __ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
- {
- /* USER CODE BEGIN 0 */
- 0x06, 0x00, 0xFF, /*HID_UsagePageVendor( 0x00)*/
- 0x09, 0x01, /*HID_Usage ( 0x01)*/
- 0xA1, 0x01, /*HID_Collection ( HID_Application)*/
- 0x15, 0x00, /*HID_LogicalMin ( 0 ) value range: 0 - 0xFF */
- 0x26, 0xFF, 0x00, /*HID_LogicalMaxS ( 0xFF)*/
- 0x75, 0x08, /*HID_ReportSize ( 8 ) 8 bits */
- //in
- 0x95, 0x40, /*HID_ReportCount ( HID_INPUT_REPORT_BYTES ) HERE I Tested with 64 or 2 bytes */
- 0x09, 0x01, /*HID_Usage ( 0x01 )*/
- 0x81, 0x02, /*HID_Input ( HID_Data | HID_Variable | HID_Absolute )*/
- //out
- 0x95, 0x40, /*HID_ReportCount ( HID_OUTPUT_REPORT_BYTES ) HERE I Tested with 64 or 2 bytes */
- 0x09, 0x01, /*HID_Usage ( 0x01 )*/
- 0x91, 0x02, /*HID_Output ( HID_Data | HID_Variable | HID_Absolute )*/
- //feature
- 0x95, 0x01, /*HID_ReportCount ( HID_FEATURE_REPORT_BYTES )*/
- 0x09, 0x01, /*HID_Usage ( 0x01 )*/
- 0xB1, 0x02, /*HID_Feature ( HID_Data | HID_Variable | HID_Absolute )*/
- /* USER CODE END 0 */
- 0xC0 /* END_COLLECTION */
- };
- //====================================================================================
- /**
- * @brief Manage the CUSTOM HID class events
- * @param event_idx: Event index
- * @param state: Event state
- * @retval USBD_OK if all operations are OK else USBD_FAIL
- */
- static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state)
- {
- /* USER CODE BEGIN 6 */
- UNUSED(event_idx);
- UNUSED(state);
- /*get the data from the PC*/
- USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef*)hUsbDeviceFS.pClassData;
- for(unsigned char i=0;i USB_RX_Buffer = hhid->Report_buf;
- /*update the TX buffer with the corect response*/
- ProcessMultipleRequest();
- /*send back the answers for the requests*/
- USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, USB_TX_Buffer, USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);
- return (USBD_OK);
- /* USER CODE END 6 */
- }
- //====================================================================================
这是在PC上读/写的代码
- //...
- System.Threading.Thread.CurrentThread.Priority = ThreadPriority.Highest;
- //...
- readHandle = FileIO.CreateFile(myDevicePathName, FileIO.GENERIC_READ, FileIO.FILE_SHARE_READ | FileIO.FILE_SHARE_WRITE, IntPtr.Zero, FileIO.OPEN_EXISTING, FileIO.FILE_FLAG_OVERLAPPED, 0);
- //...
- EventObject = FileIO.CreateEvent(IntPtr.Zero, false, false, "");
- HidOverlapped.OffsetLow = 0;
- HidOverlapped.OffsetHigh = 0;
- HidOverlapped.EventHandle = eventObject;
- nonManagedBuffer = Marshal.AllocHGlobal(inputReportBuffer.Length);
- nonManagedOverlapped = Marshal.AllocHGlobal(Marshal.SizeOf(HidOverlapped));
- Marshal.StructureToPtr(HidOverlapped, nonManagedOverlapped, false);
- success = FileIO.ReadFile(readHandle, nonManagedBuffer, inputReportBuffer.Length, ref numberOfBytesRead, nonManagedOverlapped);
- if (!success)
- {
- result = FileIO.WaitForSingleObject(eventObject, 3000);
- switch (result)
- {
- case (System.Int32)FileIO.WAIT_OBJECT_0:
- // ReadFile has completed
- success = true;
- FileIO.GetOverlappedResult(readHandle, nonManagedOverlapped, ref numberOfBytesRead, false);
- break;
- case FileIO.WAIT_TIMEOUT:
- / Cancel the operation on other error.
- CancelTransfer(hidHandle, readHandle, writeHandle, eventObject);
- success = false;
- break;
- default:
- // Cancel the operation on other error.
- CancelTransfer(hidHandle, readHandle, writeHandle, eventObject);
- success = false;
- break;
- }
- }
- if (success)
- {
- // A report was received.
- // Copy the received data to inputReportBuffer for the application to use.
- Marshal.Copy(nonManagedBuffer, inputReportBuffer, 0, numberOfBytesRead);
- }
- //.......
我还尝试创建一个优先级设置为最高的线程,该线程连续从 smt32 读取,但这不起作用。
我使用重叠读取,但是当读取线程启动时,写入和读取操作都会失败。
即使调用了 USBD_CUSTOM_HID_SendReport,读取也会因超时而失败。
有没有人取得更好的传输时间?
根据您的经验,pc 写入和读取是否经常失败?
知道我做错了什么或者我可以做些什么来改进它吗?
0
|
1个回答
|
|
|