注意: 本页记录了 EFM32 演示的原始版本(旧版本)。 现已推出包括低功耗 tickless 操作演示的更新演示。 本页面展示了基于 ARM Cortex-M3 的 Silicon Labs EFM32 微控制器的第一个 FreeRTOS 演示。 EFM32 提供了 EM1 至 EM4 四种节能模式,其中 EM4 提供了最大节能效果。 但本页面演示使用标准的 FreeRTOS ARM Cortex-M3 移植。因此,RTOS 内核本身并不利用这些节能模式。 相反,演示代码 (非 RTOS 内核代码)中添加了一些基本的节能功能,但这意味着只能演示 EM1。 使用任何其他模式 均会导致 tick 中断停止。 有关使用 EM2 和 EM3 的其他演示的链接,请参阅主要 Silicon Labs 列表。 开发套件 配备 EFM32G890F128 微控制器, 该微控制器具有 128KB 闪存和 16KB 的 RAM。 演示使用:
FreeRTOS ARM Cortex-M3 移植包括一个完全中断嵌套模型。必须按照 自定义页面上的说明设置中断优先级才能正确操作。
重要! 使用 EFM32 ARM Cortex-M3 演示的注意事项使用此 RTOS 移植之前,请阅读以下所有要点。另请参阅常见问题:我的应用程序未运行,问题可能出在哪里? 源代码组织EFM32G890F128 演示的 IAR 嵌入式工作台的工作区称为 RTOSDemo.eww,位于 FreeRTOS/Demo/CORTEX_EFMG890F128_IAR 目录。 请注意,该项目同时包含调试和释放配置,但仅对调试配置进行了配置。下载的 FreeRTOS zip 文件包含所有移植文件和演示应用程序项目文件。因此,该文件所含文件 远超此演示所用的文件。请参阅源代码组织部分,获取已下载文件的描述以及关于创建新项目的信息 。
演示应用程序构建和执行演示应用程序
演示任务main() 在启动RTOS调度程序之前创建 19 个任务。任务内容主要包括 标准演示任务(参见 演示应用程序 章节,了解各个任务的详细信息)。各项任务的存在旨在示明如何使用 FreeRTOS API ,并 仅对 FreeRTOS 移植进行测试,但不包含应用程序特定的有用功能。除了标准演示任务外,还创建了以下任务和测试:
节能特性如本页顶部所述,此演示使用标准 FreeRTOS ARM Cortex-M3 移植,因此由演示应用程序执行所有节能功能(此时), 而非由 RTOS 内核。 演示应用程序只能 使用节能模式 EM1 - 任何其他模式均会导致 tick 中断 停止(请参阅主要 Silicon Labs 列表 了解关于使用 EM2 和 EM3 的其他演示的链接)。演示应用程序在两个地方使用 EM1:
RTOS配置和使用详情RTOS 移植特定配置FreeRTOS/Demo/CORTEX_EFMG890F128_IAR/FreeRTOSConfig.h 包含此演示的特定配置项。 可以 在本文件中定义的常量,以适配您的应用程序。 特别是-
如果中断服务程序使用 FreeRTOS API 函数, 则必须设置中断的优先级。 如果将其保留为默认值 将导致最高可能优先级执行中断。 ARM Cortex-M3 核心的最低优先级实际上是 255,但不同的 ARM Cortex-M3 供应商采用了不同数量的优先位, 并提供了期望以不同方式指定优先级的库函数。 每个移植 #defines 'BaseType_t' 为该处理器的最有效数据类型。 本移植将 BaseType_t 定义为长整型。 请注意,vPortEndScheduler() 尚未实现。 中断服务程序在演示应用程序中,向量表保存在闪存。与大多数移植不同,导致上下文切换的中断服务程序没有特殊要求,可以根据编译器文档编写。 可将宏 END_SWITCHING_ISR () 用于从 ISR 内请求上下文切换。 下文提供了中断服务程序 模板示例。 示例仅供参考。 请注意,portEND_SWITCHING_ISR() 将使中断保持启用状态。 另请注意, 使用 FreeRTOS API 的任何中断优先级( 如以下模板)必须设置为等于或低于 confgiMAX_SYSCALL_INTRUPT_PRIORITY。 如果中断优先级 低于 configMAX_SYSCALL_INTERRUPT_PRIORITY,则必须在数值上高于 configMAX_SYSCALL_INTRUPT_PRIORITY,因为在 ARM Cortex-M3 上, 优先级数值低表示逻辑上的高中断优先级。
/* The interrupt service routine can be written as a standard C function. */ void vAnExampleISR( void ) { long lTaskWokenByPost = pdFALSE; unsigned long ulDataValue; /* Remember to clear the interrupt source. */ .... /* Assume the interrupting peripheral supplies a value that needs to be passed to a task. */ ulDataValue = ulGetValueFromPeripheral(); /* In this example, a queue is used to send data to a task. This could equally be a counting or other type of semaphore. Note that lTaskWokenByPost has already been initialised to pdFALSE. The queue must have already been created before this interrupt service routine executes for the first time!. */ xQueueSendFromISR( xQueue, &ulDataValue, &lTaskWokenByPost ); /* If sending to the queue caused a task to unblock, and the task that was unblocked has a priority equal to or above the currently executing task, then lTaskWokenByPost will have been set to pdTRUE. Passing pdTRUE as the parameter to portEND_SWITCHING_ISR() will cause a context switch to occur as soon as the interrupt completes. */ portEND_SWITCHING_ISR( lTaskWokenByPost ); }
中断服务程序模板
在抢占式和协同式 RTOS 内核之间切换在 FreeRTOS/Demo/CORTEX_EFMG890F128_IAR/FreeRTOSConfig.h 中将定义 configUSE_PREEMPTION 设置为 1 以使用抢占式,或设置为 0 以使用协同式。编译器选项与所有的端口一样,使用正确的编译器选项至关重要。 若要确保这一点, 最佳方法是基于提供的演示应用程序文件构建您的应用程序。内存分配Source/Portable/MemMang/heap_2.c 位于 ARM Cortex-M3 演示应用程序项目中, 用于提供 RTOS 内核所需的内存分配。 请参阅 API 文档的内存管理部分, 获取完整信息。Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|