DUE TO SPAM, SIGN-UP IS DISABLED. Goto Selfserve wiki signup and request an account.
ARMv7-M Hardfaults, SVCALL, and Debuggers
Cortex-M3 and Cortex-M4
The most popular CPUs in current MCU designs are the Cortex-M3 (ARMv7-M) and the Cortex-M4 (ARMv7E-M).
Handling of these two architectures is almost identical in NuttX (unless hardware floating point is enabled).
SVCALL
NuttX uses the SVCALL software interrupt in order to perform certain steps in the context switching for the Cortex-M3 and Cortext-M4.
This sequence of logic appears in several places:
...
NOTE: There is a technical difference between interrupts and exceptions.
In this Wiki page, the term exception will be used;
It is probably the more accurate since interrupts are really exceptions that result from device interrupt lines.
Further, when we refer to exceptions in this Wiki page, we are referring specifically to ARMv7-M configurable exceptions.
Disabling Interrupts via the PRIMASK register
The ARMv7-M architecture supports a register called the PRIMASK register.
The PRIMASK register contains a single valid bit.
If that bit is set to one, then exceptions are disabled;
if that bit is zero, exceptions are enabled.
More correctly, when this bit is set to one, it prevents the activation of all exceptions with configurable priority.
The original NuttX implementation used this PRIMASK register to enable and disable exceptions.
Things now get interesting in the sequence of logic listed above because the PRIMASK bit also disables the SVCALL exception!
So, instead of taking the SVCALL exception vector, the Cortex-M3/4 generates a hardfault exception (see ARM.com's discussion of Activation Levels.
These hardfaults are not really a problem; the design of the NuttX hardfault handler expects these exceptions and does the right thing.
However, the occurrence of hardfaults may come as a surprise to many people – and especially to some debuggers.
Hardfaults and Debuggers
These hardfaults only become a technical issue when dealing with a debugger.
What does the debugger do when the hardfault occurs?
...
So one workaround is to just reconfigure the DEMCR register so that break exceptions are no longer generated when hardfaults occur.
Here is an example of such logic for the LPC43xx MCU.
Decoupling the hardfault from the break exception in this way does not work with all debuggers, however.
Presumably because some debuggers re-enable break exceptions on hardfaults.
Disabling Interrupts via the BASEPRI register
The ARMv7-M architecture supports another way to disable exceptions using a register called the BASEPRI register.
ARMv7-M exceptions are prioritized; Each exception can be assigned an 8-bit priority.
If the BASEPRI register is set to a non-zero priority value, then it will filter exceptions in this sense:
Exceptions with priority lower than or equal to the BASEPRI register will be disabled;
Exceptions with priority higher than the BASEPRI register will still be enabled;
Normally this interrupt prioritization is used to support nested interrupt handling, but it can also be used for disabling of all exceptions if configured properly.
...