正点原子FreeRTOS学习笔记——临界段代码保护

目录

一、基本原理

临界区

Cortex-M 硬件详情

使用 RTOS 内核时的相关性

二、函数

1、任务级进出临界段

2、中断级进出临界段


一、基本原理

临界区(临界段代码):必须完整运行,不能被打断的代码段。

临界区本质:屏蔽中断。

适用场合:

                1、外设 需严格按照时序初始化的外设,如IIC、SPI等等

                2、系统自身需求

                3、用户需求

打断当前程序的运行:中断与任务调度

以下转载自官网:

原文链接:https://www.freertos.org/zh-cn-cmn-s/RTOS-Cortex-M3-M4.html

临界区

Cortex-M 硬件详情

RTOS 内核使用 ARM Cortex-M 核心的 BASEPRI 寄存器 来实现临界区。 因此,RTOS 内核能够仅屏蔽一部分中断, 从而提供灵活的中断嵌套模型。

BASEPRI 是一个位掩码。 为 BASEPRI 设置为一个值后,它可以屏蔽所有逻辑优先级等于 或低于该值的中断。 因此,无法使用 BASEPRI 来 屏蔽优先级为 0 的中断。

题外话: 可以从中断中安全调用的 FreeRTOS API 函数 使用 BASEPRI 来实现中断安全临界区。 进入临界区时, BASEPRI 的值设置为 configMAX_SYSCALL_interrupt_PRIORITY, 退出临界区时,设置为 0。 我们收到许多故障报告 认为 BASEPRI 应在退出临界区时返回到原始值,而不仅仅是设置为 0, 但是 Cortex-M NVIC 绝不会接受一个优先级低于当前正在执行的中断的优先级的中断, 不管 BASEPRI 设置为多少。 一个总是 将 BASEPRI 设置为 0 的实现执行代码的速度比一个 存储然后恢复 BASEPRI 值的实现更快 (编译器的优化器打开的情况下)。

使用 RTOS 内核时的相关性

RTOS 内核通过将 configMAX_SYSCALL_INTRUPT_PRIORITY 的值 写入 ARM Cortex-M BASEPRI 寄存器来创建临界区。 因为 BASEPRI 无法屏蔽 优先级为 0 的中断(最高的优先级), 所以不得将 configMAX_SYSCALL_INTERRUPT_PRIORITY 设置为 0。

二、函数

使用注意:

                成对使用;

                支持嵌套;

                尽量保持临界段耗时短

1、任务级进出临界段

void taskENTER_CRITICAL( void );
void taskEXIT_CRITICAL( void );

通过调用 taskENTER_CRITICAL() 进入临界区,随后 通过调用 taskEXIT_CRITICAL() 退出临界区。

宏 taskENTER_CRITICAL() 和 taskEXIT_CRITICAL() 提供了一个基本 临界区实现,只需禁用中断即可使其全局运作, 或在特定的中断优先级范围内运作。 

如果所使用的 FreeRTOS 移植未使用 configMAX_SYSCALL_INTERRUPT_PRIORITY 内核配置常量(也称为 configMAX_API_CALL_INTERRUPT_PRIORITY),则调用 taskENTER_CRITICAL() 将 全局禁用中断。 如果所使用的 FreeRTOS 移植 使用了 configMAX_SYSCALL_INTERRUPT_PRIORITY 内核配置常量, 则调用 taskENTER_CRITICAL() 会将中断保留在 由已禁用的 configMAX_SYSCALL_INTERRUPT_PRIORITY 设置的中断优先级一下, 并启用所有更高优先级的中断。

抢占式上下文切换仅在中断内发生, 在中断被禁用时不会发生。 因此,可保证 调用 taskENTER_CRITICAL() 的任务维持在运行状态,直到 退出临界区,除非任务明确试图阻塞或让出 (它不应在临界区的内部进行该操作)。

对 taskENTER_CRITICAL() 和 taskEXIT_CRITICAL() 的调用旨在嵌套。 因此,只有在执行了一次对 taskEXIT_CRITICAL() 的调用, 用于所有先前的 taskENTER_CRITICAL() 调用之后, 才会退出临界区。

临界区必须保持非常短,否则将影响 中断响应时间。 每次 taskENTER_CRITICAL() 调用都必须紧密配合 taskEXIT_CRITICAL() 调用。

不得从临界区调用 FreeRTOS API 函数。

taskENTER_CRITICAL() 和 taskEXIT_CRITICAL() 不得从中断服务程序 (ISR) 调用——请参阅 taskENTER_CRITICAL_FROM_ISR() 和 taskEXIT_CRITICAL_FROM_ISR(),获取中断安全等效项。

参数:

返回:

void vPortEnterCritical( void )
{
    portDISABLE_INTERRUPTS();
    uxCriticalNesting++;//进入临界区支持嵌套的原因,调用一次加1

    /* This is not the interrupt safe version of the enter critical function so
     * assert() if it is being called from an interrupt context.  Only API
     * functions that end in "FromISR" can be used in an interrupt.  Only assert if
     * the critical nesting count is 1 to protect against recursive calls if the
     * assert function also uses a critical section. */
    if( uxCriticalNesting == 1 )
    {
        configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
    }
}


void vPortExitCritical( void )
{
    configASSERT( uxCriticalNesting );//断点,方便调试
    uxCriticalNesting--;调用一次减1,直到0时退出临界区

    if( uxCriticalNesting == 0 )
    {
        portENABLE_INTERRUPTS();
    }
}

2、中断级进出临界段

UBaseType_t taskENTER_CRITICAL_FROM_ISR( void );
void taskEXIT_CRITICAL_FROM_ISR( UBaseType_t uxSavedInterruptStatus );

