[FreeRTOS- 野火] - - - 临界段

一、介绍

临界段最常出现在对一些全局变量进行操作的场景。

1.1 临界段的定义

临界段是指在多任务系统中,一段需要独占访问共享资源的代码。在这段代码执行期间,必须确保没有任何其他任务或中断可以访问或修改相同的共享资源。

临界段的主要目的是防止多个任务或中断同时访问共享资源,从而避免数据不一致或竞态条件。

1.2 临界段的特点

  • 1、互斥访问:

    • 临界段内的代码必须确保在任何时刻只有一个任务或中断可以访问共享资源。

    • 其他任务或中断必须等待,直到当前任务或中断完成对共享资源的访问。

  • 2、短小精悍:

    • 临界段的代码应该尽可能短小,以减少对系统性能的影响。

    • 长时间的临界段可能会导致系统响应延迟,影响实时性。

  • 3、明确的入口和出口:

    • 临界段必须有明确的入口和出口。

    • 入口处通常会禁用中断,出口处会恢复中断。

1.3 临界段的实现方式

在RTOS中,临界段可以通过以下几种方式实现:

  • 1、禁用中断:

    • 直接禁用所有中断:通过设置硬件寄存器(如Cortex-M的 PRIMASK)来禁用所有中断。

    • 设置中断优先级阈值:通过设置硬件寄存器(如Cortex-M的 BASEPRI)来屏蔽优先级高于某个值的中断。

  • 2、使用互斥量(Mutex):

    • 互斥量是一种同步原语,用于确保对共享资源的互斥访问。

    • 任务在访问共享资源前必须先获取互斥量,访问完成后释放互斥量。

// 创建互斥量
SemaphoreHandle_t xMutex = xSemaphoreCreateMutex();// 获取互斥量
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE)
{// 临界段代码
}// 释放互斥量
xSemaphoreGive(xMutex);
  • 3、使用信号量(Semaphore):

    • 信号量是一种计数器,用于控制对共享资源的访问。

    • 任务在访问共享资源前必须先获取信号量,访问完成后释放信号量。

// 创建信号量
SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary();// 获取信号量
if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE)
{// 临界段代码
}// 释放信号量
xSemaphoreGive(xSemaphore);
  • 4、使用自旋锁(Spinlock):

    • 自旋锁是一种简单的同步机制,任务在获取锁时会不断尝试,直到获取成功。

    • 自旋锁通常用于短时间的临界段,以减少上下文切换的开销。

二、Cortex-M内核快速关中断指令

为了快速地开关中断, Cortex-M 内核专门设置了一条 CPS 指令,有 4 种用法,具体如下:

CPSID I ;PRIMASK=1 ;	//关中断
CPSIE I ;PRIMASK=0 ;	//开中断
CPSID F ;FAULTMASK=1 ;	//关异常
CPSIE F ;FAULTMASK=0 ;	//开异常

在ARM Cortex-M系列处理器中,PRIMASK、FAULTMASK 和 BASEPRI 是三个用于控制中断和异常处理的系统级寄存器。

