- Vantaggi del processore multi-core
- ESP32 e FreeRTOS
- Trovare l'ID core ESP32
- Programmazione Dual Core ESP32
I moduli ESP sono popolari per le loro funzionalità Wi-Fi come ESP8266, ESP-12E, ecc. Sono tutti potenti moduli microcontrollore con funzionalità Wi-Fi. C'è un altro modulo ESP che è più potente e versatile dei precedenti moduli ESP: il suo nome è ESP32. Dispone di connettività Bluetooth e Wi-Fi e abbiamo già spiegato le capacità BLE di ESP32 e utilizzato ESP32 in molti progetti IoT. Ma pochissime persone sanno che ESP32 è un microcontrollore Dual-core.
ESP32 ha due microprocessori Tensilica Xtensa LX6 a 32 bit che lo rendono un potente microcontrollore dual-core (core0 e core1). È disponibile in due varianti single-core e dual-core. Ma la variante dual-core è più popolare perché non c'è una differenza di prezzo significativa.
ESP32 può essere programmato utilizzando Arduino IDE, Espressif IDF, Lua RTOS, ecc. Durante la programmazione con Arduino IDE, il codice funziona solo su Core1 perché Core0 è già programmato per la comunicazione RF. Ma ecco questo tutorial che mostreremo come utilizzare entrambi i core di ESP32 per eseguire due operazioni contemporaneamente. Qui il primo compito sarà lampeggiare il LED integrato e il secondo compito sarà recuperare i dati di temperatura dal sensore DHT11.
Vediamo prima i vantaggi di un processore multi-core su un singolo core.
Vantaggi del processore multi-core
- I processori multi-core sono utili quando ci sono più di 2 processi da lavorare simultaneamente.
- Poiché il lavoro è distribuito tra diversi core, la sua velocità aumenta e più processi possono essere completati contemporaneamente.
- Il consumo di energia può essere ridotto perché quando un core è in modalità inattiva, può essere utilizzato per spegnere le periferiche che non sono in uso in quel momento.
- I processori dual-core devono passare da un thread all'altro meno spesso rispetto ai processori single-core perché possono gestirne due contemporaneamente invece di uno alla volta.
ESP32 e FreeRTOS
La scheda ESP32 ha già il firmware FreeRTOS installato su di essa. FreeRTOS è un sistema operativo in tempo reale open source molto utile nel multitasking. RTOS aiuta a gestire le risorse e massimizzare le prestazioni del sistema. FreeRTOS ha molte funzioni API per scopi diversi e utilizzando queste API, possiamo creare attività e farle funzionare su core diversi.
La documentazione completa delle API FreeRTOS può essere trovata qui. Cercheremo di utilizzare alcune API nel nostro codice per creare un'applicazione multitasking che verrà eseguita su entrambi i core.
Trovare l'ID core ESP32
Qui useremo l'IDE di Arduino per caricare il codice in ESP32. Per conoscere il Core ID su cui è in esecuzione il codice, è disponibile una funzione API
xPortGetCoreID ()
Questa funzione può essere chiamata dalle funzioni void setup () e void loop () per conoscere l'ID principale su cui sono in esecuzione queste funzioni.
Puoi testare questa API caricando lo schizzo seguente:
void setup () { Serial.begin (115200); Serial.print ("funzione setup () in esecuzione sul core:"); Serial.println (xPortGetCoreID ()); } void loop () { Serial.print ("funzione loop () in esecuzione sul core:"); Serial.println (xPortGetCoreID ()); }
Dopo aver caricato lo schizzo sopra, apri il monitor seriale e scoprirai che entrambe le funzioni sono in esecuzione su core1 come mostrato di seguito.
Dalle osservazioni precedenti, si può concludere che lo sketch Arduino predefinito gira sempre su core1.
Programmazione Dual Core ESP32
L'IDE di Arduino supporta FreeRTOS per ESP32 e le API FreeRTOS ci consentono di creare attività che possono essere eseguite indipendentemente su entrambi i core. Il compito è il pezzo di codice che esegue alcune operazioni sulla scheda come il lampeggio del led, l'invio della temperatura, ecc.
La funzione seguente viene utilizzata per creare attività che possono essere eseguite su entrambi i core. In questa funzione, dobbiamo fornire alcuni argomenti come priorità, core id, ecc.
Ora, segui i passaggi seguenti per creare attività e funzione attività.
1. In primo luogo, creare attività nella funzione di configurazione del vuoto . Qui creeremo due attività, una per il lampeggiamento del LED ogni 0,5 secondi e un'altra per ottenere la lettura della temperatura ogni 2 secondi.
La funzione xTaskCreatePinnedToCore () accetta 7 argomenti:
- Nome della funzione per implementare l'attività (task1)
- Qualsiasi nome assegnato all'attività ("task1", ecc.)
- Dimensione dello stack assegnata all'attività in parole (1 parola = 2 byte)
- Parametro di input dell'attività (può essere NULL)
- Priorità dell'attività (0 è la priorità più bassa)
- Maniglia dell'attività (può essere NULL)
- ID principale in cui verrà eseguita l'attività (0 o 1)
Ora, crea Task1 per far lampeggiare il led fornendo tutti gli argomenti nella funzione xTaskCreatePinnedToCore ().
xTaskCreatePinnedToCore (Task1code, "Task1", 10000, NULL, 1, NULL, 0);
Analogamente, creare Task2 per Task2 e rendere id anima 1 nel 7 ° argomento.
xTaskCreatePinnedToCore (Task2code, "Task2", 10000, NULL, 1, NULL, 1);
È possibile modificare la priorità e la dimensione dello stack a seconda della complessità dell'attività.
2. Ora implementeremo la funzione Task1code e Task2code . Queste funzioni contengono il codice per l'attività richiesta. Nel nostro caso, la prima attività farà lampeggiare il led e un'altra attività recupererà la temperatura. Quindi crea due funzioni separate per ciascuna attività al di fuori della funzione di configurazione del vuoto.
La funzione Task1code per il lampeggio del led integrato dopo 0,5 secondi è implementata come mostrato di seguito.
Void Task1code (void * parametro) { Serial.print ("Task1 in esecuzione sul core"); Serial.println (xPortGetCoreID ()); for (;;) {// loop infinito digitalWrite (led, HIGH); ritardo (500); digitalWrite (led, LOW); ritardo (500); } }
Allo stesso modo, implementa la funzione Task2code per recuperare la temperatura.
void Task2code (void * pvParameters) { Serial.print ("Task2 in esecuzione sul core"); Serial.println (xPortGetCoreID ()); for (;;) { float t = dht.readTemperature (); Serial.print ("Temperatura:"); Serial.print (t); ritardo (2000); } }
3. Qui la funzione void loop rimarrà vuota. Come già sappiamo , la funzione loop e setup viene eseguita su core1, quindi puoi implementare l'attività core1 anche nella funzione loop void .
Ora la parte di codifica è terminata, quindi carica il codice utilizzando l'IDE di Arduino scegliendo la scheda ESP32 nel menu Strumenti. Assicurati di aver collegato il sensore DHT11 al pin D13 di ESP32.
Ora i risultati possono essere monitorati su Serial Monitor o Arduino IDE come mostrato di seguito:
Applicazioni complesse come il sistema in tempo reale possono essere create eseguendo più attività contemporaneamente utilizzando i dual core di ESP32.
Di seguito viene fornito il codice completo insieme a un video dimostrativo.