用于测试 MCU 应用程序的运行时环境
该软件包提供了所有功能,以实现用于测试 MCU 应用程序的低侵入式运行时环境。
图 1 - 运行时测试环境原理
该软件包中包含的 C 代码必须集成到被测设备 (DUT) 的固件代码中。
必须对 DUT 固件的代码进行修改,包括添加对名为“InitTestConsole()”的单个函数的调用,该函数属于运行时测试环境的 C 代码,该代码在 DUT 启动时启动运行时测试环境。
运行时测试环境旨在:
- 通过 PRINTF 和 SCANF 函数处理与连接到 DUT 的主机设备的通信
- 读取存储在 DUT 的 FLASH 存储器中的预编译测试(ELF 文件)
- 重新定位这些预编译的测试,以适应 DUT 固件的符号表
- 将这些重新定位的测试加载到 DUT 的 RAM 内存中
- 触发 DUT 与固件同时执行这些重新定位的测试
运行测试不会造成干扰,因为运行时测试环境创建的任务的优先级在 FreeRTOS 生态系统中设置为 IDLE 任务优先级。
由于测试由 DUT 直接运行,因此不需要额外的硬件。
通过在主机设备(PC、Raspberry PI)上运行脚本可以轻松设置测试的自动化,因为触发测试的执行仅涉及通过 USB 转串行连接将其名称发送到 DUT。
开发板:EVK-MIMXRT1060、MIMXRT1060-EVKB、EVK-MIMXRT1064
类别:工具
外设:USB、UART
工具链:MCUXpresso IDE
目录
1.软件包
用于测试 MCU 应用程序的运行时环境的软件以原始源文件的形式提供。
此运行时测试环境需要依赖于以下项的 DUT 固件:
- FreeRTOS 作为操作系统
- LittleFS 作为文件系统
1.1 LittleFS
此用于测试 MCU 应用程序的运行环境的实现依赖于 LittleFS 作为文件系统。
然而,此实现可以轻松适应其他文件系统(例如 VFAT)或从 FLASH 读取原始数据。实际上,必须实现以下特定的读取函数:
- “elfbufferspecific_read()”
- “elfbufferspecific_seek()”
- “elfbufferspecific_tell()”
- “elfbufferspecific_open()”
- “elfbufferspecific_close()”
然后必须在 C 文件“elf-interface.c”中实现名为“initloaderinterface_specific()”的函数:
图 2 - 回调函数 initloaderinterface_specific()
最后,函数“initloaderinterfacespecific()”必须由 C 文件“exec.c”内的回调函数“*consoleloadelf(char *path)”调用,而不是函数“initloaderinterfacelittlefs()”。
1.2 FreeRTOS
运行时测试环境创建两个 FreeRTOS 任务:
- 第一个任务在启动时启动,它处理测试加载器和连接到 DUT 的主机设备之间的通信。
- 每次 DUT 必须根据主机设备的要求运行测试时,都会创建第二个任务:
- 当运行时测试环境收到要运行的测试的名称时启动,以便:
- 读取FLASH存储器中预编译的测试
- 重新定位此预编译测试的符号以适应固件符号表
- 将重新定位的测试加载到 RAM 内存中
- 触发其执行
- 当要运行的测试执行完成后结束。
- 当运行时测试环境收到要运行的测试的名称时启动,以便:
运行时测试环境创建的两个任务的优先级均设置为 FreeRTOS 生态系统的 IDLE 任务优先级。
注意:可能需要调整这两个任务的优先级,以防它们由于优先级更高的任务不让出 DUT 的 CPU 而导致任务匮乏:
- 第一个任务的优先级在名为“console_task.c”的 C 文件中设置
- 第二个任务的优先级在名为“exec.c”的 C 文件中设置
显然,调整这两个优先事项不能影响 DUT 的功能。
1.3 集成到DUT固件
在使用 MCUXpresso 等 IDE 构建升级固件之前,必须将用于测试 MCU 应用程序的运行时环境软件集成到 DUT 固件的代码中:https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/mcuxpresso-integrated-development-environment-ide :MCUXpresso-IDE
如果使用 MCUXpresso 作为 IDE,则必须使用这些构建后步骤设置进行配置,以便在构建时生成 DUT 固件的符号表:
图 3 - MCUXpresso 构建后步骤设置
对于固件,必须将此符号表上传到 DUT 的 FLASH 存储器中的特定位置,该位置在名为“elf_interface.c”的文件中通过以下 3 个参数定义,这些参数必须使用相关值进行初始化:
- uintptrt _fwsymtab_base(起始地址)
- uintptrt _fwsymtab_end(结束地址)
- uintptrt _fwsymtab_size(大小)
FLASH 存储器映射示例包括:
- 被测设备固件
- 符号表
- 包含测试的 LittleFS 映像
如下所示:
图 4 - FLASH 存储器映射
2. 要运行的测试
本自述文件并不旨在描述与在 DUT 上运行的测试的实施和编译相关的所有细节。
本节仅提供一些指导作为以下事项的基础:
- 以可执行和可链接格式 (ELF) 实现并编译在 DUT 上运行的测试
- 将相应的 ELF 文件封装成 LittleFS 二进制映像
2.1 实施和建设
测试预计会调用 DUT 固件的函数来将此 DUT 设置为特定状态或/和获取一些参数,以检查它们的值是否符合 DUT 规格。
注:为了更好地呈现测试结果,建议使用 Unity 框架执行测试。Unity 框架的使用指南可轻松找到:https://github.com/ThrowTheSwitch/Unity
所有相关的头文件:
这些测试一旦实施,必须进行编译,生成相应的可执行文件(ELF格式)。这些ELF文件必须包含DUT所用CPU类型所需的所有特定参数。
测试实现示例如下:
图 5 - 测试实施示例
本测试示例中调用的DUT固件函数是DUTConnectivityGetConnectionModule()和DUTConnectionModuleETH()两个函数。
这两个函数都属于 API DUTConnectivity,其标头包含在此测试的实现中。(#include“DUTConnectivity.h”)。
此测试中调用的函数 setUp()、tearDown() 和 ASSERT() 来自 Unity 框架。Unity 的头文件已包含在内(#include "unity.h")。函数 ASSERT() 决定测试是通过还是失败。
2.2 LittleFS 镜像
最后,必须将 ELF 封装成 LittleFS 二进制映像。
此 LittleFS 映像必须上传到 DUT 的 FLASH 存储器中。此 LittleFS 二进制映像的起始地址和大小均在 DUT 固件代码中定义。
生成包含预编译测试的 LittleFS 映像,可以通过依赖于名为“littlefs-python”的 Python 包的 API 的 Python 脚本轻松实现。
3.硬件平台
用于测试 MCU 应用程序的运行时环境已经开发出来以适应以下硬件平台:
- RT1060-EVK
- RT1060-EVKB
- RT1064-EVK
然而,类似的依赖于 MCU 的硬件平台也可能支持这种运行时测试环境。
图 6 - DUT(RT1060-EVK)连接到主机(Raspberry)
4. 运行时测试设置
4.1 主机设备与DUT之间的连接
主机设备和 DUT(USB 转串行调试端口)之间必须连接一条 USB 电缆。
4.2 主机设备上的串行终端
主机设备上必须打开串行终端。
该串口终端的参数:
- 波特率
- 数据位数
- 平价
- 停止位
- 流量控制
必须设置为适合 DUT 的 USB 转串行调试端口。
4.3 运行时测试环境处理
可以通过在主机设备上运行的串行终端上的提示符后输入命令来激活运行时测试环境的功能,其中包括:
- 列出 DUT FLASH 存储器中可用的预编译测试
- 触发 DUT 执行其中一个测试
通过在提示符后输入命令“help”,可以在主机设备上运行的串行终端上显示运行时测试环境的所有可用命令及其使用方法。
图 7-运行时测试环境的命令
5. 运行测试结果
测试结果会在执行过程中显示在主机设备上运行的串行终端上。下方展示了一个基于 Unity 框架的测试结果示例。
图 8 - 使用运行时测试环境执行的测试结果显示
6. 支持
如果您有任何疑问或发现错误,请在此 GitHub 存储库的问题选项卡中输入问题。
项目元数据
来源:恩智浦appcodehub