当前位置: 首页 > news >正文

FreeRTOS——中断管理

中断理论剖析

中断简介

中断是一种机制,用于处理高优先级的事件或故障。当一个中断事件发生时,单片机可以立即中断正在执行的程序,转而处理中断事件。这种机制可以提高系统的响应速度和实时性。

中断优先级分组设置

ARM Cortex-M使用了8位宽的寄存器来配置中断的优先等级,这个寄存器就是中断优先级配置寄存器,也就是二的八次方,0~255的等级。但STM32,只用了中断优先级配置寄存器的高4位【7:4】,所以STM32提供了最大16级的中断有限等级

 STM32的中断优先级分为抢占优先级和子优先级

抢占优先级:抢占优先级高的中断可以打断正在执行但抢占优先级低的中断 

子优先级:当同时发生具有相同抢占优先级的两个中断时,子优先级数值小的优先执行

(中断优先级数值越小,优先级越高)

中断优先级分组设置

 一共有5中分配方式,对应着中断优先级分组的5个组

优先级分组抢占优先级子优先级优先级配置寄存器高4位
NVIC_PriorityGroup_00级抢占优先级0-15级子优先级

0bit用于抢占优先级

4bit用于子优先级

NVIC_PriorityGroup_10-1级抢占优先级0-7级子优先级

1bit用于抢占优先级

3bit用于子优先级

NVIC_PriorityGroup_20-3级抢占优先级0-3级子优先级

2bit用于抢占优先级

2bit用于子优先级

NVIC_PriorityGroup_30-7级抢占优先级0-1级子优先级

3bit用于抢占优先级

1bit用于子优先级

NVIC_PriorityGroup_40-15级抢占优先级0级子优先级

4bit用于抢占优先级

0bit用于子优先级

FreeRTOS为了方便管理,使用了NVIC_PriorityGroup_4,寄存器高4位都用于抢占优先级。

通过调用函数HAL_NVIC_SetPriorityGrouping(NVIC_PriorityGroup_4),即可完成设置优先级分组。

特点:

1、低于configMAX_SYSCALL_INTERRUPT_PRIORITY【5】优先级的中断里才允许调用FreeRTOS的API函数,也就是中断优先级需要在5~15之间才可以调用系统的API函数。

2、建议将所有的优先级指定为抢占优先级位,方便FreeRTOS管理

3、中断优先级数值越小越优先,任务优先级数值越大越优先

中断相关寄存器

三个系统中断优先级配置寄存器,分别是SHPR1、SHPR2、SHPR3

其中PendSV和SysTick的优先级是需要特别注意的,PendSV实现任务切换和任务调度等操作,SysTick提供系统节拍(心跳)

一个中断优先级配置寄存器由32位组成。

FreeRTOS如何配置PendSV和SysTick的中断优先级

所以PendSV和SysTick设置为最低中断优先级

设置最低:保证系统任务切换不会阻塞系统其他中断的响应

中断相关寄存器

三个中断屏蔽寄存器,分别是PRIMASK、FAULTMASK和BASEPRI 

FreeRTOS所使用的中断管理就是利用的BASEPRI这个寄存器

BASEPRI:屏蔽优先级低于某一阈值的中断

如:BASEPRI设置为0x50(只利用了中断优先级配置寄存器的高4位),代表中断优先级在5~15内的均被屏蔽,0~4的中断优先级正常运行。

关中断程序解析

在中断服务函数中调用FreeRTOS的API函数需注意:

1、中断服务函数的优先级需在FreeRTOS所管理的范围内

2、在中断服务函数里边需调用FreeRTOS的API函数,必须使用带“FromISR”后缀的函数

开中断程序解析

中断管理实验

实验通过使用两个定时器,一个优先级为4,一个优先级为6,注意:系统所管理的优先级范围:5~15

现象:两个定时器每1s,打印一段字符串,优先级为6的中断当关中断时,停止打印,开中断时持续打印。

中断服务函数: 

//定时器3中断服务函数
void TIM3_IRQHandler(void)
{if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断{printf("TIM3输出.......\r\n");}TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
}//定时器5中断服务函数
void TIM5_IRQHandler(void)
{if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET) //溢出中断{printf("TIM5输出.......\r\n");}TIM_ClearITPendingBit(TIM5,TIM_IT_Update);  //清除中断标志位

创建start任务,在start任务中创建task1任务,创建完之后start任务自杀。 

 

为什么if语句里面用delay_ms不用vTaskDelay()?
这是由于我们的vTaskDelay()里面的一些函数使用了退出临界区函数,而退出临界区也有调用portENABLE——INTERRUPTS(),跳转如下:

 

 

 


http://www.mrgr.cn/news/51928.html

相关文章:

  • 15分钟学Go 第3天:编写第一个Go程序
  • 常见网络钓鱼类型
  • 多模块存储器相比单模块有哪些显著优势
  • 【学术前沿】PATHWAYS:谷歌大规模异构计算编排调度系统(Jeff Dean 和 Sanjay Ghemawat联合出品)
  • MacOS虚拟机安装Windows停滞在“让我们为你连接到网络”,如何解决?
  • IDEA中文乱码�
  • 轻松备考!这款 AI 工具助你高效复习 AP、IB 和 A-Leve
  • Nature子刊排名
  • iOS GCD的基本使用
  • FreeMarker模板引擎入门:从基础到实践的全面指南
  • CesiumJS 案例 P4:创建三角形、创建多边形、创建折线、创建盒子、创建圆柱
  • 【SAM模型应用于遥感影像|论文解读3】突破边界与一致性:SAM模型革新遥感影像语义分割
  • React状态管理工具zustand
  • Android开发跳去应用市场评分功能
  • 2025选题推荐|基于SpringBoot的幼儿园智能管理与监控系统的设计与实现
  • HarmonyOS 开发知识总结
  • 深入解析:Pandas DataFrame 的强大之处与实战应用
  • GEE教程:MODIS/006/MOD17A3HGF数据中NPP的下载
  • Tauri(读音:踹你)开发简介:1.创建和运行第一个app
  • 什么是异质结