本专栏将对FreeRTOS进行快速讲解,带你了解并使用FreeRTOS的各部分内容。适用于快速了解FreeRTOS并进行开发、突击面试、对新手小白非常友好。期待您的后续关注和订阅!
目录
系统中断管理
1 什么是中断?
1.1中断定义
中断是 CPU 的一种常见特性,通常由硬件触发。当中断发生时,CPU 会暂停当前的程序,转而执行与该中断相关的服务程序。ARM Cortex-M 内核的微控制器(MCU)配备了嵌套向量中断控制器(NVIC,Nested Vectored Interrupt Controller),专门用于高效管理中断。
简而言之,让CPU打断正常运行的程序,转而去处理紧急的事件(程序),就叫中断。
1.2 中断执行机制
中断执行可以规划为三步:
- 中断请求的生成:外部设备如GPIO或定时器等产生中断请求。
- 响应中断:CPU暂停当前程序的执行,转而执行中断处理程序(ISR)。
- 退出中断:中断处理程序执行完毕后,CPU返回到被中断的程序继续执行。
举例来说,当我们在写代码的时候,肚子突然饿了。但是代码没有写完,这个时候我们可以打个中断去吃饭,在我们吃完饭之后然后回来继续写代码。
2 中断优先级如何分组
2.1 优先级介绍
ARM Coetex-M 内核采用8位带宽基础来进行配置中段的优先等级,一共有8位来配置我们的抢占优先级和子优先级。
学过STM32的朋友想必都了解抢占优先级和子优先级,在STM32中,我们只采用中断优先级配置寄存器的高4位【7:4】,进行配置抢占优先级和子优先级可以进行分组。
- 抢占优先级:抢占优先级高的中断可以打断正在执行的抢占优先级低的中断。
- 子优先级:抢占优先级相同,响应优先级高的中断不能打断响应优先级低的中断,优先级数越小优先级越高。
2.2 优先级分组
优先级分组共计有四种方式,而我们用的FreeRTOS操作系统一般采用0~15为抢占优先级,没有子优先级。并且有一点我们写程序需要注意的是,在程序中你定义任务优先级给的数值越大优先级越高。优先级分组如下表所示,在使用FreeRTOS时一般采用NVIC_PRIORITYGROUP_4。
优先级分组 | 抢占优先级 | 子优先级 | 优先级配置寄存器高 4 位 |
NVIC_PriorityGroup_0 | 0 级抢占优先级 | 0-15 级子优先级 | 0bit 用于抢占优先级 |
NVIC_PriorityGroup_1 | 0-1 级抢占优先级 | 0-7 级子优先级 | 1bit 用于抢占优先级 |
NVIC_PriorityGroup_2 | 0-3 级抢占优先级 | 0-3 级子优先级 | 2bit 用于抢占优先级 |
NVIC_PriorityGroup_3 | 0-7 级抢占优先级 | 0-1 级子优先级 | 3bit 用于抢占优先级 |
NVIC_PriorityGroup_4 | 0-15 级抢占优先级 | 0 级子优先级 | 4bit 用于抢占优先级 |
有四点我们需要注意(非常重要):
- 低于configMAX_SYSCALL_INTERRUPT_PRIORITY优先级的中断里才允许调用FreeRTOS 的API函数,也就说管理的中断需要在FreeRTOS之内,超出0~15这个范围我们无法管理。
- 中断中调用FreeRTOS的API函数,必须使用代“FromISR”后缀的函数。
- 一般也建议将所有优先级位指定为抢占优先级位,更方便我们管理。
- 中断优先级数值越小越优先,任务优先级数值越大越优先(再强调一下)。
3 中断有关寄存器(了解一下)
三个中断屏蔽寄存器,分别为 PRIMASK、 FAULTMASK 和BASEPRI
寄存器名称 | 功能描述 |
PRIMASK | 这是一个只有1个位的寄存器。当它被置1时,会屏蔽所有可屏蔽的异常,只有NMI和硬fault可以响应。默认值为0,表示不屏蔽任何中断。 |
FAULTMASK | 这是一个只有1个位的寄存器。当它被置1时,只有NMI能够响应,所有其他异常(包括中断和fault)都会被屏蔽。默认值也是0,表示不屏蔽任何异常。 |
BASEPRI | 这个寄存器最多有9个位(具体位数由优先级表示的位数决定)。它定义了被屏蔽优先级的阈值。当设为某个值后,所有优先级号大于等于该值的中断都会被屏蔽(优先级号越大,优先级越低)。但如果设为0,则不屏蔽任何中断,0也是默认值。 |
我们采用的FreeRTOS使用的中断管理其实使用BASEPRI这个寄存器。
4 实例
举例代码如下,进行创建任务;
创建好任务函数之后,依靠任务回调函数将内容输出。
代码部分多写一写就会了。
void task1(void *pvParameters)
{
uint32_t task1_num = 0;
while (1)
{
if (++task1_num == 5)
{
printf("FreeRTOS关闭中断\r\n");
portDISABLE_INTERRUPTS(); /* FreeRTOS关闭中断 */
delay_ms(5000);
printf("FreeRTOS打开中断\r\n");
portENABLE_INTERRUPTS(); /* FreeRTOS打开中断 */
}
vTaskDelay(1000);
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
//编写内容
}
本专栏将对FreeRTOS进行快速讲解,带你了解并使用FreeRTOS的各部分内容。期待诸君的订阅和关注!
标签:抢占,FreeRTOS,中断,通篇,NVIC,寄存器,第六章,优先级 From: https://blog.csdn.net/weixin_49007164/article/details/140476218