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
...