FreeRTOS学习笔记(四)Freertos的中断管理及临界保护

news2024/9/20 14:51:49

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、Cortex-M 中断管理
    • 1.1 中断优先级分组
    • 1.2 相关寄存器
    • 1.3 相关宏定义
    • 1.4 FreeRTOS 开关中断
  • 二、临界段及其保护
    • 2.1 taskENTER_CRITICAL( ) 和 taskEXIT_CRITICAL( )
    • 2.2 taskENTER_CRITICAL_FROM_ISR( ) 和 taskEXIT_CRITICAL_FROM_ISR( )
    • 2.3 任务调度器的挂起及恢复


前言

  本章主要是讲述Freertos的中断管理及临界保护,具体的基础知识不再赘述,可以移步观看裸机开发部分。


一、Cortex-M 中断管理

1.1 中断优先级分组

  Cortex-M利用8位宽的寄存器来处理优先级,但stm32实际上只使用了高四位[7:4],即16级中断优先级。stm32的中断优先级可以分为抢占优先级(高优先级抢占低优先级)和子优先级(数值小先执行)。
中断分组
  由于FreeRTOS 的中断配置没有处理子优先级这种情况,所以只能配置为组 4,即 NVIC_PriorityGroup_4 。此时4 位优先级就都全是抢占优先级了,没有子优先级,那么就有 0~15 共 16 个优先级。

1.2 相关寄存器

  PendSV 和 SysTick 寄存器主要用于中断服务,并且在 FreeRTOS 中扮演了重要的角色,尤其是在任务切换和系统计时方面。这里首先介绍设置PendSV(PRI_14)和SysTick(PRI_15)优先级的两个寄存器。
在这里插入图片描述
  如上图所示,4 个相临的寄存器可以拼成一个32位的寄存器(SHPR1~ SHPR3),因而FreeRTOS 在设置 PendSV 和 SysTick 的中断优先级的时候都是直接操作的地址 0xE000_ED20 + offset。为了保证任务切换不会阻碍其他任务,在 FreeRTOS中 PendSV 和 SysTick 的中断优先级都是最低的!
  接着这里再讲述三个中断屏蔽寄存器。值得注意的是FreeRTOS 的开关中断就是操作 BASEPRI 寄存器来实现的,它可以关闭低于某个阈值的中断,高于这个阈值的中断就不会被关闭。

寄存器描述
PRIMASK禁止除 NMI 和 HardFalut 外的所有异常和中断,置1视为开启
FAULTMASK禁止除 NM 外的所有异常和中断,置1视为开启
BASEPRI最大9bit,只屏蔽优先级低于设置阈值的中断

1.3 相关宏定义

描述
configPRIO_BITS设置 MCU 使用几位优先级
configLIBRARY_LOWEST_INTERRUPT_PRIORITY设置最低优先级
configKERNEL_INTERRUPT_PRIORITY设置内核中断优先级
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY设置 FreeRTOS 系统可管理的最大优先级
configMAX_SYSCALL_INTERRUPT_PRIORITY低于此优先级的中断可以调用 FreeRTOS 的 API 函数,反之则禁止

1.4 FreeRTOS 开关中断

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

#define portDISABLE_INTERRUPTS( ) vPortRaiseBASEPRI()
#define portENABLE_INTERRUPTS( )  vPortSetBASEPRI(0)

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

二、临界段及其保护

  临界段代码也叫做临界区,是指那些必须完整运行,不能被打断的代码段,比如有的外设的初始化需要严格的时序,初始化过程中不能被打断。
  FreeRTOS 在进入临界段代码的时候需要关闭中断,当处理完临界段代码以后再打开中断。FreeRTOS 系统本身就有很多的临界段代码,这些代码都加了临界段代码保护,我们在写自己的用户程序的时候有些地方也需要添加临界段代码保护。

2.1 taskENTER_CRITICAL( ) 和 taskEXIT_CRITICAL( )

  这两个函数用于进入和退出临界区,在任务上下文中使用。它们通过禁用中断来保护临界区中的代码,确保该代码段在执行期间不会被打断。

  • taskENTER_CRITICAL( ):调用此函数后,所有中断都会被禁用,任务调度也会被禁止,这样可以确保当前任务在执行关键代码时不会被其他任务抢占或中断。
  • taskEXIT_CRITICAL( ):退出临界区时调用该函数,恢复中断和任务调度。必须确保在进入临界区后总是退出,以防止系统卡死或影响其他任务。
// 示例
void start_task(void *pvParameters)
{
	taskENTER_CRITICAL();  // 禁用中断,进入临界区
	...				   // 关键代码
	taskEXIT_CRITICAL();   // 重新启用中断,退出临界区
}

