J'ai le code suivant dans mon programme de microcontrôleur:
// Wait for ADC conversion to complete
while ( ( ADCSRA && _BS( ADSC ) ) == _BS( ADSC ) ) {}
Où ADCSRA est un registre qui changera sa valeur une fois la conversion analogique terminée et où je veux attendre un peu pour être clair. Ce bit indique que la conversion est terminée.
En regardant le code d'assemblage résultant, la boucle entière est remplacée par une seule instruction:
in r24, 0x06 ; ADCSRA
Le registre est lu, mais sa valeur n'est même pas testée!?
Comment dois-je changer mon code C ++ pour demander au compilateur de continuer à revérifier le registre, sans retarder inutilement le programme?
J'utilise la chaîne d'outils avr-gcc.
EDIT: J'ai changé le code comme suit (Thnx: lhballoti):
while ( ( ADCSRA & _BS( ADSC ) ) == _BS( ADSC ) ) {}
Ce qui a changé le code assembleur en:
38: 36 99 sbic 0x06, 6 ; 6
3a: fe cf rjmp .-4 ; 0x38 <__CCP__+0x4>
Ce qui résout de façon apparente le problème.
Consultez cette page pour le programme complet et son code résultant démonté.
ADCSRA
n'est pas volatil, le deuxième cas n'est-il pas également soumis à la même optimisation?Réponses:
Vous devez utiliser un ET au niveau du bit. L'expression dans la première
while
boucle est évaluée à zéro, ce qui oblige le compilateur à supprimer complètement la boucle.la source