RIOT 构建系统测试工具验证:深入 `tests/build_system/test_tools` 的板级测试链路剖析
RIOT 构建系统测试工具验证深入tests/build_system/test_tools的板级测试链路剖析【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址: https://gitcode.com/GitHub_Trending/riot/RIOT导读本文聚焦 RIOT 操作系统仓库中 tests/build_system/test_tools/README.md 所定义的test_tools测试应用剖析它如何验证测试工具与板卡/测试环境集成这一核心前提。文章将逐一拆解该测试的四个 shell 命令true、shellping、toupper、getchar、make term终端链路的TERMPROG/TERMFLAGS配置机制以及01-run.py中针对本地回显、输出纯净度、空行发送等测试假设的验证方法。读完本文你将掌握 RIOT 中板卡测试前置验证的标准范式并能在自己的板卡或测试环境中复现同样的验证流程。一、test_tools测试的定位与目的test_tools是 RIOT 构建系统测试套件tests/build_system中的一个特殊应用其 README 开门见山This test is here to verify the test tools integration with your board and test setup. It verify the assumptions required for testing on the board behaviour throughmake term.即该测试不验证任何业务功能而是验证你的板卡 你的测试工具链能否满足 RIOT 自动化测试的基本前提。这些前提包括通过make term能否打开与板卡的终端会话测试运行时本地终端是否关闭了回显echo避免测试脚本把本地输入误判为设备输出板卡 shell 是否不输出多余的提示符prompt保证测试脚本读到的是纯净的设备输出是否能够向设备发送空行仅一个换行符而不触发本地终端重复上一次命令终端行编辑模式的影响。换言之test_tools是测试的测试meta-test它先于任何功能测试运行用来确认测试环境本身是可信的。这正是它被放置在 tests/build_system 目录下的原因——它属于构建系统与测试基础设施层面的自检。二、测试应用主体main.c中的四个自检命令测试应用的 C 代码位于 tests/build_system/test_tools/main.c。它并没有实现复杂逻辑而是注册了四个经过精心设计的 shell 命令让测试脚本可以通过终端交互来验证不同假设。2.1 编译期前提禁用 shell 回显与提示符main.c顶部有一段硬性约束#if !IS_ACTIVE(CONFIG_SHELL_NO_ECHO) || !IS_ACTIVE(CONFIG_SHELL_NO_PROMPT) #error This test assumes no shell echo or shell prompt #endif它要求编译时同时启用CONFIG_SHELL_NO_ECHO与CONFIG_SHELL_NO_PROMPT否则直接编译失败。这两个配置的默认值定义在 sys/include/shell.h 中#ifndef CONFIG_SHELL_NO_ECHO #define CONFIG_SHELL_NO_ECHO 0 #endif #ifndef CONFIG_SHELL_NO_PROMPT #define CONFIG_SHELL_NO_PROMPT 0 #endif默认都为 0即默认 shell 会回显、会打印提示符因此必须显式开启。这一设计用意很明确RIOT 的自动化测试脚本通过串口解析设备输出任何多余的回显字符或提示符都会污染解析结果。test_tools通过#error把这条约定从约定升级为编译期强制约束。2.2true什么都不做但成功返回static int cmd_true(int argc, char **argv) { (void)argc; (void)argv; return 0; } SHELL_COMMAND(true, do nothing, successfully, cmd_true);语义与 coreutils 的true完全一致接受任意参数恒返回 0。它在本测试中用于验证本地终端没有回显——测试脚本发送true this should not be echoed如果本地回显开启脚本会立即收到该字符串测试即失败详见 4.2 节。2.3shellpingshell 就绪握手static int cmd_shellping(int argc, char **argv) { (void)argc; (void)argv; puts(shellpong); return 0; } SHELL_COMMAND(shellping, Just print shellpong, cmd_shellping);shellping是 shell 的ping/pong握手发送shellping设备应答shellpong。这是测试脚本判断shell 是否就绪、串口链路是否通畅的标准手段。值得注意的是Makefile 中明确注释道# No need for test_utils_interactive_sync in this test since the test # synchronizes by itself through shellping command. DISABLE_MODULE test_utils_interactive_sync即本测试主动禁用了通用的test_utils_interactive_sync同步机制改由shellping自同步从而让测试脚本独立地验证这套握手逻辑本身是否可靠。2.4toupper输出纯净度验证static int cmd_toupper(int argc, char **argv) { if (argc ! 2) { puts(Invalid number of argument); printf(Usage: %s word\n, argv[0]); return 1; } size_t len strlen(argv[1]); for (size_t i 0; i len; i) { char c toupper((int)argv[1][i]); putchar(c); } putchar(\n); return 0; } SHELL_COMMAND(toupper, uppercase first argument, cmd_toupper);toupper把第一个参数转换为大写后输出源码中对char做了(int)显式转换以避免部分编译器对数组下标类型为 char的告警。它用于验证设备输出是否纯净测试脚本发送toupper lowercase后读到的下一行必须恰好是LOWERCASE中间不允许夹杂提示符、日志或其他终端输出。2.5getchar字符级输入验证static int cmd_getchar(int argc, char **argv) { (void)argc; (void)argv; printf(%s 0x%02x\n, argv[0], getchar()); return 0; } SHELL_COMMAND(getchar, Get one character and print the hex value, cmd_getchar);getchar读取一个字符并打印其十六进制值。它用于验证发送空行仅一个换行符0x0a的能力如果本地终端处于行编辑模式并重复上次命令那么发送空行后设备收到的将不是换行符测试脚本也就无法读到期望的getchar 0x0a。2.6 主循环int main(void) { puts(Running tests_tools application); char line_buf[SHELL_DEFAULT_BUFSIZE]; shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE); return 0; }main启动后打印一条标志信息然后以 sys/include/shell.h 中定义的SHELL_DEFAULT_BUFSIZE128 字节为行缓冲调用shell_run(NULL, ...)进入标准 shell 交互循环。该测试没有自定义提示符NULL配合禁用的 prompt整个会话对测试脚本保持静默等待 精确应答。三、构建配置Makefile 与测试环境声明Makefile 完整内容如下DEVELHELP 0 include ../Makefile.build_system_common USEMODULE shell # No need for test_utils_interactive_sync in this test since the test # synchronizes by itself through shellping command. DISABLE_MODULE test_utils_interactive_sync # include sys/test_utils/dummy_thread USEMODULE dummy_thread # microbit qemu failing currently TEST_ON_CI_BLACKLIST microbit include $(RIOTBASE)/Makefile.include # Set the shell echo configuration via CFLAGS if not being controlled via Kconfig # Disable shell echo and prompt to not have them in the way for testing ifndef CONFIG_KCONFIG_USEMODULE_SHELL CFLAGS -DCONFIG_SHELL_NO_ECHO -DCONFIG_SHELL_NO_PROMPT endif关键配置点逐项说明配置项作用DEVELHELP 0关闭开发辅助输出保证输出纯净include ../Makefile.build_system_common引入构建系统测试公共片段Makefile.build_system_common其中以RIOTBASE ? $(CURDIR)/../../..定位仓库根并引入仓库根部的 Makefile.tests_commonUSEMODULE shell启用 RIOT shell 模块DISABLE_MODULE test_utils_interactive_sync禁用通用交互同步模块改由shellping自同步USEMODULE dummy_thread引入 sys/test_utils/dummy_thread 下的 dummy 线程为 shell 调度提供线程上下文TEST_ON_CI_BLACKLIST microbitmicrobit 板卡在当前 CI 的 QEMU 环境下列入黑名单存在已知失败CFLAGS -DCONFIG_SHELL_NO_ECHO -DCONFIG_SHELL_NO_PROMPT在未走 Kconfig 配置时直接通过 CFLAGS 宏定义强制关闭 shell 回显与提示符其中最后一段体现了 RIOT 的双配置路径若CONFIG_KCONFIG_USEMODULE_SHELL已定义即 shell 由 Kconfig 管理则回显/提示符配置应在 Kconfig 中设置否则回退到传统的 CFLAGS 宏注入方式。这两种方式最终都作用于 sys/include/shell.h 中CONFIG_SHELL_NO_ECHO/CONFIG_SHELL_NO_PROMPT的取值。此外 Makefile.ci 声明了 CI 内存受限板卡黑名单BOARD_INSUFFICIENT_MEMORY : \ nucleo-l011k4 \ #即nucleo-l011k4STM32L011K4仅 8 KB SRAM内存不足以运行本测试CI 中会跳过。四、Python 测试脚本验证测试前提的四步真正的验证逻辑在 tests/build_system/test_tools/tests/01-run.py。它基于pexpect与 RIOT 的testrunner框架编写通过run(testfunc)入口执行。4.1 等待 shell 就绪_wait_shell_readydef _wait_shell_ready(child, numtries5): Wait until the shell is ready by using shellping. for _ in range(numtries - 1): try: _shellping(child) except pexpect.TIMEOUT: pass else: break else: # This one should fail _shellping(child)脚本反复发送shellping并期待shellpong_shellping内部通过child.expect_exact(shellpong\r\n, timeouttimeout)精确匹配注意\r\n是串口行结束符。最多重试 5 次若全部超时最后一次故意让_shellping抛出超时异常从而使测试失败。这套先握手、后测试的机制替代了test_utils_interactive_sync验证 shell 与串口链路在测试开始时确实可用。4.2 验证无本地回显_test_no_local_echodef _test_no_local_echo(child): Verify that there is not local echo while testing. msg true this should not be echoed child.sendline(msg) res child.expect_exact([pexpect.TIMEOUT, msg], timeout1) assert res 0, There should have been a timeout and not match stdin发送true this should not be echoed后用expect_exact在超时与匹配到该字符串两个分支中二选一并断言必须命中超时。因为 shell 回显已被禁用设备不会把输入原样返回若本地终端或测试工具链开启了回显脚本就会看到输入字符串断言失败——这正是true命令存在的意义。4.3 验证输出纯净_test_clean_outputdef _test_clean_output(child): Verify that only what the node sends is received. child.sendline(toupper lowercase) retline child.readline() assert retline.strip() LOWERCASE发送toupper lowercase后读取下一行断言其恰好等于LOWERCASE。任何多余的提示符、日志或终端控制序列都会导致该断言失败从而保证测试工具链不会在设备输出中混入杂质。4.4 验证空行发送_test_sending_newlinedef _test_sending_newline(child): Verify that a empty line can be send to the node. The local terminal must NOT repeat the previous command. child.sendline(getchar) child.sendline() # send only one newline character child.expect_exact(getchar 0x0a\r\n)先发送getchar此时设备阻塞在getchar()等待一个字符随后单独发送一个空行仅\n即 0x0a。若本地终端在行编辑模式下会把空行解释为重复上一条命令则getchar收到的将是字符g0x67而非换行符脚本期待getchar 0x0a就会失败。这个用例直接检验了串口工具是否以raw模式不做本地行编辑工作。4.5 测试主流程testfuncdef testfunc(child): _wait_shell_ready(child) # Verify there is no local and remote echo as it is disabled _test_no_local_echo(child) # The node should still answer after the previous one _shellping(child) # Check that the output is clean without extra terminal output _test_clean_output(child) # It is possible to send an empty newline _test_sending_newline(child)四个步骤依次执行等待就绪 → 验证无回显 → 再次握手确认链路仍通畅 → 验证输出纯净 → 验证空行发送。任何一步失败都会让run(testfunc)以非零状态退出CI 随即判定该板卡的测试环境不合格。五、make term链路测试工具与板卡的连接层test_tools验证的核心对象是make term所建立的终端链路。RIOT 的 makefiles/tools/serial.inc.mk 根据板卡/工具链配置将TERMPROG终端程序与TERMFLAGS终端参数解析为实际命令常见的几种实现包括pyterm默认串口工具RIOT 自带位于 dist/tools/pytermTERMPROG ? $(RIOTTOOLS)/pyterm/pytermTERMFLAGS ? -p $(PORT) -b $(BAUD) -ln $(PYTERMLOGDIR) -rn $(PYTERMSESSION) $(PYTERMFLAGS)socat以echo0,raw等参数打开串口确保本地不做回显与行编辑picocom/pyserial-miniterm通过--eol LF、--nolock --imap lfcrlf等参数控制换行映射J-Link RTTterm-rtt、openocdterm-rtt、boottermbt等调试器通道分别由 makefiles/tools/jlink.inc.mk、makefiles/tools/openocd.inc.mk 等定义。QEMU/模拟器环境则由 makefiles/tools/qemu.inc.mk 与 makefiles/tools/renode.inc.mk 统一包装为term.sh把模拟器串口重定向到终端程序。从这些配置可以推断test_tools对测试环境的两条硬性要求终端程序必须关闭本地回显对应_test_no_local_echo否则所有基于expect_exact的输出匹配都会被本地回显污染终端程序必须关闭本地行编辑/历史重复对应_test_sending_newline保证发送空行就是字面上的换行符。因此当你在新板卡或新终端工具上运行 CI 测试前先跑一遍test_tools即可快速定位测试脚本失败是因为板卡逻辑问题还是终端工具链配置问题。六、如何运行与扩展6.1 本地运行在仓库根目录执行示例以native板卡为例串口工具为 pytermmake -C tests/build_system/test_tools flash term或直接由 testrunner 驱动make -C tests/build_system/test_tools testmake test会先编译烧录再通过make term建立会话并自动运行 tests/build_system/test_tools/tests/01-run.py。6.2 手动交互验证也可以手动体验各命令shellping → shellpong toupper hello → HELLO getchar → 等待一个字符并打印其十六进制值 true foo → 无输出静默成功6.3 应用到新板卡/新工具链若你的板卡内存较小先在 Makefile.ci 中确认是否已列入BOARD_INSUFFICIENT_MEMORY当前仅nucleo-l011k4若更换了串口终端程序重点检查其是否以 raw 模式运行、是否关闭本地回显若板卡在模拟器中运行如 microbit QEMU注意 Makefile 中的TEST_ON_CI_BLACKLIST机制当前已将microbit列入。七、小结为什么每个板卡都需要一次test_toolsRIOT 的自动化测试体系高度依赖make term与串口终端的纯净性测试脚本通过pexpect精确匹配设备输出任何本地回显、终端提示符、行编辑行为都会造成误判。test_tools用最小的应用一个 shell 四个命令把这条链路的所有前提一次性验证清楚并借助#error、CFLAGS宏注入与testrunner断言把约定固化为可执行的检查。从 tests/build_system/test_tools/main.c 的命令设计、Makefile 的模块裁剪到 tests/01-run.py 的四步断言再到 makefiles/tools/serial.inc.mk 的终端参数解析整条链路构成了一套可复用的测试环境体检范式——无论你是为 CI 接入新板卡还是排查测试总是超时/误匹配的疑难问题test_tools都是第一步的诊断工具。【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址: https://gitcode.com/GitHub_Trending/riot/RIOT创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

