Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос по volatile
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Страницы: 1, 2
XVR
Цитата(Укушенный воблой @ Jan 19 2017, 22:42) *
Зачем?
С Вами и так все ясно.

А вы батенька хам и троль.
Укушенный воблой
Вы ошибаетесь.
Просто я не хочу обсуждать вкус устриц с человеком, который устрицу не отличает от камбалы.
Простите.
Просто Вы своим вопросом показали, что вы ещё бОльший нуб в программировании чем я.
Поэтому чего я у вас буду чего-то спрашивать?
aiwa
Цитата(Alt.F4 @ Jan 19 2017, 09:32) *
Я не против volatile, просто хочется понять, когда без него ну совсем не обойтись и код точно не будет работать.


Ожидание готовности периферии - sp, twi, usart и прочее.
Регистры, содержащие флаги объявлены как volatile: в противном случае неизбежно зацикливание.

Но у volatile есть и обратная сторона: использовать их нужно через не-volatile копии.
Совершенно искуственный, но показательный пример:

Код
volatile unsigned char tick = 1;
volatile unsigned char res_yes_volatile=0;
unsigned char           res_no_volatile=0;
unsigned char flag=0;

__irq void IRQ_Handler(void)
{
  tick++;
  flag = tick;
}

int main()
{
  while(flag < 6)
  {
    res_yes_volatile = tick*tick; // 2*2 = 6
    res_no_volatile = tick*tick;
  }
  return 0;
}


Имеем в итоге:
1. вечный цикл из-за того, что flag не объявлена как volatile.
2. второй оператор умножения в цикле компилятор просто выбросил за ненадобностью.
3. команды для первого оператора цикла компилятор добросовестно сгенерировал, но так как volatile-ный tick использован
напрямую, без посредников, возможны коллизии типа 2*2 = 6, 5*5 = 30.

Код
//   16 int main()
//   17
//   18 {
main:
        LDR.N    R0,??DataTable1
//   19  
//   20  
//   21   while(flag < 6)
        LDRB     R1,[R0, #+3]
        CMP      R1,#+6
        BGE.N    ??main_0
//   22   {
//   23     res_yes_volatile = tick*tick;
??main_1:
        LDRB     R1,[R0, #+0]
        LDRB     R2,[R0, #+0]
        MULS     R1,R2,R1
        STRB     R1,[R0, #+1]
//   24     res_no_volatile = tick*tick;
        LDRB     R1,[R0, #+0]
        LDRB     R1,[R0, #+0]
        B.N      ??main_1
//   25   }
//   26    
//   27   return 0;
??main_0:
        MOVS     R0,#+0
        BX       LR             ;; return
XVR
Цитата(Укушенный воблой @ Jan 19 2017, 23:30) *
Вы ошибаетесь.
Просто я не хочу обсуждать вкус устриц с человеком, который устрицу не отличает от камбалы.
Вы своим ответом показали, что вы все же хам, причем необразованный. Ляпнули какую то глупость, на просьбу привести пример - не привели, в оскорбили собеседника.

Цитата
Поэтому чего я у вас буду чего-то спрашивать?
Это я у вас спрашивал. Не в состоянии ответить - не отвечайте, оскорблять зачем?

Цитата
Просто я не хочу обсуждать вкус устриц с человеком, который устрицу не отличает от камбалы.
Это уже прямое оскорбление. Откуда вам знать мой уровень?

Вы форум смортели, прежде чем на человека наезжать?

Требую публичного извенения.
ViKo
Побейтесь еще за пустой мешок! w00t.gif
jcxz
Цитата(aiwa @ Jan 20 2017, 07:17) *
res_yes_volatile = tick*tick; // 2*2 = 6

Здесь компилятор вроде как должен выдать варнинг. Значит так лучше не писать.
aiwa
Цитата(jcxz @ Jan 20 2017, 12:03) *
Здесь компилятор вроде как должен выдать варнинг. Значит так лучше не писать.

Да, забыл добавить. Компилятор выдает варнинг:
"undefined behavior: the order of volatile accesses is undefined in this statement"
AHTOXA
Цитата(XVR @ Jan 20 2017, 14:40) *
Требую публичного извенения.

Ну вы нашли, с кем схлестнуться. Это же, судя по всему, Доктор ТуамОсес, он же Дон Амброзио, он же avr123, он же [ещё куча ников]. Это известный тролль, не тратьте на него своё время и нервы.
zltigo
Цитата(AHTOXA @ Jan 20 2017, 13:19) *
Ну вы нашли, с кем схлестнуться. Это же, судя по всему, Доктор ТуамОсес, он же Дон Амброзио, он же avr123, он же [ещё куча ников]. Это известный тролль, не тратьте на него своё время и нервы.

Да, это именно этот персонаж.
Укушенный воблой
Цитата(aiwa @ Jan 20 2017, 05:17) *
2. второй оператор умножения в цикле компилятор просто выбросил за ненадобностью.

Выключите оптимизацию в опциях компилятора
sigmaN
Цитата(Сергей Борщ @ Jan 19 2017, 10:11) *
Не надо изобретать велосипед. Есть два критения:
1) если переменная используется в двух потоках (читай - в основном цикле и прерывании). Компилятор обязан при каждом обращении на чтение вычитывать ее из ОЗУ и при каждом обращении на запись класть обратно.
2) если важен порядок доступа к этой переменной (читай - регистры периферии). Компилятор обязан делать то же самое, что и п.1, кроме этого не имеет права менять местами обращения к этой переменной относительно обращений к другим volatile.

Я на C++, как большой любитель делать всё правильно, столько наелся кактусов с этим volatile для переменных(экземпляров классов) используемых и в прерывании и нет, что в итоге плюнул и каким-то чудом оно работает )))))))))) Из-за строгой типизации там просто ад получается. Волатильный экземпляр может вызывать только волатильные метод и так далее короче.

Кстати кто как на плюсах выкручивается в таких ситуациях?
XVR
Цитата(Укушенный воблой @ Jan 21 2017, 12:09) *
Выключите оптимизацию в опциях компилятора

Вау! А наилучшее лекарство от головной боли - гельотина?
Укушенный воблой
Нет. twak.gif
Если с умом подходить к разработке программы то всякие "танцы с бубном" вроде включения "оптимизации лэвел 4" не нужны.

Ибо когда разработчик начинает "танцы с бубном" - это означает, что он фактически расписался в своей некомпетентности и что ситуация вышла из под контроля.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.