RIOT OS 单 UART 设备的帧格式(Mode)自动化测试指南:基于 tests/periph/uart_mode 的完整解读
2026/9/20 14:21:41 网站建设 项目流程
  • 物联网
  • 嵌入式
  • 操作系统
  • 实时系统

【免费下载链接】RIOT

RIOT - The friendly OS for IoT

项目地址:https://gitcode.com/GitHub_Trending/riot/RIOT
点击查看免费下载

本指南以 RIOT OS 仓库中的 tests/periph/uart_mode 测试应用为核心,讲解如何在只有单个 UART 外设的开发板上,自动遍历数据位、奇偶校验位与停止位的全部组合,并用逻辑分析仪(探头)验证每种帧格式是否真实生效。读完本文,你将掌握该测试的编译、烧录、观测方法,理解其背后的uart_mode()驱动 API 与底层寄存器配置原理,并能够据此判断一块开发板对 UART 帧格式的实际支持能力。

测试背景:为什么需要一个新的 UART 模式测试

RIOT OS 原有的periph_uart测试依赖开发板上存在多个UART:一个用于 shell 交互,另一个专门用于测试收发。但对许多只有单个 UART 的 MCU(例如部分 SAM R 系列、低引脚数 Cortex-M 芯片)而言,这种"双 UART"前提并不成立。

为此,tests/periph/uart_mode 应运而生,其设计目标非常明确:

  • 不需要 shell 接线,无需用户交互;
  • 程序上电后自动遍历所有模式组合;
  • 通过把 stdout(stdio)复用在同一根 UART 线上,将当前模式字符串打印出来;
  • 由**外部探头(逻辑分析仪/示波器)**抓取波形,验证帧格式是否与打印一致。

也就是说,这是一款面向单 UART 设备的"自报家门 + 外部校验"型测试应用,最终结论需要仪器确认,而不是程序自说自话。

测试原理:40 种模式组合与三字符模式串

模式空间:4 × 5 × 2 = 40 种组合

测试遍历以下三个维度的全部排列组合,共计40 种模式

维度取值数量
数据位(data bits)5 / 6 / 7 / 84
奇偶校验(parity)N(无)/ E(偶)/ O(奇)/ M(标志)/ S(空号)5
停止位(stop bits)1 / 22

在 main.c 中,这三个维度通过宏定义:

#define DATA_BIT_OPTIONS (4) #define PARITY_OPTIONS (5) #define STOP_BIT_OPTIONS (2) #define TOTAL_OPTIONS (DATA_BIT_OPTIONS * PARITY_OPTIONS * STOP_BIT_OPTIONS)

枚举数组分别来自 drivers/include/periph/uart.h 中定义的uart_data_bits_tUART_DATA_BITS_5~UART_DATA_BITS_8)、uart_parity_tUART_PARITY_NONE/EVEN/ODD/MARK/SPACE)与uart_stop_bits_tUART_STOP_BITS_1/2),见 main.c。

模式字符串格式:<数据位><奇偶><停止位>

对于每种模式,程序会生成一个长度为 3 的字符串并打印到 STDOUT,格式为:

<data-bits><parity-bits><stop-bits>

例如7 个数据位、偶校验、2 个停止位打印为7E2。字符映射规则(见 main.c 的_get_mode()):

  • 数据位:5678
  • 奇偶校验:N(无)、E(偶)、O(奇)、M(标志)、S(空号)
  • 停止位:12

只有uart_mode()返回成功(UART_OK)的模式才会被打印,不支持的组合会被静默跳过,因此探头抓到的每条模式串都代表该设备宣称支持该帧格式。

测试主流程

main.c 中main()的执行逻辑为:

  1. 三重循环遍历 40 种组合(数据位 → 奇偶 → 停止位);
  2. 每次迭代先调用stdio_init()重新初始化 stdio,保证 printf 生效;
  3. 调用uart_mode(_UART_DEV, data_bits, parity, stop_bits)尝试切换帧格式;
  4. 若返回UART_OK,打印模式串,然后延时DELAY_US(默认 50 ms)以便观测;
  5. 记录每种模式的成败到results[]数组;
  6. 全部遍历结束后,stdio_init()并调用uart_mode(_UART_DEV, UART_DATA_BITS_8, UART_PARITY_NONE, UART_STOP_BITS_1)恢复默认的 8N1 模式
  7. 逐条打印所有模式串及其Supported/Unsupported状态。

