从软件测试岗位转向嵌入式机器人芯片测试如果给到的时间只有 15 天第一反应往往是“要学的太多了”单片机、ROS2、AI 测试、芯片测试、物联网看起来像五六个完全独立的技术栈。但在实际机器人项目里这些技术是串在一起的单片机负责采集和控制ROS2 负责通信和任务调度AI 测试要验证模型部署到设备后的推理结果芯片测试则关注硬件本身是否稳定可信。如果按目录逐项学时间一定不够如果先找出主线再把每一步变成可执行的小实验15 天足够从“会做软件功能测试”切换到“能上手嵌入式系统测试”。这篇文章面向的是有软件测试基础、但缺少硬件和嵌入式经验的测试工程师。文章不会试图把大学课程压缩到半个月而是给出一条面向“入职后能干活”的补课路线先理解岗位到底测什么再准备最小环境然后分别用单片机串口、ROS2 通信、AI 模型验证和芯片测试知识串出完整实践。1. 先理解“嵌入式机器人芯片测试”到底测什么1.1 测试对象从“应用功能”变成“软硬一体”软件测试熟悉的是界面、接口、数据库和业务规则判断标准是“功能是否符合需求”。嵌入式机器人芯片测试的判断标准要更宽不但要看程序逻辑是否正确还要看 CPU 或 MCU 的外设是否正常、通信协议是否稳定、电压和时序是否满足要求、固件升级后会不会变砖、长时间运行时温度升高后功能是否漂移。一个很典型的差异是重启场景。软件项目里重启后登录态丢失属于缺陷嵌入式系统里重启后要验证的是系统能不能恢复到预期状态比如串口参数是否重新初始化、外设寄存器是否回到默认值、电机是否停在安全位置。这些验证点无法只靠读代码完成必须结合开发板或测试治具去观察真实现象。所以转岗的第一步不是急着背单片机寄存器而是把思维方式从“验证输入输出”扩展成“验证输入输出背后的硬件状态和时序行为”。原来的测试设计理论仍然有用等价类、边界值、状态迁移、异常注入都可以继续用。只是每个用例都需要增加一个维度例如信号电平、通信波特率、超时时间和异常重试。1.2 芯片测试在不同岗位里含义不同“芯片测试”这个名字在不同公司、不同团队可能指完全不同的工作。第一类是半导体制造阶段的测试常见岗位在芯片原厂或封测厂。这种测试关心芯片晶圆上是否有制造缺陷会用到 DFT 扫描链、stuck-at 故障模型、transition delay 测试、ATPG、ATE 机台程序。搜索材料里常出现的“stuck-at、transition、ac”基本属于这类。第二类是板级芯片测试常见于方案公司、模组厂、机器人公司。测试对象是 PCB 上的 MCU/SoC 芯片需要验证电源是否正常、晶振是否起振、各外设引脚能否驱动、串口 SPI I2C 能否通信、固件能否烧录运行。这类更接近嵌入式硬件测试。第三类是系统功能测试主要关注整机功能。机器人芯片测试岗如果要求会 ROS2、单片机、AI 测试更可能对应第二种与第三种的结合以嵌入式主板为基础验证外设、通信、传感器接入和 AI 推理链路。如果 15 天补课建议优先按第二、第三种准备。不要一开始就扎进 ATPG 和扫描链除非你已经确认岗位是做半导体后端测试。1.3 四个技术关键词如何串成一条主线在一个嵌入式机器人项目里单片机、ROS2、AI 测试、芯片测试并不是四门孤立的课它们的关系可以这样理解技术模块在机器人项目中的角色测试工程师最需要掌握的部分单片机采集传感器数据控制电机、灯、舵机等执行器外设功能验证串口命令测试GPIO 状态检查物联网/通信设备之间传输数据模块间组网数据帧格式丢包重传信号连接稳定性ROS2 系统机器设备上的节点通信、任务调度和日志话题/服务接口测试多节点联调系统级回归AI 测试模型在嵌入式端上的推理结果是否稳定数据集划分、精度评估、性能与内存评估芯片测试硬件底层是否健康是否存在制造缺陷或设计问题区分板级测试与制造测试看懂基础故障模型主线可以设计成一条最小闭环单片机通过串口上报传感器数据ROS2 节点把数据转发给 AI 推理模块AI 模块在嵌入式端输出结果最后通过芯片测试手段判断底层硬件是否可靠。这样 15 天里学到的每个知识点都能放到同一个场景里使用。2. 准备最小开发环境Linux、串口工具与 ROS22.1 主机侧环境先跑通串口工具链嵌入式测试的大部分操作都在主机侧完成。开发机建议选用 Ubuntu 或带有 WSL2 Linux 的 Windows。如果之前只接触 Windows 客户端软件测试这一步不要跳过后面安装交叉编译工具、查看/dev/ttyUSB0、运行 ROS2 命令都会依赖 Linux 环境。在 Ubuntu 上先安装基础包sudo apt update sudo apt install -y git python3 python3-pip python3-venv minicom screen python3 -m pip install pyserial pytestminicom和screen用于手动查看串口输出pyserial用于编写自动化串口测试pytest用于组织测试用例。安装后把当前用户加入dialout组否则普通用户无法访问 USB 串口设备sudo usermod -aG dialout $USER修改完用户组需要重新登录一次。如果使用虚拟机还要把 USB 设备透传给虚拟机如果使用 WSL2需要确认发行版能识别/dev/ttyUSB*。连接开发板后可以检查设备是否被系统识别lsusb dmesg | tail -n 20 ls -l /dev/ttyUSB0 /dev/ttyACM0在很多 Linux 环境中USB 转串口芯片会生成/dev/ttyUSB0部分开发板自带调试口会生成/dev/ttyACM0。如果两个路径都找不到优先检查数据线是否支持数据传输有些 Micro USB 线只能充电不能通信。2.2 单片机固件侧选一块开发板作为练习载体15 天补课不需要买很多硬件有一块支持 USB 转串口的 MCU 开发板即可。常见的练习载体包括 STM32F103 系列、ESP32 系列、Arduino Uno/Nano。这些板子资料多串口烧录方式简单适合快速搭测试环境。以 STM32 为例常见工具链是 STM32CubeIDE 或 STM32CubeMX GCC。如果只是为了练习串口测试逻辑也可以先不用太复杂的工程直接使用一块能通过串口打印数据的板卡重点先放在上位机测试脚本上。单片机侧的逻辑可以后补因为真实岗位里你未必负责写固件但要能读懂固件里的引脚初始化和数据发送逻辑。检查环境是否可用的方法是烧录一个最简单的“串口回显”程序MCU 收到一行字符串后原样返回。如果回显成功说明烧录链路、串口驱动、波特率、终端工具都正常之后再用自动化测试脚本接管这个串口。2.3 ROS2安装后先验证话题通信ROS2 版本与 Ubuntu 版本强相关。如果使用 Ubuntu 22.04常见选择是 ROS2 Humble。安装完整桌面版可以方便运行示例节点sudo apt install ros-humble-desktop source /opt/ros/humble/setup.bash安装完成后先验证最基础的节点和话题命令是否可用ros2 node list ros2 topic list如果本机已经运行了 ROS2 节点这两条命令会输出节点名和话题名。没有节点时输出为空也正常。想快速看到通信过程可以开两个终端一个运行发布节点一个运行订阅节点ros2 run demo_nodes_cpp talker另一终端执行ros2 run demo_nodes_cpp listener如果能看到周期性打印说明 ROS2 核心通信已经正常。学习阶段不建议只背命令而是理解每个命令对应测试链路中的哪个环节ros2 node list对应检查被测对象是否上线ros2 topic list对应检查通信主题是否存在ros2 topic echo对应查看实际报文内容。学习环境和生产环境的差别是本地 ROS2 通信默认走共享内存或 localhost网络环境较简单机器人实机测试会涉及多个设备组网不同网段、防火墙、QoS 策略都会影响话题发现。因此环境准备阶段就要区分“本机跑通”和“多机联调跑通”。3. 单片机最小测试实践用串口命令协议验证一个外设3.1 为什么先从串口协议入手串口几乎是最容易观察的嵌入式通信方式。单片机不管跑不跑操作系统都会通过 UART 输出日志或接收命令。测试工程师可以约定一套文本协议然后由上位机脚本发送命令并断言返回值。这样不需要高带宽调试器也能完成“芯片外设是否正常工作”的初筛。一个简单协议可以设计成下面这样上位机发送单片机返回含义LED:ONOK:LED_ON打开 LEDLED:OFFOK:LED_OFF关闭 LEDADC:READADC:数值读取模拟采集值GET:INFOINFO:CHIP:xxx读取芯片信息这套协议用可读文本而不是二进制帧是为了在 minicom 里手工调试时也能看懂。进入真实项目后通常还是建议采用带帧头、帧尾、长度、校验和的二进制协议因为机器人系统更容易出现丢字节和错位问题。3.2 单片机端逻辑只需要做一个命令分发嵌入式端固件不是本文重点但测试工程师至少要能读代码知道一条串口数据进来之后会走哪些分支。下面代码是示意逻辑不能直接拷到某个具体芯片工程中但结构可以复用#include string.h #include stdio.h static void uart_send(const char *s) { // 将字符串逐个字节通过 UART 发送 } static void handle_command(const char *cmd) { if (strcmp(cmd, LED:ON) 0) { set_led_pin(1); uart_send(OK:LED_ON\n); } else if (strcmp(cmd, LED:OFF) 0) { set_led_pin(0); uart_send(OK:LED_OFF\n); } else if (strcmp(cmd, ADC:READ) 0) { int adc_value read_adc_channel(0); char buf[32]; snprintf(buf, sizeof(buf), ADC:%d\n, adc_value); uart_send(buf); } else { uart_send(ERR:UNKNOWN\n); } } void uart_receive_byte(uint8_t byte) { // 实际项目要使用环形缓冲区和状态机拆帧 // 不能只按单字节处理因为串口数据可能半路断开。 }代码里的set_led_pin、read_adc_channel、uart_send都是占位函数实际实现取决于芯片型号和寄存器操作。理解这段逻辑的关键点是测试用例应该针对协议而不是针对某一次具体的运行。测试人员拿到这种代码后要能很快看出协议存在哪些测试点未知命令是否返回错误、ADC 值是否在范围内、LED 开关是否幂等、串口一帧分成两半发送时系统是否崩溃。这些后续都可以成为自动化用例的输入。3.3 上位机用 pytest pyserial 写自动化用例假设单片机串口路径是/dev/ttyUSB0波特率是 115200可以用下面代码建立测试工程import serial import pytest SERIAL_PORT /dev/ttyUSB0 BAUDRATE 115200 pytest.fixture def mcu(): with serial.Serial(SERIAL_PORT, BAUDRATE, timeout1) as ser: ser.reset_input_buffer() yield ser def test_led_on(mcu): mcu.write(bLED:ON\n) resp mcu.readline().strip() assert resp bOK:LED_ON def test_led_off(mcu): mcu.write(bLED:OFF\n) resp mcu.readline().strip() assert resp bOK:LED_OFF def test_adc_value_range(mcu): mcu.write(bADC:READ\n) resp mcu.readline().strip() assert resp.startswith(bADC:) value int(resp[5:-1]) assert 0 value 4095 def test_unknown_command(mcu): mcu.write(bUNKNOWN:CMD\n) resp mcu.readline().strip() assert resp bERR:UNKNOWN执行命令pytest -v test_serial_mcu.py正常输出的关键部分是每个用例名后的 PASS/FAIL。例如test_led_on PASSED test_led_off PASSED test_adc_value_range PASSED test_unknown_command PASSED如果测试失败第一步要看是协议串口没有响应还是返回值不符合预期。readline返回空字节通常意味着单片机没有回复需要检查波特率、引脚连接和固件是否运行。3.4 从一次命令验证扩展到稳定性测试基础功能用例跑通之后还要加入重复操作和异常恢复。嵌入式测试最容易发现的问题不是“功能不存在”而是“连续执行 100 次后某一次失败”或“拔掉串口再插上后无法恢复”。可以增加一个重复开关测试def test_led_toggle_repeated(mcu): for _ in range(100): mcu.write(bLED:ON\n) assert mcu.readline().strip() bOK:LED_ON mcu.write(bLED:OFF\n) assert mcu.readline().strip() bOK:LED_OFF这类用例跑的时间越长越能暴露固件里的资源泄漏、缓存溢出或状态机异常。真实测试环境里还要用夹具固定板子防止接口松动导致误报。4. ROS2 系统测试与 AI 测试落地4.1 ROS2 的发布订阅就是可测试接口软件测试里被测对象会暴露 HTTP 接口、数据库表或页面操作入口ROS2 系统里被测对象暴露的是话题、服务、动作和参数。测试人员可以把 ROS2 节点当成一个“带通信能力的模块”通过发布的报文验证它内部行为是否正常。一个常见场景是 MCU 通过串口上报传感器数据ROS2 节点读取串口后再发布到话题/sensor_data。测试时先运行 MCU 端程序再运行 ROS2 节点然后执行source /opt/ros/humble/setup.bash ros2 node list ros2 topic list ros2 topic echo /sensor_data --once如果/sensor_data话题能打印出符合协议的数据说明 MCU、串口驱动和 ROS2 节点之间的数据链路是通的。如果话题没有输出需要按链路倒查先看 minicom 是否能看到串口数据再看 ROS2 进程日志最后检查话题名称是否拼写一致。还可以用ros2 topic pub模拟上游输入验证下游节点在数据量变大或类型错误时是否表现正常ros2 topic pub /cmd std_msgs/msg/String data: start --once这条命令只发布一次适合做冒烟测试。实际系统测试时更推荐用测试专用节点循环发布边界数据。4.2 系统测试还要验证时间、QoS 和日志ROS2 节点之间通信不只看“能不能收到”还要关注超时、丢包和 QoS 策略。默认情况下发布者与订阅者的 QoS 如果不匹配会出现话题互相看不到的现象。排查时不要只查代码先查看两端 QoS 是否一致ros2 topic info /sensor_data -v输出会包含 Publisher 和 Subscriber 的 QoS 配置。看到类似Reliability: RELIABLE与Reliability: BEST_EFFORT不一致时就能解释为什么订阅端收不到数据。嵌入式机器人测试还建议使用ros2 bag记录现场数据。出现偶发缺陷时如果当时没有记录报文事后很难复现ros2 bag record /sensor_data /cmd -o robot_test_001录制结束后可以用ros2 bag play robot_test_001回放让同一个输入跑多轮回归测试。这是嵌入式系统测试比普通接口测试更依赖“测试现场记录”的原因。4.3 嵌入式 AI 测试从数据集到端侧结果AI 测试在嵌入式设备上的核心是“换了个推理环境后模型结果仍然可信”。普通软件测试可以假设 CPU 指令一致嵌入式环境因为算力、内存、量化方式和底层算子不同模型输出可能与 PC 端有细微差异。第一步是准备测试集。不要只用模型训练时的准确率作为测试标准要构造独立的验证集并覆盖正常、边界和异常输入。测试集可以用目录加标注文件维护ai_test_data/ images/ normal_001.jpg dark_001.jpg blur_002.jpg labels.jsonlabels.json的内容示例如下{ normal_001.jpg: cat, dark_001.jpg: cat, blur_002.jpg: unknown }第二步是写一个批量评估脚本。这里不绑定具体推理框架只给出结构import json import time def verify_inference(model, samples): results [] for sample in samples: start time.perf_counter() pred model.predict(sample[input]) latency_ms (time.perf_counter() - start) * 1000 results.append({ case: sample[name], expected: sample[expected], pred: pred, latency_ms: round(latency_ms, 2), pass: pred sample[expected], }) return results实际项目中model.predict会换成嵌入式端推理接口可能在 C 进程里也可能通过 Python 调用底层封装。测试脚本的价值是规格化输入输出让 PC 端基准结果与设备端结果可以对比。第三步是量化指标。除了准确率还要记录每帧推理耗时、CPU/内存占用、是否出现首次推理慢、长时间运行是否掉帧。如果设备端输出与 PC 端不一致优先检查预处理、输入尺寸、归一化系数和模型量化参数不要一上来就怀疑硬件故障。5. 芯片测试基础概念速读stuck-at、transition 与 AC 测试5.1 板级测试与制造测试不要混为一谈日常嵌入式测试中工程师说的“芯片测试”通常是拿芯片做板级验证比如开发板上的 MCU 能不能正常下载程序、GPIO 能不能拉高拉低、UART 能不能连续收发数据。这种测试的对象是“芯片外围电路固件”的整体。半导体制造测试则是芯片还在晶圆或封装阶段时用探针或测试座对芯片内部逻辑做扫描测试。芯片内部某一条信号线如果因为制造缺陷固定为逻辑 0 或者逻辑 1普通功能测试不一定能触发需要通过 DFT 扫描链把内部状态移位出来并与预期值对比。如果一个岗位要求“会芯片测试”面试前应该确认清楚是上面哪一种。搜索材料中常看到的 stuck-at、transition、AC 测试多数属于制造测试方向。做机器人系统测试的岗位如果只提“芯片测试”四个字通常更偏板级验证。5.2 stuck-at、transition delay、AC 扫描测试到底指什么可以用表格快速理解这三个概念术语简单解释测试目的stuck-at 测试假设某个信号节点固定为 0 或固定为 1 的逻辑故障判断芯片内部是否存在结构性短路或断路transition delay 测试检查信号从 0 跳到 1 或从 1 跳到 0 时是否能在规定时钟周期内完成判断芯片是否存在走线延迟过大或时序问题AC 扫描测试在交流/动态条件下给芯片施加时钟和向量检查时序路径是否满足要求把测试时钟提高到工作频率捕捉延迟故障做芯片制造测试的人会把这些模型转换成 ATPG 测试向量再加载到 ATE 机台上运行。普通软件测试工程师第一次接触时容易发蒙是因为这些概念建立在数字电路和可测性设计基础上不像接口测试那样可以从输入输出直接推导。如果目标岗位只是在嵌入式板级做测试理解到“stuck-at 是制造缺陷模型transition fault 是延迟故障模型”这一层就够了。工作中如果收到来自原厂的测试报告知道这些名词是在描述哪种失效即可。5.3 测试工程师可以如何验证板级芯片的“健康状态”板级芯片测试虽然不像 ATE 那么复杂但有自己的常规流程上电后检查电源电压是否在芯片规格范围内。用示波器观察晶振引脚是否有稳定频率输出。用 GPIO 点灯验证基本 IO 是否可控制。用串口/SPI/I2C 外设做数据回环测试。长时间运行压力测试观察芯片温度与日志错误数。这些验证手段可以和前面的 pytest 串口脚本结合起来把用例不断循环执行同时在系统侧记录电压、温度、日志。如果长时间运行后出现串口无响应或 ADC 值漂移问题可能不是代码逻辑而是电源纹波、接触不良或芯片热漂移。从这里可以看出测试工程师转岗后最需要补的不是数学公式而是硬件仪器和排错意识。只有先确认硬件层没问题上层 ROS2 和 AI 的结果才可信。6. 15 天冲刺路线与每日清单6.1 15 天的目标不是“学完”而是“跑通一条链路”15 天计划的关键是限定范围。不要想着学会所有单片机外设也不要试图从头实现 ROS2 节点。建议把目标定成环境能跑通Linux、串口、ROS2。一个 MCU 外设能被自动化测试脚本控制。能看懂或者写出一个简单 ROS2 话题节点。能对 AI 模型结果做批量验证并输出测试报告。对于芯片测试常见名词不再陌生。只要这条链路跑通后续在真实项目中再补具体芯片、协议和框架都容易得多。面试或团队汇报时也可以把这条链路包装成一个“最小可执行测试平台”来介绍。6.2 按阶段拆分的每日任务表下面是一个 15 天示例适用于已有软件测试基础、但从未接触嵌入式的人员。实际排期需要根据开发板型号和 ROS2 版本调整。时间段任务完成标准第 1-2 天安装 Linux 环境、串口工具、Python 依赖能在ls /dev/ttyUSB*中看到板卡设备第 3 天给开发板烧录“串口回显”示例程序minicom 手动发送字符能收到回显第 4-5 天定义 LED 和 ADC 控制协议烧录对应固件minicom 中能通过协议控制 LED 和读取 ADC第 6-7 天用 pytest pyserial 编写自动化用例执行pytest -v全绿第 8 天安装 ROS2运行 talker/listener 示例能看到消息被订阅终端打印第 9 天学习话题与节点常用命令能通过ros2 topic list找到目标话题第 10-11 天将 MCU 串口数据接入 ROS2 节点并发布话题能用ros2 topic echo看到 MCU 数据第 12 天准备 20 张图片或传感器数据做 AI 测试集标注文件完整PC 端能跑通推理脚本第 13 天在设备端跑 AI 推理记录精度和耗时输出对比报告能指出与 PC 端差异第 14-15 天整理环境清单、用例集和踩坑记录能从头搭建一套完整测试环境并重新执行全部用例这个计划不是每天都要学新知识很多天是验证前一天的内容。学习嵌入式最怕的是“教程里全看懂了真机上却什么都没输出”。每天结束前必须有一个可观察的结果否则知识没有落地。6.3 每天自检清单准备一个模板每天结束前逐项打钩[ ] 今天是否留下了一个可运行命令或测试脚本[ ] 是否知道如果脚本失败第一个日志或错误输出在哪里看[ ] 是否记录了串口设备名、波特率、ROS2 版本等环境参数[ ] 今天有没有把新知识点连接到已有串口/ROS2/AI 链路中[ ] 如果遇到硬件相关报错是否区分了“我认为”和“仪器/日志显示”有软件测试经验的人往往习惯先看程序逻辑忽略环境问题。用这个自检表可以强制自己把硬件环境、工具版本、日志路径纳入分析范围。7. 实际项目中最容易踩的坑与排查清单7.1 串口打不开或者打开后乱码现象是serial.Serial初始化成功但脚本提示PermissionError或者能读到数据但内容全是乱码。可能原因包括当前用户不在dialout组、串口号选错、波特率不一致、USB 转串口芯片松动、发送端和接收端共地问题。排查顺序是ls -l /dev/ttyUSB0 groups dmesg | tail -n 20如果权限正常再用 minicom 手动打开。如果 minicom 里能看到正常回显说明串口本身没问题问题在 Python 脚本或 pytest 使用了同一串口导致冲突。如果 minicom 也是乱码先切换波特率再看发送端是否使用 TTL 电平避免使用 RS232 电平直接接 MCU 引脚。7.2 ROS2 节点明明在运行话题却找不到现象是ros2 node list能看到节点名但ros2 topic list找不到相关话题或者两个节点在同一台机器上却无法通信。常见原因是发布与订阅的话题名不完全一致或 QoS 策略不兼容。先执行ros2 node info /节点名 ros2 topic info /话题名 -v重点检查节点实际发布的话题名、消息类型、QoS 可靠性。嵌入式板卡和上位机之间通信时还要检查 ROS_DOMAIN_ID 是否一致不一致会处于不同通信域。如果跨设备访问先ping测试网络连通性再检查防火墙是否放行 ROS2 使用的端口。7.3 AI 模型在 PC 上正确部署到设备端后结果变差这是嵌入式 AI 测试最常见的现象。可能原因通常不是芯片坏了而是模型转换时使用的算子不被设备端加速器支持或输入图片尺寸、归一化参数、像素通道顺序发生变化。排查链路如下在设备端打印模型输入前的张量内容和 PC 端预处理后的张量