T20 USB COM0 fail to receive certain amount of bytes

Hello,

We have a device that communicates through the USB port “\$device\com0” with an external application.
The app sends and receives packets that let it control the device to perform activities, but customers notified me that sometimes the device does not reply, not immediately.

I have been able to replicate this bug by sending the same packet they used and also when I tried with several variations of it: when the device should receive a packet of exactly 512 bytes, the breakpoints I set in debug for the code that manages to read from the USB port don’t break, or they show the ReadFile call exited with 0 bytes read.

if I change anything in the packet to vary its overall length to either less or more than 512 bytes, suddenly the device receives all the previous “unread” packets plus the latest new one.

Another way I can force it to read these packets is to send at least 8 of them, leading to the device suddenly reading a total amount of 4096bytes.

Without having to reveal too much of our proprietary packet protocol, I can tell you that the first bytes of the packet are very similar in each one:

  • 0x4B (fixed)
  • 0x42 (fixed for this scenario)
  • 0x01 (varies when changing the length of the packet, but fixed for this scenario)
  • 0xFA (varies when changing the length of the packet)
  • 0x7B ‘{’ (start bracket for the JSON string payload inside the packet)
  • 0x22 ‘"’ (double quote preceding the first json property)

Can you help me understand how this is possible?
I’m quite sure this issue is not on the external application on the other side, since our customers have this issue on their android app, while I can replicate it using a windows desktop software.

A quick search on google did not reveal any specific byte sequence that I should know of that could make the USB port behave like this (the active sync is disabled by default on our devices, except the one I use, but it is disabled on my PC by the driver we use for our desktop application).

The USB COM0 port is set up as default by T20, except for the Baud Rate, which we changed to 921600 for this project (but this issue is present also with the default settings). Here is the list, just for completeness:

property value
BaudRate 921600
fBinary 1
fParity 0
fOutxCtsFlow 0
fOutxDsrFlow 0
fDtrControl DTR_CONTROL_ENABLE
fDsrSensitivity 0
fTXContinueOnXoff 0
fOutX 0
fInX 0
fErrorChar 0
fNull 0
fRtsControl RTS_CONTROL_ENABLE
fAbortOnError 0
fDummy2 0
wReserved 0
XonLim 16384
XoffLim 4096
ByteSize 8
Parity 0
StopBits 0
XonChar 17
XoffChar 19
ErrorChar 13
EofChar 13
EvtChar 13
wReserved1 0

Does this have anything to do with the DTR and RTS settings being enabled in these configurations? I’m not knowledgeable on this topic yet.

Please help.
Thank you

Colibri T20 256MB 1.2B
Custom board
WEC7 BSP 2.4

Hi, I’m the Toradex AI Assistant.

I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the “Solution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.

Did you like my answer? :+1: :-1:


Hello and thank you for your very detailed description of the issue.

What you are experiencing is related to the internal USB buffer handling, rather than the DTR/RTS serial handshake configuration. The challenge with exactly 512-byte packets is not uncommon on USB-based virtual COM ports, particularly on platforms like the Colibri T20 running Windows Embedded Compact 7.

Why does this happen?

  • USB Endpoint Size: USB endpoints (the hardware buffer for each communication channel) typically have a transfer size that is a power of 2—512 bytes is a standard full-speed bulk endpoint size. When you send exactly this size, the USB stack may expect either a short packet (less than the endpoint size) or an explicit signal to know the transfer is “complete”[1].
  • Buffering Behavior: On the Toradex module running WEC7, the USB serial driver accumulates data and may not deliver it up to your application until either it gets a “short” packet (less than 512 bytes) or the application has read enough data to cause a buffer flush, such as multiple packets filling an internal 4096-byte (8 * 512B) buffer. That’s why sending one “non-512-byte” packet or 8 full 512B packets suddenly delivers all the accumulated data.

DTR/RTS Settings

The DTR and RTS signals (your DTR_CONTROL_ENABLE and RTS_CONTROL_ENABLE settings) control handshake and flow but are not involved with the internal USB packetization or delivery. They’re not contributing to this specific buffering behavior.

Recommended Approaches

  • On the Device (Toradex) Side: There’s typically no configuration parameter available to alter this buffering within Windows CE USB serial implementation.
  • On the Host/Application Side:
    • Vary the Length: Try to avoid sending packets of exactly 512 bytes. Make them a byte shorter or longer if possible.
    • Explicit Flush: After sending, try to flush the output buffer if your host environment allows it. On Windows and some Android USB libraries, this can prompt the stack to send any pending data immediately.
    • Send Termination: Consider appending a unique terminator (such as a newline) and changing your firmware to detect this as an end-of-packet signal, allowing you to read partial buffers.
    • Polling or Timeout: Ensure your read code uses a timeout or repeated polling, not blocking forever, so it can catch delayed packets.

Miscellaneous

  • This is a general USB behavior, not limited to Toradex platforms. If you port the firmware/application code to other embedded systems, you may face the same limitation if using USB serial gadgets.
  • In practice, endpoints and drivers try to optimize for throughput, not latency, which can lead to such delayed deliveries when the packet sizes are exactly the endpoint length.

References:

If you need more specific advice on changing your packet protocol or read logic within your application/firmware, please provide details, and I can give code examples or further suggestions.

Best regards,
Toradex AI Assistant.


  1. Windows CE Serial over USB (Toradex Docs) ↩︎