- Voordelen van multi-coreprocessor
- ESP32 en FreeRTOS
- De ESP32-kern-ID vinden
- ESP32 Dual Core-programmering
ESP-modules zijn populair vanwege hun Wi-Fi-functionaliteiten zoals ESP8266, ESP-12E, enz. Dit zijn allemaal krachtige Microcontroller-modules met Wi-Fi-functionaliteiten. Er is nog een ESP-module die krachtiger en veelzijdiger is dan eerdere ESP-modules - de naam is ESP32. Het heeft Bluetooth- en Wi-Fi-connectiviteit en we hebben de BLE-mogelijkheden van ESP32 al uitgelegd en hebben ESP32 in veel IoT-projecten gebruikt. Maar heel weinig mensen weten dat ESP32 een dual-core microcontroller is.
ESP32 heeft twee 32-bits Tensilica Xtensa LX6-microprocessors, waardoor het een krachtige dual-core (core0 en core1) microcontroller is. Het is verkrijgbaar in twee varianten single-core en dual-core. Maar de dual-core variant is populairder omdat er geen significant prijsverschil is.
ESP32 kan worden geprogrammeerd met Arduino IDE, Espressif IDF, Lua RTOS, etc. Tijdens het programmeren met Arduino IDE draait de code alleen op Core1 omdat Core0 al is geprogrammeerd voor RF-communicatie. Maar hier is deze tutorial, we zullen laten zien hoe je beide kernen van ESP32 kunt gebruiken om twee bewerkingen tegelijkertijd uit te voeren. Hier is de eerste taak om de ingebouwde LED te laten knipperen en de tweede taak is om de temperatuurgegevens van de DHT11-sensor op te halen.
Laten we eerst eens kijken naar de voordelen van een multi-coreprocessor ten opzichte van een enkele kern.
Voordelen van multi-coreprocessor
- Multi-core processors zijn handig als er meer dan 2 processen tegelijk werken.
- Aangezien het werk over verschillende kernen wordt verdeeld, neemt de snelheid toe en kunnen meerdere processen tegelijkertijd worden voltooid.
- Het stroomverbruik kan worden verminderd omdat wanneer een kern in inactieve modus is, deze kan worden gebruikt om de randapparatuur uit te schakelen die op dat moment niet wordt gebruikt.
- Dual-core processors hoeven minder vaak tussen verschillende threads te schakelen dan single-core processors omdat ze twee tegelijk kunnen verwerken in plaats van één tegelijk.
ESP32 en FreeRTOS
Op de ESP32-kaart is al FreeRTOS-firmware geïnstalleerd. FreeRTOS is een open-source real-time besturingssysteem dat erg handig is bij multitasking. RTOS helpt bij het beheren van de bronnen en het maximaliseren van de systeemprestaties. FreeRTOS heeft veel API-functies voor verschillende doeleinden en met behulp van deze API's kunnen we taken maken en deze op verschillende kernen laten draaien.
Volledige documentatie van FreeRTOS API's is hier te vinden. We zullen proberen om een aantal API's in onze code te gebruiken om een multitasking-applicatie te bouwen die op beide cores draait.
De ESP32-kern-ID vinden
Hier zullen we Arduino IDE gebruiken om de code naar ESP32 te uploaden. Om de Core ID te weten waarop de code draait, is er een API-functie
xPortGetCoreID ()
Deze functie kan worden aangeroepen vanuit de void setup () en void loop () functie om de core-ID te weten waarop deze functies worden uitgevoerd.
U kunt deze API testen door de onderstaande sketch te uploaden:
ongeldige setup () { Serial.begin (115200); Serial.print ("setup () functie draait op kern:"); Serial.println (xPortGetCoreID ()); } void loop () { Serial.print ("loop () functie draait op kern:"); Serial.println (xPortGetCoreID ()); }
Na het uploaden van de bovenstaande sketch, open je de Serial monitor en je zult zien dat beide functies op core1 draaien, zoals hieronder getoond.
Uit bovenstaande observaties kan worden geconcludeerd dat de standaard Arduino-sketch altijd op core1 draait.
ESP32 Dual Core-programmering
Arduino IDE ondersteunt FreeRTOS voor ESP32 en met FreeRTOS API's kunnen we taken maken die onafhankelijk op beide kernen kunnen worden uitgevoerd. De taak is het stuk code dat een bewerking op het bord uitvoert, zoals knipperende led, temperatuur verzenden, enz.
De onderstaande functie wordt gebruikt om taken te maken die op beide kernen kunnen worden uitgevoerd. In deze functie moeten we enkele argumenten opgeven, zoals een prioriteit, kern-id, enz.
Volg nu de onderstaande stappen om een taak en taakfunctie te maken.
1. Maak eerst taken aan in de functie voor het instellen van leegte . Hier zullen we twee taken maken, een voor knipperende LED na elke 0,5 seconde en een andere taak is om de temperatuur na elke 2 seconden te lezen.
De functie xTaskCreatePinnedToCore () heeft 7 argumenten nodig:
- Functienaam om de taak uit te voeren (task1)
- Elke naam die aan de taak is gegeven ("task1", enz.)
- Stapelgrootte toegewezen aan de taak in woorden (1 woord = 2 bytes)
- Taakinvoerparameter (kan NULL zijn)
- Prioriteit van de taak (0 is de laagste prioriteit)
- Taakhandgreep (kan NULL zijn)
- Kern-ID waar de taak wordt uitgevoerd (0 of 1)
Nu, creëren Task1 voor de LED te knipperen door het geven van alle argumenten in xTaskCreatePinnedToCore () functie.
xTaskCreatePinnedToCore (Task1code, "Task1", 10000, NULL, 1, NULL, 0);
Maak op dezelfde manier Task2 voor Task2 en maak kern-id 1 in het 7e argument.
xTaskCreatePinnedToCore (Task2code, "Task2", 10000, NULL, 1, NULL, 1);
U kunt de prioriteit en de stapelgrootte wijzigen, afhankelijk van de complexiteit van de taak.
2. Nu zullen we de Task1code en Task2code functie implementeren. Deze functies bevatten de code voor de vereiste taak. In ons geval zal de eerste taak de led laten knipperen en een andere taak zal de temperatuur ophalen. Maak dus voor elke taak twee aparte functies buiten de leegte-instelfunctie.
De taak1code- functie voor het knipperen van de ingebouwde led na 0,5 seconden is geïmplementeerd zoals hieronder weergegeven.
Void Task1code (void * parameter) { Serial.print ("Task1 draait op kern"); Serial.println (xPortGetCoreID ()); voor (;;) {// oneindige lus digitalWrite (led, HIGH); vertraging (500); digitalWrite (led LAAG), vertraging (500); } }
Implementeer op dezelfde manier de Task2code- functie voor het ophalen van de temperatuur.
void Task2code (void * pvParameters) { Serial.print ("Task2 draait op kern"); Serial.println (xPortGetCoreID ()); voor (;;) { float t = dht.readTemperature (); Serial.print ("Temperatuur:"); Serial.print (t); vertraging (2000); } }
3. Hier blijft de void loop- functie leeg. Zoals we al weten, draait de loop- en setup- functie op core1, zodat je de core1-taak ook in de void loop- functie kunt implementeren.
Nu is het coderingsgedeelte voorbij, dus upload de code gewoon met Arduino IDE door het ESP32-bord te kiezen in het menu Extra. Zorg ervoor dat u de DHT11-sensor hebt aangesloten op pin D13 van ESP32.
Nu kunnen de resultaten worden gecontroleerd op Serial Monitor of Arduino IDE, zoals hieronder wordt weergegeven:
Complexe applicaties zoals een real-time systeem kunnen worden gebouwd door meerdere taken tegelijkertijd uit te voeren met behulp van dubbele kernen van ESP32.
De volledige code samen met een demovideo wordt hieronder gegeven.