L'utilisation du mot clé "volatile" est indispensable à maîtriser lorsqu'on écrit du code embarqué: elle permet à l'utilisateur d'éviter que le compilateur, lorsqu'utilisé avec les optimisations qui vont bien n'en fasse trop. L'exemple le plus courant est le polling sur une pin d'entrée:
si pin_b0 est le nom de la "variable" qui permet d'accéder à la pin 0 du port B du uC, alors, sans le mot clé "volatile", le code suivant qui permet de détecter le passage à 1 de cette entrée a pour conséquence de faire "disparaitre" la boucle while et de se faire rick-roller et c'est surtout pas ça ce qu'on veut:
// Code "RACHE certified" before while loopisRisingEdgeDetected=falsewhile(!pin_b0){isRisingEdgeDetected=true}// Code "RACHE certified" after while loopif(!isRisingEdgeDetected){// Listen to Rick Roll/Never Gonna Give You Up!}
Jeter un coup d'oeil à sfr_defs.h, io.h (etc.) pour la définition des accès mémoires des pins du uC de type AVR. Pour définir une variable volatile de type "la structure que tu veux définir":
Pour l'embarqué tel que pour un AVR, lorsqu'on veut modifier une variable par le code principal et par une interruption, il faut désactiver les interruptions dans le code principal lorsqu'on y accède.
exemple, pour modifier aWord par le code principal ET par l'interruption pour un uC de type AVR:
ISR(USARTC0_RXC_vect){// Modify a "shared value"maVariableDeTypeMastructure.aWord++;}intmain(void){// Code "RACHE certified"...for(;;){// Deactivate interruptions__asm____volatile__("cli"::)// Modify a shared variablemaVariableDeTypeMastructure.aWord+=2;// Reactivate interruptions__asm____volatile__("sei"::)// Fantastic code...}return0;}
Sans désactiver les interruptions, sur un micro 8bit, on risque l'interruption en plein cours de modification de aWord dans le programme principal et là, c'est le drame!
Et même si la variable est de type 8bit, parce qu'entre le moment où la variable va être chargée dans un registre et le moment où le registre va être modifié et le moment où il va être réécrit dans la mémoire, il y a des malchances qu'une interruption claque et qu'à la fin, la variable se retrouve avec une valeur totalement indéterminée. Je te laisse imaginer le cas où cette variable est de type pointeur, à côté des dégats que celà peut engendrer, tu préfèrerais être rickrollé!
Mutex, semaphore et autres mécanismes du même type sont des implémentations pour langage "haut-niveau" (os, multithread, etc.) pour éviter ces problèmes, mais la base est ci-dessus!
# volatile et interruptions
Posté par plr . En réponse au message Volatile, struct et interruptions.. Évalué à 3.
L'utilisation du mot clé "volatile" est indispensable à maîtriser lorsqu'on écrit du code embarqué: elle permet à l'utilisateur d'éviter que le compilateur, lorsqu'utilisé avec les optimisations qui vont bien n'en fasse trop. L'exemple le plus courant est le polling sur une pin d'entrée:
si pin_b0 est le nom de la "variable" qui permet d'accéder à la pin 0 du port B du uC, alors, sans le mot clé "volatile", le code suivant qui permet de détecter le passage à 1 de cette entrée a pour conséquence de faire "disparaitre" la boucle while et de se faire rick-roller et c'est surtout pas ça ce qu'on veut:
Jeter un coup d'oeil à sfr_defs.h, io.h (etc.) pour la définition des accès mémoires des pins du uC de type AVR. Pour définir une variable volatile de type "la structure que tu veux définir":
Pour l'embarqué tel que pour un AVR, lorsqu'on veut modifier une variable par le code principal et par une interruption, il faut désactiver les interruptions dans le code principal lorsqu'on y accède.
exemple, pour modifier aWord par le code principal ET par l'interruption pour un uC de type AVR:
Sans désactiver les interruptions, sur un micro 8bit, on risque l'interruption en plein cours de modification de aWord dans le programme principal et là, c'est le drame!
Et même si la variable est de type 8bit, parce qu'entre le moment où la variable va être chargée dans un registre et le moment où le registre va être modifié et le moment où il va être réécrit dans la mémoire, il y a des malchances qu'une interruption claque et qu'à la fin, la variable se retrouve avec une valeur totalement indéterminée. Je te laisse imaginer le cas où cette variable est de type pointeur, à côté des dégats que celà peut engendrer, tu préfèrerais être rickrollé!
Mutex, semaphore et autres mécanismes du même type sont des implémentations pour langage "haut-niveau" (os, multithread, etc.) pour éviter ces problèmes, mais la base est ci-dessus!
a2g