0 修改方法
使用STM32CubeMX生成stm32MP135代码的中断优先级配置错误,将导致所有中断优先级设置不对。
如果设置EXTI0中断优先级为10,在STM32CubeMX中配置如下:
生成的中断优先级配置代码为:
正确写法应该将中断优先级左移3位:
1 错误原因分析
1.1 IRQ初始化配置
stm32MP135启动后首先会调用IRQ_Initialize()函数初始化IRQ,相关代码过多。这里列出几个关键操作:
(1)设置中断优先级位数为5位
/** \brief Set the interrupt priority mask using CPU's PMR register.
* \param [in] priority Priority mask to be set.
*/
__STATIC_INLINE void GIC_SetInterfacePriorityMask(uint32_t priority)
{GICInterface->PMR = priority & 0xFFUL; //set priority mask
}
GIC_SetInterfacePriorityMask(0xFFU);
对应寄存器描述如下:
也就是使用5位作为中断优先级。
(2)设置抢占优先级位数为5位
GIC_SetBinaryPoint(0U);
/** \brief Configures the group priority and subpriority split point using CPU's BPR register.
* \param [in] binary_point Amount of bits used as subpriority.
*/
__STATIC_INLINE void GIC_SetBinaryPoint(uint32_t binary_point)
{GICInterface->BPR = binary_point & 7U; //set binary point
}
对应寄存器描述如下:
也就是5位全部作为抢占优先级。
1.2 IRQ优先级配置
/** \brief Set the priority for the given interrupt in the GIC's IPRIORITYR register.
* \param [in] IRQn The interrupt to be configured.
* \param [in] priority The priority for the interrupt, lower values denote higher priorities.
*/
__STATIC_INLINE void GIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{uint32_t mask = GICDistributor->IPRIORITYR[IRQn / 4U] & ~(0xFFUL << ((IRQn % 4U) * 8U));GICDistributor->IPRIORITYR[IRQn / 4U] = mask | ((priority & 0xFFUL) << ((IRQn % 4U) * 8U));
}
相关寄存器描述如下:
可以看到中断优先级寄存器只有高5bit有效,因此使用GIC_SetPriority函数设置中断优先级应该左移3位。