2

我在 Windows 主机端使用 WinUSB 与我的 WINUSB USB 设备进行通信。我的 USB 设备是全速设备。我能够获取设备句柄并进行 OUT 和 IN 数据传输。

我面临 FS WinUSB 设备上的 Bulk IN 传输问题。当我将数据从 PC 环回到设备并返回到 PC 时,从 1 到 64 的大小工作正常。当我传输 65 个字节时,前 64 个字节能够在 PC 中读回。但是最后一个字节不见了。

任何人都可以面临同样的问题或可以提出一些解决方案吗?

问候,尼希德

4

2 回答 2

2

首先你应该读出MAXIMUM_TRANSFER_SIZE. 对于发送,WinUSB “如有必要,将缓冲区划分为适当大小的块”来源)。

还要检查以下备注WinUsb_ReadPipe

如果设备返回的数据大于最大传输长度,WinUSB会将请求分成最大传输长度的较小请求,依次提交。如果传输长度不是端点最大数据包大小的倍数(可通过 WINUSB_PIPE_INFORMATION 结构的 MaximumPacketSize 成员检索),WinUSB 会将传输大小增加到下一个 MaximumPacketSize 的倍数。

USB 数据包大小不会影响读取请求的传输。如果设备响应的数据包对于客户端缓冲区来说太大,则读取请求的行为对应于管道上设置的策略类型。如果管道的策略类型是 ALLOW_PARTIAL_READS,WinUSB 会将剩余数据添加到下一次传输的开头。如果未设置 ALLOW_PARTIAL_READS,则读取请求失败。有关策略类型的详细信息,请参阅用于管道策略修改的 WinUSB 函数。

检查您的设置以及最后一个字节是否通过第二次传输发送。您还应该测试实际写入/读取了多少字节。

于 2014-04-22T12:41:51.200 回答
1

最近,当我将我的STM32F4 发现板编程为 USB 设备并使用WINUSB使应用程序能够通过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接收处理器只做它的读任务保持读指针偏移

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;
}}

为了分享这个问题的更多细节,这是我在我的 GitHub 项目中的源代码。

于 2020-10-07T10:11:17.750 回答