I think the article is missing important information about how NVIC latches interrupts, or in general the relation between the interrupt signal and the execution of the interrupt. The NVIC supports both "level" and "pulse" type interrupts, and an interesting property of the "pulse" interrupts is that if the interrupt line goes low and high again while the ISR is running, the ISR will be re-executed. More info is provided in the manuals[1].

It is good to understand what is happening between the peripherals and the NVIC. Even though in many cases the device manual fails to specify exactly what type of interrupts are used and the logic in the peripherals that drives the interrupt lines. E.g. they may just say, these bits enable these interrupts which occur on these events, ommitting info such as whether the interrupts are pulsed or level and how/whether the peripheral internally latches the interrupt condition.

There are also little practical tips provided in the article to prevent "messing up" interrupts. Here's a few of mine:

- Try to get a good understanding of the interrupt logic of the peripheral.

- Make sure to clear any associated interrupt condition in the interrupt handler, as applicable.

- Before enabling the interrupt, set all variables exepected by the ISR and do a memory barrier (e.g. gcc's asm volatile with memory clutter; this may be done implicitly with "enable interrupts", i.e. asm volatile ("cpsid i" : : : "memory")).

- In case of edge-sensitive interrupts be aware they could trigger on ANY edge, including due to transient conditions. E.g. you're filling up a buffer through an interrupt that fires when at least 4 words are available to be written. Say the ISR fires with exactly 4 words available, you write the first word, then the peripheral consumes 1 word before you write the remaining 3 words. With pulse-interrupts that causes another invocation of the ISR, at the start of which you do not necessarily have 4 words of buffer space available. So, generally it is best to understand interrupts as hints only and still verify that a specific event has occurred / condition is satisfied.

- Specific to clocks, I found a very practical way to time different events though interrupts is by running timers in simple "overflowing" mode and just set the output compare units to fire whenever you want them to - treat time as modulo 2^N and deal with overflow right (by only ever looking at differences of times). It's not a problem if you want more range than the N-bit timers can provide because you can simulate that by handling counter-overflow. Also, if you need to synchronize more events than you have compare units on one timer, typically it is possible to run multiple timers synchronzied (set same clock, start them very quickly in succession).

- Some peripherals are just badly designed and you need to read every single piece of the documentation while specifically looking for behavior that's going to bite you. Specifically notable cases is when reading some register implicitly clears some interrupt flags, so you may accidentally acknowledge an interrupt outside of the ISR.

[1] http://infocenter.arm.com/help/topic/com.arm.doc.ddi0337h/CH...