Является ли энергозависимой, когда переменная считывается только во время прерывания - PullRequest
8 голосов
/ 21 марта 2019

Стандарт C гласит, что ключевое слово volatile следует использовать в определении переменной, когда существует вероятность того, что значение переменной может измениться вне нормального потока выполнения программы.

Если глобальная переменнаяизменяется (записывается) во время нормального потока выполнения и читается только вне этого нормального потока (в прерывании).Эта переменная должна быть изменчивой?А почему?

1 Ответ

5 голосов
/ 21 марта 2019

Если глобальная переменная изменяется (записывается) во время обычного потока выполнения и только для чтения вне этого нормального потока (в прерывании).Должна ли эта переменная быть энергозависимой?

Да, абсолютно.

И почему?

Чтобы обеспечить правильное выполнение обработчика прерываний (вместо обычного потока).


Позвольте мне уточнить.

Представьте, что у вас есть переменная, подобная этой:

int x;

Вы изменяете эту переменную вНормальный поток программы такой:

void modify(int *x){...some code here...}

И в подпрограмме обработки прерываний вы читаете переменную.

Помните, что прерывание может происходить асинхронно (в любое время).Также помните, что компилятор сначала преобразует ваш код в серию машинных инструкций, которые могут выглядеть примерно так:

load val from mem to register
perform modification operations
store value from registers to memory
perform other operations where the variable is used

Теперь компилятор может оптимизировать эту программу, чтобы уменьшить количество операций чтения-записи памяти какнапример:

load value
perform modifications
use value
...
modify register content
...
use
...
keep using value from the registers without ever storing in the memory.

В таком случае, если происходит прерывание (обратите внимание, что контекст прерывания обычно отличается от обычного контекста и, следовательно, имеет различный набор регистров во многих архитектурах (скажем, arm...)), он попытается прочитать значение переменной из памяти.Но содержимое памяти никогда не менялось из-за оптимизации компилятора.

Таким образом, ISR может прочитать старое значение (что еще хуже - мы не можем точно сказать, сколько лет значению), что приведет к непреднамеренномуповедение.

Итак, переменная должна быть объявлена ​​как volatile, чтобы компилятор не вмешивался в программу.

...