STM32中由NVIC高四位[7:4]来配置,最多可以表示16个中断优先级,分抢占优先级(在中断嵌套时高可以抢低的)和响应优先级,分0~4组,组0表示没有抢占优先级而响应优先级占4位,则由0~15个响应优先级,组1~4同理,普遍情况下都是全部用抢占优先级
FreeRTOS的任务调度优先级相反,是数值越大越优先。其将PendSV和SysTick设置为最低中断优先级(15),保证任务切换不会阻断其他中断响应。
FreeRTOS利用BASEPRI寄存器(属于STM32)实现中断管理,可以屏蔽优先级低于某一个阈值的中断(比如BASEPRI设置0x50,由于只看高4位,所以屏蔽的优先级位5~15(被FreeRTOS控制),而0~4正常运行;即5~15的中断被FreeRTOS管理(可以执行屏蔽/不屏蔽)起来,它们可以调用FreeRTOS的xxxFromISR函数,而0~4不可以)
FreeRTOS的开关中断(在portmacro.h中找到)
宏定义 vPortRaiseBASEPRI(),该函数开启我们设定好的中断屏蔽
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
宏定义 vPortSetBASEPRI( 0 ),该函数传入0,关闭我们设定好的中断屏蔽
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
FreeRTOS的临界区代码:只能管理BASEPRI设置的数~15这个范围的中断
临阶段代码,又称为临界区,可以避免外界的打断。适用场景:初始化外设时要求严格的时序,因此不允许被打断,就要禁用中断,所以所有的临界区代码都是通过屏蔽/开启FreeRTOS管理范围内的中断实现的,因此非管理范围内的中断还是会打断任务,比如上面例子中的0~4优先级的任务
- taskENTER_CRITICAL() :进入临界段。(其实是屏蔽中断)
- taskEXIT_CRITICAL() :退出临界段。(其实是开启中断)
- taskENTER_CRITICAL_FROM_ISR() :进入临界段(中断级)。
- taskEXIT_CRITICAL_FROM_ISR():退出临界段(中断级)。
全局变量uxCriticalNesting如果执行进入+1,执行退出-1,当uxCriticalNesting=0时才能开启中断,为了保证进入和退出是成对适用的,避免混乱
挂起和恢复调度器,该函数不需要关闭中断,调度器只是禁止/开启任务切换
挂起调度器的方法适用于临界区位于任务与任务之间的情况;这样既不需要延迟中断,同时又能确保临界区的安全性。
具体内容可以看移植到STM32中FreeRTOS的业务创建与删除,挂起与恢复_vtaskdelete 后如何恢复-CSDN博客
后期持续更新