Skip to content

Fix CDC echo test issue for IMXRT and fast MCUs#3584

Merged
hathach merged 9 commits intomasterfrom
fix-hil
Apr 5, 2026
Merged

Fix CDC echo test issue for IMXRT and fast MCUs#3584
hathach merged 9 commits intomasterfrom
fix-hil

Conversation

@hathach
Copy link
Copy Markdown
Owner

@hathach hathach commented Apr 2, 2026

Summary

Fix HIL CDC echo test failures caused by blocking board_uart_write() / printf() in USB callbacks, which stalls the main loop and
causes UART RX FIFO overrun. Also standardize board_uart_read()/board_uart_write() as non-blocking across all BSP families.

Root cause

The host CDC echo example (cdc_msc_hid) forwards USB?UART using printf() inside tuh_cdc_rx_cb(). printf() calls
board_uart_write() which was blocking (waits for each byte to transmit at 115200 baud). During this ~3ms block, incoming UART
data overflows the hardware RX FIFO, losing bytes. The test sees truncated echo data.

Changes

Host CDC echo app (examples/host/cdc_msc_hid/src/cdc_app.c):

  • Move CDC?UART forwarding from tuh_cdc_rx_cb() (USB callback) to cdc_app_task() (main loop)
  • Interleave UART TX with UART RX reads to prevent RX overrun during output

BSP board_uart_write() ? non-blocking for all families:

  • STM32 with HW UART FIFO (H7, H5, C0, G0, G4, L4, U0, U5, WB, WBA, H7RS, N6): enable FIFO mode + non-blocking register write
  • STM32 without HW FIFO (F0, F1, F2, F3, F4, F7): add RXNE interrupt + tu_fifo_t ring buffer for RX; non-blocking TX
  • STM32 F7: introduce UART_ID numeric macro in board.h, derive USARTn, USARTn_IRQn, USARTn_IRQHandler, UARTn_CLK_ENABLE via
    #if/#elif ? eliminates clang -Wunreachable-code errors
  • NXP (iMXRT, Kinetis, LPC, MCX, RW61x): non-blocking register writes
  • RP2040: use uart_is_writable() check
  • Others (AT32, Broadcom, CH32, GD32, Maxim, MSP430, TI, XMC, etc.): convert busy-wait to break-on-not-ready
  • Stubs (no UART hardware): return -1 instead of 0 to distinguish "not available" from "TX busy"

BSP board.c sys_write():

  • Retry loop for non-blocking board_uart_write() so printf() still works
  • Break immediately on negative return (UART not available) to avoid infinite loop on stub boards

Copilot AI review requested due to automatic review settings April 2, 2026 16:30
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 99b721db60

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts UART/stdio behavior and host CDC example logic to improve reliability of CDC echo testing on fast MCUs (notably IMXRT), and adds configurability to HIL retry behavior.

Changes:

  • Make some BSP UART/stdio helpers non-blocking-friendly (e.g., board_uart_write() on IMXRT; board_putchar() now returns int).
  • Add retry/looping behavior around UART writes (sys_write) and update host CDC example/config to better handle rapid transfers.
  • Update HIL runner to make retry count configurable and shorten per-chunk CDC echo wait time.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/hil/hil_test.py Adds CLI-configurable retry count and adjusts CDC echo wait timing.
hw/bsp/board.c Changes sys_write() to retry partial/non-blocking writes; updates board_putchar() signature/behavior.
hw/bsp/board_api.h Updates UART and board_putchar() API comments/signature to match new behavior.
hw/bsp/imxrt/family.c Makes IMXRT UART write path return partial writes (non-blocking style).
hw/bsp/rp2040/family.c Updates board_putchar() to return int consistently with API.
hw/bsp/espressif/boards/family.c Updates board_putchar() to return int consistently with API.
examples/host/cdc_msc_hid/src/tusb_config.h Increases host task queue size and reduces CDC instance count for this example.
examples/host/cdc_msc_hid/src/cdc_app.c Refactors CDC console<->USBH forwarding to better cope with fast transfers.
examples/host/cdc_msc_hid_freertos/src/cdc_app.c Renames console input helper for consistency.
examples/host/msc_file_explorer/src/main.c Removes large comment block / unused include.
examples/CMakeLists.txt Removes dead commented-out metrics command.
Comments suppressed due to low confidence (1)

