FreeRTOS临界区是指那些必须完整运行,不能被打断的代码段,比如有的外设的初始化需要严格的时序,初始化过程中不能被打断。 FreeRTOS 在进入临界区代码的时候需要关闭中断,当处理完临界区代码以后再打开中断。 FreeRTOS 系统本身就有很多的临界区代码,这些代码都加了临界区代码保护,我们在写自己的用户程序的时候有些地方也需要添加临界区代码保护。
  FreeRTOS 与 临界区代 码 保 护 有 关 的 函 数 有 4 个 : taskENTER_CRITICAL() 、taskEXIT_CRITICAL() 、taskENTER_CRITICAL_FROM_ISR() 和taskEXIT_CRITICAL_FROM_ISR(),这四个函数其实是宏定义,在 task.h 文件中有定义。 这四个函数的区别是前两个是任务级的临界段代码保护,后两个是中断级的临界段代码保护。

一、任务级临界区代码保护

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

/*** task. h** Macro to mark the start of a critical code region.  Preemptive context* switches cannot occur when in a critical region.** NOTE: This may alter the stack (depending on the portable implementation)* so must be used with care!** \defgroup taskENTER_CRITICAL taskENTER_CRITICAL* \ingroup SchedulerControl*/
#define taskENTER_CRITICAL()        portENTER_CRITICAL()
#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()/*** task. h** Macro to mark the end of a critical code region.  Preemptive context* switches cannot occur when in a critical region.** NOTE: This may alter the stack (depending on the portable implementation)* so must be used with care!** \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL* \ingroup SchedulerControl*/
#define taskEXIT_CRITICAL()         portEXIT_CRITICAL()
#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x )

  而 portENTER_CRITICAL()和 portEXIT_CRITICAL()也是宏定义,在文件 portmacro.h 中有定义,如下:

#define portENTER_CRITICAL()                 vPortEnterCritical()
#define portEXIT_CRITICAL()                     vPortExitCritical()

  函数 vPortEnterCritical()和 vPortExitCritical()在文件 port.c 中,函数如下:

void vPortEnterCritical( void )
{portDISABLE_INTERRUPTS();uxCriticalNesting++;/* This is not the interrupt safe version of the enter critical function soassert() if it is being called from an interrupt context.  Only APIfunctions that end in "FromISR" can be used in an interrupt.  Only assert ifthe critical nesting count is 1 to protect against recursive calls if theassert function also uses a critical section. */if( uxCriticalNesting == 1 ){configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );}
}
/*-----------------------------------------------------------*/void vPortExitCritical( void )
{configASSERT( uxCriticalNesting );uxCriticalNesting--;if( uxCriticalNesting == 0 ){portENABLE_INTERRUPTS();}
}

  可以看出在进入函数 vPortEnterCritical()以后会首先关闭中断,然后给变量 uxCriticalNesting加一, uxCriticalNesting 是个全局变量,用来记录临界段嵌套次数的。函数 vPortExitCritical()是退出临界段调用的,函数每次将 uxCriticalNesting 减一,只有当 uxCriticalNesting 为 0 的时候才会调用函数 portENABLE_INTERRUPTS()使能中断。这样保证了在有多个临界段代码的时候不会因为某一个临界段代码的退出而打乱其他临界段的保护,只有所有的临界段代码都退出以后才会使能中断!
  任务级临界代码保护使用方法如下:

void My_TaskTest(void *pvParameters)
{   while(true){ /* 为了保证对PORTA寄存器的访问不被中断,将访问操作放入临界区。进入临界区 */taskENTER_CRITICAL();/* 在taskENTER_CRITICAL() 与 taskEXIT_CRITICAL()之间不会切换到其它任务。 中断可以执行,也允许嵌套,但只是针对优先级高于configMAX_SYSCALL_INTERRUPT_PRIORITY的中断 – 而且这些中断不允许访问FreeRTOS API 函数. */PORTA |= 0x01;/* 我们已经完成了对PORTA的访问,因此可以安全地离开临界区了。 */taskEXIT_CRITICAL();vTaskDelay(20 / portTICK_PERIOD_MS);}vTaskDelete(NULL);
}

  注意临界区代码一定要精简!因为进入临界区会关闭中断,这样会导致优先级低于configMAX_SYSCALL_INTERRUPT_PRIORITY 的中断得不到及时的响应!

