-
Notifications
You must be signed in to change notification settings - Fork 973
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
USBD CDC package maybe splited when using SerialUSB.write() #2372
Comments
Hi @yp05327 |
Actually, I don't have. I'm not a pro developer of embedded system, so I have no knowledge about what embedded system engineers will do to fix it. |
The behavior is CORRECT nothing need to be fixed. CDC is emulating serial port behavior which is a bytestream with correct ordering, no lost byte or duplication. packet boundary does not exist in serial port nor CDC. |
I also have Arduino Due, but the behavior is different. But I can image this: |
If u write the cdc serial fast enough there's no splitting. |
No, IIRC, the splitting is caused by |
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 using
SerialUSB.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, in
cdc_queue.c
, we are usingTransmitQueue
to handle the output buffer, maybe for avoiding overflow? Not sure about this.And for
TransmitQueue
, 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 run
USBD_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 called
block
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 in f31d070
But it seems that the
total 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 using
USBD_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):
Board (please complete the following information):
The text was updated successfully, but these errors were encountered: