嵌入式学习笔记-freeRTOS taskENTER_CRITICAL(_FROM_ISR)跟taskEXIT_CRITICAL(_FROM_ISR)函数解析
一 函数taskENTER_CRITICAL,taskEXIT_CRITICAL
函数taskENTER_CRITICAL最终实现如下:
第①处按照系统设定的configMAX_SYSCALL_INTERRUPT_PRIORITY值对中断进行屏蔽
第②处调用一次自增一次
第③处检查中断状态寄存器位,如果有任何中断位置1,说明是在中断中,那么报错,因为此函数不允许中断中使用。
taskEXIT_CRITICAL函数最终实现如下:
第①处如果前面有过一次以上调用taskENTER_CRITICAL,那么仍然禁止中断configMAX_SYSCALL_INTERRUPT_PRIORITY值以上的中断都不能开启,直到最后一次退出才真正退出,这个意思就是从第一次调用taskENTER_CRITICAL的范围内的代码都不能被中断打扰。
第② 处直接将basepri寄存器写0开启所有中断,taskEXIT_CRITICAL函数没有参数带入,只要调用它就是开启所有中断。
二 taskENTER_CRITICAL_FROM_ISR,taskEXIT_CRITICAL_FROM_ISR
1)taskENTER_CRITICAL_FROM_ISR函数最终实现:
第①②处,将BASEPRI赋值之前先将其值取出来,之后返回
第③处,向BASEPRI寄存器赋新值,
注:BASEPRI是arm的一个寄存器,可以设置一个数值,向寄存器BASEPRI写入某数值时大于等于此数值的中断都会被屏蔽。
2) taskEXIT_CRITICAL_FROM_ISR(xReturn)实现
此函数是带参数的,并不是像taskEXIT_CRITICAL一样直接将0赋值给BASEPRI,而这个参数就是
taskENTER_CRITICAL_FROM_ISR的返回值。
3)这样做有什么作用呢?
直接用实例解释比较容易理解:
// 嵌套中断示例
void Nested_ISR(void) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
BaseType_t xSavedInterruptStatus1, xSavedInterruptStatus2;
// 第一层临界区保护
xSavedInterruptStatus1 = taskENTER_CRITICAL_FROM_ISR();
/* 执行第一层临界区代码 */
// 第二层临界区保护(嵌套)
xSavedInterruptStatus2 = taskENTER_CRITICAL_FROM_ISR();
/* 执行第二层临界区代码 */
// 按相反顺序退出临界区
taskEXIT_CRITICAL_FROM_ISR(xSavedInterruptStatus2);
taskEXIT_CRITICAL_FROM_ISR(xSavedInterruptStatus1);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
假设系统设置configMAX_SYSCALL_INTERRUPT_PRIORITY为11
第一次调用前basepri寄存器应该为0,所以xSavedInterruptStatus1=0,调用之后basepri寄存器为11,(如果当前中断优先级为11以上,那么11~15的中断都不能响应,如果当前中断优先级位11以下比如9,那么9以上都不能响应)。
第二次调用前basepri寄存器应该为11,所以xSavedInterruptStatus2=11,调用之后basepri寄存器为11,(如果当前中断优先级为11以上,那么11~15的中断都不能响应,如果当前中断优先级位11以下比如9,那么9以上都不能响应)。
第一次返回时因为xSavedInterruptStatus2=11,basepri寄存器应该为11,0~11都能执行,12~15都不能执行,此时如果使用不带ISR的临界屏蔽taskEXIT_CRITICAL()返回 ,那么0~15都能执行,违背初衷。
第二次返回时因为xSavedInterruptStatus2=0,basepri寄存器应该为0,优先级0~15都能执行。
题外话:
也许中断使用带ISR的屏蔽也许还有一个作用,就是跟任务分开,
因为任务中使用临界段仅仅可能只是想能够屏蔽其他任务的干扰,因为其他任务切换依靠最低优先级pendSV切换, 设定一个屏蔽值,可能不想屏蔽高优先级的中断。
而中断使用临界段的意图是屏蔽更高优先级的中断,起码要比当前中断的优先级要高一级(自然比任务的优先级也要高),如果同样使用 taskEXIT_CRITICAL(),一是起不到作用起不到想要的效果(屏蔽更高优先级的中断),二是起不到嵌套分层的作用,所以两者不能使用相同的屏蔽方式?
总之freeRTOS的任务跟中断是分离的两套系统,一个是任务级临界段代码保护,通过嵌套计数实现,一个是中断级代码临界段保护,通过保存和恢复寄存器BASEPRI的数值实现嵌套使用,最好是互不干扰。
可以这样理解:把任务级taskENTER_CRITICAL当成屏蔽所有中断理解,那么中断中不想屏蔽所有中断,中断中中断,那么就必须设置成可嵌套的,可嵌套的就必须带返回。所以taskENTER_CRITICAL_FROM_ISR就是为了可嵌套。
以下来自deepseek的回答有点乱感觉不对稍微参考:
FreeRTOS中断中不能使用taskENTER_CRITICAL()
的主要原因如下:
-
嵌套机制冲突
taskENTER_CRITICAL()
通过递归计数管理临界区嵌套,但中断服务程序(ISR)可能被更高优先级中断打断,导致嵌套计数不一致,从而引发中断状态恢复错误。 -
中断上下文特殊性
中断中直接关闭所有中断(如taskENTER_CRITICAL()
的操作)会破坏实时性,可能导致高优先级中断无法及时响应。FreeRTOS为此专门提供taskENTER_CRITICAL_FROM_ISR()
,仅屏蔽特定优先级的中断而非全部。 -
优先级管理差异
taskENTER_CRITICAL()
通过操作BASEPRI
寄存器屏蔽低于某优先级的中断,而中断服务程序本身可能已处于高优先级上下文,直接调用会导致不可预测的行为。 -
任务调度限制
中断中若使用任务级临界区保护,可能因调度器状态不一致引发任务切换异常,甚至死锁。
相关文章:

