In this guide, we shall take a look at what is random number and how the STM32 uses hardware to generate true random numbers and develop the code for that.
In this guide, we shall cover the following:
- What is random number.
- How STM32 generate random numbers.
- Features of the RNG peripheral of STM32.
- Developing the driver.
- Results.
1. What is Random Number:
A random number generator is a device or algorithm that can produce numbers that are unpredictable and have no discernible pattern. Random numbers are useful for many purposes, such as cryptography, gaming, simulation, statistics, and more. There are two main types of random number generators: true and pseudo-random. True random number generators use physical phenomena, such as atmospheric noise, to produce randomness. Pseudo-random number generators use mathematical formulas to create sequences of numbers that appear random, but are actually deterministic. ¹²³
2. How STM32 Generate Random Numbers:
The hardware random number generator (RNG) in STM32 microcontrollers typically exploits the inherent unpredictability in physical processes. It often relies on the thermal noise present in semiconductor devices.
Here’s a simplified explanation:
- Thermal Noise: Microcontrollers naturally exhibit thermal noise due to temperature fluctuations at the microscopic level within the silicon.
- Analog-to-Digital Conversion (ADC): The RNG circuit samples this thermal noise using an Analog-to-Digital Converter (ADC). The continuous and unpredictable nature of thermal noise provides a source of randomness.
- Bit Extraction: The digitized noise is then processed to extract random bits. Various techniques, like Von Neumann extractor or more advanced algorithms, may be employed to ensure randomness and eliminate bias.
- Output: The generated random bits are then made available for use by software.
3. Features of the RNG Peripheral of STM32:
RNG main features
• It delivers 32-bit random numbers, produced by an analog generator
• 40 periods of the RNG_CLK clock signal between two consecutive random numbers
• Monitoring of the RNG entropy to flag abnormal behavior (generation of stable values, or of a stable sequence of values)
• It can be disabled to reduce power consumption
Note: Not all STM32F4 has the RNG peripheral, please refer to the datasheet of the desired MCU to see if the MCU supports RNG or not.
4. Developing the Driver:
Before we develop the driver, first we need to configure the PLL to generate 48MHz needed for the 48MHz peripherals like SDIO and RNG as mentioned in the reference manual:
Since we need to keep the core frequency at 16MHz using internal oscillator, we need to configure the following parameters:
- PLL P.
- PLL N.
- PLL M.
- PLL Q.
From CubeMX clock configuration, we can find that PLL has the following configuration:
Hence, the following values:
- PLL M =16
- PLL N = 192
- PLL P =2
- PLL Q =4
In main.c, we start by including the following two header files:
#include "stm32f4xx.h" #include "stdint.h"
Next declare uint32_t variable to hold the generated random values:
uint32_t random_number;
Next, define the PLL values:
#define PLL_M 16 #define PLL_N 192 #define PLL_P 2 #define PLL_Q 4
In main function.
Configure the PLL with the required parameters:
RCC->PLLCFGR = (PLL_M<<RCC_PLLCFGR_PLLM_Pos) | (PLL_N << RCC_PLLCFGR_PLLN_Pos) | (((PLL_P >> 1) -1) << RCC_PLLCFGR_PLLP_Pos) | //set PLL_M,PLL_N,PLL_P (PLL_Q << RCC_PLLCFGR_PLLQ_Pos);
Enable the PLL and wait until it is enabled:
RCC->CR |= RCC_CR_PLLON; //turn on the PLL while((RCC->CR & RCC_CR_PLLRDY) == 0); //wait until PLL is active
Then we need to enable clock access to RNG peripheral:
From the datasheet of STM32F407:
We can see that RNG is connected to AHB2 bus.
Hence, we can enable clock it as following:
RCC->AHB2ENR|=RCC_AHB2ENR_RNGEN;
Next, enable the RNG:
RNG->CR|=RNG_CR_RNGEN;
In while loop:
- Wait until the new data is read.
- Read the data.
To check if there is new data:
Read DRDY bit in Status Register of the RNG:
Store the new value into the variable:
random_number=RNG->DR;
Hence, the entire code as following:
#include "stm32f4xx.h" #include "stdint.h" uint32_t random_number; #define PLL_M 16 #define PLL_N 192 #define PLL_P 2 #define PLL_Q 4 int main(void) { RCC->PLLCFGR = (PLL_M<<RCC_PLLCFGR_PLLM_Pos) | (PLL_N << RCC_PLLCFGR_PLLN_Pos) | (((PLL_P >> 1) -1) << RCC_PLLCFGR_PLLP_Pos) | //set PLL_M,PLL_N,PLL_P (PLL_Q << RCC_PLLCFGR_PLLQ_Pos); RCC->CR |= RCC_CR_PLLON; //turn on the PLL while((RCC->CR & RCC_CR_PLLRDY) == 0); //wait until PLL is active RCC->AHB2ENR|=RCC_AHB2ENR_RNGEN; RNG->CR|=RNG_CR_RNGEN; while(1) { while((RNG->SR & RNG_SR_DRDY)==0); random_number=RNG->DR; } }
5. Results:
Open new debug session and add random_number to live expression window and you should get the following:
Feel free to use interrupt to get the data in the background.
Happy coding 🙂
Add Comment