AnsweredAssumed Answered

WARNING: Found a version of core_cm3.h that could really mess up interrupt priority.

Question asked by izzy.weird on Aug 20, 2011
Latest reply on Aug 22, 2011 by Clive One
Two copies of (CMSIS) core_cm3.h were found to have different and incompatible versions of NVIC_SetPriority().  One may have been modified, but watch out for it.

On a recent build I suddenly had no interrupt preemptive priorities (no nesting) all interrupts were at the same priority.  Lower pri interrupts would block higher ones.  Systick was the top priority and it too was being blocked by lower priority interrupts.

The root cause was a change in the (CMSIS) core_cm3.h files from ARM Ltd.  One does not shift the priority bits to the upper nibble (STM32 priority position), but the other one did.  So the two CMSIS inline functions, both named NVIC_SetPriority() are not compatible with each other.  I wonder how many have been tripped up by this nasty little discrepancy.

// V1.30 dated 30 Oct. 2009:

static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

{

  if(IRQn < 0) {

    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */

  else {

    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts  */

}

// (Note: #define __NVIC_PRIO_BITS    4) 

 

// V1.10 dated 24 Feb 2009:

// (May have been modified by someone.)

/**

* @brief  Set the priority for an interrupt

*

* @param  IRQn_Type IRQn is the Number of the interrupt

* @param  priority is the priority for the interrupt

* @return  none

*

* Set the priority for the specified interrupt. The interrupt

 * number can be positive to specify an external (device specific)

 * interrupt, or negative to specify an internal (core) interrupt. \n

*

* Note: The priority cannot be set for every core interrupt.

*/

static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, int32_t priority)

{

  if(IRQn < 0) {

    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); }  /* set Priority for Cortex-M3 System Interrupts */

  else {

    //NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }         /* set Priority for device specific Interrupts      */

    NVIC->IP[(uint32_t)(IRQn)] = (priority & 0xff);    }         /* set Priority for device specific Interrupts      */

}

 

Outcomes