基于TMS320VC5402的定点指纹识别系统设计与优化

基于TMS320VC5402的定点指纹识别系统设计与优化

简介:基于TMS320VC5402 DSP的指纹识别系统设计文档,面向嵌入式系统、生物识别技术方向的工程师及在校学生,可服务于课程设计、毕业设计或项目预研。资源为docx格式,共1个文件,压缩包大小553KB,内容围绕指纹…

2026/9/19 22:16:01 阅读更多 →
Agentic Awesome Skills 与 Awesome Claude Skills 选型指南:广度型可安装技能库 vs 精选型 Awesome 列表

Agentic Awesome Skills 与 Awesome Claude Skills 选型指南:广度型可安装技能库 vs 精选型 Awesome 列表

Agentic Awesome Skills 与 Awesome Claude Skills 选型指南:广度型可安装技能库 vs 精选型 Awesome 列表 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, sta…

2026/9/19 22:16:01 阅读更多 →
XGBoost 2.1 版本深度解析:网络栈重构、联邦学习与多输出新特性全览

XGBoost 2.1 版本深度解析:网络栈重构、联邦学习与多输出新特性全览

XGBoost 2.1 版本深度解析:网络栈重构、联邦学习与多输出新特性全览 【免费下载链接】xgboost Scalable, Portable and Distributed Gradient Boosting (GBDT, GBRT or GBM) Library, for Python, R, Java, Scala, C and more. Runs on single machine, Hadoop, Spa…

