FreeRTOS系列|中断管理和临界段

2023-05-16

FreeRTOS中断管理和临界段

1. 中断管理

1.1 中断管理简介

中断是微控制器的一个常见特性,中断由硬件产生,当中断产生后CPU就会中断当前的流程转而去处理中断服务,Cortex-M内核的MCU提供了一个用于中断管理的嵌套向量中断控制器(NVIC)

当多个中断来临时处理器应该享有哪一个中断是由中断的优先级来决定的,高优先级的中断(优先级编号小)首先得到响应,而高优先级的中断可以抢占低优先级的中断,即中断嵌套。Cortex-M处理器的有些中断是具有固定的优先级的,比如复位、NMI、HardFault,这些中断的优先级都是负数,优先级也是最高的

Cortex-M处理有三个固定优先级和256个可编程的优先级,最多有128个抢占登记,实际的优先级数量由芯片厂商决定的。多数厂商都会精简设计,比如STM32就只选择了4位作为优先级,共只有16级优先级。如下图示:
在这里插入图片描述
Cortex-M处理器还把256个优先级按位分为高低两段:抢占优先级(分组优先级)和亚优先级(子优先级),通过NVIC中的AIRCR寄存器的PRIGROUP(优先级分组)位段来配置分组。下图即为抢占优先级和亚优先级的表达,以及位数和PRIGROUP分组的关系:
在这里插入图片描述
上面提到STM32只使用了4位,因此STM32最多只有5组优先级分组设置。而移植FreeRTOS到STM32时,一般都是配置组4,也就是4位优先级全都是抢占优先级了,没有亚优先级,因此就有0~15共16个优先级。

在STM32上移植FreeRTOS还需要重点关注PRIMASK、FAULTMASK和BASEPRI这三个寄存器,这三个寄存器的说明见下表。FreeRTOS的开关中断是操作BASEPRI寄存器来实现的,它可以关闭低于某个阈值的中断,高于这个阈值的中断则不会被关闭
在这里插入图片描述

1.2 中断相关函数
  • 关闭中断
/* 关闭中断 */
void taskDISABLE_INTERRUPTS(void)
//只能关掉优先级低于configMAX_SYSCALL_INTERRUPT_PRIORITY的中断
//此函数不允许嵌套
/* 源码分析 */
#define portDISABLE_INTERRUPTS()	vPortRaiseBASEPRI()
static portFORCE_INLINE void vPortRaiseBASEPRI(void)
{	/*vPortRaiseBASEPRI()是向寄存器BASEPRI写入宏configMAX_SYSCALL_INTERRUPT_PRIORITY
	**表示优先级低于configMAX_SYSCALL_INTERRUPT_PRIORITY的中断会被屏蔽*/
	uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
    __asm
    {
    	msr basepri, ulNewBASEPRI
        dsb
        isb
    }
}
  • 打开中断
/* 打开中断 */
void taskENABLE_INTERRUPTS (void)
//此函数不允许嵌套
/* 源码分析 */
#define portENABLE_INTERRUPTS()		vPortSetBASEPRI( 0 )
static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI )
{	//vPortSetBASEPRI()是向BASEPRI寄存器写入一个值		
    __asm
    {
    	msr basepri, ulBASEPRI
    }
}

2. 临界段

2.1 临界段的定义

代码的临界段也称为临界区,是指那些必须完整运行,不能被打断的代码段,比如有的外设的初始化需要严格的时序,初始化过程中不能被打断。为确保临界段代码的执行不被中断,在进入临界段之前须关中断,而临界段代码执行完毕后,要立即打开中断

在这里插入图片描述
不想被打断访问的资源有哪些:

  • 读取或者修改变量(全局变量)
  • 调用公共函数的代码(不可重入函数)
  • 使用硬件资源(外设)
  • 对时序有精准要求的操作
  • 用户不想被打断的代码
2.2 临界段相关函数
  • 进入/退出临界段:任务级临界段代码保护
/*********** 进入临界段 ***********/
函数原型:void taskENTER_CRITICAL(void)
///
/* 源码分析 */
#define taskENTER_CRITICAL()    portENTER_CRITICAL()
#define portENTER_CRITICAL()	vPortEnterCritical()
void vPortEnterCritical( void )
{	
    portDISABLE_INTERRUPTS();	//关闭中断
    uxCriticalNesting++;	//记录临界段嵌套次数
    if( uxCriticalNesting == 1 )
    {
        configASSERT((portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK) == 0);
    }
}
/*********** 退出临界段 ***********/
函数原型:void taskEXIT_CRITICAL(void)
///
/* 源码分析 */
#define taskEXIT_CRITICAL()		portEXIT_CRITICAL()
#define portEXIT_CRITICAL()     vPortExitCritical()
void vPortExitCritical( void )
{	
    configASSERT( uxCriticalNesting );
    uxCriticalNesting--;			//记录临界段嵌套次数
    if( uxCriticalNesting == 0 )	
    {
        portENABLE_INTERRUPTS();	//打开中断
    }
}
  • 进入/退出临界段:中断级临界段代码保护
