
ARM Cortex-M, Interrupts and FreeRTOS - another
https://mcuoneclipse.com/2016/08/14/arm-cortex-m-interrupts-and-freertos-part-1/
======
ambrop7
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...](http://infocenter.arm.com/help/topic/com.arm.doc.ddi0337h/CHDJFGJE.html)

~~~
ChuckMcM
Its missing a ton of information and it seems poorly presented. I found that
surprising given that the author teaches the topic.

In general I agree that the most confusing part with these chips are that the
ARM interrupts are all very well defined and they have clear semantics, but
the vendor specific interrupts are kind of all over the place as the vendors
use licensed IP from a variety of vendors and attach them to the interrupt
structure in different ways.

That said, interrupts have the inherent complexity of "you were doing
something and POW! now you're doing something else." which starts out weird to
new programmers and then when nested interrupts are brought up their head
explodes. I can imagine it is a tough topic to teach.

~~~
rkangel
It is missing some detail about how the interrupts operate, but:

a) It's a blog post not a reference manual. It's aim appears to be clear up
some confusion about terminology (and having been using a Cortex M4 for a year
I've spent a fair amount of time trying to reconcile conflicting
documentation).

b) It's only the first blog post in an intended series. Who knows what's going
to get covered next.

Even though I've got most of this sorted out in my head by now, it's still
helpful to me to have it put clearly in one place (even if it's just so that I
have a link to give to newer members of my team).

------
cmrx64
Excellent introduction! That implementations sometimes don't implement the
full range of priorities has bit me in the past with really hard to debug
issues. Not knowing much about FreeRTOS, I look forward to the next part in
the series.

------
Ericson2314
Cool, but what does the "nested" part mean? That handlers can themselves be
interrupted?

~~~
bravo22
Yes. That's exactly what it means. You can have priorities for different
interrupt sources. It has utility in many critical RTOS situations.

Imagine you have a factory machine. The micro has an IRQ for your
communication interface. This goes off when there is a packet. Obviously you
want this to be handled so there is not backlog of packets, however there is
another interrupt for a limit switch that goes off when the door to a chamber
in the device has been opened. You want to handle that interrupt above all
else so you can shut off the rotating blade in that chamber before a human
hand can get in there.

~~~
ArkyBeagle
1) You should expect lost , delayed and garbled comms. Your app layer or
stacks should handle this.

2) A limit switch will still need debounce. If it's the sort of limit switch
that will keep people's hand attached to their arm, I would be loathe to
depend on interrupt priority for it.

~~~
ambrop7
I suppose this was just an example of when you want to do safety-critical
control in software. For something as simple, hardware measures are probably
more appropriate, but your particular problem may be far too complex to solve
with simple hardware-based logic. For example, consider a system in a
radiation therapy machine which ensures the patient does not receive too much
dose or at the wrong spots.

