This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 62b41ad9b40 arch/arm/src/common/stm32: Bound SDIO command response
wait by time.
62b41ad9b40 is described below
commit 62b41ad9b40d5a513486a3b7f9be86ed8cdfe0e5
Author: Luka Filipović <[email protected]>
AuthorDate: Mon Aug 10 20:47:00 2026 +0200
arch/arm/src/common/stm32: Bound SDIO command response wait by time.
stm32_waitresponse() polls SDIO_STA bounded only by an iteration
counter, set to 0x7fffffff for all R1/R1B/R2/R4/R5/R6 commands. The
hardware CTIMEOUT flag is the intended exit for a missing response,
but it is only generated while the card clock is running and the CPSM
has reached its Wait state. If the card clock stops or the peripheral
fails, SDIO_STA never updates and the loop spins for INT32_MAX
iterations while holding the FAT filesystem lock, at the caller's
priority-inheritance boosted priority if higher priority tasks block
on the filesystem. Since the mmcsd layer retries failed commands,
the driver's recovery paths are never reached and the system never
recovers.
Bound the wait by time instead: 250 ms for response-bearing commands
(the largest timeout the SD specification allows for any operation)
and 10 ms for the no-response/R3/R7 cases. CTIMEOUT remains the
normal error exit within microseconds; the software bound only fires
when the peripheral itself is dead, converting an unbounded spin into
-ETIMEDOUT so the existing mmcsd retry logic can run.
Signed-off-by: Luka Filipović <[email protected]>
Assisted-by: Claude Code:claude-fable-5
---
arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.c
b/arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.c
index 47b7b7a02c1..e14de3221ca 100644
--- a/arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.c
+++ b/arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.c
@@ -174,8 +174,8 @@
/* Timing */
-#define SDIO_CMDTIMEOUT (100000)
-#define SDIO_LONGTIMEOUT (0x7fffffff)
+#define SDIO_CMDTIMEOUT_MS (10)
+#define SDIO_LONGTIMEOUT_MS (250)
/* DTIMER setting */
@@ -2155,14 +2155,15 @@ static int stm32_cancel(struct sdio_dev_s *dev)
static int stm32_waitresponse(struct sdio_dev_s *dev, uint32_t cmd)
{
- int32_t timeout;
+ clock_t timeout;
+ clock_t start;
uint32_t events;
switch (cmd & MMCSD_RESPONSE_MASK)
{
case MMCSD_NO_RESPONSE:
events = SDIO_CMDDONE_STA;
- timeout = SDIO_CMDTIMEOUT;
+ timeout = MSEC2TICK(SDIO_CMDTIMEOUT_MS);
break;
case MMCSD_R1_RESPONSE:
@@ -2172,13 +2173,13 @@ static int stm32_waitresponse(struct sdio_dev_s *dev,
uint32_t cmd)
case MMCSD_R5_RESPONSE:
case MMCSD_R6_RESPONSE:
events = SDIO_RESPDONE_STA;
- timeout = SDIO_LONGTIMEOUT;
+ timeout = MSEC2TICK(SDIO_LONGTIMEOUT_MS);
break;
case MMCSD_R3_RESPONSE:
case MMCSD_R7_RESPONSE:
events = SDIO_RESPDONE_STA;
- timeout = SDIO_CMDTIMEOUT;
+ timeout = MSEC2TICK(SDIO_CMDTIMEOUT_MS);
break;
default:
@@ -2187,9 +2188,11 @@ static int stm32_waitresponse(struct sdio_dev_s *dev,
uint32_t cmd)
/* Then wait for the response (or timeout) */
+ start = clock_systime_ticks();
+
while ((getreg32(STM32_SDIO_STA) & events) == 0)
{
- if (--timeout <= 0)
+ if (clock_systime_ticks() - start > timeout)
{
mcerr("ERROR: Timeout cmd: %08" PRIx32 " events: %08" PRIx32
" STA: %08" PRIx32 "\n",