This is an automated email from the ASF dual-hosted git repository.
JorgeGzm 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 ddb09bb4719 arch/stm32h7: rng: clear the error interrupt flags
ddb09bb4719 is described below
commit ddb09bb4719f045b93cd960387dc485ee7f9069b
Author: Alan Carvalho de Assis <[email protected]>
AuthorDate: Sat Oct 17 17:54:32 2026 -0300
arch/stm32h7: rng: clear the error interrupt flags
The RNG interrupt handler returned without clearing the clock error
(CEIS) and seed error (SEIS) interrupt flags. These flags are cleared
by writing zero, so the interrupt was asserted forever and the system
was starved by an interrupt storm, for example when the RNG kernel
clock (HSI48) is not enabled.
Clear the flags in the handler. On a clock error abort the read with
-EIO and report it; on a seed error restart the generator as described
in the RM0433 RNG error management.
Signed-off-by: Alan Carvalho de Assis <[email protected]>
Assisted-by: Claude Code
---
arch/arm/src/stm32h7/stm32_rng.c | 42 +++++++++++++++++++++++++++++++++++++---
1 file changed, 39 insertions(+), 3 deletions(-)
diff --git a/arch/arm/src/stm32h7/stm32_rng.c b/arch/arm/src/stm32h7/stm32_rng.c
index df53d7f7343..f8112e3fe15 100644
--- a/arch/arm/src/stm32h7/stm32_rng.c
+++ b/arch/arm/src/stm32h7/stm32_rng.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 */