这个是全网最详细的STM32项目教学视频。
第一篇在这里:
视频在这里
V3:HAL库开发、手把手教学下面功能:PID速度控制、PID循迹、PID跟随、遥控、避障、PID角度控制、openmv视觉控制、电磁循迹、FreeRTOS、K210视觉智能车(更新中)、K230视觉智能车(更新中)、MSPM0G3507视觉智能车(更新中)
22.4.2-中断优先级相关
中断优先级说明(掌握)
给出中断相关优先级说明、中断在freeRTOS的注意事项。
中断是MCU的硬件特性,STM32 MCU的NVIC管理硬件中断。STM32F103使用4位设置优先级分组策略,用于设置中断的抢占优先级和次优先级,优先级数字越小,优先级越高。每个中断有一个中断服务例程,即ISR,用于对中断做出响应。
FreeRTOS的运行用到中断,FreeRTOS的上下文切换就是在PenSV中断中进行的,FreeRTOS还需要一个基础时钟产生嘀嗒信号。在CubeMX中启用FreeRTOS后,系统会对NVIC做一些设置,例如。启用FreeRTOS后,中断优先级分组策略自动设置为4位全部用于抢占优先级,所以抢占优先级编号是0到15。
这个就是加入FreeRTOS自动设置的
还有两个参数非常重要,FreeRTOS并不是可以管理MCU的所有中断,可以设置FreeRTOS可以管理那些优先级的中断。
configLIBRARY_LOWEST_INTERRUPT_PRIORITY: ,表示中断的最低优先级数值,因为中断分组策略是4位全部用抢占优先级,所以这个数值是15。
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY :表示FreeRTOS可管理的最高优先级(freeRTOS中,中断里面使用的FreeRTOS函数和任务中使用的FreeRTOS函数是不一样的,这个我们后面会讲到),默认是5。也就是说中断优先级数等于或者大于5的中断ISR里,才可以调用FreeRTOS的中断安全API函数,也就是待用"FromISR"后缀的函数,使用taskDISABLE_INTERRUPTS()函数也只能屏蔽优先级数值等于或者大于5的中断。所以也不能在优先级高于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY的中断ISR里面调用FreeRTOS的API函数,即便是带"FromISR"的中断安全函数也是不可以的。
中断中要使用FreeRTOS的中断级 API函数(理解)
在中断的ISR中断服务函数里,有时会需要调用FreeROTS的API函数,但是调用普通的API函数可能会存在问题。列如,在ISR中断服务函数里调用osDelay就会出现问题,因为osDelay会使任务进入阻塞状态,而ISR中断服务函数根本就不是任务,ISR中断服务函数运行的时候,也不能进行任务调度。
所以FreeRTOS的API函数分为两个版本,一个称为"任务级" 即普通名称的API函数,另一个是"中断级"带有"FromISR"的函数或带有"FROM_ISR"的宏函数。
比如我们后面在按键中断中释放和消耗二值信号量就使用"FromISR"结尾的 中断释放信号量函数xSemaphoreGiveFromISR
下面总结一下为什么中断中要使用中断级API函数:
- 中断上下文与任务上下文不同,ISR 中的代码不能做任务调度和阻塞等操作。
- 使用中断级 API 函数可以确保中断中的操作是安全的,避免阻塞、调度或其他不安全的行为。
中断及其ISR的设计原则(重点)
根据FreeRTOS管理中断的特点,中断的优先级和ISR中断服务函数程序设计应该遵循如下原则。
- ISR的代码应该尽量简短,应该将比较耗时的处理功能转移到任务函数里实现.
- 在可屏蔽中断的ISR里,能调用中断级的FreeRTOS API函数,绝对不能调用普通的FreeRTOS API函数。在不可屏蔽中断的ISR里,不能调用任何的FreeRTOS API函数
-
中断优先级和任务优先级区别
- MCU的中断有中断优先级,有中断服务例程(ISR); FreeRTOS的任务有任务优先级,有任务函数。这两者的特点和区别具体如下。中断是MCU的硬件特性,由硬件事件或软件信号引起中断,运行哪个ISR是由硬件决定的。中断的优先级数字越小,表示优先级越高,所以中断的最高优先级为0。
- FreeRTOS 的任务是一个纯软件的概念,与硬件系统无关。任务的优先级是开发者在软件中赋予的,任务的优先级数字越低,表示优先级越低,所以任务的最低优先级为0。FreeRTOS 的任务调度器决定哪个任务处于运行状态,FreeRTOS 在中断优先级为 15 的PendSV中断里进行上下文切换,所以,只要有中断ISR在运行, FreeRTOS就无法进行任务切换。
- 任务只有在没有ISR运行的时候才能运行,即使优先级最低的中断,也可以抢占高优先级的任务的执行,而任务不能抢占 ISR 的运行。
在实际的软件设计中,一般要尽量简化ISR的功能,使其尽量少占用CPU的时间。一般的硬件中断都是处理一些数据的接收或发送工作,例如,采用中断方式进行ADC数据采集时,只需在 ADC 的中断里将数据读取到缓冲区,而对数据进行滤波、频谱计算等耗时间的工作,就转移到任务函数里处理。