taskENTER_CRITICAL() and taskEXIT_CRITICAL() 版本 可用于中断服务程序 (ISR)。

在 ISR 中,通过调用 taskENTER_CRITICAL_FROM_ISR() 进入临界区, 然后通过调用 taskEXIT_CRITICAL_FROM_ISR() 退出。

taskENTER_CRITICAL_FROM_ISR() 宏和 taskEXIT_CRITICAL_FROM_ISR() 宏提供了 基本临界区的实现,只需禁用中断即可使其全局运作, 可以是全局禁用,也可以是禁用到特定的中断优先级。

如果使用的 FreeRTOS 移植支持中断嵌套,则调用 taskENTER_CRITICAL_FROM_ISR() 将在内核配置常量 configMAX_SYSCALL_INTERRUPT_PRIORITY 设置的中断优先级或以下级别禁用中断,并 启用所有其他中断优先级。 如果使用的 FreeRTOS 移植不支持中断嵌套,则 taskENTER_CRITICAL_FROM_ISR() 和 taskEXIT_CRITICAL_FROM_ISR() 将不起作用。

调用 taskENTER_CRITICAL_FROM_ISR() 和 taskEXIT_CRITICAL_FROM_ISR() 旨在用于嵌套,但宏的使用方式的语义不同于 taskENTER_CRITICAL() 和 taskEXIT_CRITICAL() 等效项。

临界区必须保持非常短,否则将影响 更高优先级的中断的响应时间,会导致该中断嵌套。 每次 taskENTER_CRITICAL_FROM_ISR() 调用都必须紧密配合 taskEXIT_CRITICAL_FROM_ISR() 调用一起使用。

不得从临界区调用 FreeRTOS API 函数。

参数:

uxSavedInterruptStatustaskEXIT_CRITICAL_FROM_ISR() 将 uxSavedInterruptStatus 作为其 唯一参数。 作为 uxSavedInterruptStatus 参数使用的值 必须是从匹配的 taskENTER_CRITICAL_FROM_ISR() 调用返回的值。

taskENTER_CRITICAL_FROM_ISR() 不采用任何 参数。

返回:

taskENTER_CRITICAL_FROM_ISR() 返回调用宏之前的中断掩码状态 。 taskENTER_CRITICAL_FROM_ISR() 返回的值 必须作为 uxSavedInterruptStatus 参数用于匹配的 taskEXIT_CRITICAL_FROM_ISR() 调用。

taskEXIT_CRITICAL_FROM_ISR() 不返回值。


  • 58
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 正点原子freertos pdf是一份详细的技术文档,主要介绍了正点原子FreeRTOS实时操作系统的基本架构和实现方法。该文档详细介绍了FreeRTOS的任务管理、时间管理、内存管理、中断管理、队列管理等相应的应用、算法、数据结构、函数和宏等的使用方法和实现原理。该文档还包括了多个实际例子,展示了如何使用FreeRTOS在真实项目中实现任务调度、时间管理、共享资源管理等功能。 该文档对于想要学习和掌握FreeRTOS实时操作系统的开发人员来说,是一份非常有价值的资料。通过学习该文档,开发人员可以深入了解FreeRTOS的设计思路、内部实现和应用场景,掌握FreeRTOS的核心功能和使用方法,从而更加熟练地应用FreeRTOS进行实时操作系统开发。同时,该文档还提供了大量的代码示例,让开发人员可以更加快速地理解和应用FreeRTOS,帮助开发人员在项目开发过程中更高效地完成任务。总之,正点原子freertos pdf是一份对于实时操作系统开发人员非常有用的学习资料,可以帮助开发人员更快速地掌握FreeRTOS技术,提高开发效率。 ### 回答2: 正点原子freertos是一种嵌入式实时操作系统,采用轻量级设计的freertos内核。它具有高度可移植性、可扩展性、可配置性、可靠性等优点,可以很好地处理实时任务和多任务之间的优先级和调度问题,满足各种应用的不同需求。正点原子freertos提供了丰富的API接口,支持线程、信号量、消息队列、定时器、互斥锁等功能,方便编写实时应用程序。在使用过程中,用户可以根据系统需求进行配置参数,如内存大小、最大线程数量、时钟频率等。同时,正点原子freertos还支持跨平台开发,通过移植可以在不同的硬件平台上运行,提高了应用程序的可移植性和可重用性。normal,正点原子freertos官方也提供了详细的编程手册和示例代码,方便开发者学习和参考。总之,正点原子freertos是一款高效、灵活、可靠的实时操作系统,可以为嵌入式系统的开发提供强有力的支持。 ### 回答3: 正点原子是一家国内知名的开源电子硬件平台品牌,其推出了一款名为 FreeRTOS 的操作系统软件。该软件旨在让开发者和工程师们更加方便地进行电子设备的开发和编程。此外,正点原子还为该软件提供了一份详细的使用手册——FreeRTOS PDF。 FreeRTOS PDF 是一份面向初学者和资深工程师的完整使用手册,其中包括了从安装软件、核心概念、任务管理、队列和信号量、定时器等各方面的详细教程和指导。通过这份手册,用户可以更加深入地理解 FreeRTOS 软件的运作机制和一些常见问题的解决方案。同时,手册也提供了丰富的示例代码,方便用户在开发过程中进行参考和借鉴。 总之,正点原子FreeRTOS PDF 告诉我们,通过该软件可以轻松地实现完整的多任务管理系统,支持多个处理器、各种架构和设备等,并能保证高性能和实时性。而该手册则是完美地展现了 FreeRTOS 的功能和使用方法,为广大工程师和开发者提供了强有力的支持和指导。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值