Page 1 of 1

Buffered SIO on USARTv3 triggers “spurious interrupt” per RX byte

Posted: Thu Jan 22, 2026 4:22 pm
by alex31
HW/Stack: STM32G4 (USARTv3 FIFO), ChibiOS 21.11.
Symptom: With BufferedSIODriver (bsioStart + default callback), every received byte triggers an assert in sio_lld_serve_interrupt() (“spurious interrupt”).
Disabling the assert makes it run, but an instrumented driver with spurious event counter increments once per RX byte.

Root cause:
In __bsio_default_cb() (os/hal/lib/complex/buffered_sio/hal_buffered_sio.c), the callback calls
sioGetAndClearEventsX() before draining the RX FIFO. On USARTv3, RXNE is cleared by reading RDR, not by ICR.
sioGetAndClearEventsX() re‑enables RX interrupts while RXNE is still set, causing a pending IRQ where
u->ISR & isrmask == 0 when the handler runs → “spurious interrupt”.

Fix:
Drain/fill FIFOs before calling sioGetAndClearEventsX(). This clears RXNE first, so re‑enabling RX IRQs does not
leave a pending interrupt with no active flag.

Patch attached.
Alexandre

Re: Buffered SIO on USARTv3 triggers “spurious interrupt” per RX byte

Posted: Thu Jan 22, 2026 5:29 pm
by Giovanni
Hi,

Could you give a try to SIO in trunk? there are changes already.

The trunk version will be back-ported to 21.11 so we need to make sure to patch that one.

Giovanni

Re: Buffered SIO on USARTv3 triggers “spurious interrupt” per RX byte

Posted: Thu Jan 22, 2026 7:14 pm
by alex31
Could you give a try to SIO in trunk? there are changes already.


Just compiled/flash the test with up2date trunk, and it asserts at the same place :

Code: Select all

#0  chSysHalt (reason=0x80138d0 <__func__.0> "sio_lld_serve_interrupt") at ../../../../ChibiOS_mirror/os/rt/src/chsys.c:228
#1  0x0800ac7e in sio_lld_serve_interrupt (siop=0x20002084 <SIOD1>) at ../../../../ChibiOS_mirror/os/hal/ports/STM32/LLD/USARTv3/hal_sio_lld.c:1090
#2  0x08007aa0 in VectorD4 () at ../../../../ChibiOS_mirror/os/hal/ports/STM32/LLD/USART/stm32_usart1.inc:97
#3  <signal handler called>
#4  chSysUnlock () at ../../../../ChibiOS_mirror/os/rt/include/chsys.h:400
#5  0x080057c6 in osalSysUnlock () at ../../../../ChibiOS_mirror/os/hal/osal/rt-nil/osal.h:586
#6  0x08005b88 in iqReadTimeout (iqp=0x20002a30 <bsio1+12>, bp=0x20002e30 <waSioEcho+688> "aUUU", <incomplete sequence \312>, n=1, timeout=4294967295)
    at ../../../../ChibiOS_mirror/os/hal/src/hal_queues.c:415
#7  0x0800710c in __buffered_serial_read_timeout_impl (ip=0x20002a24 <bsio1>, bp=0x20002e30 <waSioEcho+688> "aUUU", <incomplete sequence \312>, n=1,
    timeout=4294967295) at ../../../../ChibiOS_mirror/os/hal/include/hal_buffered_serial.h:220
#8  __bsio_readt (ip=0x20002a24 <bsio1>, bp=0x20002e30 <waSioEcho+688> "aUUU", <incomplete sequence \312>, n=1, timeout=4294967295)
    at ../../../../ChibiOS_mirror/os/hal/lib/complex/buffered_sio/hal_buffered_sio.c:143
#9  0x080114fe in sioEcho (arg=0x0) at ./source/main.cpp:74
#10 0x080002f2 in __port_thread_start () at ../../../../ChibiOS_mirror/os/common/ports/ARMv7-M/compilers/GCC/chcoreasm.S:130
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) up
#1  0x0800ac7e in sio_lld_serve_interrupt (siop=0x20002084 <SIOD1>) at ../../../../ChibiOS_mirror/os/hal/ports/STM32/LLD/USARTv3/hal_sio_lld.c:1090
1090        osalDbgAssert(false, "spurious interrupt");


Alexandre

Re: Buffered SIO on USARTv3 triggers “spurious interrupt” per RX byte

Posted: Fri Jan 23, 2026 7:58 am
by alex31
Precisions:
    trunk and stable versions of os/hal/lib/complex/buffered_sio/hal_buffered_sio.c are identical, so the patch should apply cleanly to trunk as well.

    hal_buffered_sio.c is an architecture-independent module, so it would be safer to verify that the patch is compatible with the other USART LLD implementations.

Re: Buffered SIO on USARTv3 triggers “spurious interrupt” per RX byte

Posted: Mon Jan 26, 2026 10:07 am
by Giovanni
Hi,

Fixed in trunk.

Giovanni