From 58651f03b6c42b728d73e3c9fef21baab1c30d61 Mon Sep 17 00:00:00 2001 From: Jesse Braham Date: Wed, 12 Jul 2023 07:11:32 -0700 Subject: [PATCH] Derive the `Clone` and `Copy` traits for the `Rng` driver (#650) * Derive the `Clone` and `Copy` traits for the `Rng` driver * Update CHANGELOG --- CHANGELOG.md | 1 + esp-hal-common/src/rng.rs | 116 +++++++++++++++++++++++++------------- 2 files changed, 78 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 123d12ba8..072f5aab9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Update `embedded-hal-*` alpha packages to their latest versions (#640) +- Implement the `Clone` and `Copy` traits for the `Rng` driver (#650) ### Fixed diff --git a/esp-hal-common/src/rng.rs b/esp-hal-common/src/rng.rs index 64e2eeb9c..7e0c41ea2 100644 --- a/esp-hal-common/src/rng.rs +++ b/esp-hal-common/src/rng.rs @@ -1,56 +1,94 @@ -//! Random number generator driver +//! Random Number Generator +//! +//! The Random Number Generator (RNG) Driver for ESP chips is a software module +//! that provides an interface to generate random numbers using the RNG +//! peripheral on ESP chips. This driver allows you to generate random numbers +//! that can be used for various cryptographic, security, or general-purpose +//! applications. +//! +//! The RNG peripheral on ESP chips produces random numbers based on physical +//! noise sources, which provide true random numbers under specific conditions +//! (see conditions below). +//! +//! To use the [Rng] Driver, you need to initialize it with the RNG peripheral. +//! Once initialized, you can generate random numbers by calling the `random` +//! method, which returns a 32-bit unsigned integer. +//! +//! Additionally, this driver implements the +//! [Read](embedded_hal::blocking::rng::Read) trait from the `embedded_hal` +//! crate, allowing you to generate random bytes by calling the `read` method. +// +//! # Important Note +//! +//! There are certain pre-conditions which must be met in order for the RNG to +//! produce *true* random numbers. The hardware RNG produces true random numbers +//! under any of the following conditions: +//! +//! - RF subsystem is enabled (i.e. Wi-Fi or Bluetooth are enabled). +//! - An internal entropy source has been enabled by calling +//! `bootloader_random_enable()` and not yet disabled by calling +//! `bootloader_random_disable()`. +//! - While the ESP-IDF Second stage bootloader is running. This is because the +//! default ESP-IDF bootloader implementation calls +//! `bootloader_random_enable()` when the bootloader starts, and +//! `bootloader_random_disable()` before executing the app. +//! +//! When any of these conditions are true, samples of physical noise are +//! continuously mixed into the internal hardware RNG state to provide entropy. +//! If none of the above conditions are true, the output of the RNG should be +//! considered pseudo-random only. +//! +//! For more information, please refer to the ESP-IDF documentation: +//! +//! +//! # Examples +//! +//! ## Initialization +//! +//! ```no_run +//! let mut rng = Rng::new(peripherals.RNG); +//! ``` +//! +//! ## Generate a random word (u32) +//! +//! ```no_run +//! let random: u32 = rng.random(); +//! ``` +//! +//! ## Fill a buffer of arbitrary size with random bytes +//! +//! ```no_run +//! let mut buffer = [0u8; 32]; +//! rng.read(&mut buffer).unwrap(); +//! ``` -use core::convert::Infallible; +use core::{convert::Infallible, marker::PhantomData}; -use embedded_hal::blocking::rng::Read; +use crate::{peripheral::Peripheral, peripherals::RNG}; -use crate::{ - peripheral::{Peripheral, PeripheralRef}, - peripherals::RNG, -}; - -/// Random Number Generator -/// -/// It should be noted that there are certain pre-conditions which must be met -/// in order for the RNG to produce *true* random numbers. The hardware RNG -/// produces true random numbers under any of the following conditions: -/// -/// - RF subsystem is enabled (i.e. Wi-Fi or Bluetooth are enabled). -/// - An internal entropy source has been enabled by calling -/// `bootloader_random_enable()` and not yet disabled by calling -/// `bootloader_random_disable()`. -/// - While the ESP-IDF Second stage bootloader is running. This is because the -/// default ESP-IDF bootloader implementation calls -/// `bootloader_random_enable()` when the bootloader starts, and -/// `bootloader_random_disable()` before executing the app. -/// -/// When any of these conditions are true, samples of physical noise are -/// continuously mixed into the internal hardware RNG state to provide entropy. -/// If none of the above conditions are true, the output of the RNG should be -/// considered pseudo-random only. -/// -/// For more information, please refer to the ESP-IDF documentation: -/// -pub struct Rng<'d> { - rng: PeripheralRef<'d, RNG>, +/// Random number generator driver +#[derive(Clone, Copy)] +pub struct Rng { + _phantom: PhantomData, } -impl<'d> Rng<'d> { +impl Rng { /// Create a new random number generator instance - pub fn new(rng: impl Peripheral

+ 'd) -> Self { - crate::into_ref!(rng); - - Self { rng } + pub fn new(_rng: impl Peripheral

) -> Self { + Self { + _phantom: PhantomData, + } } #[inline] /// Reads currently available `u32` integer from `RNG` pub fn random(&mut self) -> u32 { - self.rng.data.read().bits() + // SAFETY: read-only register access + unsafe { &*crate::peripherals::RNG::PTR }.data.read().bits() } } -impl Read for Rng<'_> { +impl embedded_hal::blocking::rng::Read for Rng { type Error = Infallible; fn read(&mut self, buffer: &mut [u8]) -> Result<(), Self::Error> {