由于测试针对单 UART 设备,UART 设备号被固定为 0:#define _UART_DEV (UART_DEV(0))(见 main.c)。

模式间延迟:timer 与忙等两种实现

为了便于人工/仪器解析每条模式串,相邻模式之间默认插入 50 ms 延时(DELAY_US,可通过CFLAGS+=-DDELAY_US=<us>覆盖)。_delay()(见 main.c)的实现分两种路径:

  • 若启用了MODULE_XTIMER,使用xtimer_usleep(DELAY_US)精确睡眠;
  • 否则退化为纯 CPU 忙等循环:uint32_t loops = coreclk() / 20;粗略估计每次循环约 20 个 CPU 周期,专门服务于"尚未编写定时器驱动的全新移植板卡"。局部变量声明为volatile以阻止编译器将空循环优化掉。

编译与运行:从 Makefile 到烧录

构建配置解析

tests/periph/uart_mode/Makefile 的关键配置:

BOARD ?= samr34-xpro include ../Makefile.periph_common FEATURES_REQUIRED += periph_uart FEATURES_REQUIRED += periph_uart_modecfg FEATURES_OPTIONAL += periph_timer # Set this to prevent welcome message from printing and confusing output CFLAGS+=-DLOG_LEVEL=LOG_NONE include $(RIOTBASE)/Makefile.include
  • BOARD ?= samr34-xpro:默认目标板为 Microchip SAM R34(xpro),这是一款典型的单 UART 配置平台,且由 cpu/sam0_common/Makefile.features 提供periph_uart_modecfg特性;
  • FEATURES_REQUIRED += periph_uartperiph_uart_modecfg:两项为强制特性,板卡若未提供periph_uart_modecfg(即不支持运行时重配帧格式)则无法编译本测试,periph_uart_modecfg已列入 makefiles/features_existing.inc.mk 的既有特性清单;
  • FEATURES_OPTIONAL += periph_timer:可选特性,配合 Makefile.board.dep 在板卡提供periph_timer时自动拉入xtimer模块,从而让_delay()走定时器路径;
  • CFLAGS+=-DLOG_LEVEL=LOG_NONE:关闭日志输出,避免欢迎信息等额外打印混入测试输出、干扰模式串解析;
  • 公共构建逻辑由tests/Makefile.periph_common(同目录其他 periph 测试共用)引入。

编译与烧录命令

在 tests/periph/uart_mode 目录下:

# 使用默认板卡 samr34-xpro 编译 make # 指定其他板卡(须具备 periph_uart 与 periph_uart_modecfg) make BOARD=your-board # 编译并烧录 make flash # 编译并烧录且直接打开串口终端 make flash term

若目标板 RAM 过小可能无法运行:CI 清单 Makefile.ci 将nucleo-f031k6标记为BOARD_INSUFFICIENT_MEMORY,说明该板内存不足以承载本测试(40 个模式字符串 + 40 个 bool 结果,外加 printf 所需的缓冲)。

修改波特率

测试默认波特率为115200。若需其他波特率,在编译时通过 CFLAGS 覆盖 stdio 的波特率宏:

make CFLAGS+=-DSTDIO_UART_BAUDRATE=9600

通用写法即:

CFLAGS+=-DSTDIO_UART_BAUDRATE=<BAUD>

请确保终端与探头(逻辑分析仪)的波特率设置与该值一致,否则观测到的波形与打印内容将无法对应。

底层支撑:uart_mode() API 与驱动实现

驱动接口定义

uart_mode()在 drivers/include/periph/uart.h 中声明:

int uart_mode(uart_t uart, uart_data_bits_t data_bits, uart_parity_t parity, uart_stop_bits_t stop_bits);
  • 参数:uart(设备号)、data_bits(帧内数据位长度)、parity(校验模式)、stop_bits(停止位个数);
  • 返回值:0表示成功;-ENOTSUP表示给定配置不被支持;<0为其他错误。

同时 uart.h 定义了测试中使用的返回码语义:UART_OK(成功)、UART_NODEV(非法设备)、UART_NOBAUD(波特率不支持)、UART_NOMODE(模式不支持)、UART_INTERR(其他内部错误)。注意UART_NOMODEUART_NOBAUD均映射为-ENOTSUP,测试代码里只需判断是否等于UART_OK

SAM0 平台的寄存器级实现

