ESP32 - Utilisation des deux cœurs CPU pour vos propres projets

Aujourd’hui, je veux montrer dans quelles "ressources d’énergie" sont à ESP32. On sait beaucoup moins que notre microcontrôleur ESP32 n’est pas un seul processeur mais plutôt un multi-processeur avec 2 cœurs. Dans l’ESP travaillent 2 Xtensa 32 bits LX6 CPU partage RAM et ROM. Ainsi, il diffère de son prédécesseur, l’ESP8266. Les deux noyaux ont des noms différents. CPU 0 est également appelé Protocole CPU (PRO_CPU) et CPU 1 Application CPU (APP_CPU). Le processeur 0 contrôle le WLAN, Bluetooth et d’autres périphériques internes tels que SPI, I2C, ADC, etc., tandis que le processeur 1 est disponible pour notre programme utilisateur. Les sketchs que nous écrivons dans la boucle principale et que nous téléchargeons sur l’ESP sont toujours exécutés sur le processeur 1 sans exception.Le APP_CPU (CPU 0) est omis par défaut pour le code d’application. Le diagramme suivant montre la répartition standard des tâches entre les processeurs :

On peut voir que 2 noyau, qui double presque la performance de ESP32, n’est pas directement disponible pour une utilisation gratuite.

Toutefois, le Cadre ESP fournit également des fonctions avec l’IDE Arduino qui permettent de distribuer des tâches individuelles aux processeurs ESP32 et donc au processeur. 

TaskHandle_t nom de la taskhadle;

 à l’élimination. Pour créer une nouvelle tâche, nous utilisons la fonction xTaskCreatePinnedToCore avec les options suivantes :

 

