vromav 0 10 февраля, 2011 Опубликовано 10 февраля, 2011 · Жалоба Есть некоторый код, проблема в том что имеется переменная которая после выхода из прерывания восстанавливает своё значение, т.е. независимо от volatile компилятор по ходу разместил переменную event_flag в регистре??!!! При чём данная ситуация возникает не часто, иногда установленное значение в прерывании остаётся и после выхода из него(( ///////////////////////////////// // AVR Studio 4.16 Build 628 // // WinAVR-20090313 // // Atmega8535 // ///////////////////////////////// ............................ volatile uint8_t event_flags; #define START 0x01 ............................ #define PACK_NOW 0x20 volatile uint8_t macro_rx = 0; ISR (USART_RX_vect) { ............. ............. event_flags |= PACK_NOW; macro_rx = 1; //тут PACK_NOW устанавливается, но после выхода из прерывания, //в event_flags восстанавливается предыдущее значение } void main_loop() { ............ ............ if(macro_rx) { if(!(event_flags & PACK_NOW)) { //!!!!!! ОШИБКА !!!!!! //т.е. macro_rx так и осталась в установленном в прерывании значении //а event_flags нет!!! } } ............ ............ } int main() { while (true) { main_loop(); } } Помогите разобраться в ситуации... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 10 февраля, 2011 Опубликовано 10 февраля, 2011 · Жалоба Переменная сама по себе никак не может принимать произвольные значения. Где то идёт запись в эту переменную. Приведите весь код, работающий с данными volatile переменными. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vromav 0 10 февраля, 2011 Опубликовано 10 февраля, 2011 · Жалоба А где написано что event_flags принимает произвольные значения? Это не весь код, в начале программы выполняется event_flags |= START; Затем пошагово выполняю код в avr studio. Иногда натыкаюсь на вышеописанную ситуацию: В прерывании event_flags устанавливается (значение изменяется, видно в окне Watch), а на следующем шаге - выхожу из прерывания и вижу что event_flags снова равна START Весь код проблематично привести... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 10 февраля, 2011 Опубликовано 10 февраля, 2011 · Жалоба Весь код проблематично привести... Поиском найдите где эта переменная ещё меняется. И подумайте в каком из этих мест она может затираться. Очень маловероятно чтобы эта переменная была в регистре. Листинг скажет точно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vromav 0 10 февраля, 2011 Опубликовано 10 февраля, 2011 (изменено) · Жалоба Я же описал выше: Хожу по коду пошагово по F11, Попадаю в прерывание USARTa здесь пошагово дохожу до строчек event_flags |= PACK_NOW; macro_rx = 1; Смотрю в окно watch - переменная event_flags равна установленному вначале программы значению (0x01), затем выполняю 2 вышеприведенные строчки и вижу как event_flags стало равно 0x21, а macro_rx стало равным 1, затем снова делаю шаг по F11, и выхожу из прерывания и попадаю в main_loop, В ОКНЕ watch снова event_flags равен 0x01. Т.е. никаких команд после выхода из прерывания не было, а значение поменялось. Это могу объяснить только тем что event_flag была в регистре. Изменено 10 февраля, 2011 пользователем vROMAv Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 10 февраля, 2011 Опубликовано 10 февраля, 2011 · Жалоба Ходите по асм-коду. Там всё предельно ясно - в регистре или нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Oldring 0 10 февраля, 2011 Опубликовано 10 февраля, 2011 · Жалоба т.е. независимо от volatile компилятор по ходу разместил переменную event_flag в регистре??!!! Включите генерацию компилятором ассемблерного кода и посмотрите, где лежит переменная. Глюки компиляторов тоже встречаются, но реже, чем ошибки программистов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 10 февраля, 2011 Опубликовано 10 февраля, 2011 · Жалоба В AVRStudio добавте переменную в Watch и увидите где она расположена. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vromav 0 10 февраля, 2011 Опубликовано 10 февраля, 2011 · Жалоба В файле mega32.map переменной event_flags нет вообще это может чтонибудь значить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
slavka012 0 10 февраля, 2011 Опубликовано 10 февраля, 2011 (изменено) · Жалоба Дался вам этот волатайл. При чем тут вообще это? Обычная статическая переменная. Ей без разницы, где она лежит, в регистре или в памяти. Если компилятор ее в регистр положил, наверное этот регистр никто больше не используют. 99% процентов что ваша программа кривая. Изменено 10 февраля, 2011 пользователем ar__systems Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
firstvald 22 10 февраля, 2011 Опубликовано 10 февраля, 2011 · Жалоба А есть опции оптимизатора? Если есть возможность спуститься на несколклько шагов в оптимизации и посмотреть как будет работать? Ну второе , что можно посмотреть : по мапу посмотреть какие переменные размещаются до этой переменной, если там есть массив - надо насторожиться и попробовать ему размер увеличить - может он проезжается . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 10 февраля, 2011 Опубликовано 10 февраля, 2011 · Жалоба // WinAVR-20090313 //Есть и посвежее - рекомендую... volatile uint8_t event_flags;Сделайте 8 байтовых переменных вместо битовых флагов - это самое простое. Или работайте с битами атомарно (при запрещённых прерываниях, что может быть более накладно). Дался вам этот волатайл. При чем тут вообще это?При том... Читайте стандарт там всё подробно описано. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 11 февраля, 2011 Опубликовано 11 февраля, 2011 · Жалоба А у вас в main_loop'е случайно нет локальной переменной event_flags? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vromav 0 11 февраля, 2011 Опубликовано 11 февраля, 2011 · Жалоба Всем спасибо за помощь. Действительно в одном из участков кода проморгал атомарность(( ЗЫ: Старался всегда учитывать эту возможную бяку, но никогда ещё на неё не попадал. А ведь хорошо что попал, впредь буду более внимательно относится к битовым операциям. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 11 февраля, 2011 Опубликовано 11 февраля, 2011 · Жалоба А ведь хорошо что попал, впредь буду более внимательно относится к битовым операциям. Присмотритесь повнимательнее в пространство SFR - GPR0 итд - меняются легко флаги, это если не хочется в регистре переменную держать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться