FreeRTOS中断配置宏

前言

中断是我们学习嵌入式开发比较重要的一节知识,本篇文章是记录我学习FreeRTOS过程中,有关中断宏的配置的学习,希望我的分享能给你带来不一样的收获。

目录

前言

一 、FreeRTOS中断配置的宏

1、configPRIO_BITS

2、 configLIBRARY_LOWEST_INTERRUPT_PRIORITY

3、configKERNEL_INTERRUPT_PRIORITY

4、configLIBRARY_MAX_sYSCALL_INTERRUPT_PRIORITY

5、 configMAx_SYSCALL_INTERRUPT_PRIORITY

二、FreeRTOS开关中断 

 三、结语


一 、FreeRTOS中断配置的宏

1、configPRIO_BITS

此宏用来设置MCU使用几位优先级,STM32使用的是4位,因此此宏为4!

2、 configLIBRARY_LOWEST_INTERRUPT_PRIORITY

此宏是用来设置最低优先级,前面说了,STM32优先级使用了4位,而且STM32配置的使用组4,也就是4位都是抢占优先级。因此优先级数就是16个,最低优先级那就是15。所以此宏就是15,注意!不同的MCU此值不同,具体是多少要看所使用的MCU的架构,这里只针对STM32!

3、configKERNEL_INTERRUPT_PRIORITY

此宏用来设置内核中断优先级,此宏定义如下:

宏 configKERNEL_INTERRUPT_PRIORITY 为宏configLIBRARY_LOWEST_INTERRUPT_PRIORITY 左移8-configPRIO_BITS位,也就是左移4位。可是——

为什么要左移4位呢?

前面已经说过,STM32使用了4位作为优先级,而这4位是高4位,因此要左移4位才是真正的优先级。当然也可以不用移位,可以直接将宏 configKERNEL_INTERRUPT_PRIORITY 定义为0XF0。不过这样看起来不太直观。

宏configKERNEL_INTERRUPT_PRIORITY用来设置PendSV和滴答定时器的中断优先级,port.c中有如下定义:

可以看出,portNVIC_PENDSV_PRI 和portNVIC_SYSTICK_PRI都是使用了宏configKERNEL_INTERRUPT_PRIORITY ,为什么宏portNVIC_PENDSv_PRI是宏configKERNEL_INTERRUPT_PRIORITY 左移16位呢?宏portNVIC_SYSTICK_PRI也同样是左移24位。

PendSV和SysTcik的中断优先级设置是操作OxE000_ED20地址的,这样一次写入的是个32位的数据,SysTick 和 PendSV的优先级寄存器分别对应这个32位数据的最高8位和次高8位,不就是一个左移16位,一个左移24位了。


PendSV和SysTick优先级是在哪里设置的呢?在函数xPortStartScheduler()中设置,此函数在文件 port.c中,函数如下:
FreeRTOS中断配置宏_第1张图片

FreeRTOS中断配置宏_第2张图片

上述代码中红色部分就是设置PendSV 和SysTick优先级的,它们是直接向地址portNVIC_SYSPRI2_REG写入优先级数据,portNVIC_SYSPRI2_REG是个宏,在文件 port.c 中由定义,如下:

可以看到宏portNVIC_SYSPRI2_REG就是地址0XEO00ED20!同时也可以看出在FreeRTOS中PendSV和 SysTick 的中断优先级都是最低的!

这里插入一点小知识:什么是FreeRTOS的PendSV? 因为我也忘记了,所以在此温故一下!

PendSV是一种嵌入式系统中的中断服务例程,全称为Pending Supervisor Call Interrupt。它是FreeRTOS实现上下文切换的关键之一。

在FreeRTOS中,任务调度是由内核处理器级别的软件定时器触发的。当内核检测到需要切换任务时,它会通过PendSV中断来触发上下文切换。PendSV中断是一种特殊类型的中断,它具有最低的优先级,在所有其他中断服务例程完成后才会被执行。因此,PendSV中断能够确保在任务上下文切换期间不会被其他中断打断。

当PendSV中断被触发时,它会调用FreeRTOS的上下文切换函数,该函数会将当前任务的上下文保存到栈中,并将下一个任务的上下文从其栈中恢复。这个过程被称为任务上下文切换。

总结而言,PendSV是FreeRTOS系统中用于任务上下文切换的一种机制,它能够保证在任务上下文切换期间不会被其他中断打断。 

4、configLIBRARY_MAX_sYSCALL_INTERRUPT_PRIORITY

此宏用来设置FreeRTOS系统可管理的最大优先级,也就是BASEPRI寄存器的那个阈值优先级,这个大家可以自由设置,这里我设置为了5。也就是高于5的优先级(优先级数小于5)不归FreeRTOS管理!

5、 configMAx_SYSCALL_INTERRUPT_PRIORITY

此宏是configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY左移4位而来的,原因和宏configKERNEL_INTERRUPT_PRIORITY一样。此宏设置好以后,低于此优先级的中断可以安全的调用FrecRTOS的API函数,高于此优先级的中断 FreeRTOS是不能禁止的,中断服务函数也不能调用FreeRTOS的API函数!
 

这里我以STM32为例,有16个优先级,0为最高优先级,15为最低优先级,配置如下:

FreeRTOS中断配置宏_第3张图片

由于高于configMAX_SYSCALL_INTERRUPT_PRIORITY的优先级不会被FreeRTOS内核屏蔽,因此那些对实时性要求严格的任务就可以使用这些优先级,比如四轴飞行器中的壁障检测。

二、FreeRTOS开关中断 

FreeRTOS开关中断函数为portENABLE_INTERRUPTS()和portDISABLE_INTERRUPTS(),这两个函数其实是宏定义,在portmacro.h 中有定义,如下:

可以看出开关中断实际上是通过函数 vPortSetBASEPRI(O)和vPortRaiseBASEPRI()来实现的,这两个函数如下:
FreeRTOS中断配置宏_第4张图片

FreeRTOS中断配置宏_第5张图片

函数vPortSetBASEPRI()是向寄存器BASEPRI写入一个值,此值作为参数ulBASEPRI传递进来,portENABLE_INTERRUPTS()是开中断,它传递了个0给vPortSetBASEPRI(),根据前面说的BASEPRI寄存器可知,结果就是开中断。
 

函数vPortSetBASEPRI()是向寄存器BASEPRI 写入宏configMAX_SYSCALL_INTERRUPT_PRIORITY ,那么优先级低于configMAX_sYSCALL_INTERRUPT_PRIORITY的中断就会被屏蔽!

 三、结语

以上就是我在学习FreeRTOS中有关“FreeRTOS中断配置宏”的学习记录。最后希望我的分享对你有所帮助!

FreeRTOS中断配置宏_第6张图片

你可能感兴趣的:(FreeRTOS实时操作系统,单片机,嵌入式硬件,FreeRTOS)