|
volatile не помагает |
|
|
|
Feb 11 2011, 09:46
|

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

|
Цитата(_Pasha @ Feb 11 2011, 12:10)  Если Вы о портабельности, то ее здесь нет. А если не о портабельности, то о чем? Я о том, что этот заюзаный не по своему назначению регистр может быть неожиданно востребован. Не Вами так наследниками Вашего хозяйства (а мужики то не знали...) Чтобы даже гипотетически не закладывать проблемы, я всегда воздерживаюсь от таких вот выкрутасов. Ибо почити всегда есть более прямое решение, как например не использовать битовые переменные вовсе (для AVR - это отличный способ избавиться от геморроя). Таков мой подход и я его не навязываю. Вольному - воля!
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Feb 11 2011, 10:22
|
Группа: Участник
Сообщений: 13
Регистрация: 10-02-11
Из: Украина
Пользователь №: 62 859

|
Попутно ещё вопросик: Например есть код
ISR() { adc_flags |= PROCESS_I_NEG; }
loop() { ................... if ( adc_flags & PROCESS_UOUT_POS ) { cli(); adc_flags &= ~PROCESS_UOUT_POS; sei(); } else { } .......... }
Компилятор превратит во чтото следующее
;if ( adc_flags & PROCESS_UOUT_POS )
R24,adc_flags
;///////////////////////////////// ; ТУТ ВОЗНИКАЕТ ВДРУГ ПРЕРЫВАНИЕ ;(где сохраняется регистр R24, затем добавляется бит PROCESS_I_NEG к adc_flags ;и воосстанавливается R24) ;/////////////////////////////////
;далее продолжается выполнение if SBRS R24,1<<PROCESS_UOUT_POS RJMP m1
;adc_flags &= ~PROCESS_UOUT_POS;
А вот тут вопрос: будет ли компилиться так (т.е. в R24 снова считывается adc_flag) CLI LDS R24,adc_flags ANDI R24,~PROCESS_UOUT_POS STS adc_flags,R24 SEI
или же возможна ситуация когда компилер не будет считывать в R24 переменную adc_flags, а посчитает что она ранее была считана в R24 и таким образом не учтёт изменение её в прерывании
Т.е. другими словами, необходимо ли и для if тоже использовать атомарность например в виде
cli() rez=adc_flags & PROCESS_UOUT_POS; sei()
if(rez) { ....... }
|
|
|
|
|
Feb 11 2011, 15:39
|

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

|
Цитата(ar__systems @ Feb 11 2011, 16:43)  Переменная однобайтовая. Какая атомарность? Да байтовая но в ней 8 бит-флагов: как происходит изменение бита в ОЗУ, а вот так: 1 load 2 modify 3 store так если произойдёт прерывание между пунктами 1-3 изменяющее этот же байт, то все изменения сделанные в прерывании будут похерены пунктом 3. И напоследок: volatile нужен для любой переменной хоть битовой хоть байтовой, хоть QWORD , если эта переменная используется (пишется или только читается) в прерываниях или является частью SFR. Всё! Учим наизусть и повторяем вместо мантры:-) Не хотите читать стандарт - поищите по форуму, тема про volatile уже неоднократно всплывала.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Feb 11 2011, 16:12
|
Группа: Участник
Сообщений: 13
Регистрация: 10-02-11
Из: Украина
Пользователь №: 62 859

|
Цитата Переменная однобайтовая. Какая атомарность? Код посмотри: Си: adc_flags &= ~PROCESS_UOUT_POS; Асма: LDS R24,adc_flags ANDI R24,~PROCESS_UOUT_POS STS adc_flags,R24
|
|
|
|
|
Feb 11 2011, 18:05
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (demiurg_spb @ Feb 11 2011, 17:39)  если эта переменная используется (пишется или только читается) в прерываниях или является частью SFR. Если эта переменная используется и в прерываниях и в основном цикле (или в нескольких потоках при использовании ОС).
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Feb 11 2011, 18:30
|
self made
   
Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795

|
Цитата(demiurg_spb @ Feb 11 2011, 10:39)  Да байтовая но в ней 8 бит-флагов: как происходит изменение бита в ОЗУ, а вот так: 1 load 2 modify 3 store
так если произойдёт прерывание между пунктами 1-3 изменяющее этот же байт, то все изменения сделанные в прерывании будут похерены пунктом 3. Да volatile к этой проблеме никакого отношения не имеет, и никак не поможет! Тут единственное что поможет, так это запрет прерываний на время доступа! Цитата Если эта переменная используется и в прерываниях и в основном цикле (или в нескольких потоках при использовании ОС). Да ради бога, только если у вас разграничение доступа не организвано должным образом, работать не будет все равно, volatile или нет. Иными словами, от критических секций вы все равно не избавитесь.
|
|
|
|
|
Feb 11 2011, 20:10
|

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

|
Цитата(ar__systems @ Feb 11 2011, 21:30)  Да ради бога, только если у вас разграничение доступа не организвано должным образом, работать не будет все равно, volatile или нет. Иными словами, от критических секций вы все равно не избавитесь. Для байтовой переменной на AVR избавлюсь от критической секции. И работать будет только если volatile. Я Вас не пойму. Вы что-то из пустого в порожнее всё переливаете и переливаете. К чему это? Перечитайте Ваши сообщения в этой ветке. Либо странные утверждения либо повторение за кем-то прописных истин после доходчивого разъяснения... Цитата(Сергей Борщ @ Feb 11 2011, 21:05)  Если эта переменная используется и в прерываниях и в основном цикле (или в нескольких потоках при использовании ОС). Ваша формулировка как всегда более точная:-)
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|