2.2 taskENTER_CRITICAL_FROM_ISR( ) 和 taskEXIT_CRITICAL_FROM_ISR( )

  这两个函数是在中断服务程序(ISR)中使用的版本,与任务上下文中的函数不同,这些函数可以确保临界区在中断中安全运行。除此之外,这个中断的优先级一定要低于前面提到的configMAX_SYSCALL_INTERRUPT_PRIORITY。

  • taskENTER_CRITICAL_FROM_ISR( ):与 taskENTER_CRITICAL() 类似,它也会禁用中断,但是该函数会返回一个变量,指示中断的先前状态,以便在退出临界区时恢复到正确的状态。
  • taskEXIT_CRITICAL_FROM_ISR( ):退出临界区时使用,需要传入先前的中断状态来恢复中断。
// 示例
UBaseType_t uxSavedInterruptStatus;	// FreeRTOS 中用于保存中断状态的变量
uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();// 保存中断状态并进入临界区
	...											   // ISR 中的关键代码
taskEXIT_CRITICAL_FROM_ISR(uxSavedInterruptStatus);// 退出临界区并恢复中断状态

2.3 任务调度器的挂起及恢复

  任务调度器的挂起和恢复常用于需要确保一段代码在不被其他任务打断的情况下执行,比如同时修改多个任务的优先级或共享资源。值得注意的是,调度器的挂起和恢复会影响整个系统,不管有多少任务,它都会停止任务的切换行为,而我们前面提到的任务挂起和恢复仅影响指定的任务。
  此外,与临界区不同的是任务调度器的挂起不会影响中断,它仅仅是防止任务之间相互抢占资源。适用于临界区位于任务和任务之间,可以做到既不采用延时,也可以保护临界段。

函数描述
vTaskSuspendAll( )暂停整个任务调度器的运行
xTaskResumeAll( )恢复任务调度器,重新允许任务切换

免责声明:本文参考了网上公开资料,仅用于学习交流,若有错误或侵权请联系笔者。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2115133.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。…

828华为云征文|部署RedisStack+可视化操作

目录 1.介绍 1.1 什么是华为云Flexus X实例 1.2 什么是Redis Stack ​编辑 2 准备华为云Flexus应用服务器L实例 3 准备docker环境 4 docker 安装 Redis Stack 4.1拉取镜像 4.2 确认镜像 4.3 启动容器 4.4 放行安全组端口 4.5 操作redis 5 docker compose 配置持久 1.…

Vision Transformer(ViT)模型原理及PyTorch逐行实现

Vision Transformer(ViT)模型原理及PyTorch逐行实现 一、TRM模型结构 1.Encoder Position Embedding 注入位置信息Multi-head Self-attention 对各个位置的embedding融合(空间融合)LayerNorm & ResidualFeedforward Neural Network 对每个位置上单…

LabVIEW FIFO详解

在LabVIEW的FPGA开发中,FIFO(先入先出队列)是常用的数据传输机制。通过配置FIFO的属性,工程师可以在FPGA和主机之间,或不同FPGA VIs之间进行高效的数据传输。根据具体需求,FIFO有多种类型与实现方式&#x…

SpringSecurity原理解析(二):认证流程

1、SpringSecurity认证流程包含哪几个子流程? 1)账号验证 2)密码验证 3)记住我—>Cookie记录 4)登录成功—>页面跳转 2、UsernamePasswordAuthenticationFilter 在SpringSecurity中处理认证逻辑是在UsernamePas…

iOS——线程安全、线程同步与线程通信

线程安全和线程同步 线程安全:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。 若每个…

18055 主对角线上的元素之和

### 思路 1. 输入一个3行4列的整数矩阵。 2. 计算主对角线上的元素之和。 3. 输出主对角线上的元素之和。 ### 伪代码 1. 初始化一个3行4列的矩阵 matrix。 2. 输入矩阵的元素。 3. 初始化一个变量 sum 为0,用于存储主对角线元素之和。 4. 遍历矩阵的行&#xff0c…

【Day08-IO-文件字节流】

File 1. 概述 File对象既可以代表文件、也可以代表文件夹。它封装的对象仅仅是一个路径名,这个路径可以存在,也可以不存在 构造器 说明 public File​(String pathname) 根据文件路径创建文件对象 public File​(String parent, String child) 根据…

vscode中使用go环境配置细节

1、在docker容器中下载了go的sdk 2、在/etc/profile.d/go.sh里填入如下内容: #!/bin/bashexport GOROOT=/home/ud_dev/go export PATH=$GOROOT/bin:$PATH 3、设置go env go env -w GOPROXY=https://goproxy.cn,direct go env -w GO111MODULE=on 4、重启这个容器,使得vscod…