以默认板卡所在的 SAM0 平台为例,cpu/sam0_common/periph/uart.c 中的uart_mode()揭示了运行时切帧格式的底层细节:

  1. 参数合法性检查:设备号越界返回UART_NODEV;停止位不是 1/2、奇偶校验不是 NONE/EVEN/ODD 时直接返回UART_NOMODE这意味着该平台硬件(SERCOM USART)不支持 MARK/SPACE 校验——测试中打印结果里M/S开头的模式串必然标记为Unsupported,这与uart_parity_t枚举中定义了 5 种校验、但硬件未必全部支持的情况相符;
  2. 解除写保护:SERCOM 的CTRLB寄存器在使能状态下受写保护,因此实现先清除CTRLA.ENABLE位并等待同步(_syncbusy);
  3. 重新编排控制寄存器:无校验时清掉CTRLA.FORM字段;有校验时设置FORM(1)并通过CTRLB.PMODE区分奇/偶校验;
  4. 恢复使能:重新置位ENABLE并等待同步;
  5. 清空 RX 缓冲_drain_rxbuf),防止残留字节干扰后续接收;
  6. 重挂 RX 中断:若此前注册过接收回调,则重新使能RXC中断。

可见,uart_mode()的"支持/不支持"结论本质上取决于两点:驱动代码的预检,以及硬件控制寄存器对某种帧格式的组合能力。这也解释了为什么测试要求"最终必须用探头验证"——UART_OK只代表驱动认为配置可写,不代表示波器上的电平时序一定符合预期。

结果解读与硬件验证

运行观察

将逻辑分析仪(或示波器)的通道接在测试板的 UART TX 引脚上,按测试的波特率(默认 115200)解码,上电后应看到一串模式串依次出现,例如:

8N1 8E1 8O1 7N1 ...

随后是总结列表:

8N1: Supported 8E1: Supported 8O1: Supported ... 5S2: Unsupported

其中被打印过的模式串应与总结列表中的Supported条目一一对应。

人工核对帧格式

对每一条模式串,结合示波器/逻辑分析仪捕获的实际波形核对:

  • 数据位个数:起始位后到(可能的)校验位/停止位之前的数据位数量是否为模式串第一位的数字;
  • 校验位电平:若为E,数据位加校验位中"1"的总数应为偶数;O则为奇数;N表示校验位位置不存在(波形上该位置直接是停止位);M/S分别表示校验位恒为高/恒为低;
  • 停止位个数:帧尾高电平持续 1 或 2 个位宽,对应模式串第三位。

测试末尾自动恢复默认的8N1模式(见 main.c),因此测试结束后串口依然可以正常交互,不会把开发板留在某个奇怪的非默认帧格式上。

适用范围与使用建议

  • 适用对象:只有单个 UART、无法同时兼顾 shell 与测试 UART 的开发板;亦可用于任何想快速验证periph_uart_modecfg帧格式支持矩阵的板卡;
  • 前置条件:板卡必须同时满足periph_uartperiph_uart_modecfg两项特性(可在 makefiles/features_existing.inc.mk 查看该系列特性的完整清单);内存过小的板卡(如nucleo-f031k6)会被 CI 排除;
  • 验证手段:测试的输出与总结只能说明驱动层的成功/失败,帧格式是否真正按声明生效必须依赖逻辑分析仪/示波器,这也是本测试命名为"Expected result"而非自断言测试的原因;
  • 参数裁剪:通过CFLAGS+=-DSTDIO_UART_BAUDRATE=<BAUD>调整波特率,通过CFLAGS+=-DDELAY_US=<us>调整模式间间隔,以适应不同探头的解码能力。

简而言之,tests/periph/uart_mode 是一份"面向单 UART 板卡的 UART 帧格式能力自检工具":读懂它的输出格式、构建参数与uart_mode()底层实现,你就能在任何支持模式重配的 RIOT 板卡上快速完成 UART 帧格式的兼容性摸底,并把仪器观测与驱动返回码一一对应起来。

  • 物联网
  • 嵌入式
  • 操作系统
  • 实时系统

【免费下载链接】RIOT

RIOT - The friendly OS for IoT

项目地址:https://gitcode.com/GitHub_Trending/riot/RIOT
点击查看免费下载

相关推荐

上一篇:提升.NET Core开发效率:Aspose.Words.dll资源下载推荐
下一篇:Video2X完整指南:用AI免费实现视频超分辨率与帧率提升

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询