嵌入式学习笔记-freeRTOS taskENTER_CRITICAL(_FROM_ISR)跟taskEXIT_CRITICAL(_FROM_ISR)函数解析

news2025/6/7 16:03:58

一 函数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()的主要原因如下:

  1. 嵌套机制冲突
    taskENTER_CRITICAL()通过递归计数管理临界区嵌套,但中断服务程序(ISR)可能被更高优先级中断打断,导致嵌套计数不一致,从而引发中断状态恢复错误。

  2. 中断上下文特殊性
    中断中直接关闭所有中断(如taskENTER_CRITICAL()的操作)会破坏实时性,可能导致高优先级中断无法及时响应。FreeRTOS为此专门提供taskENTER_CRITICAL_FROM_ISR(),仅屏蔽特定优先级的中断而非全部。

  3. 优先级管理差异
    taskENTER_CRITICAL()通过操作BASEPRI寄存器屏蔽低于某优先级的中断,而中断服务程序本身可能已处于高优先级上下文,直接调用会导致不可预测的行为。

  4. 任务调度限制
    中断中若使用任务级临界区保护,可能因调度器状态不一致引发任务切换异常,甚至

    死锁。

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

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

相关文章

1panel面板中部署SpringBoot和Vue前后端分离系统 【图文教程】

1panel面板中部署SpringBoot和Vue前后端分离系统 一,1panel面板部署二,安装OpenResty三,安装MySQL,Redis等Spring boot 运行依赖环境四,SpringBoot 应用配置及打包部署配置打包部署 五 ,前端VUE应用配置打包…

【Android基础回顾】二:handler消息机制

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

每日Prompt:每天上班的状态

提示词 一个穿着清朝官服的僵尸脸上贴着符纸,在电脑面前办公,房间阴暗,电脑桌面很乱,烟灰缸里面满是烟头

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";//密码…

【递归、搜索与回溯】综合练习(四)

📝前言说明: 本专栏主要记录本人递归,搜索与回溯算法的学习以及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可以节约模型训练和推理时间…

物联网数据归档之数据存储方案选择分析

在上一篇文章中《物联网数据归档方案选择分析》中凯哥分析了归档设计的两种方案,并对两种方案进行了对比。这篇文章咱们就来分析分析,归档后数据应该存储在哪里?及存储方案对比。 这里就选择常用的mysql及taos数据库来存储归档后的数据吧。 你在处理设备归档表存储方案时对…

【C语言】C语言经典小游戏:贪吃蛇(上)

文章目录 一、游戏背景及其功能二、Win32 API介绍1、Win32 API2、控制台程序3、定位坐标(COORD)4、获得句柄(GetStdHandle)5、获得光标属性(GetConsoleCursorInfo)1)描述光标属性(CO…

vue2中使用jspdf插件实现页面自定义块pdf下载

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

如何防止服务器被用于僵尸网络(Botnet)攻击 ?

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

基于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提出了…

口罩佩戴检测算法AI智能分析网关V4工厂/工业等多场景守护公共卫生安全

一、引言​ 在公共卫生安全日益受到重视的当下,口罩佩戴成为预防病毒传播、保障人员健康的重要措施。为了高效、精准地实现对人员口罩佩戴情况的监测,AI智能分析网关V4口罩检测方案应运而生。该方案依托先进的人工智能技术与强大的硬件性能,…

Double/Debiased Machine Learning

独立同步分布的观测数据 { W i ( Y i , D i , X i ) ∣ i ∈ { 1 , . . . , n } } \{W_i(Y_i,D_i,X_i)| i\in \{1,...,n\}\} {Wi​(Yi​,Di​,Xi​)∣i∈{1,...,n}},其中 Y i Y_i Yi​表示结果变量, D i D_i Di​表示因变量, X i X_i Xi​表…

HarmonyOS Next 弹窗系列教程(4)

HarmonyOS Next 弹窗系列教程(4) 介绍 本章主要介绍和用户点击关联更加密切的菜单控制(Menu) 和 气泡提示(Popup) 它们出现显示弹窗出现的位置都是在用户点击屏幕的位置相关 菜单控制(Menu&…

【C】-递归

1、递归概念 递归(Recursion)是编程中一种重要的解决问题的方法,其核心思想是函数通过调用自身来解决规模更小的子问题,直到达到最小的、可以直接解决的基准情形(Base Case)。 核心:自己调用…