- 物联网
- 嵌入式
- 操作系统
- 实时系统
【免费下载链接】RIOT
RIOT - The friendly OS for IoT
本指南以 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 / 8 | 4 |
| 奇偶校验(parity) | N(无)/ E(偶)/ O(奇)/ M(标志)/ S(空号) | 5 |
| 停止位(stop bits) | 1 / 2 | 2 |
在 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_t(UART_DATA_BITS_5~UART_DATA_BITS_8)、uart_parity_t(UART_PARITY_NONE/EVEN/ODD/MARK/SPACE)与uart_stop_bits_t(UART_STOP_BITS_1/2),见 main.c。
模式字符串格式:<数据位><奇偶><停止位>
对于每种模式,程序会生成一个长度为 3 的字符串并打印到 STDOUT,格式为:
<data-bits><parity-bits><stop-bits>例如7 个数据位、偶校验、2 个停止位打印为7E2。字符映射规则(见 main.c 的_get_mode()):
- 数据位:
5、6、7、8 - 奇偶校验:
N(无)、E(偶)、O(奇)、M(标志)、S(空号) - 停止位:
1、2
只有uart_mode()返回成功(UART_OK)的模式才会被打印,不支持的组合会被静默跳过,因此探头抓到的每条模式串都代表该设备宣称支持该帧格式。
测试主流程
main.c 中main()的执行逻辑为:
- 三重循环遍历 40 种组合(数据位 → 奇偶 → 停止位);
- 每次迭代先调用
stdio_init()重新初始化 stdio,保证 printf 生效; - 调用
uart_mode(_UART_DEV, data_bits, parity, stop_bits)尝试切换帧格式; - 若返回
UART_OK,打印模式串,然后延时DELAY_US(默认 50 ms)以便观测; - 记录每种模式的成败到
results[]数组; - 全部遍历结束后,
stdio_init()并调用uart_mode(_UART_DEV, UART_DATA_BITS_8, UART_PARITY_NONE, UART_STOP_BITS_1)恢复默认的 8N1 模式; - 逐条打印所有模式串及其
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.includeBOARD ?= samr34-xpro:默认目标板为 Microchip SAM R34(xpro),这是一款典型的单 UART 配置平台,且由 cpu/sam0_common/Makefile.features 提供periph_uart_modecfg特性;FEATURES_REQUIRED += periph_uart与periph_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_NOMODE与UART_NOBAUD均映射为-ENOTSUP,测试代码里只需判断是否等于UART_OK。
SAM0 平台的寄存器级实现
以默认板卡所在的 SAM0 平台为例,cpu/sam0_common/periph/uart.c 中的uart_mode()揭示了运行时切帧格式的底层细节:
- 参数合法性检查:设备号越界返回
UART_NODEV;停止位不是 1/2、奇偶校验不是 NONE/EVEN/ODD 时直接返回UART_NOMODE。这意味着该平台硬件(SERCOM USART)不支持 MARK/SPACE 校验——测试中打印结果里M/S开头的模式串必然标记为Unsupported,这与uart_parity_t枚举中定义了 5 种校验、但硬件未必全部支持的情况相符; - 解除写保护:SERCOM 的
CTRLB寄存器在使能状态下受写保护,因此实现先清除CTRLA.ENABLE位并等待同步(_syncbusy); - 重新编排控制寄存器:无校验时清掉
CTRLA.FORM字段;有校验时设置FORM(1)并通过CTRLB.PMODE区分奇/偶校验; - 恢复使能:重新置位
ENABLE并等待同步; - 清空 RX 缓冲(
_drain_rxbuf),防止残留字节干扰后续接收; - 重挂 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_uart与periph_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
相关推荐
科学论文摘要关键词提取:keyphrase-extraction-kbir-semeval2017 终极性能评测报告
科学论文摘要关键词提取:keyphrase extraction kbir semeval2017 终极性能评测报告 在当今信息爆炸的时代, 关键词提取技术 已
物联网嵌入式操作系统实时系统RIOT OS 定时器负载基准测试:解读 tests/bench/xtimer_load 的 drift/jitter 测量原理与实战
RIOT OS 定时器负载基准测试:解读 tests/bench/xtimer_load 的 drift/jitter 测量原理与实战 RIOT OS 的 te
物联网嵌入式操作系统实时系统RIOT 备份电池电压监测:tests/periph/vbat 测试应用的构建、运行与实现原理
RIOT 备份电池电压监测:tests/periph/vbat 测试应用的构建、运行与实现原理 导读 在 RIOT 操作系统中,很多 MCU(尤其是带备份域与
物联网嵌入式操作系统实时系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考