volatile для переменной, которая читается только в ISR?

Проверьте свой JNI / собственный код. Одна из моих ссылок была нулевой, но она была прерывистой, поэтому это было не очень очевидно.

1
задан Cacahuete Frito 3 March 2019 в 09:09
поделиться

2 ответа

Нужна ли переменная для переменной, которая читается и записывается в основном цикле, но доступна только для чтения в ISR?

volatile здесь не проблема, так как страхование main записи цикла не разбиваются на части.

Любые изменения в main() без защиты от вызова ISR могут привести к проблемам, volatile или нет. Объявление volatile не спасает код от этой проблемы.

volatile some_type obj;

void ISR() {
  foo(obj);
}

int main() {
  for (;;) {
    // volatile useful here to prevent the assignment from being optimized away.
    some_type tmp = bar();

    // protect from potential interruption need here.

    // Without protection, ISR(), 
    // doesn't know it is working with a completely written `obj`
    obj = tmp;

    // release from potential interruption
}

volatile полезно в обоих направлениях, чтобы main() знал, что ISR() мог измениться obj, а для main() не оптимизировать выездные назначения.

Тем не менее, поскольку ISR() не изменяется obj, поэтому volatile не требуется.

Объявление obj atomic может помочь, но это другое вопрос.

0
ответ дан chux 3 March 2019 в 09:09
поделиться

volatile - плохой способ синхронизации доступа. Это барьер для оптимизации, но не более.

  • это не атомарный; например когда ваш some_type - uint64_t на платформе без собственных 64-битных типов данных, там может быть только часть для чтения. Э.Г.

    main()                  irq()
    
    /* initialization */ 
    var[0..31]  = 4
    var[32..63] = 8
    
    /* modificatoin */ 
    var[32..63] = 23
                          /* read */
                          a_hi = var[32..64] = 32
                          a_lo = var[0..31]  = 4
    var[0..31] = 42
    
  • , в зависимости от архитектуры, могут быть необходимы операции с барьером памяти. Например. когда main и irq работают на разных ядрах с выделенными кэшами, irq никогда не увидит обновленное значение

Первая проблема требует блокировки, но операции блокировки обычно подразумевают оптимизационный барьер, так что volatile излишне.

То же самое касается второй проблемы, где барьеры памяти действуют также как барьер оптимизации.

volatile полезен для реализации доступа к памяти процессора (которая может изменяться между двумя операциями чтения или иметь побочные эффекты при записи). Но обычно это не нужно и слишком дорого.

0
ответ дан ensc 3 March 2019 в 09:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: