Quand dois-je utiliser volatile dans les ISR?

Je crée un micrologiciel intégré dans lequel tout ce qui se passe après l’initialisation a lieu dans les ISR. J’ai des variables qui sont partagées entre elles et je me demande dans quels cas elles doivent être volatiles. Je ne bloque jamais, dans l’attente d’un changement dans un autre ISR.

Quand puis-je être certain que la mémoire réelle est lue ou écrite lorsque je n’utilise pas volatile? Une fois tous les ISR?

Addenda:
Ceci concerne ARM Cortex-M0, mais il ne s’agit pas tant de questions de rapport ISR que d’optimisation du compilateur. La plateforme ne devrait donc pas être vraiment importante.

La question est entièrement répondable, et la réponse est simple:

Sans installation volatile, vous ne pouvez pas supposer (de façon simpliste) que l’access réel à la mémoire sera possible – le compilateur est libre de conclure que les résultats sont soit totalement inutilisés (si cela est visible dans ce qu’il peut voir), ou qu’ils peuvent être mis en cache en toute sécurité un registre, ou calculé dans le désordre (tant que des dépendances visibles sont conservées).

Vous avez besoin de volatile pour indiquer au compilateur que les effets secondaires de l’access peuvent être importants pour un élément impossible à parsingr par l’optimiseur, tel qu’un contexte d’interruption ou le contexte d’un autre “thread”.

En fait, volatil, c’est ce que vous dites au compilateur: “Je sais quelque chose que vous ne connaissez pas, alors n’essayez pas d’être malin ici”

Attention, volatile ne garantit pas l’ atomicité de lecture-modification-écriture, voire de lecture ou d’écriture seule, lorsque le type de données (ou son désalignement) nécessite un access en plusieurs étapes. Dans ces cas, vous risquez non seulement d’obtenir une valeur périmée, mais une valeur totalement erronée.

Il a déjà été mentionné que l’écriture dans la mémoire / le cache n’est pas exactement prévisible lors de l’utilisation de variables non volatiles. mais il convient également de mentionner un autre aspect où la variable volatile pourrait être mise en cache et nécessiter un vidage forcé du cache pour écrire dans la mémoire réelle (dépend de l’utilisation d’une règle d’écriture directe ou d’écriture arrière).

Considérons un autre cas où la variable volatile n’est pas mise en cache (placée dans une zone non mise en cache) mais, en raison de la présence de tampons d’écriture et de ponts de bus, il est parfois imprévisible que l’écriture réelle se produise dans le registre prévu et qu’elle nécessite une lecture fictive. assurez-vous que l’écriture s’est réellement produite dans le registre / la mémoire réels. Ceci est particulièrement utile pour éviter les situations de concurrence lors de la suppression / du masquage des interruptions.

bien que les compilateurs ne soient pas supposés être intelligents en ce qui concerne les variables volatiles, il est libre d’effectuer certaines optimisations en ce qui concerne les points de séquence volatils (l’optimisation entre les points de la séquence n’est pas autorisée, mais l’optimisation entre les points de la séquence est autorisée)

Les variables qui ont besoin de volatile sont:

1) Partagez des données entre ISR et des données de programme ou d’autres threads.
Ce sont des indicateurs préférables qui indiquent un access bloqué à diverses structures de données.

 // main() code; disable_interrupts(); if (flag == 0) { flag = 1; enable_interrupts(); Manipulate_data(); flag = 0; } else { enable_interrupts(); Cope_with_data_unavailable(); } 

2) Registres matériels mappés en mémoire.
Cette “mémoire” peut changer à tout moment en raison des conditions matérielles. Le client doit savoir que ses valeurs ne sont pas nécessairement cohérentes. Sans volatile , un compresseur naïf échantillonnerait une seule fois fred créant ainsi une boucle sans fin potentielle.

 volatile int *fred = 0x1234; // Hardware reg at address 0x1234; while (*fred);