ESP32 (10) – Random number generator

by luca
1 comment

Today a short tutorial that will explain how to use the random number generator, a peripheral included in the esp32 chip. It’s also an opportunity to show how to interact with internal peripherals and to understand some additional details about how the framework is designed.

After having published this article, I received an interesting tweet from Ivan Grokhotkov (@i_grr) explaining the best way to get random numbers without draining the entropy. The framework does include a function designed for this purpose:


Address space

Both the esp32 CPUs (PRO e APP) share (with some minor exceptions) the same address space, i.e. they can use the same address to leverage the same functionality. Using different addresses, the CPUs can access different memory segments (internal ROM and SRAM, fast and slow RTC memory…) and interact with the internal peripherals.

The technical reference manual explains in detail how the address space is organized:


Random number generator

As explained above, the communication between a CPU and an internal peripherals is through specific memory addresses, called registers.

In particular, the random number generator stores the number it produces in a register named RNG_DATA_REG, located at address 0x3FF75144:


Register size is 32bit.

In your code, you can use a macro to read the content of a register:

#define DR_REG_RNG_BASE                        0x3ff75144

To be able to generate real random numbers, the peripheral uses the RF noise captured by the WiFi/Bluetooth interface; this is the reason why you have to enable it (via menuconfig):


In this way, you are assured that the number generated are really random (a data sample of 2GB passed the Diehard test suite). If both the peripherals (WiFi and BT) are disabled, the numbers are only pseudo-random.


The address of the different registers are normally defined in the soc.h file, but this doesn’t include the address oof the RND_DATA_REG register. Let’s define it in our program:

uint32_t randomNumber = READ_PERI_REG(DR_REG_RNG_BASE);
printf("New random number: %u\n", randomNumber);

Our program can read the register content and print the random number generated as follows:

uint32_t randomNumber = READ_PERI_REG(DR_REG_RNG_BASE);
printf("New random number: %u\n", randomNumber);

The example I put on Github reads every 5 seconds the register value and displays it:


Related Posts

1 comment

saba Monday July 15th, 2019 - 02:41 PM

Hi Luca,
thanks for your helpful information. I have a problem when I compile this code and my error is :
implicit declaration of function ‘READ_PERI_REG’ [-Werror=implicit-function-declaration]
uint32_t randomNumber = READ_PERI_REG(DR_REG_RNG_BASE);

Could you help me to resolve this error?
thanks a lot beforehand.


Leave a Comment

five × four =