- Notifications
You must be signed in to change notification settings - Fork1k
Description
As the title, I noticed that sometimes the output buffer will be splited into two bulk packages.
e.g. if I send [1, 2, 3, 4, 5, 6, 7] by usingSerialUSB.write()
, sometimes the output package will be [1, 2, 3, 4] and [5, 6, 7], not [1, 2, 3, 4, 5, 6, 7].
Then I found that, incdc_queue.c
, we are usingTransmitQueue
to handle the output buffer, maybe for avoiding overflow? Not sure about this.
And forTransmitQueue
, actually, it is a ring buffer. So whenwrite pointer < read pointer
, which means something like this:
[x4 x5 x6 x7 0 0 ...... 0 0 x0 x1 x2 x3]
x(n) means the output buffer we provided, 0 means no-related bytes.
Then the current approach will runUSBD_LL_Transmit
twice to send the whole output buffer.
first time, we send [x0 x1 x2 x3]
then, we send [x4 x5 x6 x7]
(it seems that each of them are calledblock
in the code, I will call them block bellow)
Function call:
USBSerial::write
|-> CDC_TransmitQueue_Enqueue
|-> CDC_continue_transmit
|-> |-> CDC_TransmitQueue_ReadBlock
|-> |-> USBD_CDC_SetTxBuffer
|-> |-> USBD_CDC_TransmitPacket
|-> |-> |-> USBD_LL_Transmit
Before we send the data, as the comment in L980, the following code will set the total length of the packet.
Arduino_Core_STM32/cores/arduino/stm32/usb/cdc/usbd_cdc.c
Lines 980 to 981 inf31d070
/* Update the packet total length */ | |
pdev->ep_in[CDCInEpAdd&0xFU].total_length=hcdc->TxLength; |
But it seems that thetotal length
is incorrect. It is same to the length of the block.
So two packets will be sent instead of one as expected.
For the solusion, I'm usingUSBD_LL_Transmit
directly, instead of using the ring bufferTransmitQueue
.
And it works as expected now, so I think there's a bug in the output buffer handling approach.
Desktop (please complete the following information):
- OS: Windows
- Arduino Cli: 0.34.2
- STM32 core version: 2.7.1
Board (please complete the following information):
- Name: Nucleo H753ZI