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
commit 1943268d3c8e74ecd405b3f3fdce9ef199b794b8 Author: raiden00pl <[email protected]> AuthorDate: Wed Nov 4 12:15:28 2026 +0100 arch/arm/stm32: Fix RNG read hang on seed or clock error. On a seed error (SEIS) or clock error (CEIS) the interrupt handler returned without clearing the flag, so the interrupt fired forever and read() never returned. Now the handler clears the flag and: - seed error: restarts the RNG, - clock error: read() fails with -EIO. This is how the removed STM32H7 driver handled errors. Also affects STM32F2, STM32F4 and STM32G4. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: raiden00pl <[email protected]> --- arch/arm/src/common/stm32/stm32_rng_v1.c | 42 +++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/arch/arm/src/common/stm32/stm32_rng_v1.c b/arch/arm/src/common/stm32/stm32_rng_v1.c index c51373db1fb..5d83115300f 100644 --- a/arch/arm/src/common/stm32/stm32_rng_v1.c +++ b/arch/arm/src/common/stm32/stm32_rng_v1.c @@ -65,6 +65,7 @@ struct rng_dev_s char *rd_buf; size_t rd_buflen; uint32_t rd_lastval; + int rd_error; /* Error reported by the interrupt handler */ bool rd_first; }; @@ -157,10 +158,39 @@ static int stm32_rng_interrupt(int irq, void *context, void *arg) rngsr = getreg32(STM32_RNG_SR); - if ((rngsr & (RNG_SR_SEIS | RNG_SR_CEIS)) /* Check for error bits */ - || !(rngsr & RNG_SR_DRDY)) /* Data ready must be set */ + if (rngsr & (RNG_SR_SEIS | RNG_SR_CEIS)) { - /* This random value is not valid, we will try again. */ + /* The error interrupt flags are cleared by writing zero, otherwise + * the interrupt is asserted forever. + */ + + putreg32(rngsr & ~(RNG_SR_SEIS | RNG_SR_CEIS), STM32_RNG_SR); + stm32_rng_disable(); + + if (rngsr & RNG_SR_CEIS) + { + /* The RNG kernel clock is missing or too slow (e.g. HSI48 not + * enabled): abort the read. + */ + + g_rngdev.rd_error = -EIO; + nxsem_post(&g_rngdev.rd_readsem); + } + else + { + /* Seed error: restart the generator (RM0433 RNG error + * management). + */ + + stm32_rng_enable(); + } + + return OK; + } + + if (!(rngsr & RNG_SR_DRDY)) + { + /* Data ready must be set, we will try again. */ return OK; } @@ -244,6 +274,7 @@ static ssize_t stm32_rng_read(struct file *filep, char *buffer, g_rngdev.rd_buflen = buflen; g_rngdev.rd_buf = buffer; + g_rngdev.rd_error = 0; /* Enable RNG with interrupts */ @@ -252,6 +283,11 @@ static ssize_t stm32_rng_read(struct file *filep, char *buffer, /* Wait until the buffer is filled */ ret = nxsem_wait(&g_rngdev.rd_readsem); + if (ret >= 0 && g_rngdev.rd_error < 0) + { + _err("ERROR: RNG clock error, check the RNG kernel clock\n"); + ret = g_rngdev.rd_error; + } /* Free RNG for next use */
