Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: IAR MSP430 заоптимизировал?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
Dog Pawlowa
Эта конструкция используется в нескольких местах этой функции, вызываемой в прерывании. Оказывается, что компилятор выкидывает присвоение переменной.
Как победить то? Неприятные грабли - это неожиданные, которые происходят, когда сложный проект работает, осталось немного подправить smile.gifНажмите для просмотра прикрепленного файла
vmp
Цитата(Dog Pawlowa @ Jun 8 2007, 11:02) *
Оказывается, что компилятор выкидывает присвоение переменной.

Не вижу никакого выкидывания.
pump_state кешируется в R14. В зависимости от missing_pulses в R14 пишется либо 0 (001F94), либо 1 (001F98), после чего R14 сохраняется в pump_state (001F9A). Просто компилятор чуть-чуть не попал с комментариями - это простительно на высоких уровнях оптимизации.

P.S. Основной источник глюков при использовании прерываний - программист, не знающий про ключевое слово volatile.
Dog Pawlowa
Цитата(vmp @ Jun 8 2007, 10:48) *
Не вижу никакого выкидывания.
pump_state кешируется в R14. В зависимости от missing_pulses в R14 пишется либо 0 (001F94), либо 1 (001F98), после чего R14 сохраняется в pump_state (001F9A). Просто компилятор чуть-чуть не попал с комментариями - это простительно на высоких уровнях оптимизации.

Спасибо. Действительно, погорячился. Простительно - отладчик в прерываниях ведет себя неадекватно, запаниковал.

Цитата(vmp @ Jun 8 2007, 10:48) *
P.S. Основной источник глюков при использовании прерываний - программист, не знающий про ключевое слово volatile.


Никогда не называл себя программистом :-)
А поясните, пожалуйста.
volatile на самом то деле указано для pump_state. И я думаю, что это совершенно не нужно. Если переменная используется ТОЛЬКО в прерывании, то volatile на самом то деле и не нужно, правда?
vmp
Цитата(Dog Pawlowa @ Jun 8 2007, 15:39) *
Если переменная используется ТОЛЬКО в прерывании, то volatile на самом то деле и не нужно, правда?


Если только в одном невложенном прерывании - то не нужно.
Если только в основной программе - тоже не нужно.
Если и в основной программе и в прерывании - необходимо.
Если в двух вложенных прерываниях - необходимо.

Короче говоря, volatile надо ставить на те переменные, которые могут изменяться асинхронно. Или в прерываниях, или по DMA, или ещё как-нибудь (напрммер, регистры внешних устройств).
Такие переменные компилятор не кеширует в регистрах процессора, а берет всегда свежие данные из ОЗУ.
Dog Pawlowa
Цитата(vmp @ Jun 8 2007, 14:50) *
Короче говоря, volatile надо ставить на те переменные, которые могут изменяться асинхронно.

Спасибо, я так и представлял.
Признаюсь, в старых проектах не пользовался. Тем не менее все вроде-бы работает, а теперь менять вроде бы ни к чему ("Папа, а почему солнце всходит на востоке, а заходит на западе? - Проверял? - Проверял! - Работает? - Работает! - Только ничего не меняй! ").
Видимо, когда количество переменных достаточно велико, компилятор не может расположить эти переменные в регистрах ввиду их сравнительно редкого использования и берет из памяти.
Сергей Борщ
Цитата(Dog Pawlowa @ Jun 8 2007, 17:20) *
Видимо, когда количество переменных достаточно велико, компилятор не может расположить эти переменные в регистрах ввиду их сравнительно редкого использования и берет из памяти.
на конструкцию
Код
flag = 0; while(flag != 1);
много регистров не нужно. Если flag не volatile, то при слабой оптимизаци компилятор считает flag в регистр и далее будет тупо проверять регистр, хороший - заменит эту конструкцию на бесконечный цикл, ибо внутри цикла flag не меняется и проверять его снова не нужно.
Dog Pawlowa
Цитата(Сергей Борщ @ Jun 8 2007, 19:32) *
на конструкцию
Код
flag = 0; while(flag != 1);
много регистров не нужно.

Тем не менее постоянно использую такое:
Код
__no_init int delay_count;
void Delay(int ms)
{ StartDelay(ms);
  while(delay_count>0)  CheckTimeAndResetWDT();
}

Повезло?
Ребят, знал бы, что программировать так сложно - ни за что бы не брался! biggrin.gif
vmp
Цитата(Dog Pawlowa @ Jun 9 2007, 00:26) *
Тем не менее постоянно использую такое:
Код
__no_init int delay_count;
void Delay(int ms)
{ StartDelay(ms);
  while(delay_count>0)  CheckTimeAndResetWDT();
}

Повезло?

Если CheckTimeAndResetWDT() - это функция, а не макрос, то все в порядке. Компилятор в общем случае ничего о ней не знает и поэтому считает, что она может изменить все глобальные переменные, в том числе и delay_count.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.