DBAPI如何使用内存缓存

背景 在使用DBAPI创建API的时候,有时候SQL查询比较耗时,如果业务上对数据时效性要求不高,这种耗时的SQL可以使用缓存插件来将数据缓存起来,避免重复查询。 一般来说,可以使用redis memcache等缓存服务来存储缓存数据。…

活动|华院计算宣晓华受邀出席“AI引领新工业革命”大会,探讨全球科技的最新趋势

8月31日,“AI引领新工业革命”大会于上海图书馆圆满落幕。本次大会由TAA校联会和台协科创工委会联合主办,得到上海市台办、上海市台联、康师傅的大力支持。大会邀请了NVIDIA全球副总裁、亚太区企业营销负责人刘念宁,元禾厚望资本创始合伙人潘…

ispunct函数讲解 <ctype.h>头文件函数

目录 1.头文件函数 2.ispunct函数使用 小心&#xff01;VS2022不可直接接触&#xff0c;否则..!没有这个必要&#xff0c;方源一把抓住VS2022&#xff0c;顷刻 炼化&#xff01; 1.头文件函数 以上函数都需要包括头文件<ctype.h> &#xff0c;其中包括 ispunct 函数 #…

esp8266+sg90实现远程开关灯(接线问题)

1需要准备的设备 首先需要的设备 硬件&#xff1a;esp8266开发板和sg90舵机&#xff0c;还有公对母的杜邦线&#xff0c;以及一根usb程序下载线。 软件&#xff1a;Arduino IDE 因为sg90舵机接口是三个连着的&#xff0c;只能用公对母的杜邦线把三条信号线接到esp8266的不同引…

Linux驱动.之字符设备驱动框架,新内核框架,设备树(二)

第一篇比较长&#xff0c;第二篇&#xff0c;继续写&#xff0c;内容有重复 一、字符设备驱动框架 在用户空间中调用open&#xff0c;打开一个字符设备&#xff0c;执行流程如下&#xff1a;最终会执行chrdev中的ops对应的open函数。

【python计算机视觉编程——8.图像内容分类】

python计算机视觉编程——8.图像内容分类 8.图像内容分类8.1 K邻近分类法&#xff08;KNN&#xff09;8.1.1 一个简单的二维示例8.1.2 用稠密SIFT作为图像特征8.1.3 图像分类:手势识别 8.2贝叶斯分类器用PCA降维 8.3 支持向量机8.3.2 再论手势识别 8.4 光学字符识别8.4.2 选取特…

面试官:你是怎么处理vue项目中的错误的?

一、错误类型 任何一个框架&#xff0c;对于错误的处理都是一种必备的能力 在Vue 中&#xff0c;则是定义了一套对应的错误处理规则给到使用者&#xff0c;且在源代码级别&#xff0c;对部分必要的过程做了一定的错误处理。 主要的错误来源包括&#xff1a; 后端接口错误代…

网络原理之TCP协议(万字详解!!!)

目录 前言 TCP协议段格式 TCP协议相关特性 1.确认应答 2.超时重传 3.连接管理&#xff08;三次握手、四次挥手&#xff09; 三次握手&#xff08;建立TCP连接&#xff09; 四次挥手&#xff08;断开连接&#xff09; 4.滑动窗口 5.流量控制 6.拥塞控制 7.延迟应答…

(入门篇)JavaScript 网页设计案例浅析-简单的交互式图片轮播

网页设计已经成为了每个前端开发者的必备技能,而 JavaScript 作为前端三大基础之一,更是为网页赋予了互动性和动态效果。本篇文章将通过一个简单的 JavaScript 案例,带你了解网页设计中的一些常见技巧和技术原理。今天就说一说一个常见的图片轮播效果。相信大家在各类电商网…

使用vscode上传git远程仓库流程(Gitee)

目录 参考附件 git远程仓库上传流程 1&#xff0c;先将文件夹用VScode打开 2&#xff0c;第一次进入要初始化一下仓库 3&#xff0c;通过这个&#xff08;.gitignore&#xff09;可以把一些不重要的文件不显示 注&#xff1a;&#xff08;.gitignore中&#xff09;可屏蔽…

AI辅助编程里的 Atom Group 的概念和使用

背景 在我们实际的开发当中&#xff0c;一个需求往往会涉及到多个文件修改&#xff0c;而需求也往往有相似性。 举个例子&#xff0c;我经常需要在 auto-coder中需要添加命令行参数&#xff0c;通常是这样的&#xff1a; /coding 添加一个新的命令行参数 --chat_model 默认值为…