/*********** 进入临界段 ***********/
函数原型:UBaseType_t taskENTER_CRITICAL_FROM_ISR(void)
返 回 值:返回上次中断屏蔽寄存器操作值
///
/* 源码分析 */
#define taskENTER_CRITICAL_FROM_ISR() 		portSET_INTERRUPT_MASK_FROM_ISR()
#define portSET_INTERRUPT_MASK_FROM_ISR()	ulPortRaiseBASEPRI()
static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void )
{	
	uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
    __asm
    {
        mrs ulReturn, basepri		//读出BASEPRI的值,保存在ulReturn中
        msr basepri, ulNewBASEPRI	//将ulNewBASEPRI的值写入到BASEPRI寄存器中
        dsb
        isb
    }
    return ulReturn;				//返回ulReturn,退出临界区代码保护时要使用
}
/*********** 退出临界段 ***********/
函数原型:void taskENTER_CRITICAL_FROM_ISR(UBaseType_t uxSavedInterruptStatus)
传 入 值:传入上次中断屏蔽寄存器操作值
///
/* 源码分析 */
#define taskEXIT_CRITICAL_FROM_ISR(x)	portCLEAR_INTERRUPT_MASK_FROM_ISR(x)
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x)	vPortSetBASEPRI(x)
static portFORCE_INLINE void vPortSetBASEPRI(uint32_t ulBASEPRI)
{	
	__asm
    {
        msr basepri, ulBASEPRI	//将进入临界区时的返回值,传入BASEPRI寄存器
    }
}

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOS系列|中断管理和临界段 的相关文章

  • FreeRTOS例程4-串口DMA收发不定长数据

    FreeRTOS例程4 串口DMA收发不定长数据 知乎 zhihu com
  • 基于HAL库的FREERTOS----------二.任务API函数

    任务API函数览概 CUBEMX对 做了API的封装 很多 的函数没有封装到位 可以用原函数调用 任务API函数分别介绍 1 uxTaskPriorityGet 此函数用来获取指定任务的优先级 要使用此函数的话宏 INCLUDE uxTas
  • FreeRTOS 软件定时器的使用

    FreeRTOS中加入了软件定时器这个功能组件 是一个可选的 不属于freeRTOS内核的功能 由定时器服务任务 其实就是一个定时器任务 来提供 软件定时器是当设定一个定时时间 当达到设定的时间之后就会执行指定的功能函数 而这个功能函数就叫
  • 一文教你学会keil软件仿真

    仿真在我们调试代码中是非常重要的 通过仿真 我们可以快速定位到错误代码 或者错误逻辑的地方 这里我就以上一篇博客为例 教大家如何软件仿真 软件仿真不需要单片机 直接通过keil软件进行代码调试 一 打开工具 二 选择软件仿真 三 开始仿真
  • FreeRTOS学习笔记(3、信号量、互斥量的使用)

    FreeRTOS学习笔记 3 信号量 互斥量的使用 前言 往期学习笔记链接 学习工程 信号量 semaphore 两种信号量的对比 信号量的使用 1 创建信号量 2 give 3 take 4 删除信号量 使用计数型信号量实现同步功能 使用
  • FreeRTOS学习(八) 延时函数

    声明及感谢 跟随正点原子资料学习 在此作为学习的记录和总结 环境 keil stm32f103 FreeRTOS延时函数有两个 分别是 vTaskDelay vTaskDelayUntil 1 vTaskDelay 任务相对延时 函数原型
  • Freertos中vTaskDelay()是怎么用的

    1 常见的使用场景 void vLED Task void pvParameters while 1 Heartbeat LED vTaskDelay 1000 portTICK RATE MS 说明 上面这段代码的意思是 led翻转后经过
  • freertos---软定时器

    一 软件定时器介绍 freeRTOS软件定时器的时基是基于系统时钟节拍实现的 可以创建很多个 在硬件定时器资源不充足的情况下非常有用 软件定时器一般用作周期性地执行函数 在创建软件定时器时指定软件定时器的回调函数 在回调函数中实现相应的功能
  • FreeRTOS打印任务对CPU的占有率

    1 配置RTOS 1 打开RTOS Config Parameter 找到Run Time And Task States gathering related definitions 使能GENERATE RUN TIME STATS US
  • 基于HAL库的FREERTOS----------一.任务

    FreeROTS 就是一个免费的 RTOS 类系统 这里要注意 RTOS 不是指某一个确定的系统 而是指一类系统 比如 UCOS FreeRTOS RTX RT Thread 等这些都是 RTOS 类操作系统 FreeRTOS 是 RTOS
  • Error: L6218E: Undefined symbol vApplicationGetIdleTaskMemory (referred from tasks.o).

    我用的是F103ZET6的板子 移植成功后 编译出现两个错误是关于stm32f10x it c 里 void SVC Handler void void PendSV Handler void 两个函数的占用问题 随后编译出现以下两个问题
  • 基于HAL库的FREERTOS-----------三.队列

    一 队列简介 在实际的应用中 常常会遇到一个任务或者中断服务需要和另外一个任务进行 沟通交流 这个 沟通交流 的过程其实就是消息传递的过程 在没有操作系统的时候两个应用程序进行消息传递一般使用全局变量的方式 但是如果在使用操作系统的应用中用
  • freertos————互斥锁

    线程安全 多线程程序处于一个多变的环境 可访问的全局变量和堆数据随时可能被其他的线程改变 多个线程同时访问一个共享数据 可能造成严重的后果 出现问题的是之前移植了一个freemodbus的从站 多个任务访问全局变量保持寄存器区 导致最后读出
  • 基于STM32的FreeRTOS学习之中断测试实验(五)

    记录一下 方便以后翻阅 本章内容是接着上一章节进行的实际演练 1 实验目的 FreeRTOS可以屏蔽优先级低于configMAX SYSCALL INTERRUPT PRIORITY的中断 不会屏蔽高于其的中断 本次实验就是验证这个说法 本
  • STM32 Freertos 添加 外部sram heap_5.c

    1 添加外部SRAM 初始化 2 添加heap 5 c 3 初始化heap 5 c 外部堆栈 Define the start address and size of the two RAM regions not used by the
  • 当一个任务写入变量而其他任务读取该变量时,我们是否需要信号量?

    我正在研究 freeRtos 并且我有一个名为 x 的变量 现在 每秒只有一个任务正在写入该变量 而其他任务正在读取该变量值 我需要用互斥锁来保护变量吗 如果变量为 32 位或更小 并且其值是独立的并且不与任何其他变量一起解释 则不需要互斥
  • FreeRTOS 匈牙利表示法 [重复]

    这个问题在这里已经有答案了 我是 RTOS 和 C 编程的新手 而且我仍在习惯 C 的良好实践 因此 我打开了一个使用 FreeRTOS 的项目 我注意到操作系统文件使用匈牙利表示法 我知道一点符号 但面临一些新的 标准 FreeRTOS
  • GNU Arm Cortex m4 上的 C++ 异常处理程序与 freertos

    2016 年 12 月更新现在还有一个关于此行为的最小示例 https community nxp com message 862676 https community nxp com message 862676 我正在使用带有 free
  • 小型 ARM 微控制器的 RTOS 内核之间的可量化差异 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 有许多不同的 RTOS 可用于微控制器 我专门寻找支持 ARM Cortex M 处理器的 RTOS 另外 我对闭源解决方案不感兴趣 试图从网站
  • 有关 CMake 错误的问题:没有为目标提供源

    我正在尝试使用 cmake 和 eclipse 将 FreeRtos 添加到我的项目中 但出现错误 我运行的是 debian 10 我的 cmake 版本是 3 13 4 cmake 的文件可以在以下位置找到这个 git 仓库 https

随机推荐

  • 从零完成slam实战,以Vins-Fusion为例

    写在前面 1 本文以vins fusion为例 xff0c 是因为其框架正统 简单清晰 xff0c 易于调试和后续改进 xff1b camera imu外参及同步时间td可实时估计 xff1b 已有融合gps方案且较为容易可添加融合其它传感
  • Vins-Fusion整体框架,数据流分析

    一 VINS Fusion VINS Fusion是一种基于优化的多传感器状态估计器 xff0c 可实现自主应用 xff08 无人机 汽车和AR VR xff09 的精确自我定位 VINS Fusion是VINS Mono的扩展 xff0c
  • Vins-Fusion初始化位姿——3D-2D:PNP求解当前帧位姿

    继上一篇博文Vins Fusion 外参camera imu 标定 xff0c 本文继续介绍Vins Fusion初始化时 xff0c 通过PNP求解当前帧位姿 一 3D 2D xff1a PNP PnP是求解3D到2D点对运动的估计 xf
  • ORB_SLAM3启动流程以stereo_inertial_realsense_D435i为例

    概述 ORB SLAM3 是第一个同时具备纯视觉 xff08 visual xff09 数据处理 视觉 43 惯性 xff08 visual inertial xff09 数据处理 和构建多地图 xff08 multi map xff09
  • BoW(词袋)模型详细介绍

    最近学习BoW模型 xff0c 将自己网上看到的资料及对论文的理解 xff0c 将BoW模型总结如下 xff01 BoW模型 Bag of words model BoW model 最早出现在自然语言处理 xff08 Natural La
  • Win10 VS Code + CMake STM32开发环境

    Win10 VS Code 43 CMake STM32开发环境 软件 软件安装与环境变量的配置不多讲 xff0c 这步都搞不定还是老老实实用MDK把 VS Codecmake 插件 c c 43 43 插件mingwgcc arm non
  • makefile 转 cmake STM32工程

    makefile 转 cmake STM32工程 STM32开发由MDK转到 vscode好久了 每次新建工程 xff0c stm32cubemx生成代码都要手动把makefile转到cmake xff0c 好烦 xff0c 特别一下小的频
  • STM32使用FreeRtos + C++

    编译环境 MDK5 25 gcc arm7 2 C文件不可包含CPP的头文件 C调用C 43 43 函数 在CPP文件内编写C函数 xff0c 头文件声明 头文件不可出现C 43 43 关键字 在main中调用此函数作为程序入口即可 voi
  • FreeRTOS系列|时间管理

    FreeRTOS时间管理 1 FreeRTOS延时函数 在使用FreeRTOS的过程中经常会在一个任务中使用延时函数对该任务延时 xff0c 当执行延时函数的时候就会进行任务切换 xff0c 并且此任务就会进入阻塞态 xff0c 直到延时完
  • 【Linux C与C++一线开发实践】之一 Linux概述与Linux C++开发

    Linux系统启动的基本过程 对于一台Linux系统来说 xff0c 用户按下开机按钮后 xff0c 一共要经历如下几个过程
  • 【Linux C与C++一线开发实践】之三 Linux多进程

    进程是操作系统结构的基础 进程是一个具有独立功能的程序对某个数据集在处理机上的执行过程 xff0c 进程也是作为资源分配的一个基本单位 Linux作为一个多用户 多任务的操作系统 xff0c 必定支持多进程 多进程是现代操作系统的基本特征
  • C++--结构体和类

    结构体和类只有一个区别就是前者访问控制默认为public xff0c 而类的默认访问控制是private 而对于public private protected的访问控制都是在编译期间由编译器检查的 xff0c 编译通过后 xff0c 程序
  • 嵌入式开发工程师面试题 – C语言部分

    嵌入式开发工程师面试题 C语言部分 申明 xff1a 来源于嵌入式开发工程师面试题 C语言部分 和 网摘 xff09 xff01 1 内核的裁剪怎么裁剪 解析 xff1a 在linux 下的ubuntu 上面做内核的 裁剪 xff0c 主要
  • 协方差与自相关

    协方差矩阵是一个矩阵 xff0c 其每个元素是各个向量元素之间的协方差 这是从标量随机变量 到高维度随机向量 的自然推广 假设是以个标量随机变量组成的列向量 xff0c 并且是其第i个元素的期望值 xff0c 即 协方差矩阵被定义的第i x
  • 基础解系

    基础解系首先是线性无关的 xff0c 简单的理解就是能够用它的线性组合表示出该 方程组的任意一组解 xff0c 基础解系是针对有无数多组解的方程而言 xff0c 若是齐次线性方程组则应是有效方程组的个数少于未知数的个数 xff0c 若非齐次
  • 机器学习实践指南:案例应用解析(第二版)

    试读及购买链接 机器学习实践指南2版代码及资源 原书中的360网盘链接因为360关闭网盘的原因已经失效 1 https pan baidu com s 1nw37A5N 2 http www hzbook com Books 9324 ht
  • 数学之路-python计算实战(7)-机器视觉-图像产生加性零均值高斯噪声

    图像产生加性零均值高斯噪声 xff0c 在灰度图上加上噪声 xff0c 加上噪声的方式是每个点的灰度值加上一个噪声值 xff0c 噪声值的产生方式为Box Muller算法 生成高斯噪声 在计算机模拟中 xff0c 经常需要生成正态分布的数
  • 数学之路-python计算实战(16)-机器视觉-滤波去噪(邻域平均法滤波)

    coding utf 8 code myhaspl 64 myhaspl com 邻域平均法滤波 半径为2 import cv2 import numpy as np fn 61 34 test3 jpg 34 myimg 61 cv2 i
  • R语言与数据模型(1)-平均,方差,中位数,分位数,极差

    1 求平均数 gt x lt c 1 10 20 30 40 50 NA 60 gt xm lt mean x gt xm 1 NA na rm表示允许缺失数据NA gt xm lt mean x na rm 61 TRUE gt xm 1
  • FreeRTOS系列|中断管理和临界段

    FreeRTOS中断管理和临界段 1 中断管理 1 1 中断管理简介 中断是微控制器的一个常见特性 xff0c 中断由硬件产生 xff0c 当中断产生后CPU就会中断当前的流程转而去处理中断服务 xff0c Cortex M内核的MCU提供