USB虚拟串口发送数据注意事项
Questions: 在使用USB 虚拟串口发送数据时,如果每帧发送的字节数一直是当前BULK IN 端点的
最大包长度(如64Byte),上位机工具不能正常显示数据。
例如:利用上位机工具发送64Byte 数据给USB 设备,USB 设备将此64Byte 数据在返回给上位机,
我们在上位机的输出界面上可能看不到有收到64Byte 数据。
Answer:
此种情况和USB2.0 协议bulk 传输的定义有关系,参考usb2.0 specification 5.8 节Bulk transfers 有如下描
述:
简单来说:一个bulk 传输完成有三种条件:
1. 确切知道要收发多少数据
2. 发送的一帧数据少于最大包长度
3. 发送一个0 长度数据的包
我们看到前面的问题,USB 发送的数据一直是最大的包长度,会导致主机认为当前的bulk 传输并没有全部
完成,因此在上位机上看不到收到的数据。
解决方法:
可以采用条件3 的方式来解决此问题,前面的数据传输完成,当前已经没有数据要传输的时候,USB device
发送一个0 长度的数据包来告诉主机传输已经完成。
以BSP 里面的403A VirtualComPort_loopback demo 为例:
void EP1_IN_Callback(void)
{
uint16_t dwSendLen = 0;
uint32_t SendPtr = 0;
static uint8_t send0packet = 0;
/*no data need send*/
if (usb_txfifo.wrpointer == usb_txfifo.curpointer )
{
if ( send0packet == 1 )
{
SetEPTxCount(ENDP1, 0);
SetEPTxValid(ENDP1);
send0packet = 0;
}
return;
}
if ( usb_txfifo.wrpointer > usb_txfifo.curpointer )
{
dwSendLen = usb_txfifo.wrpointer - usb_txfifo.curpointer;
}
else
{
dwSendLen = USB_FIFO_MAX - usb_txfifo.curpointer;
}
SendPtr = usb_txfifo.curpointer;
if ( dwSendLen > VIRTUAL_COM_PORT_DATA_SIZE )
{
dwSendLen = VIRTUAL_COM_PORT_DATA_SIZE;
}
usb_txfifo.curpointer += dwSendLen;
if ( usb_txfifo.curpointer >= USB_FIFO_MAX )
usb_txfifo.curpointer = 0;
send0packet = 1;
/* send packet to PMA*/
UserToPMABufferCopy(&usb_txfifo.fifo[SendPtr], ENDP1_TXADDR, dwSendLen);
SetEPTxCount(ENDP1, dwSendLen);
SetEPTxValid(ENDP1);
}
类型:MCU 应用
适用型号:所有AT32F403/403A/407/413 系列产品
主功能:Bulk 传输发送问题
次功能:无
|