{"record":{"id":"1466d150704d42ce","repo":"embassy-rs/embassy","slug":"rng-error-persists-after-reset-check-the-rcc-cloc","errorCode":null,"errorMessage":"RNG error persists after reset; check the RCC clock configuration","messagePattern":"RNG error persists after reset; check the RCC clock configuration","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-stm32/src/rng.rs","lineNumber":418,"sourceCode":"\n    /// Get a random u32.\n    ///\n    /// This call is infallible: a seed or clock error is recovered by resetting\n    /// the RNG. If the error persists after `MAX_RESET_RETRIES` resets (almost\n    /// always a misconfigured RNG clock) it panics, since an infallible API has\n    /// no other way to surface the fault. Use [`fill_bytes`](Rng::<Async>::fill_bytes)\n    /// for a fallible path that returns [`Error`] instead.\n    pub fn blocking_next_u32(&mut self) -> u32 {\n        // Only resets are bounded, not poll iterations: a healthy RNG may take\n        // many reads to produce the first word, and that must not count as a\n        // failure.\n        let mut retries = 0;\n        loop {\n            if let Some(word) = self.poll_word() {\n                return word;\n            }\n            if retries >= MAX_RESET_RETRIES {\n                panic!(\"RNG error persists after reset; check the RCC clock configuration\");\n            }\n            retries += 1;\n            self.reset();\n        }\n    }\n\n    /// Get a random u64\n    pub fn blocking_next_u64(&mut self) -> u64 {\n        let mut rand = self.blocking_next_u32() as u64;\n        rand |= (self.blocking_next_u32() as u64) << 32;\n        rand\n    }\n\n    /// Fill a slice with random bytes\n    pub fn blocking_fill_bytes(&mut self, dest: &mut [u8]) {\n        for chunk in dest.chunks_mut(4) {\n            let rand = self.blocking_next_u32();\n            for (slot, num) in chunk.iter_mut().zip(rand.to_ne_bytes().iter()) {","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-stm32/src/rng.rs#L400-L436","documentation":"The blocking RNG read polls for a valid random word; after repeated clock/health failures it resets the RNG peripheral and retries up to MAX_RESET_RETRIES. If errors still persist it panics, because the usual root cause is that the RNG peripheral clock does not meet the required frequency in the RCC configuration.","triggerScenarios":"Calling blocking_next_u32 (or blocking fill via it) when poll_word() repeatedly returns None after full RNG resets — i.e. the RNG keeps signaling seed/clock errors.","commonSituations":"RNG kernel clock misconfigured (too slow or gated) in RCC init; running on a board where the RNG clock source is wrong; silicon health-error conditions.","solutions":["Fix the RCC config so the RNG peripheral clock is enabled and within the datasheet-required frequency range.","Verify the RNG kernel clock source selection (e.g. HSI48/HSE/PLL output) matches your board's clock tree.","If the hardware still errors, replace the chip or fall back to a software RNG / external entropy source."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before using the RNG, confirm the kernel clock is enabled and fast enough\n// e.g. with embassy-stm32 rcc config: ensure rng clock source set and HSI48/PLL enabled.\n// let rng_clk = rcc.clocks.rng; // debug-log its value in a probe run\n","typeGuard":null,"tryCatchPattern":"// Panic cannot be caught; wrap blocking reads at a higher level with a fallback:\nmatch std::panic::catch_unwind(|| rng.blocking_next_u32()) {\n    Ok(w) => Some(w),\n    Err(_) => { log::error!(\"RNG hardware fault\"); None /* use software RNG fallback */ }\n}","preventionTips":["Always configure the RNG kernel clock source in RCC init (e.g. HSI48).","Verify clock frequency meets the datasheet minimum for RNG.","Test RNG output health early in bring-up before relying on it.","Provide a software RNG fallback for fault-tolerant systems."],"tags":["rng","embedded","panic","clock-config"],"backgroundTag":"module-init-failed","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}