下载 FreeRTOS
 

出色的 RTOS & 嵌入式软件

内核
最新资讯
简化任何设备的身份验证云连接。
利用 CoAP 设计节能型云连接 IoT 解决方案。
11.0.0 版 FreeRTOS 内核简介:
FreeRTOS 路线图和代码贡献流程。
使用 FreeRTOS 实现 OPC-UA over TSN。

低功耗 RTOS 演示——ST STM32L
使用 IAR 和 STM32L Discovery 开发板
[RTOS 移植]


由 ST 提供,适用于低功耗应用程序的 STM32L Discovery 开发板
STM32L Discovery 开发板

简介

此页面上记录的演示应用程序演示了如何利用 FreeRTOS 滴答抑制 (无滴答空闲模式) 功能来尽量降低 运行在 STM32L152 ARM Cortex-M3 微控制器 (来自 ST)上应用程序的功耗。 STM32L 是 专为需要极低功耗的应用程序 设计的。

演示使用 FreeRTOS IAR ARM Cortex-M3/4 端口, IAR适用于 ARM IDE (EWARM) 的嵌入式工作台, 和 STM32L 标准外设库的组件。 该项目预配置为在成本极低的 STM32L Discovery 开发板上运行。



EWARM 配备 FreeRTOS 内核感知插件


重要提示!关于使用 STM32L RTOS 演示的注意事项

使用此 RTOS 移植之前,请阅读以下所有要点。

  1. 源代码组织
  2. 演示应用程序
  3. RTOS 配置和使用详情
另请参阅常见问题:我的应用程序未运行,问题可能出在哪里?

源代码组织

官方 FreeRTOS zip 文件下载包含所有 RTOS 移植的源文件和所有演示应用程序,其中只有少数 是本项目需要的。 请参阅源代码组织 了解关于已下载文件的说明 和创建新项目的信息。

STM32L152 演示应用程序的 IAR 项目文件被称为 RTOSDemo.eww,位于 FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR 目录中。



ST STM32 ARM Cortex-M3 演示应用程序


硬件设置

演示使用内置在 STM32L Discovery 开发板上的 LED,无需硬件设置。


功能

单个项目文件可以被配置为创建低功率演示,或 标准 RTOS 演示。 ConfigCREATE_LOW_POWER_DEMO 常量用于在 两者之间切换。 configCREATE_LOW_POWER_DEMO 在 FreeRTOSConfig.h 顶部定义 (FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/include/FreeRTOSConfig.h,并包含在 IAR 项目中)。


ConfigCREATE_LOW_POWER_DEMO 设置为 1 时的功能

如果 configCREATE_LOW_POWER_DEMO 设置为 1 ,则 main() 调用 main_low_power()。 main_low_power() 在 main_low_power.c C 源文件中实现。

当 RTOS 滴答停止(抑制)时,进入低功耗模式。 与较浅的低功率模式相比,较深的低功率模式的唤醒时间更长, 而且仅仅是进入和(特别是)退出低功率模式 也要耗费功率。 因此,需要仔细考虑如何使用低功率模式, 以确保功耗真正降到最低, 并确保嵌入式设备满足其实时要求。

低功耗演示被配置为 根据预期的空闲期在四种不同的模式之间进行选择。 请注意,用于决定进入哪种低功耗模式的时间阈值 纯粹是为了方便演示,并不代表 任何特定应用程序的最佳值。

STM32L 的无滴答操作的特定部分在 STM32L_low_power_tick_management.c C 源文件中实现。 滴答中断是由 TIM2 外设产生的, 因此可以使用慢速输入时钟, 并且可以配置定时器在 STM32 处于较浅的低功耗模式中时继续运行。

实现:

  • 该演示会创建两个任务,一个 Rx 任务和一个 Tx 任务。 通过创建一个队列 来将 Tx 的信息传递到 Rx 任务。

  • Rx 任务在队列中阻塞以等待数据,每当收到数据时, LED 就会闪烁(打开,然后再关闭), 然后再一次返回队列中阻塞。

  • Tx 任务在尝试获取信号量时反复阻塞, 如果收到信号量或其阻塞时间过期,则解除阻塞。 离开阻塞状态后,Tx 任务使用队列 向 Rx 任务发送一个值,这反过来又导致 Rx 任务 退出阻塞状态并闪烁 LED。 因此,看到 LED 闪烁的速度 取决于阻塞时间。

  • Tx 任务的阻塞时间由中断服务程序改变, 该程序在按下 USER 按钮时执行。 进入的低功耗模式 取决于阻塞时间(如下文“观察到的行为”章节 所述)。 使用四种阻塞时间:短、中、长、无限。


