Мне было интересно, приведет ли в следующем сценарии временный квалификатор volatile к правильному поведению. Предположим, что ISR собирает значения в массиве, и как только будет собрано достаточное количество значений, он сигнализирует о готовности.
int array[10]; // observe no volatile here
int idx = 0; // neither here
volatile bool ready = false; // but here
Здесь ISR является псевдокодом
ISR() {
if (idx < 10)
array[idx++] = ...;
ready = (idx >= 10);
}
Предположим, что мы можем гарантировать, что array
будет считываться только после ready
, а доступ к элементам осуществляется с помощью определенного метода только:
int read(int idx) {
// temporary volatile semantics
volatile int *e = (volatile int*)(array + idx);
return *e;
}
что, кажется, разрешено в соответствии с cpp-reference
Приведение энергонезависимого значения к изменчивому типу не имеет никакого эффекта. Чтобы получить доступ к энергонезависимому объекту с использованием семантики volatile, его адрес должен быть приведен к указателю на volatile, а затем доступ должен осуществляться через этот указатель.
Для полноты основная процедура делает следующее
void loop() {
if (ready) {
int val = read(0); // Read value
// do something with val.
}
}
В таком сценарии я должен ожидать считывания правильных значений из array
или изменчив в элементах массива, необходимых для гарантии того, что запись в массив из ISR()
действительно выполняется в ОЗУ?
Обратите внимание, что Почему volatile необходимо в C? не уточняет, является ли в этот особый случай volatile необходим.
volatile
предотвращает только оптимизацию компилятора. Не требует доступа к переменным. - person LPs   schedule 28.10.2016