Иногда мне нужен какой-то код, который будет выполняться процессором точно так же, как я положил его в исходный код. Но у любого компилятора C есть алгоритмы оптимизации, поэтому я могу ожидать некоторые трюки. Например:Как мне сказать «компилятору», что код не должен быть оптимизирован?
unsigned char flag=0;
interrupt ADC_ISR(){
ADC_result = ADCH;
flag = 1;
}
void main(){
while(!flag);
echo ADC_result;
}
Некоторые компиляторы, безусловно, сделать while(!flag);
цикл инфинитив, как это будет предполагать, flag
равно ложь (!flag
поэтому всегда верно).
Иногда я могу использовать ключевое слово volatile
. И иногда это может помочь. Но на самом деле в моем случае (AVR GCC) volatile
ключевое слово заставляет компилятор размещать переменную в SRAM вместо регистров (что плохо по некоторым причинам). Кроме того, многие статьи в Интернете предлагают использовать ключевое слово с большим вниманием, поскольку результат может стать нестабильным (в зависимости от компилятора, его настроек оптимизации, платформы и т. Д.).
Так что я определенно предпочел бы как-то указать инструкцию по исходному коду и сообщить компилятору, что этот код должен быть скомпилирован точно так, как есть. Например: volatile while(!flag);
Есть ли какая-либо стандартная инструкция C для этого?
Конечно, переменная 'volatile' переходит в ОЗУ! Регистры предназначены для временных значений. Прерывание может происходить в любое время. Я бы рекомендовал сделать еще несколько исследований параллельности, особенно обработчиков прерываний и разработки встроенного программного обеспечения.Например, для логического флага вы должны использовать булевский стандартный тип. – Olaf
Volatile означает, что значение переменной не может быть кэшировано между чтениями (и что записи не могут перемещаться). Да, это обычно приводит к разгрузке в ОЗУ каждый раз. Если вы думаете, что можете сделать лучше, вам следует попробовать [встроенную сборку] (http://www.ethernut.de/en/documents/arm-inline-asm.html). – Cubic
@Cubic: Какое изменение сделало бы встроенную сборку для переменных? OP, похоже, даже не думает о плохо оптимизированном коде, а об использовании ресурсов. Единственным решением для этого было бы написать ** все ** в Assembler, чтобы он мог контролировать регистр CPU и распределение памяти на 100%. Микроуправление в лучшем виде. Я делал это много лет и очень рад, что у нас есть компиляторы, которые заботятся об этом. – Olaf