Il breve tutorial di oggi vi mostrerà come utilizzare il generatore numeri random, periferica hardware inclusa nel chip esp32. Sarà anche l’occasione per capire come interagire con tali periferiche e per vedere qualche dettaglio in più relativo alla struttura del framework.
Address space
Entrambe le CPU (PRO e APP) del chip esp32 condividono (a parte piccole eccezioni) uno spazio indirizzi (address space), ovvero utilizzano il medesimo indirizzo per accedere alla medesima funzionalità. Tramite diversi indirizzi, le CPU possono accedere a diverse aree di memoria (ROM e SRAM interne, memoria lenta e veloce del modulo RTC…) e interagire con le periferiche interne.
Il technical reference manual illustra nel dettaglio l’organizzazione di tale spazio indirizzi:
Generatore di numeri random
Come scritto poco sopra, la comunicazione tra CPU e periferiche interne avviene tramite particolari indirizzi di memoria, detti registri.
In particolare, il generatore di numeri random scrive i dati generati all’interno di un registro chiamato RNG_DATA_REG, che si trova all’indirizzo 0x3FF75144:
Il registro ha dimensione 32bit.
La macro che possiamo utilizzare nel nostro codice per leggere il contenuto di un registro è:
#define DR_REG_RNG_BASE 0x3ff75144 |
Per poter generare numeri realmente randomici, la periferica utilizza il rumore in radiofrequenza dell’interfaccia Wifi/Bluetooth; per questo è necessario che tale interfaccia sia abilitata (via menuconfig):
In tal modo vi è la garanzia che i numeri generati siano veramente randomici (una sequenza di 2GB di valori ha superato la suite di test Diehard). Se entrambe le periferiche (WiFi e BT) sono disabilitate, i numeri generati saranno solo pseudo-random.
Esempio
Gli indirizzi dei vari registri sono normalmente definiti all’interno del file soc.h, che però non contiene l’indirizzo del registro RND_DATA_REG. Andiamo quindi a definirlo nel nostro programma:
uint32_t randomNumber = READ_PERI_REG(DR_REG_RNG_BASE); printf("New random number: %u\n", randomNumber); |
Possiamo leggere e stampare a video il numero random generato dalla periferica con:
uint32_t randomNumber = READ_PERI_REG(DR_REG_RNG_BASE); printf("New random number: %u\n", randomNumber); |
L’esempio presente su Github legge ogni 5 secondi il valore del registro e lo visualizza:
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.
you need to add #include “soc/soc.h”