ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

RK3568硬件调试三板斧:串口日志、ADB与设备树实战

RK3568硬件调试三板斧:串口日志、ADB与设备树实战 RK3568 设备树这么多不知道怎么选先从硬件调试三板斧说起做 OpenHarmony 系统移植和硬件适配的朋友大概率都经历过这种场景开发板拿到手代码编出来了烧录也成功了结果屏幕不亮、触摸没反应、Wi-Fi 死活搜不到热点甚至开机就卡在 logo 附近。更让人难受的是OpenHarmony 官方仓库里 RK3568 的设备树文件一眼望去十几个dts 命名看着都差不多选哪个、改哪里、怎么验证完全是一笔糊涂账。我一开始也在这个泥潭里打过滚。后来摸索出一套相对固定的排查链路就是标题里说的“硬件调试三板斧”——串口日志、ADB shell、设备树与日志交叉验证。这套打法不挑具体板子也不挑外设型号只要你是基于 OpenHarmony 做 RK 系列或类似 ARM 开发板的硬件适配都能直接套用。它解决的核心问题不是“写出某个驱动”而是“在硬件不正常时如何快速判断问题出在硬件、设备树还是内核驱动”。我手头常用的平台是 RK3568 的开发板OpenHarmony 3.2 之后的标准系统代码同步到最新 release 分支。下面所有实操命令和日志片段都基于这个环境。如果你用的是 RK3588 或者 x86 版本移植到其他板卡思路完全相同只是具体节点路径会有差异。1. 硬件调试为什么是“三板斧”而不是“一套流程”先说一个观念问题。很多刚接触 OpenHarmony 硬件调试的人一上来就希望有一套完整的排障手册按部就班执行就能解决所有问题。这种想法基本不现实。硬件调试的难点在于同一个现象可能由完全不同的底层原因引起而且它在软件层面的表现往往具有迷惑性。屏幕不亮可能是背光供电没起来可能是有机发光二极管控制的 GPIO 被复用成别的功能可能是显示接口的 I2C 通道没有正确配置也可能是内核根本没加载显示驱动。如果你没有一个快速的筛选机制一上来就去读驱动源码大概率是从早到晚眼睛看瞎也找不出问题。串口日志、ADB、设备树这三样东西正好对应三个层面的信息获取能力而且它们之间是有覆盖和递进关系的串口是底线它在内核最开始启动的阶段就能输出信息哪怕系统还没完全起来你也能看到打印。这是烧录后第一件要确认的事。ADB 是活线它工作在系统起来之后能够让你进入一个可交互的 shell动态查看设备状态、读写节点、触发调试代码。这是定位驱动问题时最高效的入口。设备树是地图它决定了内核看到什么硬件、怎么初始化。日志告诉你“发生了什么”ADB 告诉你“现在什么状态”设备树告诉你“到底是哪个配置引起这一切”。平时做业务开发你可以只依赖 IDE 的日志窗口。但做硬件适配消息日志可能完全打印不出来IDE 窗口一片空白。这时候如果你手里只有一把锤子看什么都是钉子——而真正的答案往往需要三把工具配合着才能敲出来。所以这套三板斧的底层逻辑是用最少的工具覆盖最多的故障面先确认系统活着再确认系统看到的硬件最后确认配置。步骤顺序可以调整但框架是稳定的。我在后面的章节里逐个展开。2. 第一板斧串口日志确认系统起动到哪一步串口日志这块值得从选硬件和接线说起不是所有人都知道串口电平这回事。2.1 串口是调试的生命线接线前先确认电平标准RK3568 开发板的调试串口绝大多数板子引出的是 TTL 电平不是 RS232。买 USB 转串口模块要选支持 TTL 电平的产品常见的是 CP2102、CH340、FT232 这类芯片做的调试模块。我之前把一个 5V 电平的模块直接接到了 3.3V 的调试串口上虽然没有烧坏引脚但日志输出乱码了很久最后换模块才发现是电平不匹配。接线遵循同一个原则模块的 TX 接板子的 RX模块的 RX 接板子的 TX地线一定要共地。很多新人在这一步忽略共地结果是什么都收不到或者信息断断续续。如果板子的串口引脚是 2.54mm 排针形式找几根杜邦线就行但建议线长控制在 20 厘米以内太长了信号质量会下降容易出现掉字。调试串口的波特率OpenHarmony 标准系统在 RK3568 平台上默认是 1500000也就是 1.5Mbps。这个和 Linux 内核默认的 115200 不一样Uboot 阶段和内核阶段可能还会切换波特率如果你打开串口终端看到一段乱码后跳出正常日志不用慌张。串口调试助手建议直接用 minicom 或者 PuTTY设好对应参数保存会话。2.2 烧录后第一件事在串口日志里找内核启动标记烧录完镜像后第一步不要急着接屏幕、点应用先打开串口终端观察起动输出。如果串口什么都没打优先排查的是线有没有接反、模块有没有选对、波特率是否匹配、板子供电是否足够。很多时候板子的电源适配器电流不够起动到一半会掉电重启串口日志里反复出现同一段引导信息。这时候不要怀疑软件先换电源。RK3568 整板满载电流不低建议使用原装适配器不要用面包板电源或者 USB 口直接带。串口日志正常输出后你会先看到引导程序阶段的打印然后是内核解压和初始化的大量信息。这个阶段要特别注意一个关键字就是内核启动过程中是否出现Kernel command line这一行。它会在启动早期把你传给内核的启动参数打印出来里面包含了 console 串口号和波特率。比如类似下边这样的信息Kernel command line: ... consolettyFIQ0,1500000 ...如果你最终看到的console值和你串口终端里设置的参数不一致后半段的日志一定会丢失或乱码。OpenHarmony 标准系统里调试串口设备节点通常是/dev/ttyFIQ0不是传统 ARM Linux 的ttyS0。在看到系统运行起来之前你先确认这个节点能少走很多弯路。然后是起动阶段的关键字符比如Freeing unused kernel memory、run_init_process、init: ...这些标志能告诉你内核有没有把第一阶段交接给用户态。如果日志停在内核解压完成之后迟迟不见用户态启动可以判断问题大概率在 init 流程、selinux 策略或引导镜像配置上。2.3 用 dmesg 看内核消息但要知道消息会在哪一层被截断内核起来之后如果 ADB 还没通串口是你唯一能敲命令的操作入口。在串口终端登录后第一件事跑一下dmesg把内核环形缓冲区里的消息拉出来。这一步非常关键很多设备的 probe 失败信息在内核启动早期已经打印过只是刷屏太快你没看到。当时我调试一个 USB 外设现象是插上后系统没反应。串口日志里一查usb 1-1: device descriptor read/64, error -71反复出现。这个错误指向 USB 信号质量问题而不是驱动配置问题。后来在 USB 线上加了一个磁环把杜邦线换成屏蔽线问题就消失了。有一点要提醒的是如果你用串口去敲dmesg因为它走的是同一个调试串口输出可能看到的信息和系统日志服务抓到的略有差异。而且 dmesg 环形缓冲区有大小限制启动后的海量日志可能会覆盖掉早期错误。所以更稳妥的做法是启动时先利用串口把完整日志用终端软件的日志记录功能保存下来再去翻查关键字。3. 第二板斧ADB 和 Shell把系统运行状态拉到眼前串口能确认系统“活着”但要判断硬件设备“有没有被正确认识”就得进系统内部去看。3.1 连接设备的几种方式记得先区分“ADB over USB”和“ADB over Network”OpenHarmony 标准系统通常自带 ADB你可以在 PC 上通过hdc命令连接设备。HDC 是 OpenHarmony 的调试工具用法类似 Android 的 ADB但命令名字略有差异。理论上插上 USB 线PC 端敲hdc list targets就能看到设备序列号。但前提是设备端的 USB 配置正确。如果你烧录的镜像没有使能 USB 调试功能或者没有对应的 USB gadget 配置HDC 根本枚举不到设备。遇到这种情况最常见也最有效的替代办法是走网络连接。确保开发板和 PC 在同一个局域网里然后执行hdc tconn 板子IP:8710OpenHarmony 的 hdc 默认监听 8710 端口。连接成功后再执行hdc shell就能进入设备 shell。这种做法在调试 USB 相关的外设时特别有用——因为你一旦要抓 USB 的枚举过程USB 链路本身可能因为插着调试线而互相干扰。3.2 Shell 环境里最常用的一套“体检命令”进入 shell 之后我先执行一套固定的体检命令按顺序排查param get | grep -i product确认当前固件的产品名称和版本信息是否烧录正确。比如 RK3568 标准版会遇到同一份镜像烧进不同板卡导致启动参数错误的问题这里一眼能看出来。cat /proc/cmdline查看内核启动参数重点确认root,console等关键值是否符合预期。设备树配置不当经常会让某些外设对应的驱动没被打开并不是没有驱动而是启动参数里就没使能。ls /dev/看看设备节点有没有生成。很多外设故障在“设备节点缺失”这一层就能定位。比如触摸屏的/dev/input/eventX没出现那说明内核根本没有注册对应输入设备问题在更底层。hdc shell hidumper -s 3301查看系统服务运行情况。3301 是软总线服务3302 是外部设备管理等具体服务 ID 随时查阅组件清单。如果你调的外设属于某个系统服务的管理范围用这个命令能看到服务的注册和运行状态。这些命令跑完后我对设备“在哪一层死了”基本有一个大概判断。比如ls /dev/能看到节点但事件上报不了那就是驱动已经 probe 成功但中断或事件上报有问题如果节点根本不存在那无论是设备树还是驱动加载都有嫌疑。3.3 不要绕过 USB Manager 和 libusb 这两个“坑”在 OpenHarmony 的 USB 相关调试里有个高频搜索词是“openharmony usbmanager libusb 的使用”说明不少人在这里栽过跟头。我简单讲一下OpenHarmony 的应用层访问 USB 外设尤其是自定义 USB 设备时并不是直接打开/dev/bus/usb/...这样的节点。系统有 USB Manager 服务做了一层管理和策略控制应用需要先通过 USB Manager 申请权限、获取设备列表然后才能用 libusb 去和设备通信。libusb 在 OpenHarmony 上属于 Native 层的能力一般通过 NDK 接口暴露给上层应用。调试时最容易出现的问题是你在 shell 里用 root 权限直接访问 USB 节点能成功但应用层因为权限模型和 seccomp 策略调用 libusb 却返回权限错误。我之前做过一个 USB 串口读取的设备应用在 shell 里测试一切正常打包成应用后始终打不开设备排查到最后就是缺少相应的能力权限声明。所以如果你在调 USB 相关硬件先确认应用有没有申请ohos.permission.USB_ACCESS这类权限而不是一头扎进驱动代码里。4. 第三板斧设备树筛选从“十几个 dts”里找对属于你的那一份现在终于要正面回答标题里那个问题了RK3568 的 OpenHarmony 仓库里设备树文件这么多到底咋选4.1 RK3568 设备树文件太多乱选会引发哪些坑我第一次拿到一块 RK3568 板子按照开发文档编译标准系统烧录后发现触摸屏方向不对、HDMI 无输出、以太网不通。回头查日志dmesg里其实早就打印了设备树匹配的型号信息。我没有去看结果等于带着错误的地图跑了半天自然处处碰壁。OpenHarmony 内核仓库的arch/arm64/boot/dts/rockchip/目录下大量以rk3568-evb*.dts、rk3568-*.dts命名的文件并存。它们之间的差异主要在以下几方面板级外设差异不同开发板的屏幕接口、触摸 IC、Wi-Fi/BT 模组、以太网 PHY 可能完全不同。内存容量差异同样是 RK35682GB、4GB、8GB 版本的启动参数和 CMA 预留策略区别很大。设备树里有reg属性直接描述内存区间选错会引发内核崩溃。电源时序差异不同设计对 PMIC 的依赖和 GPIO 控制不同。板厂通常会在出厂时提供一份适配过的设备树它就是最优参考。所以核心原则非常直接如果板子是某个厂家的开发板直接用板厂提供的 dts 或 config如果是自己画的板子必须根据原理图和 PCB 布局去修改官方 dts而不是随手选一个“看起来差不多”的。4.2 确认当前加载设备树、定位编译产物对应关系的实操方法“我怎么知道我编译的镜像用的是哪个设备树”这是另一个高频问题。方法有三条第一步在内核编译配置里确认默认设备树。执行make ARCHarm64 rockchip_linux_defconfig然后通过make ARCHarm64 dtbs查看生成的 dtb 文件列表。你也可以直接把编译产物反编译回 dts 源文件搜索板型关键词来反查匹配情况。第二步用串口日志或/sys/firmware/devicetree/base/model来确认实际加载的模型名称。model属性通常直接写明板卡型号。执行cat /sys/firmware/devicetree/base/model第三步是在设备树里加一个临时的 bootargs 打印或用initcall_debug参数引导内核配合串口日志看内核在选择设备树和 probe 驱动时的顺序。加入initcall_debug后串口会输出大量设备初始化调用次序虽然刷屏但信息量非常大尤其在怀疑驱动加载顺序导致资源冲突的时候。4.3 设备树调试的三种快速实验手段实践中我发现与其反复修改 dts 后烧录验证不如掌握几个“快速迭代”的技巧。设备树 overlay叠加层OpenHarmony 的引导链支持 DTB overlay 能力。改动不频繁时把差异化的节点写到 overlay dts 里比直接改主 dts 更快对后续 kernel 版本升级也友好。在用户态验证引脚和寄存器如果怀疑某个 GPIO 没有正确拉高可以在 shell 里用gpio_export或写/sys/class/gpio做一次快速实验如果能控制电平翻转至少说明引脚没被硬件损坏或复用成别的功能。在 dts 里临时打开调试节点比如在 USB 控制器的节点里增加status okay或者把某个 regulator 的regulator-always-on属性打开观察日志变化。注意这是临时手段问题定位后要还原否则会掩盖硬件本身的功耗问题。5. 一个典型排障案例网口不通从日志到设备树的完整走查下面用一个我实际遇到过的问题把目前提到的工具串起来。场景是 RK3568 板子做 OpenHarmony 标准系统适配以太网口插上网线后ifconfig看不到eth0。排查第一步看驱动有没有加载。串口里敲dmesg | grep -i eth dmesg | grep -i stmmacRK3568 的 GMAC 驱动在内核里通常叫stmmac。日志里如果完全没有出现这个驱动说明可能是设备树里没使能 eth 节点或者编译内核时根本没把相关驱动编进去。第二步查看设备树节点。执行ls /sys/firmware/devicetree/base/ethernetfe2a0000/如果这个节点不存在说明当前加载的 dts 根本没有网口描述。按照官方参考设计RK3568 有两个 GMAC 控制器其中fe2a0000对应 GMAC0fe2c0000对应 GMAC1。出厂固件会按硬件实际连接选择使能哪一个。当时我选的通用 dts 只使能了 GMAC1但板子实际走的是 GMAC0于是总线虽然起来了PHY 却没有被正确驱动网络自然不通。第三步用 ADB shell 去查 PHY 寄存器和物理连接状态。这一步对判断问题层级至关重要hdc shell cat /sys/class/net/eth0/phy/phy_registers cat /sys/class/net/eth0/carrier如果carrier返回 0说明物理链路没有建立。要么是 PHY 的复位 GPIO 没有被释放要么是 PHY 的地址不对。回设备树里查phy-mode和reset-gpios对照原理图确认。最终的坑说出来有点可笑——板子的 PHY 复位引脚和 another I2C 设备的引脚冲突了早期 bootloader 拉低了复位电平内核启动后设备树配置的 GPIO 又被另一设备复用导致以太网 PHY 始终处于复位状态。这种问题只看驱动代码根本查不出来必须结合串口日志的 GPIO 初始化顺序和设备树里的pinctrl复用状态才能真正确定。这个案例给我一个很深的感觉硬件调试中真正难的不是读代码而是把不同层面的信息对起来。串口日志给你时间线ADB 给你状态快照设备树给你配置地图三个东西放在一张纸上一起看问题才会显形。6. 三板斧用完仍然没结果接下来可以动用的手段有了串口、ADB、设备树三把工具绝大部分问题已经具备排查方向。但硬件调试总有疑难杂症三板斧砍完还是没解决这时候我会再加两招辅助手段。6.1 拿逻辑分析仪或示波器做硬件层验证如果设备树和内核配置都确认没问题日志里也不见报错那问题可能出在物理信号层。比如你怀疑某个 UART 外设没数据——代码配置都对寄存器状态也正常那就要用示波器去看对应引脚在通信时有没有电平翻转。没有示波器的话即便便宜的 8 通道逻辑分析仪也够用大部分协议解析如 UART、I2C、SPI都能在 PC 端软件上直接解码。这一招在我调试一个奇怪的传感器时立过功当时日志显示 I2C 通信正常但数据永远是 0xFF用分析仪一看时钟线的一根走线有虚焊信号时有时无纯软件排查一辈子也定位不了。6.2 用内核的 trace 机制追踪驱动行为如果驱动会加载但行为不符合预期比如 probe 成功后中断没有触发那可以用内核的tracepoint配合perf或者trace-cmd去做函数层面的追踪。虽然 OpenHarmony 标准系统的内核默认裁剪了一部分 trace 功能但很多基础的 tracepoint 依然可用。打开/sys/kernel/debug/tracing/available_events能看到系统当前支持的跟踪事件。中断相关的irq:irq_handler_entry这类事件往往能快速告诉你“中断有没有进来”。有一次我调一个 GPIO 按键现象是按下去完全没有事件上报。设备树查过没问题驱动也加载了。用 trace 一看发现 GPIO 中断注册成功后共享中断里被另一个驱动抢先标记为 handled导致按键事件永远不被处理。这个案例也说明硬件调试的终点往往不在硬件而在内核资源管理和驱动协作上。结束做 OpenHarmony 硬件适配这一年多我最大的感受是这活儿的瓶颈不在设备树语法有多难也不在编译错误多奇葩而在于你有没有一套稳定的方法论能在问题面前不慌。串口、ADB、设备树这三板斧事后来看都算不上什么高深技巧但用熟了它们每次遇到新板子、新外设我心里都会有一个明确的起点先看串口日志确认系统是否活着再用 ADB 确认设备被系统识别成什么最后用设备树确认“是不是地图画错了”。如果这三步都走完了还没答案那才轮到去啃驱动源码或者找示波器——而大多数问题到不了这一步就会现出原形。
返回列表