在 FreeRTOS™ 10.3.1 版本看到两个新 AVR® 微控制器 (MCU) 端口或者六个新端口令人为之一振。这些端口不仅涵盖了 MCU 的 MegaAVR ® 0 系列和全新的 AVR Dx 设备,还包含 AVR MCU 的三个主要编译器: MPLAB XC8 编译器、AVR-GCC 和 AVR 的IAR嵌入式工作台 ®。为什么这是个好消息?原因在于 FreeRTOS 早期版本支持的 ATmega323 和 ATmega128 MCU 属于陈旧设备。虽然这些设备产品仍然可用,但 AVR MCU 早已历经演进,性能显著提升:每个人都想体验最新一代产品!
通过对新设备和新编译器的支持功能,我很想了解标准 FreeRTOS 演示示例在某个新 MCU 上消耗多少内存、编译器的选择对代码大小的实际影响。我将仅关注 AVR Dx MCU 系列端口,确保本文言简意赅。
AVR Dx 大揭秘:是 tinyAVR ® 、megaAVR 还是 AVR XMEGA ® MCU?
广为人知的 AVR MCU 可能是 ATmega328 ,即 Arduino® UNO 套件上使用的 MCU。AVR Dx 是最新一代 AVR MCU ,类似于最新的 tinyAVR 1 系列,如 ATtiny817 ,也与 AVR XMEGA 设备相类似。因此,相较于旧版 MegaAVR MCU,AVR Dx 的复杂度更高。这种差异在外围设备中最为明显,也体现在如何在内存映射中更好地组织它们。
目前有两个AVR Dx MCU 系列。AVR DA 系列采用用于接口电容式传感器的最新版本外围触摸控制器 (PTC) 模块,可用于可触摸用户界面。 AVR DB 系列具有内置运算放大器和多电压 I/O,即表示可以从单独电压域运行所选引脚。这样就无需使用昂贵的电平转换器。
与过去AVR MCU 相比,AVR Dx MCU 性能有显著改善。内部稳压电源运行核心逻辑,表示核心的最大速度不受外部电源电压的限制。无论电源电压如何,皆可以在 24 MHz 条件下运行。换言之,即使在低电压应用中,也可以获得更多马力且有源模式功耗更低。
IDE 和编译器
新版编译器支持 AVR MCU,属于 MPLAB XC8 编译器,是 GCC 编译器的变体版本。现已将其集成到 MPLAB X 集成开发环境中,并已添加至Microchip Studio 的 v7.0.2542 版本中。MPLAB XC8 编译器提供免费版本,囊括优化选项子集。MPLAB XC8 PRO 属于商业版本,提供用户期待的专业级编译器的所有优化。虽然 IAR EWAVR 和 Microchip Studio 仅适用于 Windows® 操作系统,但 MPLAB X 和 MPLAB XC8 编译器可用于 Linux® 和 macOS® 以及 Windows 系统。顺便一提,MPLAB X IDE 亦兼容 AVR-GCC 编译器。
多年来用户群一直维护 GNU GCC 编译器的 AVR-GCC 变体版本,虽然并未积极维护 WIN-AVR 原有版本,也这一版本仍然存在。后来 Atmel 决定将 AVR-GCC 并入 Atmel Studio 集成开发环境,然后将 AVR-GCC 作为 Atmel Studio 插件提供给 AVR MCU 用户 。AVR-GCC 编译器和 Arduino 板为 AVR MCU 在 Maker 社区的普及发挥重大作用。2020 年 11 月,Microchip 将 Atmel Studio 7 更名为 AVR 和 SAM 设备专属 Microchip Studio ;我将其称为 Microchip Studio。虽然功能未作更改,但值得一提的是有一项绝佳附加功能: Microchip Studio 兼容 MPLAB XC8 编译器。这说明熟悉 Atmel Studio 和 AVR-GCC 的用户可以仍然使用这一知名的集成开发环境,同时能够发挥 MPLAB XC8 编译器的优势。
IAR AVR 嵌入式工作台(简称 IAR EWAVR )是首个可使用 AVR MCU 的 C 编译器。如果定义指令集,则 AVR Core 发明者与 IAR 密切合作,产生优化 C 代码的较好指令集。IAR EWAVR 集 IDE、编译器和模拟器于一身。Microchip’ EWAVR 兼容 IAR 的调试和编程工具。
所用编译器版本:
- AR EWAVR (v7.30)
- AVR-GCC (build v3.6.2.1778)
- MPLAB XC8 编译器 (v2.30)
查找合适的端口和设备
查看 FreeRTOS 网站的支持设备时,我意识到有必要向你们介绍一下半导体公司历史。虽然 AVR MCU 属于Microchip 产品,但最初是由 Atmel(后于 2016 年被 Microchip 收购)发布。这就是 FreeRTOS 网站在 Atmel 下列出 AVR 设备而非在 Microchip 下列出的原因。此处还提供了 Microchip’ 的 Arm® 基于核心的 MCU 完整列表。
深入浏览 FreeRTOS 网站结构后,我找到了AVR Dx 端口页面,该页面同时支持 AVR DA 和 AVR DB 设备。端口附带演示使用 AVR128DA48 设备和相应的 AVR128DA48 Curiosity Nano 评估板。此主板适用于所有端口,用于确认代码是否正在运行。
下载(或使用 Git 克隆)
我从FreeRTOS下载页面下载了标准发行版。标准发行版是包含所有端口和演示、以及内核和 FreeRTOS 库的 zip 压缩文件。如果用户希望拥有代码的本地 Git 分支,也可以从 FreeRTOS GitHub 项目中将其克隆出来。
下载 zip 压缩文件,将其解压并存放到 Demo 文件夹。如果您喜欢使用 MCU,那么这里就如同糖果店一样,琳琅满目,选择多样!
在详细介绍编译器之前,值得一提的是 Demo 示例。
Demo 示例
AVR Dx 端口带有三个 demo。将三个 demo 集成到各编译器端口的单个代码项目中。这三个 demo 是:
- Blinky
- Minimal
- Full
可以使用 mainSELECTED_APPLICATION define 在编译时选择 demo。在 main.c 文件中,可将 mainSELECTED_APPLICATION 定义为 0、1 或 2,进而在点击 build 按键之前选择所需的 demo。
MPLAB X IDE (v5.40) 和 MPLAB XC8 编译器 (v2.31)
在菜单中,“打开项目”并导航到 AVR_DX_MPLAB 项目文件。MPLAB X IDE 中的项目文件是一个扩展名为“.X”的文件夹,在这种情况下为“ AVR_Dx_MPLAB.X ”。
“项目属性”描述了编译器的配置方式。“配置”确认项目被配置为使用 MPLAB XC8 v2.31 编译器,并且所选的“设备”是AVR128DA48。端口页面指出,MPLAB XC8 v2.20 编译器用于端口的开发和测试,但使用 v2.31(本文撰写时最新版本)也很流畅。
那么,启用了哪些优化级别?优化选项位于选项类别下拉菜单中的 XC8 全局选项 -> XC8 编译器。
选中所有优化复选框,但“调试”选项除外,这样旨在检查是否使用系统内调试器进行调试,例如 MPLAB PICkit™ 4、MPLAB ICD 4 或 Atmel-ICE 编程器/调试器 ,但这完全是两回事。“优化级别”设置为 “s” ,这是自由优化的最高级别。此优化级别可供 MPLAB XC8 PRO编译器的 PRO 版本访问。MPLAB XC8 编译器免费版支持优化级别 -O1 和 -O2。使用 -Os 编译会发出警告,即由于 -Os 某些优化设置需要 MPLAB XC8 PRO 编译器,因而这些优化能会被忽略掉,但编译时不会出错。
此外,在“附加选项”文本框中指定 -flto 开关。我参考了 MPLAB XC8 编译器用户指南查看开关控件。-flto 开关打开“标准链接时间优化器” ,这是在 MPLAB XC8 编译器 PRO 版本中发现的一个功能。附带说明:AVR-GCC 编译器未记录 -flto 选项,因此这是 MPLAB XC8 编译器和 AVR-GCC 的区别所在。
由于 Microchip 拥有 MPLAB XC 编译器所有既往版本的在线存档和相应用户指南,因此搜索引擎可能无法提供最新版本的用户指南;建议直接从 MPLAB XC 编译器产品页面获取所需版本。
代码大小结果
由于并非每个人皆持有 MPLAB XC8 PRO 编译器许可证,现已提供免费编译器和 PRO 编译器的代码大小结果。编译器不会在“输出”窗口中生成任何代码大小信息,但“控制面板”窗口则显示了规整图形和纯文本表现形式。
根据三个示例的代码大小结果,获得 demo 应用程序的大小:
MPLAB XC8 PRO 版编译器 (-Os) | MPLAB XC8 免费版编译器 (-Os) | |||
Demo | 闪存大小 | SRAM 大小 | 闪存大小 | SRAM 大小 |
Blinky | 6836 | 4271 | 9078 | 4287 |
Minimal | 10230 | 4308 | 13840 (-O1) | 4319 |
Full | 13255 | 4332 | 16691 | 4338 |
如您所见,在生成小于免费版本的程序代码方面,MPLAB XC8 PRO 编译器显然性能更佳,而这两项设置的数据内存使用率几乎无差异。
Microchip Studio (v7.0.2542) 和 AVR-GCC (v3.6.2.1778)
现在可以打开 Microchip Studio 项目了。在Microchip Studio选择“打开项目” ,导航到FreeRTOS/Demo/AVR_Dx_Atmel_Studio文件夹,然后打开 RTOSDemo 文件。
在方案资源管理器 (Solution Explore)(导航)中,右键单击项目并选择“属性” ,打开编译器配置。从中选择 AVR/GNU C 编译器 -> 优化项目。选中所有复选框,优化选为 -Os。
在 Debugging 选项中,将“调试级别”设置为 -g2(默认级别)。
对于链接器 -> 优化 ,选中 "Garbage collection unused section" 选项。GUI 似乎包括最常见的 GCC 选项,但也可以手动指定其他选项。
搜索结果
Microchip Studio 和 AVR-GCC 以及其他编译器都会生成一些警告。其中有些警告涉及完成超出变量支持宽度的移位,本文不作赘述。Microchip Studio 在编译器输出窗口中显示代码大小:
警告:如果在程序代码标准 .text 段之外的其他段放置代码,则代码大小信息可能缺乏准确性。通过使用 avr-size 工具查看 ELF 输出文件,得出结论:代码主要使用 .text 段,由于这种方式的代码大小误差极小,所以较为合理。
演示 | 闪存大小 | SRAM 大小 |
Blinky | 8026 | 4309 |
Minimal | 12490 | 4420 |
Full | 15152 | 4555 |
AVR 专用 IAR 嵌入式工作台
在 IAR EWAVR 中,使用工作区文件打开 FreeRTOS 端口项目。右键单击项目并选择“选项” ,即可进行优化设置。GUI 选项有限,任何关键内容一览无余,因此简单易用。选择优化级别以及是否需要优化代码的大小或速度,然后选中所有复选框。
Porthardware.h 包含 FreeRTOSConfig.h ,但由于某种原因,编译器无法自行定位此文件,因此,必须指定编译代码的路径。这个解决方法极简单,但我曾期待代码开箱即可编译。
在“项目” 菜单中点击“重新生成所有” …
Demo: | 闪存大小 | SRAM 大小 |
Blinky | 7278 | 4636 |
Minimal | 11341 | 4728 |
Full | 11921 | 4863 |
我并不是编译器专家……
并非每个人都是编译器方面的专家。所以,我联系了 Microchip’ 和 IAR 的编译专家,询问是否可以进一步改进端口的优化设置。这些优化设置可能坑许多用户并不熟悉,因此,我学以致用,希望能为那些需要将代码缩小至最低限度的人带来一些启发。
Microchip 提供的专家建议
Microchip’的专家建议在 MPLAB XC8 编译器的“全局选项”中添加以下切换开关:
这项功能极大改善了代码大小,降至 7.9% 至 10.6% :
Demo | 闪存大小 | SRAM 大小 | 改进 |
Blinky | 6242 | 4271 | 8.7% |
Minimal | 9426 | 4308 | 7.9% |
Full | 11847 | 4332 | 10.6% |
IAR 提供的专家建议
IAR 的专家建议在命令行选项中添加以下内容:
这项改进会使所有三个 demo 示例的代码大小减少约 200 字节,即指实现 1.5% 至 3.1% 的改进:
IAR EWAVR(专家版) | |||
Demo: | 闪存大小 | SRAM 大小 | 改进 |
Blinky | 7056 | 4636 | 3.1% |
Minimal | 11099 | 4728 | 2.1% |
Full | 11739 | 4863 | 1.5% |
概述
我们的任务是找出 AVR Dx 系列在内存消耗方面是否适合运行 FreeRTOS。因此,在 IAR 和 Microchip: 并未提供专家反馈的情况下,对比框中代码大小结果。
AVR-GCC | MPLAB XC8 PRO 版编译器 | MPLAB XC8 免费版编译器 | IAR EWAVR | |||||
Demo: | 闪存大小 | SRAM 大小 | 闪存大小 | SRAM 大小 | 闪存大小 | SRAM 大小 | 闪存大小 | SRAM 大小 |
Blinky | 8026 | 4309 | 6836 | 4271 | 9078 | 4287 | 7278 | 4636 |
Minimal | 12490 | 4420 | 10230 | 4308 | 13840 | 4319 | 11341 | 4728 |
Full | 15152 | 4555 | 13255 | 4332 | 16691 | 4338 | 11921 | 4863 |