daniel-p-carvalho opened a new pull request, #20173:
URL: https://github.com/apache/nuttx/pull/20173

   ## Summary
   
   This PR addresses two critical timing bugs in the single-timer 
capture/compare tickless OS drivers across STM32 families 
(`stm32_tickless_m3m4_v1.c` for F1/F2/F3/F4/G4, `stm32f7`, `stm32h7`, and 
`stm32wb`), along with wall time progression fixes for tickless timekeeping:
   
   1. **Zero-period handling:**
      When `up_timer_start()` is invoked with a zero/negative duration (or when 
converted delay equals 0 ticks), the driver now enables the compare match 
interrupt and immediately forces a hardware event via the Event Generation 
Register (`EGR_CCxG`). Previously, zero period could lead to missed events, 
improper compare programming, or undefined timeout behavior.
   
   2. **Compare-match race condition (elimination of ~71-minute hang):**
      In the single-timer continuous free-running architecture (32-bit counter, 
0 to `0xFFFFFFFF`), interval timing relies on setting the capture/compare 
register (`CCR = count + period`) and waiting for the counter to match. If the 
counter reaches or advances past `count + period` during register programming 
or critical section entry, the compare match event is missed, causing the CPU 
to hang until the 32-bit counter wraps all the way around (4,294,967,295 ticks, 
which corresponds to ~71.5 minutes at 1 MHz).
      A post-configuration check is introduced to verify whether `(counter - 
count) >= period`. If the target timestamp already elapsed, the compare 
interrupt is triggered immediately via `EGR`, preventing any hang.
   
   3. **`up_timer_cancel()` remaining time calculation:**
      Fixes signed/unsigned casting and remaining time calculation when the 
timer has already expired.
   
   4. **Sched / Clock Timekeeping:**
      - In `nxsched_process_timer()`, `clock_update_wall_time()` is now called 
under `CONFIG_CLOCK_TIMEKEEPING`, ensuring monotonic progression of wall time 
across tickless timer wakeups.
      - In `clock_timekeeping_get_wall_time()`, `clock_update_wall_time()` is 
called prior to sampling.
      - Allows overriding `NTP_MAX_ADJUST` with 
`CONFIG_CLOCK_ADJTIME_SLEWLIMIT_PPM`.
   
   *Note on STM32L4/L5/U5:* STM32L4/L5/U5 utilizes a fundamentally different 
two-timer tickless architecture (`stm32l4_tickless.c` with 1 oneshot timer in 
pulse mode + 1 freerun timer). It does not use compare match and is 
intentionally excluded from this PR.
   
   ## Impact
   
   - **Bug fix:** Eliminates intermittent multi-minute / 71-minute deadlocks in 
tickless OS mode on STM32 platforms when short sleeps or zero-delay timeouts 
are scheduled.
   - **Affected targets:** STM32F1, STM32F2, STM32F3, STM32F4, STM32F7, 
STM32G4, STM32H7, STM32WB.
   - **Compatibility:** Fully backward-compatible. No API breaks.
   
   ## Testing
   
   Host machine: Linux x86_64, arm-none-eabi-gcc 13.3.1.
   All patches verified with `./tools/checkpatch.sh` (zero errors, zero 
warnings).
   
   ### Hardware tested (validated in bench):
   1. **STM32H7 (STM32H743ZI / Custom IED Pextron R550):**
      - Driver: `arch/arm/src/stm32h7/stm32_tickless.c`
      - Config: `CONFIG_SCHED_TICKLESS=y`, 32-bit TIM2 at 1 MHz, Ethernet RMII 
active.
      - Results:
        - Continuous ICMP ping during tickless idle sleeps: 0% packet loss, RTT 
~0.6 ms.
        - Accurate `sleep 1s`, `sleep 2s`, `sleep 5s` executions.
        - Rapid `usleep` calls wake up immediately without deadlocks or missed 
interrupts.
   
   2. **STM32G4 (Nucleo-G431KB):**
      - Driver: `arch/arm/src/common/stm32/stm32_tickless_m3m4_v1.c` (shared 
core driver with F1/F2/F3/F4)
      - Config: `nucleo-g431kb:nsh` with `CONFIG_SCHED_TICKLESS=y`, `TIM2` at 1 
MHz (`CONFIG_USEC_PER_TICK=1`).
      - Results:
        - `sleep 1` wall-clock: 0.9989s
        - `sleep 2` wall-clock: 1.9966s
        - `sleep 3` wall-clock: 2.9931s
        - `usleep 1000` wakes up immediately without hang.
   
   ### What was NOT tested on real hardware:
   - **STM32F7 / STM32WB:** Drivers received the identical logic and build 
cleanly, but physical F7/WB boards were not connected to bench during this test 
session.
   - **STM32F4 / F1 / F2 / F3:** Code executed is the exact same 
`stm32_tickless_m3m4_v1.c` validated on STM32G4, but physical F4/F1/F2/F3 
boards were not flashed.
   - **STM32L4:** Tested on Nucleo-L432KC, confirmed that it uses a different 
two-timer strategy (`stm32l4_tickless.c`) and is not part of this PR.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to