volatile для переменной, которая читается только в ISR? - PullRequest
0 голосов
/ 03 марта 2019

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

РЕДАКТИРОВАТЬ: В момент записи в основном ISR отключен.Таким образом, переменная эффективно используется атомарно.

РЕДАКТИРОВАТЬ: (очень сильно связаны):

энергозависимый по сравнению с барьером памяти для прерываний

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

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 голосов
/ 03 марта 2019

Нужна ли переменная для переменной, которая читается и записывается в главном цикле, но доступна только для чтения в 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 может помочь - но это другой вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...