Comment savoir si on est dans une ISR ?

Bonjour à toutes et à tous

J'écris des séquences, dans des fonctions qui peuvent être partagées entre tache ou ISR, qui ont besoin d'être protégées. Dans le cas d'un ESP32 par des mutex, sinon en masquant / démasquant les interruptions. Mais lorsque la fonction est appelée depuis une ISR, la gestion des protections est différente de ce qu'elle est dans une "tache" normale du processeur, qu'on se trouve dans un contexte FreeRtos ou simplement dans les séquences de "setup"" ou "loop".

Donc question, comment, lors de la mise en place ou levée de la protection, tester par programme si on est sur un niveau d'interruption (appel depuis une ISR) ou seulement sur une tache ? J'ai pensé à rajouter dans les paramètres d'appel un flag qui dit si oui ou non on appelle depuis l'un ou l'autre mode, mais j'aimerais éviter cette complication et cette perte de temps.

Par défaut quand on entre dans une ISR, les interruptions sont désactivées, il peut alors suffire de lire le flag d'autorisation des interruptions . Mais je ne connais pas du tout le ESP32 pour donner plus de précisions.

hello
comme vileroi, je ne connais pas l'esp32

sur µ328, il existe un registre appellé EIFR (external interrupt flag register) dont les bits 0 et 1 sont respectivement les flags des interruptions INT0 et INT1.
ces flags passent à 1 sur déclenchement de l'interruption et repassent à zéro sur un acquittement géré par le micro ou en manuel en ecrivant un 1 dans le flag .
voir la datasheet du 328 en page 73.

peut etre trouveras tu l'équivalent en ESP32

Bosnoir

je ne connais aps assez 'intimement' l'ESP32 pour répondre.
l'ESP32 étant un SOC et non un microcontrolleur je reste près de la surface !!
FreeRTOS, double coeur , code exécuté sur place(Flash ou en RAM (IRAM)... je suis vite perdu....

Cette doc donne peut être des éléments :
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/intr_alloc.html

(Esp32, c'est FreeRtos a 100% il me semble
On fait du FreeRTOS sans le savoir quand on n'y fait pas appel explicitement)

hello
voir ici

en chapitre 3.3.1

Après parcours en diagonale de tutos sur les interruptions Arduino d'une part, du manuel ESP32 d'autre part, j'en arrive à la conclusion que la structure des registres, et notamment pour ce qui est des interruptions, n'a rien à voir. Dans le premier cas, lire l'EIFR doit permettre de savoir si on est dans une ISR ou non. Dans le second, j'avais espéré que le problème était réglé par les primitives sur le mutex, mais je constate que son'utilisation est différente suivant qu'on est en ISR ou pas, et qu'il faut pouvoir tester dans quel environnement on est avant de se protéger par un mutex. Rajoutez à ça le fait que l'ISR peut s'exécuter sur le même coeur que la tache de fond ou sur l'autre, et que ma bibliothèque ne le sait pas forcément.

Donc je n'y couperai pas, il faut se farcir des dizaines de pages pour comprendre la structure des registres. Dans tous les tutos que je trouve, on présuppose qu'on sait si on se trouve dans une ISR ou pas : je cherche vraiment les emmerdes en voulant écrire une bibliothèque dont les mêmes fonctions peuvent être appelées indifféremment d'un côté ou de l'autre.

J'étais parti sur l'idée, à l'init, de passer l'adresse du mutex en paramètre et, si elle est vide, considérer que je suis sur un ardino pur jus. Mais ça risque de devenir lourd. Je crains fort d'être obligé en final d'avoir deux bibliothèques distinctes.

A suivre donc. Peut-être aurais-je intérêt à poser la question sur le forum anglo-chinois de l'ESP32 en espérant que quelqu'un puisse me trouver un tuto ou un exemple. A suivre... C'est décidément très fun la découverte du monde de l'arduino, de l'ESP32, du C++...

Je tente de programmer un test Arduino / ESP32, et de manipuler les registres en conséquence. Avec les bibliothèques ESP32 installées, le compilateur ne connait pas "SREG" ou "EIFR". A moins qu'il lui faille un #include pour ça.

Ces deux registres existent-ils physiquement dans un ESP32 ? @dfgh les a mentionnés pour l'architecture ATMega 328.

Je me demande si c'est bien nécessaire de faire la distinction...

si vos fonctions peuvent être appelées à la fois dans une interruption et dans une tâche normale elle doivent respecter 2 critères fondamentaux:

  • être ré-entrantes (pas de buffer static dans la fonction par exemple)
  • protéger tout ce qui est en section critique

En effet, vous pouvez être appelé depuis une tâche "normale" mais une interruption peut alors venir modifier certaines de vos variables, donc il faut vous protéger de toutes façons...

j'ai raté un truc ?

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.