Enquanto loop otimizado

8

Eu tenho o seguinte código no meu programa de microcontrolador:

// Wait for ADC conversion to complete
while ( ( ADCSRA && _BS( ADSC ) ) == _BS( ADSC ) ) {}

Onde ADCSRA é um registro que alterará seu valor assim que uma conversão analógica for concluída e onde eu quero esperar um pouco para ficar claro. Este bit indica que a conversão foi concluída.

Observando o código de montagem resultante, o loop inteiro é substituído por uma única instrução:

in      r24, 0x06       ; ADCSRA

O registro é lido, mas seu valor nem é testado !?

Como preciso alterar meu código C ++ para instruir o compilador a continuar verificando novamente o registro, sem atrasar desnecessariamente o programa?

Eu uso o conjunto de ferramentas avr-gcc.

Edição: Eu alterei o código da seguinte forma (Thnx: lhballoti):

while ( ( ADCSRA & _BS( ADSC ) ) == _BS( ADSC ) ) {}

O que alterou o código do assembly para:

38:   36 99           sbic    0x06, 6         ; 6
3a:   fe cf           rjmp    .-4             ; 0x38 <__CCP__+0x4>

O que resolve resolvidamente o problema.

Verifique esta página para o programa completo e seu código resultante desmontado.

jippie
fonte
3
Você não pretende usar um AND bit a bit?
21712 lhballoti
normalmente você declararia os registros voláteis e, em seguida, os loops onde você não modifica as coisas não serão otimizados ... mas isso deve ser feito nos arquivos de inclusão.
W5VO 07/07/2012
Embora tenha percebido o erro imediatamente, estou tendo problemas para entender por que o compilador otimizou o loop no primeiro caso. Se ADCSRAnão é volátil, o segundo caso também não está sujeito à mesma otimização?
Lhballoti 07/07
Você não deve editar sua pergunta com a resposta, mas sim aceitar a resposta de alguém ou escrever sua própria resposta e aceitá-la.
Kellenjb 07/07
@Kellenjb - jippie adicionou antes de ser uma resposta. lhballoti primeiro fez isso como um comentário.
Stevenvh

Respostas:

11

Você deve usar um AND bit a bit. A expressão no primeiro whileloop é avaliada como zero, o que faz com que o compilador remova o loop completamente.

lhballoti
fonte