Menu

#162 QF critical sections require modification for M7 core

QP
closed
None
1
2024-08-01
2017-03-20
LawrenceC
No

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.

Discussion

  • Quantum Leaps

    Quantum Leaps - 2017-05-26
    • status: open --> closed
     
  • Quantum Leaps

    Quantum Leaps - 2017-05-26

    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 BASEPRI is not applied in QF_INT_ENABLE(). For example, here is the interrupt disable/enable code for the IAR toolset:

        /* Cortex-M3/M4/M7 interrupt disabling policy, see NOTE3 and NOTE4 */
        #define QF_INT_DISABLE() do { \
            QF_PRIMASK_DISABLE(); \
            __set_BASEPRI(QF_BASEPRI); \
            QF_PRIMASK_ENABLE(); \
        } while (0)
        #define QF_INT_ENABLE()      __set_BASEPRI(0U)
    

    --MMS

     

    Last edit: Quantum Leaps 2017-10-23
  • Quantum Leaps

    Quantum Leaps - 2017-09-07
    • assigned_to: Quantum Leaps
    • Group: QP-C --> QP-C-C++
     

Anonymous
Anonymous

Add attachments
Cancel





MongoDB Logo MongoDB