|
volatile не помагает |
|
|
|
Feb 10 2011, 13:16
|
Группа: Участник
Сообщений: 13
Регистрация: 10-02-11
Из: Украина
Пользователь №: 62 859

|
Есть некоторый код, проблема в том что имеется переменная которая после выхода из прерывания восстанавливает своё значение, т.е. независимо от 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(); } }
Помогите разобраться в ситуации...
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 14)
|
Feb 10 2011, 13:49
|
Группа: Участник
Сообщений: 13
Регистрация: 10-02-11
Из: Украина
Пользователь №: 62 859

|
А где написано что event_flags принимает произвольные значения? Это не весь код, в начале программы выполняется event_flags |= START; Затем пошагово выполняю код в avr studio. Иногда натыкаюсь на вышеописанную ситуацию: В прерывании event_flags устанавливается (значение изменяется, видно в окне Watch), а на следующем шаге - выхожу из прерывания и вижу что event_flags снова равна START
Весь код проблематично привести...
|
|
|
|
|
Feb 10 2011, 14:15
|
Группа: Участник
Сообщений: 13
Регистрация: 10-02-11
Из: Украина
Пользователь №: 62 859

|
Я же описал выше: Хожу по коду пошагово по 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 была в регистре.
Сообщение отредактировал vROMAv - Feb 10 2011, 14:16
|
|
|
|
|
Feb 10 2011, 14:56
|
Группа: Участник
Сообщений: 13
Регистрация: 10-02-11
Из: Украина
Пользователь №: 62 859

|
В файле mega32.map переменной event_flags нет вообще это может чтонибудь значить?
|
|
|
|
|
Feb 10 2011, 17:19
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(vROMAv @ Feb 10 2011, 16:16)  // WinAVR-20090313 // Есть и посвежее - рекомендую... Цитата volatile uint8_t event_flags; Сделайте 8 байтовых переменных вместо битовых флагов - это самое простое. Или работайте с битами атомарно (при запрещённых прерываниях, что может быть более накладно). Цитата(ar__systems @ Feb 10 2011, 19:06)  Дался вам этот волатайл. При чем тут вообще это? При том... Читайте стандарт там всё подробно описано.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Feb 11 2011, 08:53
|
Группа: Участник
Сообщений: 13
Регистрация: 10-02-11
Из: Украина
Пользователь №: 62 859

|
Всем спасибо за помощь. Действительно в одном из участков кода проморгал атомарность((
ЗЫ: Старался всегда учитывать эту возможную бяку, но никогда ещё на неё не попадал. А ведь хорошо что попал, впредь буду более внимательно относится к битовым операциям.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|