嵌入式学习笔记-freeRTOS taskENTER_CRITICAL(_FROM_ISR)跟taskEXIT_CRITICAL(_FROM_ISR)函数解析
一 函数taskENTER_CRITICAL,taskEXIT_CRITICAL 函数taskENTER_CRITICAL最终实现如下: 第①处按照系统设定的configMAX_SYSCALL_INTERRUPT_PRIORITY值对中断进行屏蔽 第②处调用一次自增一次 第③处检查中断状态寄存器位,如果有任何中断位置…...
Unity基础-数学向量
Unity基础-数学向量 二、向量相关用法 概述 向量在Unity游戏开发中扮演着重要角色,用于表示位置、方向、速度等。Unity提供了Vector2、Vector3等结构体来处理向量运算。 1. 向量基础操作 1.1 向量创建和访问 // 创建向量 Vector3 position new Vector3(1, 2,…...
【华为云Astro-服务编排】服务编排中图元的使用与配置
目录 子服务编排图元 子服务编排图元的作用 如何使用子服务编排图元 脚本图元 脚本图元的作用 如何使用脚本图元 记录创建图元 记录创建图元的作用 如何使用记录创建图元 记录删除图元 记录删除图元的作用 如何使用记录删除图元 记录查询图元 记录查询图元的作用…...

