2011-08-19 04:43 PM
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: &sharpdefine __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 */
}
#cmsis #interrupt #nvic #priority2011-08-19 09:38 PM
Thanks for the posting. So to be clear, the first one you posted (the V1.3) is the good one - the one we should be using? And the second one (the V1.1) is the one that caused you the troubles? Is this correct?
2011-08-22 09:32 AM
2011-08-22 10:32 AM
Can you identify the source package where the modified file came from, because the original version of V1.10 does not contain the code you describe.
V1.10 24-Feb-2009 from STM32F10x_DSP_Lib_V2.0.0 is not modified V1.10 24-Feb-2009 from STM3210E-EVAL_FW_V2.0.0 is not modified Unmodified versions within immediate reach... V1.10 24-Feb-2009 core_cm3.h, 42,077 bytes V1.20 22-May-2009 core_cm3.h, 46,533 bytes (one example) V1.30 30-Oct-2009 core_cm3.h, 85,714 bytes2011-08-22 11:24 AM
Hi Clive,
Still looking for the source of the hacked up file. It may have come via someone (possibly from IAR) who was helping us get our project up on IAR EW Ver. 6.20 (versus 6.10). I know that the folder CoreSupport (below Libraries/CMSIS/CM3) had to be replaced, (this new version of the folder also contained a new folder called Intrinsics). I also searched through several example projects and found only the (assumed to be correct) first version.2011-08-22 12:43 PM
I found one bodged up file someone was using with an IAR project, so that it didn't pull in the ''intrinsics.h'' file.
Some other versions of 1.3 from Energy Micro which had the GCC in-line assembler lines modified