2026/9/19 22:16:01 阅读更多 →

最新新闻

不懂代码想建站?电子商务主要就业岗位里哪家好

不懂代码想建站?电子商务主要就业岗位里哪家好

不懂代码想建站?电子商务主要就业岗位里哪家好 自己不会代码,却硬要搭个网站,这是很多中小老板踩过的坑。 别急着被“技术门槛”吓退,也别盲目找外包,问一句 哪家好 才是正道。 其实,搭建网站这件事,早就不是程序员的专利了。 只要选对路子,普通人也能把网站稳稳当当地立起来。 今天咱们不聊虚的,就聊聊在…

2026/9/21 4:32:34 阅读更多 →
合肥建站公司排名前十名揭秘:保姆级建站教程与选型指南

合肥建站公司排名前十名揭秘:保姆级建站教程与选型指南

合肥建站公司排名前十名揭秘:保姆级建站教程与选型指南 域名服务器配置报错,SSL证书部署失败,ICP备案卡在初审?别慌,这往往是新手在寻找 合肥建站公司排名前十名…

2026/9/21 4:18:24 阅读更多 →
ARIS 工作流总览:从 idea 到 paper 的 13 条 pipeline 如何一次看全

ARIS 工作流总览:从 idea 到 paper 的 13 条 pipeline 如何一次看全

