传输大小超过最大数据包大小时,WinUSB批量传输失败

时间:2014-04-22 11:50:00

标签: c usb winusb

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

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

任何人都可以面对同样的问题或建议解决方案吗?

此致 Nisheedh

2 个答案:

答案 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上的源代码。