2.1 PRIMASK

  • 功能:禁用除NMI(不可屏蔽中断)和Hard Fault(硬件故障)之外的所有异常和中断。

  • 作用机制:设置 PRIMASK (通过 MSR PRIMASK, #1 或 CPSID I;)把当前中断优先级提为0,来屏蔽除NMI和Hard Fault之外的所有异常和中断。

  • 典型用途:用于快速进入临界区,保护关键代码段不被中断打断,例如在RTOS任务切换或共享资源访问等应用中。

  • 特点:简单易用,但对系统实时性影响较大,长时间开启可能导致高优先级中断无法响应。

是一个单一比特的寄存器。缺省值是0,表示没有关中断。

2.2 FAULTMASK

  • 功能:禁用除NMI之外的所有异常和中断,包括Hard Fault。

  • 作用机制:设置 FAULTMASK(通过MSR FAULTMASK, #1或CPSID F ;)会把当前中断优先级提升到-1,仅允许NMI。

  • 典型用途:在异常处理程序中临时屏蔽可能引发嵌套故障的操作(如内存访问)。

  • 特点:比PRIMASK更严格,可能影响系统稳定性,仅在特权模式(Privileged Mode)下可修改。

是一个只有1位的寄存器。缺省值是0,表示没有关异常。

2.3 BASEPRI

  • 功能:基于优先级的动态中断屏蔽,仅屏蔽优先级低于阈值的中断。

  • 作用机制:设置 BASEPRI (通过 MSR BASEPRI, #priority)允许优先级低于阈值的中断继续执行,高于阈值的中断被屏蔽。

  • 典型用途:灵活控制中断优先级,允许高优先级任务/中断优先执行,同时屏蔽低优先级中断。

  • 特点:更精细的控制,避免完全禁用所有中断,但需要合理设置优先级阈值,否则可能导致意外屏蔽。

三、关中断

关中断函数分为带返回值不带返回值两种。

3.1 不带返回值的关中断函数

static portFORCE_INLINE void vPortRaiseBASEPRI( void )		// 不带返回值的函数是不能嵌套的
{
uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;__asm{/* Set BASEPRI to the max syscall priority to effect a criticalsection. */msr basepri, ulNewBASEPRI			// 11 大于11的中断不能被响应 小于11则可以 根据 configMAX_SYSCALL_INTERRUPT_PRIORITY 的值来配置dsbisb}
}
  • dsb(Data Synchronization Barrier):数据同步屏障,确保所有之前的内存访问操作(如读写操作)都完成后再继续执行后续代码。
  • isb(Instruction Synchronization Barrier):指令同步屏障,确保所有之前的指令都执行完成后再继续执行后续代码。

3.2 带返回值的关中断函数

static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void )		// 可嵌套
{
uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;__asm{/* Set BASEPRI to the max syscall priority to effect a criticalsection. */mrs ulReturn, basepri					// 先将 basepri 的值保存在 返回值中msr basepri, ulNewBASEPRI			// 再设置 basepri 的值dsbisb}return ulReturn;
}

四、开中断

static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI )
{__asm{/* Barrier instructions are not used as this function is only used tolower the BASEPRI value. */msr basepri, ulBASEPRI}
}

五、进入/退出临界段的宏

5.1 进入临界段的宏

5.1.1 不带中断保护

#define taskENTER_CRITICAL() portENTER_CRITICAL()	// task.h中定义#define portENTER_CRITICAL() vPortEnterCritical()	// portmacro.h中定义#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()	// portmacro.h中定义

5.1.2 带中断保护

#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()	// task.h 中定义#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()	// portmacro.h 中定义

5.2 退出临界段的宏

5.2.1 不带中断保护

#define taskEXIT_CRITICAL() portEXIT_CRITICAL()		// task.h 中定义#define portEXIT_CRITICAL() vPortExitCritical()		// portmacro.h 中定义#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )	//portmacro.h 中定义

5.2.2 带中断保护

#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x )	// task.h 中定义#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)	//  portmacro.h 中定义

六、临界段代码的应用

在 FreeRTOS 中,对临界段的保护出现在两种场合,一种是在中断场合,一种是在非中断场合

6.1 中断场合

// 在中断场合,临界段可以嵌套
{uint32_t ulReturn;// 进入临界段,临界段可以嵌套ulReturn = taskENTER_CRITICAL_FROM_ISR();// 临界段代码// 退出临界段taskEXIT_CRITICAL_FROM_ISR( ulReturn );
}

6.2 非中断场合

// 非中断场合,临界段不能嵌套
{// 进入临界段taskENTER_CRITICAL();// 临界段代码// 退出临界段taskEXIT_CRITICAL();
}

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

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

相关文章

Vad-R1:通过从感知到认知的思维链进行视频异常推理

文章目录 速览摘要1 引言2 相关工作视频异常检测与数据集视频多模态大语言模型具备推理能力的多模态大语言模型 3 方法:Vad-R13.1 从感知到认知的思维链(Perception-to-Cognition Chain-of-Thought)3.2 数据集:Vad-Reasoning3.3 A…

CSS Day07

1.搭建项目目录 2.网页头部SEO三大标签 3.Favicon图标与版心 (1)Favicon图标 (2)版心 4.快捷导航 5.头部-布局 6.头部-logo 7.头部-导航 8.头部-搜索 9头部-购物车 10.底部-布局 11.底部-服务区域 12.底部-帮助中心 13.底部-版权…

Flutter图片Image、本地图片、程程图片、圆片剪切、圆形图片

目录 图片组件的介绍 1.Image.network加载图片 1.1 Image scale图片缩小一倍 1.2 Image alignment使用 1.3 Image fit 属性的取值及说明 1.3.1 Contain 默认效果 1.3.2 Fill 图片会缩放至完全填满目标区域(宽高) 1.3.3 Fill 图片会缩放至完全填满目…

Prometheus学习之pushgateway和altermanager组件

[rootnode-exporter41 /usr/local/alertmanager-0.28.1.linux-amd64]# pwd /usr/local/alertmanager-0.28.1.linux-amd64[rootnode-exporter41 /usr/local/alertmanager-0.28.1.linux-amd64]# cat alertmanager.yml # 通用配置 global:resolve_timeout: 5msmtp_from: 914XXXXX…

NHANES指标推荐:CQI

文章题目:The impact of carbohydrate quality index on menopausal symptoms and quality of life in postmenopausal women 中文标题:碳水化合物质量指数对绝经后妇女更年期症状和生活质量的影响 发表杂志:BMC Womens Health 影响因子&…

【cpp-httplib】 安装与使用

cpp-httplib 1. 介绍2. 安装3. 类与接口3.1 httplib请求3.2 httplib响应3.3 httplib服务端3.4 httplib客户端 4. 使用4.1 服务端4.2 客户端 1. 介绍 C HTTP 库(cpp-httplib)是一个轻量级的 C HTTP 客户端/服务器库,它提供了简单的 API 来创建…

Electron-vite【实战】MD 编辑器 -- 系统菜单(含菜单封装,新建文件,打开文件,打开文件夹,保存文件,退出系统)

最终效果 整体架构 src/main/index.ts import { createMenu } from ./menu在 const mainWindow 后 // 加载菜单createMenu(mainWindow)src/main/menu.ts import { BrowserWindow, Menu, MenuItem, MenuItemConstructorOptions, dialog, shell } from electron import fs from…

【第4章 图像与视频】4.5 操作图像的像素

文章目录 前言示例-获取和修改图像数据图像数据的遍历方式图像滤镜负片滤镜黑白滤镜浮雕滤镜filter滤镜属性 前言 getImageData() 与 putImageData() 这两个方法分别用来获取图像的像素信息,以及向图像中插入像素。与此同时,如果有需要,也可…

【Docker 从入门到实战全攻略(一):核心概念 + 命令详解 + 部署案例】

1. 是什么 Docker 是一个用于开发、部署和运行应用程序的开源平台,它使用 容器化技术 将应用及其依赖打包成独立的容器,确保应用在不同环境中一致运行。 2. Docker与虚拟机 2.1 Docker(容器化) 容器化是一种轻量级的虚拟化技术…

Vue:axios(POST请求)

发送 POST 请求 基本用法 axios.post(/api/login, {username: lcyyyy,password: 123456 }) .then(response > {console.log(请求成功:, response.data); }) .catch(error > {console.error(请求失败:, error); });在 Vue 组件中使用 export default {methods: {async …

一周学会Pandas2之Python数据处理与分析-数据重塑与透视-unstack() - 解堆 (行 -> 列)

锋哥原创的Pandas2 Python数据处理与分析 视频教程: 2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili unstack() 是 pandas 中用于数据重塑的重要方法,它与 stack() 互为逆操作。unstack() 的主要功能是将行索…

基于大模型预测的FicatIII-IV期股骨头坏死综合治疗研究报告

目录 一、引言 1.1 研究背景与目的 1.2 国内外研究现状 1.3 研究意义和创新点 二、FicatIII-IV 期股骨头坏死概述 2.1 疾病定义与分期 2.2 病因与病理机制 2.3 临床症状与诊断方法 三、大模型预测原理与方法 3.1 大模型简介 3.2 数据收集与预处理 3.3 模型训练与优…

C++?多态!!!

一、引言 众所周知,C有三大特性,它们分别是封装、继承和多态,在之前的文章中已经详细介绍过封装和继承了,今天我们将一起学习多态相关的知识,如果还想了解封装、继承相关的知识,可以跳转到以下链接&#xf…

electron安装报错处理

electron安装报错 解决方法: 修改 C:\Users\用户名.npmrc下配置文件 添加代码 electron_mirrorhttps://cdn.npmmirror.com/binaries/electron/ electron_builder_binaries_mirrorhttps://npmmirror.com/mirrors/electron-builder-binaries/最后代码 registryhtt…

Windows10下使用QEMU安装Ubuntu20.04虚拟机,并启用硬件加速

Windows10下使用QEMU安装Ubuntu20.04虚拟机,并启用硬件加速 作者将狼才鲸创建日期2025-05-30 CSDN阅读地址:Windows10下使用QEMU安装Ubuntu20.04虚拟机,并启用硬件加速 本文档源码地址:Windows10下使用QEMU安装Ubuntu20.04虚拟机…

顶刊SCS | 基于视觉语言大模型推理分割的建筑足迹尺度功能分类, 样本数据和代码已开源!

论文介绍 题目:Visual-language reasoning segmentation (LARSE) of function-level building footprint across Yangtze River Economic Belt of China 期刊:Sustainable cities and society(中科院一区TOP,IF10.5)…

【软件】navicat 官方免费版

Navicat Premium Lite https://www.navicat.com.cn/download/navicat-premium-lite

每个路由器接口,都必须分配所属网络内的 IP 地址,用于转发数据包

在IP网络中,主机(Host)和路由器接口(Router Interface)都需要分配网络地址(IP地址)。 1. 主机(Host)的IP地址分配 (1) 作用 主机的IP地址用于唯一标识该设备&#xff0…

鸿蒙OSUniApp页面切换动效实战:打造流畅精致的转场体验#三方框架 #Uniapp

UniApp页面切换动效实战:打造流畅精致的转场体验 引言 在移动应用开发中,页面切换动效不仅能提升用户体验,还能传达应用的品质感。随着HarmonyOS的普及,用户对应用的动效体验要求越来越高。本文将深入探讨如何在UniApp中实现流畅…

Tesseract OCR 安装与中文+英文识别实现

一、下载 https://digi.bib.uni-mannheim.de/tesseract/ 下载,尽量选择时间靠前的(识别更好些)。符合你的运行机(我的是windows64) 持续点击下一步安装,安装你认可的路径即可,没必要配置环境变…