спасибо, что нашли время для чтения.Встраиваемый 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;
линия.
Материал я попытался
Я посмотрел на скомпилированной сборки, и что я нашел своего рода пни меня.
Если я смотрю на «если» в основном, это то, что я вижу:
Так он загружает значение из адреса: 0x011D из SRAM, который я могу подтвердить это 0x01.
Затем «CPI» сравнивает R24 напрямую с 0x01, что должно явно работать.
Затем «BREQ», если ветвь, если она равна, и увеличите счетчик программ дважды до функции uart ниже. Также имеет смысл.
Однако эта часть странная. В противном случае используйте «RJMP», чтобы перейти к инструкции, в которой он сейчас находится. Если я не ошибаюсь, это будет задерживаться здесь на вечность?
Итак, помните, когда я упомянул, что когда я помещаю блок if в foo.c после записи в u_newVar? Да, это не слишком интересно:
«тогда», как предполагается, после того, как «u_newVar = 0x01», но компилятор слишком умный и оптимизирует его, как. Вот почему он всегда работает там.
Человек, вы - Бог, я сейчас как-то влюблён в вас. Это было именно это. –
Также, спасибо! –
Технически это должно быть 'volatile sig_atomic_t' или атомно-квалифицированная переменная. Согласно спецификации,' volatile' недостаточно. – EOF