STM32与FreeRTOS的中断管理实现详解
中断管理:
一、优先级设置
ARM Cortex-M使用8位寄存器来配置中断优先级,这8位寄存器就是中断优先级配置寄存器。
而ST32只使用了其中的高 4 位(7:4),即最高可提供2^4=16个可编程的中断优先等级。
图片来源:正点原子FreeRTOS教程
中断优先级又分为抢占优先级和子优先级(又称响应优先级)。(默认读者学会裸机编程后才学操作系统,故此不再赘述优先级知识)
图片来源:CSDN@W.I.Li
在FreeRTOS中这四位应该如何分别配呢?
建议全部分配为抢占优先级,设置分组4!!!即不分配子优先级,以便FreeRTOS管理。
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
需要注意!!!
1、中断优先级与任务优先级不同两套系统:中断优先级数字越小优先级越高,任务优先级数字越大,优先级越高。
2、FreeRTOS使用Systick定时器作为心跳时钟,是调度器的核心。中断优先级和任务优先级没有任何关系,不管中断优先级是多少,中断的优先级永远高于任何线程任务的优先级。
3、任务优先级主要是在PendSV中断中实现的,而中断优先级主要依靠于SysTick的优先级。
4、在FreeRTOS中断是硬件级别的事件处理机制,!!!中断可以打断任意的任务,而任务不能打断中断!!!这是因为中断可能涉及到紧急的事件处理。例如读取串口接收到的数据,防止数据丢失,所以一般都把SysTick优先级设置为最低。
二、中断相关重要的寄存器
中断屏蔽寄存器
图片来源:《Cortex-M3权威指南(中文).pdf》第八章 【直接浏览器搜索可下载全文档】
PRIMASK:
在FreeRTOS中主要用于临界区的保护,通过禁用全局中断来防止任务间的干扰。临界区是指在多任务环境中,需要保护的代码段,以防止多个任务同时访问共享资源。FreeRTOS提供了宏定义来操作PRIMASK寄存器,例如portENTER_CRITICAL()和portEXIT_CRITICAL(),这些宏通常会通过设置PRIMASK寄存器来禁用中断,从而保护临界区。
FAULTMASK:
在FreeRTOS中用于极端情况下的中断屏蔽,它比PRIMASK寄存器更严格,能够屏蔽包括HardFault在内的所有异常和中断。在使用时需要谨慎,以避免影响系统的正常运行。
BASEPRI:
用于设置一个中断屏蔽的阈值。当BASEPRI寄存器被设置为某个值时,所有优先级低于该值的中断都会被屏蔽。这使得FreeRTOS可以灵活地控制中断的响应顺序,确保高优先级的任务和中断能够优先处理。
例如:对BASEPRI赋值为0x60时,6~15优先级的中断不被启用,而0~5的中断不受影响。
需要注意!!!
1、在FreeRTOS中,BASEPRI能够允许操作的范围为5~15中断优先级,而0~4不被允许操作
2、在对BASEPRI寄存器操作时,需要了解到中断优先级配置寄存器的低四位不可用。即对寄存器写值时,需要将所需要屏蔽的值左移4位后赋值给寄存器。在代码中就如下方式设置便于阅读:
//设置FreeRTOS可管理中断优先级
//左移四位因寄存器低四位不可用
#define configMAX_SYSCALL_INTERRUPT_PRIORITY (0x05<<4)
该宏在“FreeRTOSConfig.h”中可以找到。
BASEPRI赋值为0x50时:
图片来源:正点原子FreeRTOS教程
在中断中调用FreeRTOS的API函数需要注意!!!
在FreeRTOS所管理的中断服务函数(5~15)中调用FreeRTOS的API函数时,必须使用带有”FromISR”后缀的函数。
在优先级为0~4的中断中,无法使用FreeRTOS的API函数。
其他补充:
我们在《Cortex-M3权威指南(中文).PDF》的第表8.3B可以了解道PendSV与SysTick优先级地址。
在32位系统中,PRI_14与PRI_15位于SHPR3的高位位置
图片来源:《Cortex-M3权威指南(中文).pdf》
作者:推推发际线