低功耗行为:

  1. Tx 任务使用的阻塞时间被初始化为其“短”值, 因此,当 Tx 任务阻塞信号量时,它会快速超时,导致 LED 快速切换。 超时时间小于 configEXPECTED_IDLE_TIME_BEFORE_SLEEP (在 FreeRTOSConfig.h 中设置),所以 初始状态不抑制滴答中断或进入低功率模式。

  2. 按下按钮时, Tx 任务使用的阻塞时间增加 到其“中”值。 较长的阻塞时间会导致 lED 切换的速率变慢。 Tx 任务在阻塞状态下花费的时间 现在大于 configEXPECTED_IDLE_TIME_BEFORE_SLEEP,所以 tick 被抑制。 MCU 被置于“睡眠”低功耗状态,而 滴答被抑制。

  3. 当再次按下按钮时, Tx 任务使用的阻塞时间增加 到其“长”值,因此观察到的 LED 闪烁速率 变得更慢。 当使用“长”阻塞时间时,MCU 进入“低功耗睡眠”的低功耗状态。

  4. 下次按下按钮时, Tx 任务使用的阻塞时间 被设置为无限,因此 Tx 任务在尝试获取信号量时不会超时, 因此 LED 完全停止闪烁。 这两项任务 现在都被无限期阻塞,MCU 进入其“停止”低功耗状态 。

  5. 最后一次按下按钮的结果是,信号量被 "给予 " 以解除对 Tx 任务的阻塞,CPU 时钟被恢复到停止前的状态, 并且阻塞时间被重置为其“短”时间。 然后, 系统恢复到初始状态,LED 快速闪烁。


configCREATE_LOW_POWER_DEMO 设置为 0 时的功能

如果 configCREATE_LOW_POWER_DEMO 设置为0 ,则main() 调用 main_full()。 main_full() 在 main_full.c C 源文件中实现。

main_full() 会创建全面测试和演示应用程序 这表明:

创建的任务来自标准演示 集。 所有 RTOS 移植演示应用程序都使用标准演示任务。 这些任务没有特定的功能,创建它们仅为演示如何使用 FreeRTOS API 并测试 RTOS 端口。

创建“检查”任务以定期检查标准 演示任务,以确保所有任务都能 正常运行。 检查软件定时器的 回调函数切换 STM32L 开发板上的 LED。 这直观地反映出了系统的 运行状况。 如果 LED 每 3 秒切换一次,则 检查软件定时器未发现任何问题。 如果 LED 每 200 毫秒切换一次,则表明检查软件定时器 在至少一个任务中发现了一个潜在问题。


构建和执行演示应用程序

  1. 打开 FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/RTOSDemo.eww -从 IAR IDE 中。

  2. 打开 FreeRTOSConfig.h,并设置 configCREATE_LOW_POWER_DEMO 以生成 低功耗无滴答模式演示,或完整测试和演示应用程序, 根据需求操作。

  3. 确保目标硬件使用合适的 USB 数据线连接到主机。

  4. 按 F7 构建项目。 该演示应在没有任何错误 或警告的情况下构建。

  5. 构建完成后,按 CTRL+D 对 STM32L 微控制器 的闪存进行编程,启动调试 会话,并让调试器在进入 main() 函数时中断。



RTOS配置和使用详情


ARM Cortex-M3 FreeRTOS 移植特定配置

此演示的特定配置项目位于 FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/include/FreeRTOSConfig.h 中。 您可以编辑此文件中定义的常量,使其适合您的应用程序。 特别是:
  • configTICK_RATE_HZ

    此常量设置了 RTOS tick 中断的频率。 此演示 使用的设置取决于 configCREATE_LOW_POWER_DEMO 设置。

  • configKERNEL_INTERRUPT_PRIORITY 和 configMAX_SYSCALL_INTERRUPT_PRIORITY

    请 参阅 RTOS 内核配置文档,获取这些配置常量的完整信息。

  • configLIBRARY_LOWEST_INTERRUPT_PRIORITY 和 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY

    尽管 configKERNEL_INTERRUPT_PRIORITY 和 configMAX_SYSCALL_INTERRUPT_PRIORITY 是完整的八位移位值,根据定义可作为原始数字直接用于 ARM CORTEX-M3 NVIC 寄存器中,但 configLIBRARY_LOWEST_INTERRUPT_PRIORITY 和 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 是仅使用 STM32L NVIC 中实现的 4 个优先位定义的等效物 。 提供这些值是因为 CMSIS 库函数 NVIC_SetPriority() 和 STM32 标准外设库函数需要未移位的 4 位格式。

