1. 项目概述:为什么嵌入式开发离不开硬件单元测试
在嵌入式Linux的世界里,尤其是基于NXP i.MX这类高性能应用处理器的项目,硬件驱动的稳定性和功能完整性直接决定了产品的成败。你可能花了几周时间调通了BSP,系统也能正常启动,但一个不经意的硬件操作——比如同时进行视频解码和GPU渲染——就可能导致系统死锁或显示异常。这种问题在实验室里可能难以复现,但到了客户手中,就是致命的产品缺陷。硬件单元测试,就是我们在产品出厂前,为每一个关键硬件模块准备的“体检报告”。
我接触过不少团队,他们的测试流程往往停留在应用层,用几个简单的用户程序跑一跑就认为硬件没问题了。直到量产阶段,才暴露出USB枚举失败、UART数据丢包、VPU解码特定格式视频花屏等底层问题,此时修复成本极高。NXP官方提供的这套单元测试集,正是为了解决这类问题而生。它不像那些高层的、综合性的性能测试,而是深入到每一个硬件IP(知识产权模块)的驱动层,用最直接的方式“敲打”硬件,验证其基础功能是否按照数据手册的描述正确工作。
简单来说,这套测试的核心原理就是“白盒验证”。它绕过复杂的应用框架,直接调用内核驱动提供的接口或操作设备文件(如/dev/ttymxc0,/dev/fb0),向硬件发送特定的指令或数据流,然后检查硬件的响应是否符合预期。例如,mxc_uart_test.out会直接向串口设备写入数据并回读,验证数据链路是否通畅、波特率是否准确;gpu.sh则会运行一系列OpenGL ES和OpenVG的演示程序,检验GPU的渲染管线、着色器执行和纹理处理能力是否正常。
对于从事i.MX平台开发的工程师——无论是驱动开发者、系统集成工程师还是质量保证人员——熟练掌握并运行这些测试,是确保硬件平台稳定可靠的必修课。它不仅能帮助你在早期发现硬件设计缺陷(如PCB布线问题、电源噪声干扰)或驱动程序的Bug,还能在批量生产时作为产线快速测试(Quick Test)的基准,确保每一块出厂的板卡都是功能完好的。接下来,我将结合多年的一线调试经验,为你拆解这套测试工具集的核心用法、背后的原理,以及那些手册上没写的“避坑指南”。
2. 测试环境准备与框架理解
在开始动手运行测试之前,搭建一个正确的环境并理解测试框架的组织结构,能让你事半功倍,避免很多“明明照着做却报错”的尴尬。
2.1 测试代码获取与部署
这些单元测试源代码通常包含在 NXP 官方发布的imx-testGit 仓库中。你需要在 Yocto Project 或 Buildroot 这类构建系统中,将对应的软件包(如imx-test)添加到你的镜像配方(recipe)中。一个常见的做法是在local.conf或你的镜像bb文件里添加IMAGE_INSTALL:append = " imx-test"。编译完成后,这些测试的可执行文件和脚本就会出现在根文件系统的/unit_tests/目录下。
这里有个关键细节:测试程序的版本必须与你的内核版本、BSP版本严格匹配。手册中引用的是 L5.4.24_2.1.0 版本,如果你使用的是 L5.10.y 或更晚的内核,部分测试程序(尤其是涉及内核驱动接口的)可能无法编译通过,或者运行时出现Invalid argument之类的错误。我建议直接从你使用的 BSP 发布包或对应的 Git 分支(如lf-5.10.y)中获取imx-test仓库,这是最稳妥的方式。
部署到目标板后,首先检查/unit_tests/目录是否存在,并大致浏览其结构。你会看到按模块分类的子目录:Keyboard/、UART/、GPU/、Display/、VPU/等。每个目录下通常包含:
- 自动化脚本:以
autorun-开头的.sh脚本,用于一键执行该模块的主要测试流程。 - 核心测试程序:以
mxc_或模块名开头的.out可执行文件,是测试的具体实现。 - 可能的配置文件或资源文件:如 VPU 测试需要的视频样本文件。
2.2 内核配置与驱动加载
许多测试依赖于特定的内核驱动选项。手册中零散地提到了需要在板级配置文件(defconfig)中开启的CONFIG_*选项。根据我的经验,最好在项目初期就系统性地检查并启用它们。以下是一个针对图形和显示测试的常用配置清单,你可以将其作为参考:
# 显示框架与FB驱动 CONFIG_FB=y CONFIG_FB_MXC=y CONFIG_FB_MXC_EDID=y CONFIG_FB_MXC_SYNC_PANEL=y CONFIG_FB_MXC_LDB=y # 对于LVDS显示 CONFIG_FB_MXC_HDMI=y # 对于HDMI显示 CONFIG_FB_MXC_EINK_PANEL=y # 对于电子墨水屏(EPDC) # GPU驱动 CONFIG_MXC_GPU_VIV=y # HDMI CEC功能 CONFIG_MXC_HDMI_CEC=y # 安全相关RTC CONFIG_RTC_DRV_SNVS=y注意:修改
defconfig后,必须重新编译内核并更新到目标板。仅仅修改.config文件是不够的,因为下一次make menuconfig可能会覆盖你的更改。正确做法是在arch/arm64/configs/(或arch/arm/configs/)下找到你的板级默认配置文件进行修改。
对于 USB 测试,它依赖的内核模块(如g_ether.ko,arcotg_udc.ko,ehci-hcd.ko)通常是动态加载的。你需要确保文件系统中存在这些.ko文件,并且依赖的模块已正确加载。可以使用lsmod命令查看,或用modprobe手动加载。
2.3 硬件连接与物理准备
硬件测试,顾名思义,离不开正确的物理连接。这是一个容易疏忽但后果严重的地方。
- 键盘/USB测试:需要将 USB 键盘连接到开发板的USB OTG 端口。请注意,很多 i.MX 开发板有多个 USB 口,其中只有一个被设计为 OTG(On-The-Go)端口,可以扮演主机(Host)角色枚举外设。接错端口会导致测试程序无法检测到键盘。通常这个端口在丝印上会标明“OTG”或“USB0”。
- UART测试:这通常需要两个串口。一个用于运行测试程序和控制台(我们称之为
debug UART,连接到你电脑的串口调试工具)。另一个作为测试对象(/dev/ttymxc#),需要用一个 USB 转 TTL 串口线将其 TX 和 RX 引脚短接,形成自发自收的回路。这是验证串口数据收发功能是否正常的最基本方法。 - 显示测试:必须连接显示设备(LCD、HDMI 显示器等)。很多显示测试(如
mxc_fb_test.out)是交互式的,需要你在屏幕上观察颜色、方块、旋转动画是否正确渲染。没有连接显示设备,测试可能无法启动或报错。 - VPU测试:除了显示设备,还需要准备测试用的视频文件(如
.h264,.m4v)。这些文件通常不随imx-test默认部署,你需要手动从 NXP 的服务器或社区获取,并放置到指定的路径(如/usr/vectors/)。没有这些文件,解码测试无法进行。
3. 核心模块测试详解与实操
理解了框架和环境,我们就可以深入每个模块,看看这些测试具体在做什么,以及如何正确地运行和解读结果。
3.1 人机交互:键盘与USB功能验证
键盘测试看似简单,却是验证 USB Host 控制器驱动和 Linux 输入子系统(Input Subsystem)是否正常工作的有效手段。
测试脚本解析:
autorun-keypad.sh:这是一个自动化封装脚本。它的核心逻辑通常是检查/dev/input/下是否有新的事件设备(eventX)出现,然后可能调用evtest之类的工具监听按键事件。当它打印出PASS时,意味着系统成功识别了键盘这个 USB HID 设备,并为其创建了输入��备节点。mxc_keyb_test.sh:这个脚本可能更底层一些。它可能会直接读取/dev/input/eventX的原始数据,或者调用特定的 IOCTL 来测试键盘矩阵扫描功能。当按键被按下时,你会在控制台看到类似 “key event: code XX, value 1 (press)” 的输出。
实操步骤与要点:
- 将 USB 键盘插入开发板的 USB OTG 端口。
- 在串口终端中,切换到测试目录:
cd /unit_tests/Keyboard。 - 运行自动化测试:
./autorun-keypad.sh。观察输出,预期应看到PASS或类似成功提示。 - 运行底层测试:
./mxc_keyb_test.sh。此时脚本可能会等待输入。尝试按下键盘上的几个键(如字母键、回车键),观察终端是否有对应的按键事件打印出来。
避坑指南:如果测试失败,首先用
lsusb命令查看系统是否识别到了键盘设备。如果lsusb列表中没有键盘,问题可能出在硬件连接(端口错误)、USB Host 控制器驱动未加载(检查dmesg | grep usb),或板子的 VBUS 供电有问题。如果lsusb能识别但测试失败,检查/dev/input/目录,看是否有eventX设备节点。可能是文件系统缺少evdev或相关输入驱动的支持。
USB Gadget/Host 测试:autorun-usb-gadget.sh和autorun-usb-host.sh测试的是 USB OTG 控制器的双重角色功能。
- Gadget模式:将开发板模拟成一个USB设备(如网卡、U盘)。测试前需要加载相应的 Gadget 驱动模块(如
g_ether.ko)。运行脚本后,你可以用 USB 线将开发板连接到 PC,在 PC 的设备管理器中查看是否出现了新的网络适配器或存储设备。 - Host模式:测试开发板作为主机连接U盘等设备的能力。你需要准备一个U盘,插入 USB Host 端口,运行脚本后,检查
/dev/sda1等设备节点是否出现,并能成功挂载。
这两个测试验证了 USB 控制器的物理层、协议栈和驱动程序的完整性,对于需要 USB 通信的产品至关重要。
3.2 数据通道:LPUART串口通信测试
串口是嵌入式系统最经典的调试和通信接口。LPUART(低功耗通用异步收发器)测试确保数据收发无误,波特率、数据位、停止位、校验位等参数配置正确。
测试程序解析:
mxc_uart_test.out:这是基础的端到端测试。它需要指定一个串口设备节点(如/dev/ttymxc2)。其内部工作流程是:打开设备 -> 配置波特率等参数 -> 写入一串已知数据 -> 从同一端口读回数据 -> 比较写入和读出的数据是否一致。一致则通过。mxc_uart_stress_test.out:压力测试。它会进行长时间、大数据量的循环收发测试,用于发现偶发性的数据错误或驱动在高压下的稳定性问题(如缓冲区溢出)。mxc_uart_xmit_test.out:可能侧重于测试发送(Transmit)功能,或者特定的传输模式(如 DMA 传输)。
实操步骤与要点:
- 硬件回路连接:确定你要测试的 UART 端口(例如
ttymxc2)。找到该端口对应的 TX 和 RX 引脚,用杜邦线或跳线帽将其短接。这样,从这个端口发送的数据会立刻被自己接收。 - 在终端中,进入目录:
cd /unit_tests/UART。 - 运行基础测试(以
ttymxc2为例):./mxc_uart_test.out /dev/ttymxc2。程序会输出测试过程,最终提示成功或失败。 - 运行压力测试:
./mxc_uart_stress_test.out /dev/ttymxc2。你可以让它运行一段时间(如几分钟),观察是否有错误计数。
结果解读与深度分析:
- 测试通过:意味着该 UART 端口的基本驱动功能和硬件链路是好的。
- 测试失败(数据不匹配):首先检查硬件短接是否可靠,接触不良是常见原因。其次,用示波器或逻辑分析仪测量 TX 引脚波形,确认实际波特率是否与程序设置一致(例如,设置 115200,实际可能是 113000)。这可能是时钟源分频计算有误。
- 压力测试出错:如果大数据量测试出现偶发错误,可能指向驱动中的竞态条件(Race Condition)、DMA 描述符配置错误,或者是 PCB 布线过长导致的信号完整性下降。此时需要结合
dmesg内核日志,查看是否有相关错误或警告信息。
3.3 图形与视觉:GPU、显示与VPU测试
这是 i.MX 系列处理器的强项,也是测试中最复杂、最有趣的部分。
3.3.1 GPU图形处理单元测试
GPU测试验证 Vivante 图形核心的 2D、3D 和矢量图形加速能力。
测试内容解析:
gpu.sh:这是一个综合测试脚本,它会依次运行多个演示程序:tutorial3:测试 OpenGL ES 1.1 固定功能管线,渲染一个带纹理的旋转立方体。这是检验基础 3D 光栅化能力。tutorial4_es20:测试 OpenGL ES 2.0 可编程着色器管线,渲染一个具有反射和折射效果的玻璃球。这验证了顶点着色器和片元着色器的执行能力。tiger:测试 OpenVG 1.1 矢量图形加速,渲染一个旋转的老虎矢量图。这常用于 UI 和地图渲染。tvui:测试 Vivante 的 2D 光栅引擎和其专有的 DK API,绘制视频剪辑和电视控制面板界面。
gpuinfo.sh:此脚本调用底层库,查询 GPU 的硬件信息,如型号(model)、修订版本(revision)、各 GPU 核心(如果有多核)的状态,以及视频内存(VIDEO MEMORY)的分配情况。这是诊断 GPU 驱动是否成功初始化的关键工具。
实操与问题排查:
- 确保内核配置已包含
CONFIG_MXC_GPU_VIV=y,并且/dev/galcore设备节点存在。 - 连接好 LVDS 或 HDMI 显示器。
- 运行
./gpuinfo.sh。这是第一步,必须做。输出应清晰列出 GPU 信息,如果报错或没有输出,说明 GPU 驱动未加载或加载失败。检查内核启动日志(dmesg | grep galcore)。 - 运行
./gpu.sh。屏幕上应依次出现上述的演示动画。同时,控制台会输出性能数据,如Rendered 100 frames in 624 milliseconds: 160.26 fps。请重点关注脚本运行中是否有错误。手册示例中有一个错误:./gpu.sh: line 28: cd: /opt/viv_samples/hal/: No such file or directory。这说明测试脚本试图访问一个不存在的示例目录,但这通常不影响核心的 GPU 功能测试,只是一个路径配置问题。
经验之谈:如果
tutorial3或tutorial4_es20运行时报错,比如Failed to create EGL context,这通常与 EGL(嵌入式图形库)和显示系统的集成有关。需要检查:
libEGL.so、libGLESv2.so等库文件是否正确安装。- 环境变量
EGL_PLATFORM是否设置正确(通常为fbdev或wayland)。- 帧缓冲设备(
/dev/fb0)的权限是否正确。
3.3.2 显示控制器与帧缓冲测试
显示测试验证从 GPU 或 VPU 出来的图像,能否正确地通过显示处理单元(如 DCSS、LCDIF)输出到屏幕上。
核心测试程序解析:
mxc_fb_test.out:这是最全面的帧缓冲测试工具。它测试的功能包括:- 基本fb操作:打开设备,获取屏幕信息(分辨率、色深)。
- 色深切换:在 16bpp、24bpp、32bpp 之间切换,并填充纯色(红、绿、蓝)验证。
- 全局Alpha混合:测试前景层和背景层的透明度混合效果。
- 颜色键(Color Key):测试特定颜色的透明效果。
- 帧缓��平移(Panning):测试平滑滚动显示区域的能力。
- Gamma校正:测试不同 Gamma 值下的显示效果。
autorun-fb.sh:自动化脚本,主要检查/dev/fb0等设备节点是否存在,并执行一些基础的色彩和 panning 测试。mxc_fb_vsync_test.out:垂直同步测试。它测量渲染指定帧数所需的时间,并计算帧率。这对于验证显示刷新率是否稳定、有无撕裂现象非常重要。用法:./mxc_fb_vsync_test.out <fb编号> <帧数>,例如./mxc_fb_vsync_test.out 0 100。
实操步骤与深度分析:
- 运行
./autorun-fb.sh。它会快速检查显示子系统的基础状态。 - 运行
./mxc_fb_test.out。这是一个交互式测试,你需要密切观察屏幕。程序会在控制台提示“Verify the screen and press any key to continue!”,此时屏幕上应显示对应的测试图案(如黑白方块、混合色块等)。确认无误后按任意键继续下一项测试。 - 关键验证点:
- 色深切换:当程序切换色深时,观察屏幕颜色是否纯净、有无条纹或噪点。24bpp到32bpp的切换,有时会因为字节对齐问题导致颜色异常。
- Alpha混合:前景层(通常是一个小方块)在背景层上移动时,透明度效果是否平滑。
- Panning测试:图像应能平滑移动,无闪烁或残留。
- 运行性能测试:
echo 0 > /sys/class/graphics/fb0/blank(取消屏幕休眠),然后执行./mxc_fb_vsync_test.out 0 100。输出的帧率应接近你显示器的刷新率(如60Hz对应约16.67ms每帧)。如果帧率远低于预期,可能意味着图形管线存在性能瓶颈,或者 VSYNC 信号有问题。
电子墨水屏(EPDC)测试:对于带有电子墨水屏的设备,mxc_epdc_fb_test.out测试至关重要。它测试了电子纸显示的特殊波形更新模式、局部刷新、灰度过渡等。运行时可使用-n参数选择特定测试项,例如./mxc_epdc_fb_test.out -n 1,3,5只运行基础更新、灰度更新和平移更新测试。电子墨水屏测试耗时较长,需要耐心等待每次“刷屏”完成。
3.3.3 VPU视频编解码单元测试
VPU测试验证硬件视频编解码器的功能完整性,这是多媒体应用的核心。
测试逻辑与版本差异: i.MX 6 系列和 i.MX 8 系列使用的 VPU IP 不同(分别是科胜讯和瀚拓),因此测试程序也不同。
- i.MX 6:使用
mxc_vpu_test.out,一个功能强大的多功能工具,支持编解码、显示、文件保存等多种模式。 - i.MX 8M Quad/Mini:使用
/unit_tests/VPU/hantro/目录下的多个独立编解码器测试程序,如hx170dec(H.264解码)、g2dec(HEVC/VP9解码)、h264_testenc(H.264编码)等。 - i.MX 8QuadXPlus/Max:使用 V4L2(Video for Linux 2)框架的测试程序
mxc_v4l2_vpu_dec.out和mxc_v4l2_vpu_enc.out,架构更现代。
i.MX 6 VPU 测试实操详解:
- 准备测试视频文件:这是最容易出错的一步。你需要将测试视频(如
akiyo.mp4或file.264)放到/usr/vectors/目录下。如果目录不存在,需要手动创建。 - 解码并显示测试:这是最常用的测试,验证解码和显示流水线。
参数解释:# 解码H.264文件并在屏幕显示 ./mxc_vpu_test.out -D "-i /usr/vectors/file.264 -f 2"-D表示解码模式,-i指定输入文件,-f 2指定格式为 H.264(0: MPEG-4, 1: H.263, 2: H.264)。运行后,视频应在连接的显示器上正常播放。 - 解码并保存到文件:验证解码器的输出数据是否正确。
这会生成一个原始的 YUV 文件。你可以用 PC 工具(如 ffplay)播放./mxc_vpu_test.out -D "-i /usr/vectors/file.264 -f 2 -o out.yuv"out.yuv来验证内容是否正确。命令示例:ffplay -f rawvideo -video_size 1920x1080 out.yuv(需要根据视频实际分辨率调整)。 - 编码测试:需要准备一个原始的 YUV 源文件。
参数解释:./mxc_vpu_test.out -E "-i input.yuv -w 1280 -h 720 -f 2 -o encoded.h264"-E表示编码模式,-w和-h是视频宽高,-f 2表示编码为 H.264。生成的encoded.h264文件可以拷贝到 PC 上用播放器验证。
常见问题与排查:
- 错误:
Failed to open decoder或VPU init failed:首先检查libvpu.so库文件是否存在且版本匹配。使用ldd ./mxc_vpu_test.out查看动态链接库依赖。其次,检查内核是否加载了 VPU 驱动(dmesg | grep vpu)。最后,确认测试视频文件的格式、分辨率、帧率是否在 VPU 的支持范围内。 - 播放卡顿或花屏:可能原因有:1) 显示刷新率设置不正确;2) 内存带宽不足,尤其是同时运行多个视频流时;3) 视频文件本身损坏或不标准。可以尝试一个标准的小分辨率测试片源(如 CIF 格式)。
- 多流解码测试失败:
./mxc_vpu_test.out -D "-i file1.264 -f 2" -D "-i file2.m4v -f 0"这个命令测试 VPU 同时解码多个流的能力。失败可能意味着系统内存(特别是 CMA 预留区)不足,或者驱动对多实例的支持有问题。需要检查内核启动参数中的 CMA 大小(如cma=512M)。
4. 其他关键模块测试与系统级验证
除了上述核心模块,单元测试集还覆盖了音频、安全等关键子系统,这些对于特定应用同样重要。
4.1 音频子系统测试
音频测试主要验证 ASoC(ALSA System on Chip)框架和异步采样率转换器(ASRC)。
mxc_asrc_test.out:这是一个实用的工具,用于转换音频文件的采样率。例如,将 8kHz 的单声道 WAV 文件转换为 48kHz:
测试通过会输出./mxc_asrc_test.out -to 48000 audio8k16S.wav audio48k16S.wavAll tests passed with success。这个测试验证了 ASRC 硬件模块的时钟配置和数据重采样算法是否正确。- 基础音频功能验证:手册提到了
aplay和arecord工具。在实际项目中,我通常会额外进行环路测试:将板载音频输出(耳机孔)通过音频线连接到音频输入(麦克风孔),然后用arecord录制一段由aplay播放的特定频率正弦波或白噪声,最后在 PC 上分析录制的文件,检查频响和失真度。这能更全面地验证音频编解码器(Codec)的模拟性能。
4.2 安全与完整性测试
- RTC测试(
autorun-rtc.sh,rtctest.out):验证安全非易失存储(SNVS)域内的实时时钟。这对于需要保持时间和日期信息的产品(如数据记录仪、智能电表)至关重要。测试会检查时钟的设置、读取、以及闹钟唤醒功能。确保内核配置了CONFIG_RTC_DRV_SNVS=y。 - DCIC测试(
mxc_dcic_test.out):显示内容完整性检查。这在汽车或工业安全场景中非常重要,用于确保显示在屏幕上的关键信息(如车速、警告)没有被内存错误或软件故障篡改。测试程序会计算屏幕上特定区域(ROI)的 CRC 校验值,并与预期值对比。输出中crcRS和crcCS的值应一一对应相等,All ROI CRC check success!表示通过。
5. 测试实践中的常见问题与系统化排错思路
即使按照手册一步步操作,你也难免会遇到测试失败的情况。以下是我总结的一套系统化排错思路和常见问题速查表。
5.1 通用排错流程
- 权限检查:首先确认你是在
root用户下运行测试。许多测试需要直接访问/dev/下的设备节点,普通用户权限不足。 - 设备节点检查:在运行任何测试前,先用
ls -l /dev/查看相关设备节点是否存在。例如:- 显示:
/dev/fb0,/dev/galcore - 视频:
/dev/mxc_vpu,/dev/video0(V4L2) - 串口:
/dev/ttymxc* - 输入:
/dev/input/event*如果节点不存在,意味着驱动没有成功加载或设备树(Device Tree)配置有误。
- 显示:
- 内核日志分析:这是最强大的排错工具。在运行测试前后,立即使用
dmesg或journalctl -k查看内核日志。关注ERROR、Failed、not found、timeout等关键词。驱动加载失败、硬件访问错误、DMA超时等信息都会在这里打印。 - 依赖库检查:对于 GPU、VPU 测试,使用
ldd <测试程序>命令检查动态链接库。确保所有列出的.so库(如libvpu.so,libGAL.so)都能在库路径(如/usr/lib)中找到,且版本兼容。 - 资源与配置确认:
- 内存:GPU 和 VPU 需要大量的连续物理内存(CMA)。检查内核启动参数中的
cma=大小是否足够(例如 512MB 或更多)。可以通过cat /proc/meminfo | grep Cma查看 CMA 内存总量和剩余量。 - 时钟与电源:某些外设(如 GPU、VPU)可能需要特定的时钟和电源域配置。检查设备树中相关节点的
status是否为"okay",时钟配置是否正确。复杂的电源管理可能导致测试时模块被意外关闭。 - 引脚复用:确保测试外设所使用的 GPIO/UART/USB 引脚没有被其他功能复用(IOMUX 配置冲突)。这需要检查设备树源文件(
.dts)中的pinctrl配置。
- 内存:GPU 和 VPU 需要大量的连续物理内存(CMA)。检查内核启动参数中的
5.2 常见问题速查表
| 问题现象 | 可能原因 | 排查步骤 |
|---|---|---|
任何测试:No such file or directory | 1. 测试程序未正确部署。 2. 依赖的动态库缺失。 | 1. 检查/unit_tests/下对应文件是否存在且可执行 (ls -l)。2. 运行 ldd <程序名>检查库依赖。 |
| USB/Gadget 测试失败 | 1. USB线缆或端口问题。 2. 内核模块未加载。 3. 设备树未使能 USB 控制器。 | 1. 换线、换端口。 2. lsmod | grep udc|gadget|dwc3。3. 检查设备树中 usb*节点状态。 |
| UART 测试数据错误 | 1. TX/RX 短接不良。 2. 波特率不匹配。 3. 流控引脚干扰。 | 1. 重新连接,确保接触可靠。 2. 用示波器测量实际波特率。 3. 检查设备树,确认流控(CTS/RTS)未被错误使能。 |
| GPU 测试无显示或报错 | 1. 显示器未连接或未上电。 2. CONFIG_MXC_GPU_VIV未开启。3. EGL/VIVANTE 库缺失或版本错误。 4. 帧缓冲设备 ( /dev/fb0) 权限问题。 | 1. 确认显示器连接和电源。 2. 检查内核 .config文件。3. 检查 /usr/lib下相关.so文件。4. 确认用户有读写 /dev/fb0的权限。 |
| VPU 解码失败 | 1. 测试视频文件缺失或路径错误。 2. 视频格式/分辨率超出 VPU 支持范围。 3. libvpu.so库问题。4. CMA 内存不足。 | 1. 确认文件在/usr/vectors/且可读。2. 尝试一个标准的小分辨率 H.264 Baseline 文件。 3. 使用 ldd和strings libvpu.so | grep Version检查。4. 增加内核参数 cma=640M并重启。 |
| 显示测试色彩异常 | 1. 帧缓冲色深(bpp)设置与显示器不匹配。 2. 显示时序参数(如 porch, sync)配置错误。 3. 硬件连接(如 LVDS 线序)错误。 | 1. 使用fbset命令查看当前 fb 参数。2. 核对设备树中显示时序参数与显示器规格书。 3. 检查硬件原理图,确认 LVDS 数据线对是否接反。 |
| 系统在测试中卡死或重启 | 1. 电源供电不足,大负载时跌落。 2. 散热不良,芯片过热保护。 3. 内存访问错误(硬件或驱动 Bug)。 | 1. 测量核心电源电压在负载下的波形。 2. 触摸芯片温度,或读取内核温度传感器。 3. 分析卡死前的最后几条 dmesg日志,可能指向某个驱动模块。 |
5.3 构建自动化测试流水线
在产品开发中,手动逐个运行测试效率低下。我们可以将这些测试脚本整合到自动化框架中。
一个简单的思路是编写一个总控脚本run_all_unit_tests.sh,其逻辑如下:
#!/bin/bash LOG_FILE="/var/log/unit_test_$(date +%Y%m%d_%H%M%S).log" exec > >(tee -a "$LOG_FILE") 2>&1 # 同时输出到屏幕和日志文件 echo "=== Starting i.MX Unit Test Suite ===" echo "Timestamp: $(date)" # 1. 键盘测试 cd /unit_tests/Keyboard && ./autorun-keypad.sh check_result $? "Keyboard Test" # 2. UART 测试 (假设 ttymxc2 已短接) cd /unit_tests/UART && ./mxc_uart_test.out /dev/ttymxc2 check_result $? "UART Test" # 3. GPU 测试 cd /unit_tests/GPU && ./gpuinfo.sh ./gpu.sh > /dev/null 2>&1 & # 后台运行,避免阻塞 GPU_PID=$! sleep 30 # 等待演示程序运行一段时间 kill $GPU_PID 2>/dev/null # 结束演示 check_result 0 "GPU Test (visual check required)" # 此处需要人工确认 # 4. 显示测试 cd /unit_tests/Display && ./autorun-fb.sh check_result $? "Framebuffer Basic Test" # ... 添加更多测试 echo "=== All Tests Completed ==="这个脚本可以集成到 CI/CD 系统中,每次构建新镜像后自动刷入设备并执行,生成统一的测试报告。对于需要人工观察的测试(如 GPU 渲染),可以在日志中标记,由工程师进行二次确认。
硬件单元测试不是一次性的任务,而应贯穿于产品开发的整个生命周期——从 EVK 评估、核心板设计、到量产测试。吃透这套测试工具,不仅能帮你快速定位和解决硬件驱动问题,更能深刻理解 i.MX 芯片各个模块的工作原理,从而设计出更稳定、更高效的嵌入式系统。