FreeRTOS 临界段和开关中断

本文详细介绍了FreeRTOS中的临界段概念,强调了临界段代码执行时应避免中断,以保证系统实时性。FreeRTOS通过操作basepri寄存器实现任务代码和中断服务程序的临界段管理,提供了taskENTER_CRITICAL、taskEXIT_CRITICAL等函数,并讨论了中断服务程序中开关中断的处理方法。此外,还提到了BSP板级支持包中如何适应FreeRTOS的中断管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下转载自安富莱电子: http://forum.armfly.com/forum.php

临界段
代码的临界段也称为临界区,一旦这部分代码开始执行,则不允许任何中断打断。为确保临界段代码
的执行不被中断,在进入临界段之前须关中断,而临界段代码执行完毕后,要立即开中断。
FreeRTOS 临界段相关知识补充
FreeRTOS 的源码中有多处临界段的地方, 临界段虽然保护了关键代码的执行不被打断, 但也会
影响系统的实时性。比如此时某个任务正在调用系统 API 函数,而且此时中断正好关闭了,也就是进
入到了临界区中,这个时候如果有一个紧急的中断事件被触发,这个中断就不能得到及时执行,必须
等到中断开启才可以得到执行, 如果关中断时间超过了紧急中断能够容忍的限度, 危害是可想而知的。


FreeRTOS 源码中就有多处临界段的处理,跟 FreeRTOS 一样,uCOS-II 和 uCOS-III 源码中都是有
临界段的,而 RTX 的源码中不存在临界段。 另外,除了 FreeRTOS 操作系统源码所带的临界段以外,用
户写应用的时候也有临界段的问题,比如以下两种:
读取或者修改变量(特别是用于任务间通信的全局变量)的代码,一般来说这是最常见的临界代码。
调用公共函数的代码,特别是不可重入的函数,如果多个任务都访问这个函数,结果是可想而知的。
总之,对于临界段要做到执行时间越短越好,否则会影响系统的实时性。

### FreeRTOS开关中断临界区的实现方式与使用方法 在 FreeRTOS 中,开关中断临界区的管理是为了确保多任务环境下的资源访问安全性代码的正确性。以下是关于 FreeRTOS开关中断临界区的实现方式及使用方法的详细说明。 #### 1. 开关中断的实现 FreeRTOS开关中断功能主要通过操作 `BASEPRI` 寄存器来实现。对于基于 ARM Cortex-M 架构的处理器,`BASEPRI` 寄存器可以设置一个优先级阈值,低于该阈值的中断会被屏蔽,而高于或等于该阈值的中断仍然可以被响应[^2]。 - **关闭中断**: 使用函数 `portDISABLE_INTERRUPTS()` 来关闭低于某个优先级阈值的中断。 - **开启中断**: 使用函数 `portENABLE_INTERRUPTS()` 来恢复中断的正常响应。 这些函数的具体实现依赖于目标硬件平台,通常由 FreeRTOS 的端口层(port 层)提供。 #### 2. 临界区的实现 为了保护共享资源,FreeRTOS 提供了专门的临界区管理机制。临界区的退通过以下两个宏实现: - **临界区**: ```c taskENTER_CRITICAL(); ``` 此宏会关闭低于某个优先级阈值的中断,并维护一个嵌套计数变量 `uxCriticalNesting`,以支持临界区的嵌套调用[^3]。 - **退临界区**: ```c taskEXIT_CRITICAL(); ``` 此宏会检查嵌套计数变量 `uxCriticalNesting`,并在所有嵌套的临界区退后重新启用中断。 #### 3. 为什么需要专门的临界区管理? 直接使用开关中断函数(如 `portDISABLE_INTERRUPTS()` `portENABLE_INTERRUPTS()`)可能会导致问题,尤其是在临界区中存在嵌套调用的情况下。例如,如果在关闭中断后嵌套调用了另一个关闭中断临界区代码,当嵌套的临界区退时直接开启中断,会导致外层临界区的中断状态不一致[^1]。 通过引入嵌套计数变量 `uxCriticalNesting`,FreeRTOS临界区管理能够确保即使在嵌套调用的情况下,中断状态也能正确恢复。 #### 4. 示例代码 以下是一个简单的示例,展示如何在 FreeRTOS 中使用临界区保护共享资源: ```c #include "FreeRTOS.h" #include "task.h" // 假设这是一个共享资源 int sharedResource = 0; void criticalSectionExample(void) { // 临界区 taskENTER_CRITICAL(); // 访问共享资源 sharedResource++; // 模拟嵌套临界区 { taskENTER_CRITICAL(); sharedResource++; taskEXIT_CRITICAL(); } // 退临界区 taskEXIT_CRITICAL(); } ``` #### 5. 注意事项 - 在使用临界区时,应尽量减少临界区内的代码量,以降低对系统性能的影响。 - 如果临界区内需要处理高优先级中断,可以通过设置 `configMAX_SYSCALL_INTERRUPT_PRIORITY` 配置项来允许高优先级中断打断临界区代码。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值