ARM Cortex M7 core has an errata 837070 for changing the BASEPRI level which causes the change to be delayed by one instruction, this can result in an ISR triggering at the start of a critical section when interrupts should be disabled. Due to the exit of an ISR setting BASEPRI back to 0 in the QK_EXIT macro, the ISR will return and leave BASEPRI at 0 leaving the entire critical section unprotected.
Errata is here: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.epm064408/index.html
qf_port.h requires the following modification:
#define QF_INT_DISABLE() do { \
__disable_interrupt(); \
__set_BASEPRI(QF_BASEPRI); \
__enable_interrupt(); \
} while (0)
#define QF_INT_ENABLE() do { \
__disable_interrupt(); \
__set_BASEPRI(0U); \
__enable_interrupt(); \
} while (0)
qk_port.s requires modifications to BASEPRI change in PendSV_Handler and NMI_Handler:
CPSID i
MSR BASEPRI,r0 ; selectively disable interrupts
CPSIE i
These changes will be required for QV, QK and QXK ports.
Strictly speaking the modification to the NMI_Handler and QF_INT_ENABLE are unnecessary, however seems like a good idea to do the NMI handler just in case future changes allow a bug to creep in.
For QF_INT_ENABLE, if the modification were not added and a user coded a back to back QF_INT_ENABLE followed by a QF_INT_DISABLE call, the issue would allow the critical sections to merge, which could introduce subtle bugs.
Anonymous
This bug has bee fixed in QP/C/C++ 5.9.0.
Specifically, the ARM-EPM-064408, errata 837070 for Cortex-M7 r0p1 cores (which are all licensed M7 cores at this time) has been applied in QP/C/C++. The applied code is slightly different than the code proposed in the OP in that the pair of instructions (CPSID i/CPSIE i) around
MSR BASEPRIis not applied inQF_INT_ENABLE(). For example, here is the interrupt disable/enable code for the IAR toolset:--MMS
Last edit: Quantum Leaps 2017-10-23