FreeRTOS临界区相关推荐

  1. FreeRTOS临界区应用与总结

    https://blog.csdn.net/chipsea_mltsum/article/details/85612939 项目背景: 做一个测量阻抗脉搏波的设备,设备功能其中之一是采集阻抗信号,通过 ...

  2. FreeRTOS 临界区总结

    当一名嵌入式开发人员从裸机开发切换到 基于 FreeRTOS 的开发后就要注意 中断,资源竞争等等问题了. 下面,总结一下 FreeRTOS 临界区的知识及用法: 1. 应用程序使用临界区 1.1 深 ...

  3. 【STM32】FreeRTOS临界区

    00. 目录 文章目录 00. 目录 01. 概述 02. 任务级临界区代码保护 03.中断级临界区代码保护 04. 预留 05. 预留 06. 附录 07. 参考 01. 概述 临界段代码也叫做临界 ...

  4. freeRtos学习笔(3)临界区管理

    freeRtos学习笔记 freeRtos临界区管理 freeRtos临界区 代码的临界段也称为临界区,一旦这部分代码开始执行,则不允许任何中断打断.为确保临界段代码的执行不被中断,在进入临界段之前须 ...

  5. 嵌入式中断:如何正确设置中断优先级 (万字总结) - 基于Cortex-M和FreeRTOS

    嵌入式中断:深入探讨如何正确设置中断优先级 - 基于Cortex-M和FreeRTOS 1. 如何正确设置中断优先级 2. 从Cortex-M角度 configPRIO_BITS 3. 从RTOS角度 ...

  6. STM32F103和AIR32F103的FreeRTOS中断优先级

    关于 Arm Cortex M 系列内核的中断优先级 Cortex M 的中断和优先级 首先要区分开 中断 和 中断优先级 这是两个不同的东西, 不要搞混了 对于 Cortex-M0 和 Cortex ...

  7. 【STM32】STM32系列教程汇总(暂时暂停更新...)

    00. 目录 文章目录 00. 目录 01. STM32平台简介 02. STM32开发环境 03. STM32初级教程 04. STM32中级教程 05. STM32高级教程 06. FreeRTO ...

  8. FreeRTOS记录(四、FreeRTOS任务堆栈溢出问题和临界区)

    本来计划是消息队列.信号量.任务通知.事件集.邮件的文章 但是因为自己调试的时候遇到了一个问题,还是把堆栈溢出问题放到前面来说 ..增加临界区的使用说明 2021/11/7 ..临界区的使用部分增加任 ...

  9. FreeRTOS 资源管理之临界区

    目录 1.taskENTER_CRITICAL 2.vTaskSuspendAll 3.Mutexes 3.1.Usage 临界区的概念在任何的 SoC 都存在,比如,针对一个寄存器,基本操作为:读- ...

最新文章

  1. 吐血整理:论文写作中注意这些细节,能显著提升成稿质量
  2. 【第二组】项目冲刺(Beta版本)第六次每日例会 2017/7/24
  3. 【深度学习】深入浅出YOLOv3目标检测算法和实现(图片和视频)
  4. 这样写的博客才有更多的人愿意看
  5. TypeError: Can not convert a float32 into a Tensor or Operation.
  6. 不用注册的麦咖啡永久使用
  7. 数据库事务原理详解-事务的嵌套
  8. 【20171025中】alert(1) to win 脚本渲染自建
  9. [css] body{height:100%}和html,body{height:100%}有什么区别?为什么html要设置height:100%呢,html不就是整个窗口吗?
  10. springboot 之Spring Web Mvc Framework
  11. 判断是否离开当前页面
  12. 2 Advanced Read/Write Splitting with PHP’s MySQLnd
  13. python使用什么关键字声明匿名函数_Python通过关键字____创造匿名函数。
  14. scratch教程2-程序sb,sb2,sb3转换EXE,HTML
  15. 使用Nodejs+puppeteer 批量保存网页为图片或PDF
  16. ggplot2 画图 X 轴排序问题
  17. 取消微信抢票的服务器,微信抢票怎么取消?
  18. 治疗贫血的几款食疗方
  19. HTML5页面跳转的几种方法
  20. APP元素定位工具Weditor连接夜神模拟器

热门文章

  1. 【香蕉oi】校庆(猫树、线性基)
  2. Go编译android,go语言的程序跑在android上
  3. 一步一步的写自己的相册
  4. tomcat html中文乱码解决
  5. 微信朋友圈“文字发”操作技巧,轻松实现不带图发布
  6. FPGA数字信号处理(22)FSK调制技术
  7. thinkphp curd 列表关联展现方式分享
  8. 2BizBox-ERP那点事儿系列之9
  9. oracle listagg支持,如何在Oracle查询上使用listagg上的条件
  10. 机器学习中的数学——激活函数(七):Softmax函数