ARIS 工作流总览:从 idea 到 paper 的 13 条 pipeline 如何一次看全 【免费下载链接】Auto-claude-code-research-in-sleep ARIS ⚔️ (Auto-Research-In-Sleep) — Lightweight Markdown-only skills for autonomous ML research: cross-model review loops, idea …

2026/9/21 4:06:15 阅读更多 →
Roc 格式化器幂等性测试实战:从 issue 8851 快照看多行分发与字段访问的格式化处理

Roc 格式化器幂等性测试实战:从 issue 8851 快照看多行分发与字段访问的格式化处理

Roc 格式化器幂等性测试实战:从 issue 8851 快照看多行分发与字段访问的格式化处理 【免费下载链接】roc A fast, friendly, functional language. 项目地址: https://gitcode.com/GitHub_Trending/ro/roc 导读:本文以 Roc 编译器仓库中的快照测试…

2026/9/21 4:04:14 阅读更多 →
TypePHP编译器API参考:程序化调用PHP AOT编译器的完整指南

TypePHP编译器API参考:程序化调用PHP AOT编译器的完整指南

TypePHP编译器API参考:程序化调用PHP AOT编译器的完整指南 【免费下载链接】typephp Compile PHP to Native Binaries 项目地址: https://gitcode.com/GitHub_Trending/ty/typephp TypePHP 是一款用 PHP 编写的原生 AOT 编译器(tpc)&a…

2026/9/21 4:04:14 阅读更多 →
React Admin 实时数据提供者(Realtime Data Provider)接入完整指南:方法签名、内置适配器与自定义实现

React Admin 实时数据提供者(Realtime Data Provider)接入完整指南:方法签名、内置适配器与自定义实现

前端UI组件 【免费下载链接】react-admin A frontend Framework for single-page applications on top of REST/GraphQL APIs, using TypeScript, React and Material Design 项目地址: https://gitcode.com/gh_mirrors/re/react-admin 点击查看 免费下载 本指南系…

2026/9/21 4:04:14 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →