FreeRTOS任务级临界代码保护

前言

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


一、临界段代码保护函数

  • 任务中使用:taskENTER_CRITICA()/taskEXIT_CRITICAL()
  • ISR中使用:taskENTER_CRITICAL_FROM_ISR()/taskEXIT_CRITICAL_FROM_ISR()

二、如何使用

1、任务中使用

taskENTER_CRITICAL()和 taskEXIT_CRITICAL()是任务级的临界代码保护,一个是进入临界段,一个是退出临界段,这两个函数是成对使用的

eg:

void taskcritical_test(void)
{
        while(1)
        {
                taskENTER_CRITICAL(); (1)//进入临界区
                TTS_Play("欢迎光临");//语音播报
                taskEXIT_CRITICAL(); (2)//退出临界区
                 vTaskDelay(1000);
        }

}

以上就是典型的例子,在我们常见的语音播报中,如何不在任务进行临街保护,如何发生任务调度和中断发生,会导致我们的语音播报发生停顿,所以我们在这上加上临街保护,可解决此问题

2、中断中使用

//定时器 3 中断服务函数
void TIM3_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
        {
        status_value=taskENTER_CRITICAL_FROM_ISR(); (1)//进入临界区,进入有一个返回值要保存起来
        total_num+=1;
        printf("float_num 的值为: %d\r\n",total_num);
        taskEXIT_CRITICAL_FROM_ISR(status_value); (2)//退出临界区,用上面的返回值作为参数写进来才可以完成
        TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位
        }
}

上面的语句就是在中断服务函数中使用的临街保护语句。

我们现在知道如何使用,但是原理我们需要知道,究其根本才有应对问题的发生解决,下面使用点需要你我清楚知道,那我们接下里探讨下

三、临界保护原理

1、下面是taskENTER_CRITICAL源码

void vPortEnterCritical( void )
{
    portDISABLE_INTERRUPTS();
    uxCriticalNesting++;


    if( uxCriticalNesting == 1 )
    {
        configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
    }
}


    #define portDISABLE_INTERRUPTS()                  vPortRaiseBASEPRI()

    static portFORCE_INLINE void vPortRaiseBASEPRI( void )
    {
        uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;

        __asm
        {
            msr basepri, ulNewBASEPRI
            dsb
            isb
        }
    }

从代码中可以看出,进入临界区其实就是关闭中断,然后将中断嵌套变量加一,并检查这个函数是否在中断中调用。
uxCriticalNesting是记录中断嵌套层数,防止中断嵌套导致退出中断后无法正常打开中断。
关闭中断其实是通过设置BASEPRI寄存器实现的,然后这个值是根据configMAX_SYSCALL_INTERRUPT_PRIORITY来的

好了,那接下来我们就看下BASEPRI寄存器寄存器和configMAX_SYSCALL_INTERRUPT_PRIORITY的值

2、BASEPRI寄存器

FreeRTOS之所以能进行临街保护,是的被保护的代码能够完整运行结束,其根本是它控制着中断,FreeRtos通过直接操作CortexM4或者CortexM3的BASEPRI寄存器来屏蔽中断。

BASEPRI的作用是屏蔽优先级不高于某个具体数值的中断。当它被设置为某个值时,所有优先级值大于等于这个数值的中断都会被关闭(中断的优先级值越大,优先级越低)。若被设置为0,则不关闭任何中断。

CortexM4或者CortexM3的BASEPRI寄存器各位的含义如下:

 由图可看出:

(1)BASEPRI寄存器实际只有高四位有效 (7-4)

(2)高四位值若被设置为0,则无法控制,即不关闭任何中断

我们再看Freertosconfig.h文件配置的configMAX_SYSCALL_INTERRUPT_PRIORITY     的值

#ifdef __NVIC_PRIO_BITS
    #define configPRIO_BITS               __NVIC_PRIO_BITS
#else
    #define configPRIO_BITS               4                  
#endif

#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY            15     //中断最低优先级


#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5     //系统可管理的最高中断优先级


#define configKERNEL_INTERRUPT_PRIORITY         ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )


#define configMAX_SYSCALL_INTERRUPT_PRIORITY     ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

总结:

通过计算可以得到configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY的值为0x50,BASEPRI寄存器实际只有高四位有效,也就是说进入临界区函数taskENTER_CRITICAL其实只是屏蔽了优先级数值大于5的所有其他优先级,并非是关闭所有的中断。

即按照现在这个配置 0 1 2 3 4这四个高优先级中断,你是屏蔽不了的,只能屏蔽5-15的中断。

而控制着Freertos运行任务调度的滴答定时优先级是最低的。所以到现在应该都明白了。


到这里,我们就明白为什么可以对代码进行临界保护的原理,所以我们在使用中一定要注意你配置的中断优先级,以及你函数的分配与高优先级中断的合理分配。

上面讲解任务中的保护,那么中断的保护taskENTER_CRITICAL_FROM_ISR()和taskEXIT_CRITICAL_FROM_ISR()中断级别临界段代码保护,是用在中断服务程序中的,当前的这个中断的优先级值一定要低于configMAX_SYSCALL_INTERRUPT_PRIORITY!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何搭建自动化测试框架?资深测试整理的PO模式,一套打通自动化...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Po模型介绍 1、简…

wpf 3d 坐标系和基本三角形复习

wpf 3d 坐标系的描述见此&#xff0c; WPF 3d坐标系和基本三角形_wpf 坐标系_bcbobo21cn的博客-CSDN博客 X轴正向向右&#xff0c;Y轴正向向上&#xff1b;Z轴&#xff0c;正向是从屏幕里边出来&#xff0c;负向是往屏幕里边去&#xff1b;坐标原点是在呈现区域的中心&#x…

史上最细,自动化测试-logging日志采集详细实战(一)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 日志概述 1、日志…

C#实现旋转图片验证码

开发环境&#xff1a;C#&#xff0c;VS2019&#xff0c;.NET Core 3.1&#xff0c;ASP.NET Core 1、建立一个验证码控制器 新建两个方法Create和Check&#xff0c;Create用于创建验证码&#xff08;返回1张图片和令牌&#xff09;&#xff0c;Check用于验证&#xff08;验证图…

决策树和随机森林对比

1.用accuracy来对比 # -*-coding:utf-8-*-""" accuracy来对比决策树和随机森林 """ from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import RandomForestClassifier from sklearn.datasets import load_wine#(178, 13…

【LeetCode】240.搜索二维矩阵Ⅱ

题目 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,…

Iotdb 0.13配置集群和数据同步共享

描述 官网集群配置示例&#xff1a;官方文档 准备2台服务器&#xff0c;并且相互可以ping通和相关端口开放&#xff1a; 192.168.1.1192.168.1.2 相关介绍请查看官网及相关文档。 配置 1、iotdb 0.13版本下载&#xff08;如果已安装请跳过&#xff09;&#xff0c;进入op…

24届近5年杭州电子科技大学自动化考研院校分析

今天给大家带来的是杭州电子科技大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 一、杭州电子科技大学 学校简介 杭州电子科技大学&#xff08;Hangzhou Dianzi University&#xff09;&#xff0c;简称“杭电”&#xff0c;位于杭州市&#xff0c;是浙江省人民政…

PE半透明屏,在建筑行业中,有哪些应用展示?

PE半透明屏是一种新型的屏幕材料&#xff0c;具有半透明的特点。 它由聚乙烯&#xff08;PE&#xff09;材料制成&#xff0c;具有良好的透明度和柔韧性。 PE半透明屏广泛应用于建筑、广告、展览等领域&#xff0c;具有很高的市场潜力。 PE半透明屏的特点之一是其半透明性。…

弘扬“两弹一星”精神,勇攀科学技术高峰——道本科技商业大学党日活动圆满落幕

2023年8月2日&#xff0c;道本科技与商业大学携手举办了一场主题为“弘扬‘两弹一星’精神&#xff0c;勇攀科学技术高峰”的党日活动。本次活动旨在了解党领导下的中国核工业发展历程&#xff0c;传承和弘扬“两弹一星”精神&#xff0c;同时展示道本科技创新产品&#xff0c;…

【数据结构】单链表OJ题

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;数据结构 &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、移除链表元素 &#x1f4a1;方法一&#xff1a; &#x1f4a1;方法二…

Netty: 向ChannelPipeline中添加ChannelHandler的顺序

Netty中的ChannelHandler有inbound handler&#xff0c;处理接收数据的过程&#xff1b;有outbound handler&#xff0c;处理发数据的过程。当然&#xff0c;也有的handler既处理接收的数据 &#xff0c;也处理发送的数据。 每个channel对应一个ChannelPipeline。handler被添加…

echarts绘制甘特图

说在前面 项目上有需求&#xff0c;需要在大屏上展示进度甘特图&#xff0c;调研了DHTMLX和普加甘特图&#xff0c;效果都不是特别符合需求现状&#xff0c;查询了一些博客&#xff0c;决定使用echarts来绘制甘特图。 实现效果展示 实现思路分析 1、应该采用柱状图&#xff…

mysql--InnoDB存储引擎--架构和事务

MySQL进阶篇 文章目录 架构1、逻辑结构InnoDB 逻辑存储单元主层级关系图&#xff1a;1、表空间2、段3、区4、页5、行总结&#xff1a; 2、架构2、1 内存架构2、2 磁盘架构 3、事务3、1事务基础&#xff08;1&#xff09;事务&#xff08;2&#xff09;特性 架构 1、逻辑结构 I…

嵌入式Linux驱动开发系列五:Linux系统和HelloWorld

三个问题 了解Hello World程序的执行过程有什么用? 编译和执行&#xff1a;Hello World程序的执行分为两个主要步骤&#xff1a;编译和执行。编译器将源代码转换为可执行文件&#xff0c;然后计算机执行该文件并输出相应的结果。了解这个过程可以帮助我们理解如何将代码转化…

D455+VINS-Fusion+surfelmapping 稠密建图(三)

继续&#xff0c;由surfelmapping建立的点云生成octomap八叉树栅格地图 一、安装OctomapServer 建图包 安装插件 sudo apt-get install ros-melodic-octomap-ros sudo apt-get install ros-melodic-octomap-msgs sudo apt-get install ros-melodic-octomap-server sudo apt-…

IT 基础架构自动化

什么是 IT 基础架构自动化 IT 基础架构自动化是通过使用技术来控制和管理构成 IT 基础架构的软件、硬件、存储和其他网络组件来减少人为干预的过程&#xff0c;目标是构建高效、可靠的 IT 环境。 为什么要自动化 IT 基础架构 为客户和员工提供无缝的数字体验已成为企业的当务…

mybtis-plus分页查询

文章目录 2.2 代码开发2.2.1 设计DTO类2.2.2 封装PageResult2.2.3 Controller层2.2.4 Service层接口2.2.5 Service层实现类2.2.6 Mapper层 3.3 代码实现3.3.1 分页插件配置3.3.2 分页查询实现 2.2 代码开发 2.2.1 设计DTO类 根据请求参数进行封装&#xff0c;在sky-pojo模块中…

SpringCloud整体架构概览

什么是SpringCloud 目标 协调任何服务&#xff0c;简化分布式系统开发。 简介 构建分布式系统不应该是复杂的&#xff0c;SpringCloud对常见的分布式系统模式提供了简单易用的编程模型&#xff0c;帮助开发者构建弹性、可靠、协调的应用程序。SpringCloud是在SpringBoot的基…

蓝牙资讯|苹果AirPods耳机新专利曝光,类似项链圈和钥匙圈

根据美国商标和专利局&#xff08;USPTO&#xff09;公示的清单&#xff0c;苹果近日获得了 AirPods 耳机相关的设计专利&#xff0c;在不使用时可以放置到“项链”和“钥匙圈”内&#xff0c;方便用户携带。 苹果在专利中表示&#xff0c;便携式电子设备虽然可以放到口袋或者…