2015-03-21 1 views
0

спасибо, что нашли время для чтения.Встраиваемый C: AVR; переменная в заголовке не может быть оценена в основном

Проблема Я вижу

У меня есть:

main.h 

, который объявляет:

uint8_t u_newVar 

У меня также есть

foo.h 

, который пишет:

extern uint8_t u_newVar 

Приложение находится в бесконечном цикле while в main.c до появления ISR.

В foo.c указанный ISR вызывает функцию внутри foo.c.

В этой функции (foo_function(), если хотите): 0x01 записывается в u_newVar.

Наконец, после возвращения из прерывания и обратно в бесконечное время, есть один «если» заявление:

while(1){ 
    if(u_newVar == 0x01){ 
    uartTX_sendArray(st_uartRX_MessageContents->u_command, (sizeof st_uartRX_MessageContents->u_command)); 
    uartTX_sendButtonPressData(st_uartRX_MessageContents->u32_value);  
    u_newVar = 0x00; 
    } 
} 

Однако приложение никогда не входит в случае. Этот блок «if» будет работать, если он находится в foo.c, после

u_newVar = 0x01; 

линия.

Материал я попытался

Я посмотрел на скомпилированной сборки, и что я нашел своего рода пни меня.

Если я смотрю на «если» в основном, это то, что я вижу:

enter image description here

Так он загружает значение из адреса: 0x011D из SRAM, который я могу подтвердить это 0x01.

Затем «CPI» сравнивает R24 напрямую с 0x01, что должно явно работать.

Затем «BREQ», если ветвь, если она равна, и увеличите счетчик программ дважды до функции uart ниже. Также имеет смысл.

Однако эта часть странная. В противном случае используйте «RJMP», чтобы перейти к инструкции, в которой он сейчас находится. Если я не ошибаюсь, это будет задерживаться здесь на вечность?

Итак, помните, когда я упомянул, что когда я помещаю блок if в foo.c после записи в u_newVar? Да, это не слишком интересно:

enter image description here

«тогда», как предполагается, после того, как «u_newVar = 0x01», но компилятор слишком умный и оптимизирует его, как. Вот почему он всегда работает там.

ответ

8

Вы забыли сообщить компилятору, что переменная может быть изменена асинхронно. Например, в ISR.

volatile uint8_t u_newVar; 
+0

Человек, вы - Бог, я сейчас как-то влюблён в вас. Это было именно это. –

+0

Также, спасибо! –

+0

Технически это должно быть 'volatile sig_atomic_t' или атомно-квалифицированная переменная. Согласно спецификации,' volatile' недостаточно. – EOF

-1

Что вы смотрите на выход ассемблера, а не на связанный код.

В линкере есть информация в таблице перемещений для этого смещения в коде (байты данных инструкции и фактическое смещение цели) во время процесса компоновки (или для определенных сред во время обработки загрузки) эти байты данных будут обновлены, чтобы содержать правильное значение

Смежные вопросы