1panel面板中部署SpringBoot和Vue前后端分离系统 【图文教程】
1panel面板中部署SpringBoot和Vue前后端分离系统 一,1panel面板部署二,安装OpenResty三,安装MySQL,Redis等Spring boot 运行依赖环境四,SpringBoot 应用配置及打包部署配置打包部署 五 ,前端VUE应用配置打包…...
C++.OpenGL (7/64)摄像机(Camera)
摄像机(Camera) 摄像机系统核心组件 #mermaid-svg-lmysTXAyyzKytiOC {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-lmysTXAyyzKytiOC .error-icon{fill:#552222;}#mermaid-svg-lmysTXAyyzKytiOC .error-text{fi…...
使用xdocreport导出word
之前java总用freemaker进行导出,但是改xml实在是太繁琐了,这次找了另一个工具进行体验. 一、简单导出 pom引入 <dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.core</arti…...
青少年编程与数学 01-011 系统软件简介 05 macOS操作系统
青少年编程与数学 01-011 系统软件简介 05 macOS操作系统 一、历史发展(一)经典 Mac OS(1984-2001)(二)Mac OS X(2001-2016)(三)macOS(2016-至今&…...
Python打卡训练营学习记录Day43
作业: kaggle找到一个图像数据集,用cnn网络进行训练并且用grad-cam做可视化 进阶:并拆分成多个文件 从谷歌图片中拍摄的 10 种不同类别的动物图片 数据预处理 import os from torchvision import datasets, transforms from torch.utils…...

【Android基础回顾】二:handler消息机制
Android 的 Handler 机制 是 Android 应用中实现线程间通信、任务调度、消息分发的核心机制之一,它基于 消息队列(MessageQueue) 消息循环(Looper) 消息处理器(Handler) 组成。 1 handler的使用…...

每日Prompt:每天上班的状态
提示词 一个穿着清朝官服的僵尸脸上贴着符纸,在电脑面前办公,房间阴暗,电脑桌面很乱,烟灰缸里面满是烟头...
.net ORM框架dapper批量插入
.NET ORM 框架 Dapper 批量插入全解析 在 .NET 开发中,与数据库交互是常见需求。Dapper 作为轻量级的 ORM(对象关系映射)库,在简化数据库交互方面表现出色。今天我们就来深入探讨 Dapper 实现批量插入的几种方法。 为什么需要批…...

C++11 右值引用:从入门到精通
文章目录 一、引言二、左值和右值(一)概念(二)区别和判断方法 三、左值引用和右值引用(一)左值引用(二)右值引用 四、移动语义(一)概念和必要性(二…...

.net 使用MQTT订阅消息
在nuGet下载M2Mqtt V4.3.0版本。(支持.net framework) 订阅主题 public void LoadMQQCData() {string enpoint "xxx.xxx.x.x";//ip地址int port 1883;//端口string user "usrname";//用户名string pwd "pwd";//密码…...
Python实现快速排序的三种经典写法及算法解析
今天想熟悉一下python的基础写法,那就从最经典的快速排序来开始吧: 1、经典分治写法(原地排序) 时间复杂度:平均O(nlogn),最坏O(n) 空间复杂度:O(logn)递归栈空间 特点:通过左右指针…...

【递归、搜索与回溯】综合练习(四)
📝前言说明: 本专栏主要记录本人递归,搜索与回溯算法的学习以及LeetCode刷题记录,按专题划分每题主要记录:(1)本人解法 本人屎山代码;(2)优质解法 优质代码…...

强化学习入门:Gym实现CartPole随机智能体
前言 最近想开一个关于强化学习专栏,因为DeepSeek-R1很火,但本人对于LLM连门都没入。因此,只是记录一些类似的读书笔记,内容不深,大多数只是一些概念的东西,数学公式也不会太多,还望读者多多指教…...

STM32:CAN总线精髓:特性、电路、帧格式与波形分析详解
声明:此博客是我的学习笔记,所看课程是江协科技的CAN总线课程,知识点都大同小异,我仅进行总结并加上了我自己的理解,所引案例也都是课程中的案例,希望对你的理解有所帮助! 知识点1【CAN总线的概…...

贝叶斯深度学习!华科大《Nat. Commun.》发表BNN重大突破!
华科大提出基于贝叶斯深度学习的超分辨率成像,成功被Nat. Commun.收录。可以说,这是贝叶斯神经网络BNN近期最值得关注的成果之一了。另外还有AAAI 2025上的Bella新框架,计算成本降低了99.7%,也非常值得研读。 显然鉴于BNN“不确定…...

【大模型LLM学习】Flash-Attention的学习记录
【大模型LLM学习】Flash-Attention的学习记录 0. 前言1. flash-attention原理简述2. 从softmax到online softmax2.1 safe-softmax2.2 3-pass safe softmax2.3 Online softmax2.4 Flash-attention2.5 Flash-attention tiling 0. 前言 Flash Attention可以节约模型训练和推理时间…...
三、元器件的选型
前言:我们确立了题目的功能后,就可以开始元器件的选型,元器件的选型关乎到我们后面代码编写的一个难易。 一、主控的选择 主控的选择很大程度上决定我们后续使用的代码编译器,比如ESP32使用的是VScode,或者Arduino&a…...
精益数据分析(95/126):Socialight的定价转型启示——B2B商业模式的价格策略与利润优化
精益数据分析(95/126):Socialight的定价转型启示——B2B商业模式的价格策略与利润优化 在创业过程中,从B2C转向B2B不仅是商业模式的转变,更是定价策略与成本结构的全面重构。今天,我们将通过Socialight的实…...
stm32_DMA
DMA 1. 概念与基本原理 DMA,全称Direct Memory Access,即直接存储器访问。它是微控制器(MCU)、嵌入式处理器中的一个独立硬件模块,用于在无需CPU干预的情况下,在不同内存区域(包括外设寄存器和…...

物联网数据归档之数据存储方案选择分析
在上一篇文章中《物联网数据归档方案选择分析》中凯哥分析了归档设计的两种方案,并对两种方案进行了对比。这篇文章咱们就来分析分析,归档后数据应该存储在哪里?及存储方案对比。 这里就选择常用的mysql及taos数据库来存储归档后的数据吧。 你在处理设备归档表存储方案时对…...
【自动驾驶避障开发】如何让障碍物在 RViz 中‘显形’?呈现感知数据转 Polygon 全流程
【自动驾驶避障开发】如何让障碍物在 RViz 中"显形"?呈现感知数据转 Polygon 全流程 自动驾驶系统中的障碍物可视化是开发调试过程中至关重要的一环。本文将详细介绍如何将自动驾驶感知模块检测到的障碍物数据转换为RViz可显示的Polygon(多边形)形式,实现障碍物…...

【C语言】C语言经典小游戏:贪吃蛇(上)
文章目录 一、游戏背景及其功能二、Win32 API介绍1、Win32 API2、控制台程序3、定位坐标(COORD)4、获得句柄(GetStdHandle)5、获得光标属性(GetConsoleCursorInfo)1)描述光标属性(CO…...
usbutils工具的使用帮助
作为嵌入式系统开发中的常用工具,usbutils 是一套用于管理和调试USB设备的Linux命令行工具集。以下是其核心功能和使用方法的详细说明: 1. 工具组成 核心命令: lsusb:列出所有连接的USB设备及详细信息(默认安装&#…...

vue2中使用jspdf插件实现页面自定义块pdf下载
pdf下载 实现pdf下载的环境安装jspdf插件在项目中使用 实现pdf下载的环境 项目需求案例背景,点击【pdf下载】按钮,弹出pdf下载弹窗,显示需要下载四个模块的下载进度,下载完成后,关闭弹窗即可! 项目使用的是…...

如何防止服务器被用于僵尸网络(Botnet)攻击 ?
防止服务器被用于僵尸网络(Botnet)攻击是关键的网络安全措施之一。僵尸网络是黑客利用大量被感染的计算机、服务器或物联网设备来发起攻击的网络。以下是关于如何防止服务器被用于僵尸网络攻击的技术文章: 防止服务器被用于僵尸网络ÿ…...

基于cornerstone3D的dicom影像浏览器 第二十九章 自定义菜单组件
文章目录 前言一、程序结构1. 菜单数据结构2. XMenu.vue3. XSubMenu.vue4. XSubMenuSlot.vue5. XMenuItem.vue 二、调用流程总结 前言 菜单用于组织程序功能,为用户提供导航。是用户与程序交互非常重要的接口。 开源组件库像Element Plus和Ant Design中都提供了功能…...

【Block总结】DBlock,结合膨胀空间注意模块(Di-SpAM)和频域模块Gated-FFN|即插即用|CVPR2025
论文信息 标题: DarkIR: Robust Low-Light Image Restoration 作者: Daniel Feijoo, Juan C. Benito, Alvaro Garcia, Marcos Conde 论文链接:https://arxiv.org/pdf/2412.13443 GitHub链接:https://github.com/cidautai/DarkIR 创新点 DarkIR提出了…...