Merci "terwal" pour cette confirmation de ce que je pensais.
Pour autant, je suis incapable de le mettre en œuvre dans une application. Voilà ce que je voudrais faire :
L'application comporte deux tâches :
Tâche 1 : acquisition de données : vE, iE, pA
- dure 200 mS
- lancée toutes les 300 mS
Tâche 2 : Traitement sur ces variables
- prends les variables vE, iE, pA au moment où cette tâche est lancée
- dure 1 S
- lancée toutes les 5 secondes
- ne doit pas affecter aucune des acquisitions
En m'inspirant de cet exemple, voilà le code que j'ai écrit :
xSemaphoreHandle xMutex;
double vE, iE, vEff, iEff, pAct;
void setup() {
xMutex = xSemaphoreCreateMutex();
xTaskCreatePinnedToCore(&MesureP, "MesureP", 2048, NULL, 1, NULL, 1); // Priorité haute (1), exécutée sur le noyau 1
xTaskCreatePinnedToCore(&Traitement, "Traitement", 2048, NULL, 0, NULL, 0); // Priorité basse (0), exécutée sur le noyau 0
}
void loop() {
}
void MesureP(void *params)
{
while (true)
{
printf("Déclenchement Mesure ");
if (xSemaphoreTake(xMutex, /*portMAX_DELAY*/200 / portTICK_PERIOD_MS) == pdTRUE)
{
for (int i = 0; i < 450; i++) { //La saisie et les calcules durent 200 mS
vE = analogReadMilliVolts(34);
iE = analogReadMilliVolts(35);
/* Calcul des valeurs efficaces et de la puissance active :
vEff = efficace(vE) {...}
iEff = efficace(iE) {...}
pAct = calculP(vE, iE) {...}*/
}
printf("Mesures faites\n");
xSemaphoreGive(xMutex);
} else {
printf(" ???\n");
}
vTaskDelay(100 / portTICK_PERIOD_MS); // 200 mS de traitement + 100 mS d'attente = 300 mS de récurrence
}
}
void Traitement(void *params)
{
while (true)
{
printf("Déclenchement Traitement ");
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE)
{
for (int i = 0; i <10; i++) {
printf("Traite ...");
delay(100); // Simulation de la durée du traitement : 100 x 10 mS = 1 seconde
}
printf("Traite\n");
printf("Traitement terminé\n");
xSemaphoreGive(xMutex);
} else {
printf(" !!!\n");
}
vTaskDelay(4000 / portTICK_PERIOD_MS); // 1 S de traitement + 4 S d'attente = 5 S de récurrence
}
}
Voilà ce que ça affiche dans le moniteur série lorsque j'ai if (xSemaphoreTake(xMutex, 200 / portTICK_PERIOD_MS) == pdTRUE)
dans la tâche d'acquisition :
20:28:15.683 -> Déclenchement Mesure Mesures faites
20:28:15.822 -> Déclenchement Mesure Mesures faites
20:28:16.049 -> Déclenchement Mesure Mesures faites
20:28:16.219 -> Déclenchement Mesure Mesures faites
20:28:16.416 -> Déclenchement Mesure Mesures faites
20:28:16.563 -> Déclenchement Mesure Mesures faites
20:28:16.764 -> Déclenchement Mesure Mesures faites
20:28:17.050 -> Déclenchement Traitement Traite ...Déclenchement Mesure Traite ...Traite ... ???
20:28:17.383 -> Traite ...Déclenchement Mesure Traite ...Traite ... ???
20:28:17.651 -> Traite ...Déclenchement Mesure Traite ...Traite ... ???
20:28:17.784 -> Traite ...Déclenchement Mesure Traite
20:28:17.784 -> Traitement terminé
20:28:17.885 -> Mesures faites
20:28:18.069 -> Déclenchement Mesure Mesures faites
20:28:18.252 -> Déclenchement Mesure Mesures faites
20:28:18.421 -> Déclenchement Mesure Mesures faites
20:28:18.627 -> Déclenchement Mesure Mesures faites
20:28:18.830 -> Déclenchement Mesure Mesures faites
20:28:19.002 -> Déclenchement Mesure Mesures faites
20:28:19.161 -> Déclenchement Mesure Mesures faites
20:28:19.377 -> Déclenchement Mesure Mesures faites
20:28:19.535 -> Déclenchement Mesure Mesures faites
20:28:19.715 -> Déclenchement Mesure Mesures faites
20:28:19.900 -> Déclenchement Mesure Mesures faites
20:28:20.100 -> Déclenchement Mesure Mesures faites
20:28:20.299 -> Déclenchement Mesure Mesures faites
20:28:20.500 -> Déclenchement Mesure Mesures faites
20:28:20.662 -> Déclenchement Mesure Mesures faites
20:28:20.826 -> Déclenchement Mesure Mesures faites
20:28:21.022 -> Déclenchement Mesure Mesures faites
20:28:21.222 -> Déclenchement Mesure Mesures faites
20:28:21.399 -> Déclenchement Mesure Mesures faites
20:28:21.566 -> Déclenchement Mesure Mesures faites
20:28:21.783 -> Déclenchement Mesure Mesures faites
20:28:22.082 -> Déclenchement Traitement Traite ...Déclenchement Mesure Traite ...Traite ... ???
20:28:22.389 -> Traite ...Déclenchement Mesure Traite ...Traite ... ???
20:28:22.686 -> Traite ...Déclenchement Mesure Traite ...Traite ... ???
20:28:22.786 -> Traite ...Déclenchement Mesure Traite
20:28:22.817 -> Traitement terminé
20:28:22.886 -> Mesures faites
20:28:23.103 -> Déclenchement Mesure Mesures faites
Les données arrivent à une cadence à peu près régulière, mais elles ne sont pas valides (???) lors de l'activité de la tâche de traitement.
Si je diminue le temps dans xSemaphoreTake
, (200 --> 50) j’obtiens :
20:35:44.770 -> Déclenchement Mesure Mesures faites
20:35:44.955 -> Déclenchement Mesure Déclenchement Traitement Mesures faites
20:35:45.067 -> Traite ...Déclenchement Mesure Traite ... ???
20:35:45.148 -> Traite ...Déclenchement Mesure ???
20:35:45.271 -> Traite ...Déclenchement Mesure ???
20:35:45.386 -> Traite ...Déclenchement Mesure ???
20:35:45.517 -> Traite ...Déclenchement Mesure ???
20:35:45.588 -> Traite ...Déclenchement Mesure ???
20:35:45.703 -> Traite ...Déclenchement Mesure ???
20:35:45.833 -> Traite ...Déclenchement Mesure ???
20:35:45.918 -> Traite ...Déclenchement Mesure ???
20:35:45.956 -> Traite
20:35:45.956 -> Traitement terminé
20:35:46.134 -> Déclenchement Mesure Mesures faites
20:35:46.316 -> Déclenchement Mesure Mesures faites
Le déclenchement est régulier, mais aucune mesure n'est valide.
Si maintenant je joue sur la durée de xSemaphoreTake
dans l'autre tâche, cette fois il y a des blocages des acquisitions pendant la tâche de traitement.
Bien que je n'ai certainement pas été clair malgré la longueur de mon discours, je résume la situation de la manière suivante :
- Je n'ai strictement rien compris au fonctionnement de
xSemaphoreTake
- Le code que j'ai écrit ne correspond peut-être pas à ce que je veux faire.
Merci d'avoir eu le courage d'être arrivé ici.
Cordialement.
Pierre.