xTaskCreatePinnedToCore (
CoreTask0, / - Fonction de tâche à appeler - /
"Task1", / - Nom de la tâche Tout nom - /
1000, / - mémoire de tas disponible de la tâche - /
NULL, / - peut-être le paramètre de la tâche - /
1, / - priorité de tâche - /
et Core0TaskHnd, / - poignée de tâches usagée - /

 

Notre objectif est d’exécuter le code personnalisé comme une tâche sur le processeur1, de sorte que comme indiqué ci-dessous, notre code fonctionne comme une tâche sur le processeur1 indépendant du CPU0, comme illustré dans l’image suivante:

 

 

Nous entrons maintenant le code d’exemple suivant dans notre IDE et le téléchargeons sur l’ESP32 :

 

 

TaskHandle_t  Core0TaskHnd (en anglais seulement) ;  
TaskHandle_t  Core1TaskHnd ; 

Vide Configuration() 
{   Série.Commencer(9600);     xTaskCreatePinnedToCore(CoreTask0 CoreTask0,"CPU_0",1000,Null,1,&Core0TaskHnd (en anglais seulement),0);   xTaskCreatePinnedToCore(CoreTask1 (en anglais seulement),"CPU_1",1000,Null,1,&Core0TaskHnd (en anglais seulement),1);
}

Vide Boucle() 
{   Série.Imprimer ("Application CPU est au cœur:");   Série.println (xPortGetCoreID (en anglais seulement)());   Retard (500);
}  

Vide CoreTask0 CoreTask0( Vide * Paramètre ) 
{    Pour (;;)    {      Série.Imprimer("CoreTask0 fonctionne sur Core: ");      Série.println(xPortGetCoreID (en anglais seulement)());      Rendement();     Retard (600);   } 
} 

Vide CoreTask1 (en anglais seulement)( Vide * Paramètre ) 
{    Pour (;;)    {      Série.Imprimer("CoreTask1 fonctionne sur Core: ");      Série.println(xPortGetCoreID (en anglais seulement)());      Retard (700);   } 
}

 

 

.

Avec la fonction interne ESP xPortGetCoreID() nous pouvons obtenir le numéro de base sur lequel notre section de code est actuellement en cours d’exécution. Ce numéro de base peut être soit 0 ou 1. Nous utilisons cette fonctionnalité pour produire des informations en série sur le noyau sur lequel la tâche est actuellement en cours d’exécution:

La sortie en série montre quelle tâche s’exécute sur quel noyau

Nous voyons maintenant dans la sortie qu’un total de 3 tâches sont en cours d’exécution. Une tâche nommée CoreTask 0 sur CPU 0, une tâche nommée CoreTask1 sur CPU 1, et notre tâche principale de journal (boucle) sur le noyau 1.

Jusqu’à présent, tout semble trop beau pour être vrai. En fait, nous avons un problème avec l’utilisation de CPU 0 que nous devons prêter attention à: Comme indiqué sur l’image supérieure, la tâche de protocole de noyau est également en cours d’exécution sur le processeur 0. Cette tâche s’occupe également de la pile WiFi et TCP/IP. Si ce temps plus long n’est pas en cours d’exécution parce que, par exemple, notre tâche nécessite trop de temps CPU, le système peut devenir instable et planter dans l’ensemble. Nous devons donc nous assurer que notre propre tâche ne reçoit pas d’instructions de retard ou seulement de très petites déclarations de retard, de sorte que la tâche de protocole de noyau est allouée assez de temps de calcul.

 

em lecteur attentif aura remarqué un autre problème du code: Le programme génère 3 tâches, qui fonctionnent indépendamment sur différents processeurs, mais partagent toujours une ressource (le port COM de l’ESP). Étant donné que les tâches ne « savent » rien les uns des autres et ne savent donc pas quand une ressource est occupée ou modifiée par une autre tâche, des collisions peuvent se produire ici. Ceux-ci provoquent un résultat imprévisible parce qu’il n’est pas possible de déterminer exactement quand la ressource utilise quelle tâche. Ces constellations peuvent alors, au mieux, être soit dans un Condition de course ou même dans un Impasse Extrémités. Qu’est-ce qu’une impasse explique Problème du philosophe, où 5 philosophes s’assoient autour d’une table à spaghetti, très vives. Je veux pour éviter mutuellement Exclusion problèmes mutuels par l’exclusion mutuelle ( Mutex ) et les collisions lors de l’accès à la recherche de ressources partagées à mesure que les variables ou les interfaces évitent,

Cela nous met au milieu du sujet de communication interprocessus . Nous avons beaucoup appris sur les tâches et le multitâche.

Plus d’informations sur la génération de tâches et le système d’opération en temps réel (RTOS) est disponible dans la deuxième partie de cette série ou sur ::

https://exploreembedded.com/wiki/index.php?title=Hello%20World%20with%20ESP32%20Explained

Et maintenant, amusez-vous à expérimenter.


 

 

Esp-32Logiciel de base

3 commentaires

doob

doob

{
Serial.begin(9600);
xTaskCreatePinnedToCore(CoreTask0,“CPU_0”,1000,NULL,1,&Core0TaskHnd,0);
xTaskCreatePinnedToCore(CoreTask1,“CPU_1”,1000,NULL,1,&Core0TaskHnd,1);
}
noch ein Tippfehler? sollte es beim zweiten pinning nicht Core1TaskHnd heißen?

Sven

Sven

CPU 1 ist für das Anwenderprogramm verantwortlich.

Der Tippfehler wird bestimmt zeitnah korrigiert.

veit

veit

Diese Namentliche Unterscheidung wird getroffen, um zu verdeutlichen, dass die CPU 0 das WLAN, Bluetooth und andere interne Peripheriegeräte wie SPI, I2C, ADC usw. steuert, während die CPU 0 für unser Anwenderprogramm zur Verfügung steht.

bitte korrigieren …. irgendwas müsste von cpu 1 gemacht werden

Laisser un commentaire

Tous les commentaires sont modérés avant d'être publiés

Messages de blogs recommandés

  1. Installez maintenant ESP32 via l'administrateur de la carte
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA-Over the Air-ESP Programmation par WiFi