请注意:请参阅说明如何在 ARM Cortex-M 设备上设置中断优先级的页面。 请记住,ARM Cortex-M 核心中, 数字越小表示中断优先级越高。 这一点 可能有悖直觉,容易混淆! 如果要将 中断设置为低优先级,请不要将其优先级指定为 0(或其他低数值), 因为这会导致该中断在系统中具有 最高优先级,并且如果这个优先级 高于 configMAX_SYSCALL_INTERRUPT_PRIORITY,可能会导致系统崩溃。 另外,请勿忘记 分配中断优先级,因为默认情况下,中断优先级为 0, 这可能导致其处于最高优先级。

ARM Cortex-M 核心上的最低优先级实际上是 255,但不同 ARM Cortex-M 微控制器制造商会实现不同数量的优先级位, 并提供优先级指定方式不同的库函数。 例如, 在 STM32 ARM Cortex-M3 微控制器上,您可以指定的最低优先级实际上是 15 -这是由 FreeRTOSConfig.h 中的常量 configLIBRARY_LOWEST_INTERRUPT_PRIORITY 定义的。 可指定的最高优先级 始终为零。

NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ) 必须在 STM32 标准外设 库中任何其他与中断优先级有关的函数之前调用,就像在提供的演示中一样。

每个移植都将 "BaseType_t" 定义为 数据类型。 此移植将 BaseType_t 定义为长类型。


中断服务例程

与许多 FreeRTOS 移植不同的是,引发上下文切换的中断服务例程 无特殊要求,可根据编译器文档进行编写。 宏 portEND_SWITCHING_ISR() 可用于在 中断服务程序内请求上下文切换。

请注意,portEND_SWITCHING_ISR() 将启用中断。

下列源代码片段仅作为示例提供。 中断 使用信号量与任务(未显示)同步,并调用 portEND_SWITCHING_ISR() 以确保如果任务的优先级等同或高于中断优先级, 则中断会直接返回任务。 另一例子请参阅 此演示项目中包含的文件 main_low_power.c 中的函数 EXTI0_IRQHandler() 。

void Dummy_IRQHandler(void)
{
long lHigherPriorityTaskWoken = pdFALSE;

    /* Clear the interrupt if necessary. */
    Dummy_ClearITPendingBit();

    /* This interrupt does nothing more than demonstrate how to synchronise a
    task with an interrupt.  A semaphore is used for this purpose.  Note
    lHigherPriorityTaskWoken is initialised to zero. */
    xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );

    /* If there was a task that was blocked on the semaphore, and giving the
    semaphore caused the task to unblock, and the unblocked task has a priority
    higher than the current Running state task (the task that this interrupt
    interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
    internally within xSemaphoreGiveFromISR().  Passing pdTRUE into the
    portEND_SWITCHING_ISR() macro will result in a context switch being pended to
    ensure this interrupt returns directly to the unblocked, higher priority,
    task.  Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
    portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}

只有以 “FromISR” 结尾的 FreeRTOS API 函数可以从 中断服务例程中调用 - 而且中断的优先级须 小于或等于 configMAX_SYSCALL_interrupt_PRIORITY 配置常量(或 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)设置的优先级。


FreeRTOS 使用的资源

当 configCREATE_LOW_POWER_DEMO 设置为 0 时,标准 FreeRTOS Cortex-M 端口被 使用,此时需要独占使用 SysTick 和 PendSV 中断。 还会使用 SVC 编号 #0。

当 configCREATE_LOW_POWER_DEMO 设置为1时,可对 TIM2 外设进行独占访问。



内存分配

ARM Cortex-M3 演示应用程序项目中包含 Source/Portable/MemMang/heap_4.c,用于提供 RTOS内核所需的内存分配。 请参阅 API 文档的内存管理部分, 以获取完整信息。


其他事项

请注意,vPortEndScheduler() 尚未实现。




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.