什麽是中断?
让CPU打断正常运行的程序,转而去处理紧急的事件(程序),就叫中断
中断执行机制,可简单概括为三步:
1,中断请求:外设产生中断请求(GPIO外部中断、定时器中断等);即中断标志置位。
2,响应中断:CPU停止执行当前程序,转而去执行中断处理程序(ISR);即中断处理。
3,退出中断:执行完毕,返回被打断的程序处,继续往下执行。即清除中断标志位。
中断优先级分组设置(以ARM为例)
ARM Cortex-M 使用了 8 位宽的寄存器来配置中断的优先等级,这个寄存器就是中断优先级配置寄存器。但STM32,只用了中断优先级配置寄存器的高4位 [7 : 4],所以STM32提供了最大16级的中断优先等级。
STM32 的中断优先级可以分为抢占优先级和子优先级:
抢占优先级: 抢占优先级高的中断可以打断正在执行但抢占优先级低的中断;
**子优先级:*当同时发生具有相同抢占优先级的两个中断时,子优先级数值小的优先执行。(有人也称为响应优先级,就是当两个中断抢占优先级数值相同时,对响应优先级进行比较,响应优先级数值越小,优先响应)
注意:中断优先级数值越小越优先。任务优先级数值越大越优先
一共有 5 种分配方式,对应着中断优先级分组的 5 个组
例如:通过调用函数HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4)即可完成设置
使用过STM的应该都知道这么配置。
特点:
1、低于configMAX_SYSCALL_INTERRUPT_PRIORITY优先级的中断里才允许调用FreeRTOS 的API函数
2、建议将所有优先级位指定为抢占优先级位,方便FreeRTOS管理(例如:(调用函数HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4)
)
3、中断优先级数值越小越优先,任务优先级数值越大越优先
FreeRTOS如何配置PendSV和Systick中断优先级?
所以:PendSV和SysTick设置最低优先级
设置最低:保证系统任务切换不会阻塞系统其他中断的响应
中断相关寄存器
三个中断屏蔽寄存器,分别为 PRIMASK、 FAULTMASK 和BASEPRI
FreeRTOS所使用的中断管理就是利用的BASEPRI这个寄存器
BASEPRI:屏蔽优先级低于某一个阈值的中断
BASEPRI:屏蔽优先级低于某一个阈值的中断,当设置为0时,则不关闭任何中断
例如:#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
static portFORCE_INLINE void vPortRaiseBASEPRI( void )
{
uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
__asm
{
msr basepri, ulNewBASEPRI
dsb
isb
}
}
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 / FreeRTOS可管理的最高中断优先级 */
中断优先级在5 ~ 15的全部被关闭
在中断服务函数中调度FreeRTOS的API函数需注意:
1、中断服务函数的优先级需在FreeRTOS所管理的范围内
2、在中断服务函数里边需调用FreeRTOS的API函数,必须使用带“FromISR”后缀的函数
BASEPRI:屏蔽优先级低于某一个阈值的中断,当设置为0时,则不关闭任何中断
开中断程序示例:
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI )
{
__asm
{
msr basepri, ulBASEPRI
}
}