examples/host/cdc_msc_hid_freertos/src/cdc_app.c:62

  • board_getchar() is documented/implemented as returning a negative value when no character is available. Using ch <= 0 treats NUL (0) as "no input" and is inconsistent with the non-FreeRTOS variant in this PR (which uses ch < 0). Consider changing this check to ch < 0 for correctness and consistency.
static size_t console_read(uint8_t *buf, size_t bufsize) {
  size_t count = 0;
  while (count < bufsize) {
    int ch = board_getchar();
    if (ch <= 0) {
      break;
    }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 2, 2026

Size Difference Report

Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds.

Note: If there is no change, only one value is shown.

Changes >1% in size

file .text .rodata .data .bss size % diff
cdc_host.c 6617 ➙ 6381 (-236) 487 15 1498 ➙ 985 (-513) 8327 ➙ 7579 (-748) -9.0%
usbh.c 4652 55 99 961 ➙ 1034 (+73) 5734 ➙ 5807 (+73) +1.3%
TOTAL 11269 ➙ 11033 (-236) 542 114 2459 ➙ 2019 (-440) 14061 ➙ 13386 (-675) -4.8%

Changes <1% in size

file .text .data size % diff
tusb_fifo.c 841 ➙ 846 (+5) 480 836 ➙ 841 (+5) +0.6%
TOTAL 841 ➙ 846 (+5) 480 836 ➙ 841 (+5) +0.6%
No changes
file .text .rodata .data .bss size % diff
audio_device.c 2897 0 1260 1627 4518 +0.0%
cdc_device.c 1252 16 1106 684 1935 +0.0%
dcd_ch32_usbfs.c 1473 0 0 2444 3917 +0.0%
dcd_ch32_usbhs.c 1469 0 0 448 1917 +0.0%
dcd_ci_fs.c 1925 0 0 1290 3215 +0.0%
dcd_ci_hs.c 1759 0 0 1344 2538 +0.0%
dcd_da146xx.c 3067 0 0 144 3211 +0.0%
dcd_dwc2.c 4210 25 0 265 4500 +0.0%
dcd_eptri.c 2271 0 0 259 2530 +0.0%
dcd_ft9xx.c 3276 0 0 172 3448 +0.0%
dcd_khci.c 1953 0 0 1290 3243 +0.0%
dcd_lpc17_40.c 1474 0 0 648 1798 +0.0%
dcd_lpc_ip3511.c 1463 0 0 264 1683 +0.0%
dcd_mm32f327x_otg.c 1478 0 0 1290 2768 +0.0%
dcd_msp430x5xx.c 1798 0 0 176 1974 +0.0%
dcd_musb.c 2445 0 0 160 2605 +0.0%
dcd_nrf5x.c 2918 0 0 292 3210 +0.0%
dcd_nuc120.c 1094 0 0 78 1172 +0.0%
dcd_nuc121.c 1168 0 0 101 1269 +0.0%
dcd_nuc505.c 0 0 1531 157 1688 +0.0%
dcd_rp2040.c 838 0 764 655 2257 +0.0%
dcd_rusb2.c 2919 0 0 156 3075 +0.0%
dcd_samd.c 1034 0 0 266 1300 +0.0%
dcd_samg.c 1320 0 0 72 1392 +0.0%
dcd_stm32_fsdev.c 2558 0 0 291 2849 +0.0%
dfu_device.c 777 28 712 140 916 +0.0%
dfu_rt_device.c 157 0 134 0 157 +0.0%
dwc2_common.c 602 30 0 0 618 +0.0%
ecm_rndis_device.c 1037 0 1 2858 3896 +0.0%
ehci.c 2763 0 0 6043 7597 +0.0%
fsdev_common.c 180 0 0 0 180 +0.0%
hcd_ch32_usbfs.c 2485 0 0 498 2983 +0.0%
hcd_ci_hs.c 184 0 0 0 184 +0.0%
hcd_dwc2.c 4994 33 1 513 5540 +0.0%
hcd_khci.c 2442 0 0 449 2891 +0.0%
hcd_musb.c 3073 0 0 157 3230 +0.0%
hcd_pio_usb.c 262 0 240 0 502 +0.0%
hcd_rp2040.c 2000 17 4 321 2342 +0.0%
hcd_rusb2.c 2923 0 0 245 3168 +0.0%
hcd_samd.c 2220 0 0 324 2544 +0.0%
hcd_stm32_fsdev.c 3287 0 1 420 3708 +0.0%
hid_device.c 1125 44 997 119 1244 +0.0%
hid_host.c 1240 0 0 1251 2491 +0.0%
hub.c 1384 8 8 30 1418 +0.0%
midi_device.c 1151 0 1007 623 1772 +0.0%
midi_host.c 1341 7 7 3635 4979 +0.0%
msc_device.c 2525 108 2286 547 3071 +0.0%
msc_host.c 1587 0 0 394 1982 +0.0%
mtp_device.c 1696 22 735 588 2292 +0.0%
ncm_device.c 1538 28 718 5843 7395 +0.0%
ohci.c 1940 0 0 2414 4353 +0.0%
printer_device.c 830 0 706 566 1394 +0.0%
rp2040_usb.c 382 35 625 11 1053 +0.0%
rusb2_common.c 160 0 16 0 176 +0.0%
tusb.c 451 0 383 3 453 +0.0%
typec_stm32.c 820 8 2 12 842 +0.0%
usbc.c 420 2 20 166 608 +0.0%
usbd.c 3224 57 88 275 3564 +0.0%
usbd_control.c 538 0 484 79 616 +0.0%
usbtmc_device.c 2196 24 68 316 2544 +0.0%
vendor_device.c 641 0 534 565 1204 +0.0%
video_device.c 4443 5 1235 479 4914 +0.0%
TOTAL 107077 497 15673 44457 152833 +0.0%

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 2, 2026

MemBrowse Memory Report

Top 10 targets by memory change (%) (out of 2156 targets) View Project Dashboard →

target .text .rodata .data .bss total % diff
lpcxpresso1769/board_test 3,544 → 3,904 (+360) 3,916 → 4,276 (+360) +9.2%
raspberrypi_cm4/board_test 49,092 → 49,156 (+64) 1,545 → 5,577 (+4,032) 50,637 → 54,733 (+4,096) +8.1%
stm32c071nucleo/board_test 7,324 → 7,796 (+472) 144 → 160 (+16) 7,660 → 8,148 (+488) +6.4%
stm32c071nucleo/dfu_runtime 11,392 → 12,008 (+616) 488 → 504 (+16) 12,072 → 12,704 (+632) +5.2%
stlinkv3mini/board_test 7,896 → 8,412 (+516) 344 → 388 (+44) 10,732 → 11,288 (+556) +5.2%
stm32g0b1nucleo/board_test 9,360 → 9,832 (+472) 140 → 156 (+16) 9,696 → 10,184 (+488) +5.0%
stm32c071nucleo/hid_generic_inout 12,420 → 13,036 (+616) 316 → 332 (+16) 12,928 → 13,560 (+632) +4.9%
stm32f070rbnucleo/board_test 8,616 → 9,112 (+496) 104 → 240 (+136) 480 → 388 (-92) 11,460 → 12,004 (+544) +4.7%
stm32c071nucleo/hid_multiple_interface 13,048 → 13,664 (+616) 488 → 504 (+16) 13,728 → 14,360 (+632) +4.6%
stm32c071nucleo/hid_boot_interface 13,104 → 13,720 (+616) 444 → 460 (+16) 13,740 → 14,372 (+632) +4.6%

@hathach hathach merged commit 333a38d into master Apr 5, 2026
513 of 515 checks passed
@hathach hathach deleted the fix-hil branch April 5, 2026 04:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants