我在Windows主机端使用WinUSB与我的WINUSB USB设备进行通信。 我的USB设备是全速设备。 我能够获得设备句柄并进行OUT和IN数据传输。
我在FS WinUSB设备上遇到了Bulk IN传输问题。当我从PC到设备和PC返回数据时,从1到64的大小正常工作。当我传输65个字节时,前64个字节能够在PC中读回。但是遗漏了最后一个字节。
任何人都可以面对同样的问题或建议解决方案吗?
此致 Nisheedh
答案 0 :(得分:0)
首先你应该读出MAXIMUM_TRANSFER_SIZE
。对于发送,WinUSB "将缓冲区划分为适当大小的块,如有必要" (source)。
另请查看WinUsb_ReadPipe
的评论:
如果设备返回的数据大于最大传输数 长度,WinUSB将请求分成较小的最大请求 传输长度并按顺序提交 。如果转移长度是 不是端点的最大数据包大小的倍数(可检索 通过WINUSB_PIPE_INFORMATION结构的MaximumPacketSize 成员),WinUSB将传输的大小增加到下一个 MaximumPacketSize的倍数。
USB数据包大小不会影响读取请求的传输。 如果设备响应的数据包对于客户端来说太大 缓冲区,读取请求的行为对应于类型 在管道上设置的策略。 如果管道的政策类型是 ALLOW_PARTIAL_READS,WinUSB将剩余数据添加到开头 下一次转移。 如果未设置ALLOW_PARTIAL_READS,则读取 请求失败。有关策略类型的更多信息,请参阅WinUSB 管道策略修改的功能。
检查您的设置以及是否通过第二次传输发送最后一个字节。 您还应该测试实际写入/读取的字节数。
答案 1 :(得分:0)
最近,当我将 STM32F4发现板编程为USB设备并使用 WINUSB 使应用程序能够传输回送< / strong>通过 USB BULK 发送消息。
我做三件事是让PC发送并从设备接收超过64字节的数据包作为环回消息传递方式:
1。对于应用,请设置管道策略以允许部分读取:
BOOL policy_allow_partial = true;
if (WinUsb_SetPipePolicy(deviceData.WinusbHandle, pipe_id.PipeInId, ALLOW_PARTIAL_READS,sizeof(UCHAR), &policy_allow_partial)) {
printf("WinUsb_SetPipePolicy for ALLOW_PARTIAL_READS OK\n");
}
else {
printf("WinUsb_SetPipePolicy for ALLOW_PARTIAL_READS failed:%s\n", GetLastErrorAsString().c_str());
}
2。对于固件,只需让USB接收处理程序仅执行读取任务,并很好地保持读取指针偏移。< / p>
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) {
/* USER CODE BEGIN 6 */
extern void on_CDC_Receive_FS(uint32_t len);
extern volatile int8_t usb_rxne;
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
uint32_t len = *Len;
if ((ir + len) >= RX_DATA_LEN ) {
len = RX_DATA_LEN - 1 - ir;
if (len > 0 ) {
memcpy(usb_rx+ir, Buf, len);
}
ir = RX_DATA_LEN - 1;
}
else {
memcpy(usb_rx+ir, Buf, len);
ir += len;
}
usb_rxne = SET;
on_CDC_Receive_FS(len);
return (USBD_OK); }
void on_CDC_Receive_FS(uint32_t len) {
extern int8_t CDC_is_busy(void);
if (CDC_is_busy()) return;
//USB loopback method 2, transmit later but can support more than 64 bytes
if (iw < 512) {
memcpy(usb_tx+iw, usb_rx, len);
iw += len;
tx_len += len;
}
else {
memset(usb_tx, 0, 512);
iw = 0;
tx_len = 0;
}
}}
3。让传输任务在主循环中运行。
int main(void) {
while (1) {
if (iw != 0) {
usb_txe = RESET;
ret_tran = CDC_Transmit_FS(usb_tx, tx_len);
iw = 0;
tx_len = 0;
usb_txe = SET;
}
else {
usb_txe = SET;
}}
要分享有关此问题的更多详细信息,请参见my GitHub project上的源代码。