Переменная AVR прерывания обновлена в основной
Используя 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 ответ
Если счетчик выбран, а не сброшен, проблем с синхронизацией не возникнет. Приращения, происходящие при отправке, будут учтены в следующей итерации. Тип данных без знака переменных счетчика гарантирует четко определенное поведение переполнения.
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);
}