Using a 8-bit AVR micro, I arrived to a simple situation which might not be that easy to solve.
Consider the following snippet:
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.) It can happen that send_uart is followed by an isr which increases the counter, and then the next statement zeroes it out.
Therefore I'll miss one data from the counter.
2.) If I use ATOMIC_BLOCK(ATOMIC_RESTORESTATE) in the main fn, I can avoid the problems declared in (1), but it can happen that I miss an ISR because in this case INTs are disabled for a short time.
Is there a better way to pass information from the main fn to ISR?
ATOMIC_BLOCKfrom AVR Libc just disables interrupts, it does not clear any interrupt flags that got set while the block was running, so the interrupts will run after it finishes and re-enables interrupts. Using that will harm the latency of all the interrupts in your program though; there might be better options available if you answer all my questions. Also you'll only get one interrupt if two interrupt-triggering events happen during the atomic block (so make sure you keep it short). - David Grayson