This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LAUNCHXL-CC26X2R1: XDS110 UART is bursty and very high latency under certain conditions

Part Number: LAUNCHXL-CC26X2R1

At certain data volumes going from the target to the host (most severely around 1 kbyte/sec), the XDS110 UART to USB CDC-ACM bridge sends UART data to the host in an extremely bursty and high latency manner. This effect is most visible at higher baud rates (above 400 kbaud). Under certain combinations of baud rate and data volume, it seems UART data is buffered on the XDS110 for periods that can exceed half a second before it is sent to the host over USB. This is unusable for any latency-sensitive monitoring of microcontroller outputs.

To reproduce this issue, modify the uartecho example in the SDK as follows:

--- a/examples/nortos/CC26X2R1_LAUNCHXL/drivers/uartecho/uartecho.c
+++ b/examples/nortos/CC26X2R1_LAUNCHXL/drivers/uartecho/uartecho.c
@@ -35,6 +35,7 @@
  */
 #include <stdint.h>
 #include <stddef.h>
+#include <unistd.h>
 
 /* Driver Header files */
 #include <ti/drivers/GPIO.h>
@@ -48,8 +49,7 @@
  */
 void *mainThread(void *arg0)
 {
-    char        input;
-    const char  echoPrompt[] = "Echoing characters:\r\n";
+    const char  echoPrompt[] = "Writing chars:\r\n";
     UART_Handle uart;
     UART_Params uartParams;
 
@@ -65,7 +65,7 @@ void *mainThread(void *arg0)
     uartParams.writeDataMode = UART_DATA_BINARY;
     uartParams.readDataMode = UART_DATA_BINARY;
     uartParams.readReturnMode = UART_RETURN_FULL;
-    uartParams.baudRate = 115200;
+    uartParams.baudRate = 2000000;
 
     uart = UART_open(CONFIG_UART_0, &uartParams);
 
@@ -77,11 +77,8 @@ void *mainThread(void *arg0)
     /* Turn on user LED to indicate successful initialization */
     GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
 
-    UART_write(uart, echoPrompt, sizeof(echoPrompt));
-
-    /* Loop forever echoing */
     while (1) {
-        UART_read(uart, &input, 1);
-        UART_write(uart, &input, 1);
+        UART_write(uart, echoPrompt, sizeof(echoPrompt) - 1);
+        usleep(15000);
     }
 }

The above code will send a line of text every 15 milliseconds. However, at least on Mac OS and Linux, the data will come to the host over USB CDC-ACM in bursts that are over half a second apart. You can visually observe the bursts with high latency between them using any terminal program. However, for easier measurement and visualization of the burstiness and high latency, you can use the following simple Python script:

#!/usr/bin/env python3

from serial import Serial
from time import time

ser = Serial("/dev/ttyACM0", 2000000)

while True:
    stime = time()
    l = ser.readline()
    dt = time() - stime
    print("Read took %.3f ms" % (dt*1000))

The output of the script would look something like this, on Linux and Mac at least. Note the large delays waiting for bursts of buffered data.

...
Read took 0.137 ms
Read took 0.136 ms
Read took 576.868 ms
Read took 0.154 ms
Read took 0.134 ms
...
Read took 0.082 ms
Read took 0.088 ms
Read took 595.470 ms
Read took 0.136 ms
Read took 0.120 ms
...
Read took 0.089 ms
Read took 0.082 ms
Read took 948.779 ms
Read took 0.068 ms
Read took 0.058 ms
...
Read took 0.064 ms
Read took 0.063 ms
Read took 425.929 ms
Read took 0.135 ms
Read took 0.121 ms
...
Read took 0.088 ms
Read took 0.082 ms
Read took 950.437 ms
Read took 0.138 ms
...
Read took 0.080 ms
Read took 0.074 ms
Read took 422.823 ms
Read took 0.136 ms
Read took 0.121 ms
...

  • For reference, using an FTDI FT232H cable as a UART->USB bridge instead of the XDS110 will solve all the latency and burstiness issues. Thus, this appears to be an issue with the implementation of UART buffering in the XDS110 firmware.

    Also, lowering the baud rate to 200000 fixes the burstiness/latency issues with the example above. However, 230400 baud is bursty, as is any higher baud rate I tried.

  • Hi Sultan,

    I am not seeing any such delay when using your code example, but I am using a LAUNCHXL-CC26X2R1 with 230400 baud and logging using Tera Term on a Windows 10 OS.  I am reliably receiving 7 packets about every 110 milliseconds.  Please make sure a debug session is not active when running your test as this will interfere with the XDS110 throughput.

    Regards,
    Ryan

  • Thanks for looking into this. My CC2652 code example doesn't visualize the latency very well because it prints the same thing repeatedly (making the burstiness less visible in a terminal). However, the burstiness is there on Windows, Mac, and Linux (I tried all three OSes running on bare metal). I get bursts of data every 100 ms at 230400 baud, worsening to 500+ ms at 2 megabaud. The easiest way to observe the burstiness is with my Python script in the first post. Here's what I get with the Python script on Windows (edited to use COM3 at 230400 baud):

    C:\Users\Sultan\Documents>py test.py
    Read took 0.000 ms
    Read took 0.000 ms
    Read took 0.000 ms
    Read took 0.000 ms
    Read took 0.000 ms
    Read took 0.000 ms
    Read took 0.000 ms
    Read took 122.476 ms
    Read took 0.000 ms
    Read took 0.000 ms
    Read took 0.000 ms
    Read took 0.000 ms
    Read took 0.000 ms
    Read took 0.000 ms
    Read took 100.318 ms
    Read took 0.000 ms
    Read took 0.000 ms
    Read took 0.000 ms
    Read took 0.000 ms
    Read took 0.000 ms
    Read took 0.000 ms
    Read took 100.343 ms
    Read took 0.000 ms
    Read took 0.000 ms
    ...

  • Hi Sultan,

    Yes, this is a limitation of the XDS110 firmware that I've observed as well.  As you've already suggested, a UART to USB bridge can be used instead if you do not require the JTAG program/debug functionality.

    Regards,
    Ryan

  • Thanks for confirming this Ryan. For now, I'm using an FTDI UART to USB bridge to work around this, but it would be nice for TI to improve the XDS110 firmware to place a cap on the time between bursts, especially for higher baud rates.