Переменная AVR прерывания обновлена ​​в основной - PullRequest
0 голосов
/ 08 декабря 2018

Используя 8-битный AVR micro, я пришел к простой ситуации, которую, возможно, не так просто решить.

Рассмотрим следующий фрагмент:

static volatile uint8_t counter;

//fires often and I need all the values of the counter.
void isr(void) {
  counter++;
}

int main (void) {

  while(1) {
    send_uart(counter);
    counter = 0;
    delay_ms(1000); //1 sec pause
  }  

  return 0;
}

1.)может случиться так, что за send_uart следует isr, который увеличивает счетчик, а затем следующий оператор обнуляет его.Поэтому я пропущу одну информацию со счетчика.

2.) Если я использую ATOMIC_BLOCK(ATOMIC_RESTORESTATE) в основном fn, я могу избежать проблем, заявленных в (1), но может случиться так, что я пропущуISR, потому что в этом случае INT отключаются на короткое время.

Есть ли лучший способ передачи информации из основного fn в ISR?

1 Ответ

0 голосов
/ 08 декабря 2018

Если счетчик сэмплируется, а не сбрасывается, проблем с синхронизацией не будет.Приращения, происходящие при отправке, будут учтены в следующей итерации.Тип данных без знака переменных счетчика гарантирует четко определенное поведение переполнения.

uint8_t cs = 0;                  // counter sample at time of sending
uint8_t n = 0;                   // counter as last reported

while (1) {
  cs = counter;                  // sample the counter
  send_uart((uint8_t)(cs - n));  // report difference between sample and last time
  n = cs;                        // update last reported value
  delay_ms(1000);
}
...