
1. 为什么硬件调试总是卡在三板斧这一步做OpenHarmony设备开发的朋友应该都有同感真正把系统跑起来之前大半时间都耗在硬件调试上。尤其是刚接触RK3566、RK3568这类开发板时会遇到一个特别尴尬的局面——代码写得再漂亮板子点不亮或者启动到一半就崩了你根本不知道问题出在哪。这时候大家都在反复念叨三件事串口有没有输出、日志能不能看到、调试器连不连得上。我见过不少新手在这上面绕远路。有人一上来就翻设备树对着几百行dts文件逐条核对搞了一整天发现只是串口波特率配错了有人板子插上USB半天没反应折腾驱动装了一堆软件结果是数据线压根不支持数据传输。说句实话硬件调试没那么多玄学抓稳最基础的三板斧——串口、日志、调试器——九成问题都能定位清楚。这篇内容就是围绕这套方法论展开的。我会从OpenHarmony系统实战开发的视角把这三种调试手段的原理、配置方法、常见坑位一次讲透。不管你是刚拿到开发板的小白还是已经能编译烧录但遇到疑难杂症的老手这篇都能给你提供一套直接可用的排查思路。文章涉及的内容全部基于标准OpenHarmony发行版和常见RK系列开发板不绑定特定厂商的魔改环境尽量做到换块板子也能照葫芦画瓢。我个人始终认为调试能力才是嵌入式开发的真正分水岭。写代码谁都会能在漆黑的串口日志里把问题揪出来才是经验积累的体现。接下来从一个反直觉的现象聊起——为什么有时候OpenHarmony板子看着一切正常却就是无法运行你的第一个程序这背后的原因往往就藏在调试三板斧的细节里。很多人可能会问这三板斧听着太基础了能解决什么复杂问题实际上恰恰相反。我在实际项目里遇到过Wi-Fi模块反复掉线、GPU渲染花屏、甚至系统随机重启这类疑难问题最终定位手段没有一样超出串口、日志和调试器的范畴。区别只在于你会不会把这三样工具用到极致。就拿串口来说大多数人只拿它看开机的内核日志但真正的调试老手会用它构建交互式shell、动态调整内核参数、甚至在系统完全卡死时通过串口中断进入救援模式。这些玩法往后会逐一展开。2. 第一板斧串口——调试的生命线2.1 串口在OpenHarmony调试中的真正定位串口在嵌入式调试中的地位相当于手术台上的心电监护仪——它不是万能的但没有它你几乎就是在盲操。OpenHarmony系统启动时从引导加载程序U-Boot到内核再到用户态的init进程都会通过串口输出运行状态信息。这些信息是判断系统活着还是死了的第一手依据。在内核启动阶段串口日志的详细程度远超显示屏。显示屏要等GPU驱动和显示服务加载完成后才能工作而串口从CPU上电那一刻就开始输出固化在引导程序里的启动信息。如果板子连串口都没有任何反应问题基本锁定在硬件供电、时钟配置或者DDR初始化这几块跟系统软件关系不大。反之如果串口有输出但到某个阶段戛然而止那至少说明硬件基础是好的问题出在输出中断点附近的驱动或服务上。这样一来串口就把到底是硬件坏了还是软件写错了这个大问题拆解成了一个可以逐步缩小范围的排查过程。你在OpenHarmony上遇到的绝大多数启动失败问题都可以通过串口日志划分责任边界。2.2 从零接线到跑通串口控制台串口调试的第一步是硬件连接。以最常见的RK3568开发板为例板上通常会引出3.3V电平的UART调试接口一般标记为DEBUG或UART2。你需要准备一个USB转串口模块市面上常见的CP2102、CH340、FT232都行接线规则是开发板的TX接模块的RX开发板的RX接模块的TXGND对GND。这里有个新手特别容易犯的错——把TX和TX接在一起结果什么输出都没有。串口是交叉连接的这点记牢能省不少事。接线完成后把USB转串口模块插到电脑上然后确认设备节点。在Linux系统里执行ls /dev/ttyUSB*或者ls /dev/ttyACM*在Windows上则打开设备管理器查看COM口编号。接着用串口工具连接我用得最多的是minicom和PuTTY。以minicom为例首次配置可以用sudo minicom -s进入设置界面选择Serial port setup把波特率设为1500000数据位8停止位1无校验关闭硬件流控。这里必须强调一下波特率。很多OpenHarmony开发板默认的控制台波特率是1500000也就是1.5Mbps跟传统嵌入式开发常见的115200完全不同。如果你用115200去连串口会输出一堆乱码看起来像是系统崩溃了实际上只是速率不对。我当时第一次连RK3566开发板就踩了这个坑屏幕上滚动的全是不可读字符差点误判成固件损坏。判断波特率是否正确的一个笨办法是乱码是否有规律地持续滚动且间隔稳定——如果是大概率只是波特率设置问题而不是硬件故障。连接成功后给板子上电串口终端里应该能看到U-Boot的启动信息。在倒计时阶段按任意键可以进入U-Boot命令行这是后续很多底层调试的基础入口。完整的U-Boot输出看起来类似这样U-Boot 2017.09-g72b0f71 (Jan 05 2024 - 18:00:00) CPU: rk3568 DRAM: 2 GiB MMC: dwmmcfe2b0000: 1, dwmmcfe2c0000: 0 ... Hit any key to stop autoboot: 0看到这段输出意味着串口通道已经打通第一板斧算是握住了。2.3 串口日志的分段解析方法拿到串口日志最关键的是学会分段定位问题。我把OpenHarmony从上电到系统就绪的串口输出划分为四个阶段每个阶段对应不同的排查方向第一阶段是U-Boot阶段从启动到Starting kernel ...。这个阶段的日志主要关注DDR初始化是否成功、存储介质eMMC/SD卡是否能正常识别。如果卡在DDR初始化日志通常会反复打印类似ddrbin: ddr4_32bit_3840_400um这样的初始化参数然后死循环这基本是硬件问题或者固件里的DDR配置和实际颗粒不匹配。第二阶段是内核早期启动从Starting kernel ...到设备驱动初始化完成。这个阶段重点看有没有Unable to handle kernel NULL pointer dereference、Kernel panic、Oops这样的关键字。一旦出现说明内核在初始化某个驱动时崩溃了导致崩溃的驱动名称一般会在日志里打印出来顺着这个驱动名去查设备树配置通常能找到答案。比如我在调试一个RGB LCD屏驱动时内核反复崩溃日志指向rockchip,drm驱动最后发现是设备树里clock-names属性少写了一个时钟项。第三阶段是内核态到用户态的切换特征是日志中出现Freeing unused kernel memory和Run /init as init process。此时如果系统卡住说明init进程或者它依赖的服务有问题这类问题单纯看内核日志难以定位要配合ramdisk里的init脚本日志来判断。第四阶段是OpenHarmony用户态服务启动特征是能看到大量的AbilityManagerService、BundleManagerService这类系统服务标签。如果卡在这一阶段通常是某个系统服务崩溃导致init反复拉起又反复崩溃日志里伴随服务重启的循环记录。每个阶段划分清楚了你拿到一段日志就能快速判断问题大概发生在哪个环节再决定是去查U-Boot配置、内核驱动还是用户态服务效率能提升一大截。这也是把调试三板斧从工具层面上升到方法论层面的关键一步。2.4 串口相关的常见坑位与排查建议基于我给不少开发者远程看过问题的经验串口调试最常见的异常现象和原因我有必要整理一个对照表方便大家直接查阅。现象可能原因检查方向完全没有输出TX/RX接反、GND未共地、开发板未上电用万用表测TX引脚电平接线交叉重试输出乱码波特率不正确、电平不匹配尝试115200/57600/1500000多组波特率只有部分启动输出内核阶段串口驱动配置错误查内核cmdline里console参数和设备树aliases输出断断续续供电不稳或USB转串口模块质量差更换带屏蔽的杜邦线外接稳定电源无法输入命令串口工具开启了硬件流控关闭RTS/CTS流控这里有一条根深蒂固的经验串口调试的问题七成出在接线和配置上三成才真正是系统或硬件故障。遇到串口没输出的情况不要急着怀疑固件先拿万用表量一下开发板TX引脚在启动瞬间是否有电平跳变。只要有跳变说明板子在发数据问题出在你的接收链路反过来才是板子根本没工作。3. 第二板斧日志——让系统状态变得可视化3.1 OpenHarmony日志系统的层次结构与读取途径串口能解决启动阶段的问题但系统跑起来之后App崩溃、服务异常、性能劣化这类问题单靠串口日志已经不够用了。OpenHarmony提供了完整的日志系统按来源可以分为内核日志dmesg、系统服务日志hilog、应用日志HiLog三个层次。先说内核日志。它记录的是内核态驱动和子系统的运行状态通过dmesg命令查看。在OpenHarmony设备上内核日志对于排查外设驱动问题尤其重要。比如你的GPIO驱动的中断没有触发在/sys/kernel/debug/gpio可以查看引脚状态而具体的中断上报过程则要靠dmesg里irq相关的打印。然后是用户态的hilog。这是OpenHarmony最核心的日志系统有点类似Android的logcat。系统所有C和JS层的服务、框架、应用都会通过hilog输出日志。hilog的日志按域domain和标签tag来组织同一个系统服务使用统一的domain配合tag可以精确过滤出某个模块的日志。实际使用中hilog命令的参数组合非常灵活我经常用的几条如下# 查看所有日志持续输出类似于logcat的-v time hilog -x # 按域过滤比如查看软总线模块的日志 hilog -D 0xD001560 # 按标签过滤比如只看某一个特定服务 hilog -e AbilityManagerService # 把日志保存到文件方便后续分析 hilog -w core -f /data/log/hilog.log这里面有几个关键细节值得展开讲。hilog -w core会把日志写入文件适合做长时间抓取因为终端缓冲区容量有限滚动太快会导致旧的日志丢帧。如果要做自动化分析可以用hilog -r从已保存的日志文件里读取再配合grep、awk这类文本工具做过滤。另外一个常用姿势是hilog -p配合-e比如hilog -e FATAL可以直接把fatal级别的崩溃日志筛出来在排查闪退类问题时会快很多。3.2 日志过滤与追踪的高效姿势日志系统最怕的就是信息过载。一个跑着完整OpenHarmony系统的设备每秒钟产生的hilog可能上千行想从海量日志里捞出一条关键错误无异于大海捞针。从业这些年我总结了一套过滤思路按优先级排列第一优先级是抓崩溃信息。不管是应用还是系统服务崩溃hilog里都会出现FATAL关键字这是最高优先级。一条典型的崩溃日志会包含崩溃进程名、信号类型比如SIGSEGV表示段错误、崩溃时PC寄存器的值以及调用栈。调用栈尤其关键它直接告诉你崩溃发生在哪一行代码。比方说看到#01 pc 000000000002a6f4 /system/lib/ld-musl-aarch64.so.1说明崩溃发生在动态链接器的某个偏移地址结合符号表就能还原出具体的函数。第二优先级是按业务模块跟踪。比如你在调试一个分布式硬件的接入问题核心域是软总线那就要把日志过滤范围收窄到软总线域。OpenHarmony把系统服务划分为很多domain每个domain有唯一ID在日志里能看到类似D001560这样的标识。用hilog -D按域过滤可以把无关模块的日志全部排除掉只盯着软总线的运行轨迹。第三优先级是跨模块关联。有些问题不是单一模块的bug而是模块间的交互异常。比如摄像头预览黑屏可能是Camera服务的问题也可能是显示合成服务的问题还可能是硬件编解码的问题。这时候单独看一个模块的日志远远不够需要把相关几个域的时间戳对齐拼出一条完整的事件链。一个实用做法是先把各个模块的日志都落到文件里然后用Python脚本按时间戳做关联分析把同一毫秒级别的事件串起来看。另外还有一个小技巧在OpenHarmony的hilog里日志级别一般有DEBUG/INFO/WARN/ERROR/FATAL五级。在正式调试时可以用hilog -z关闭冗长的DEBUG日志只保留INFO以上级别减少干扰。等到需要深挖特定逻辑时再打开对应模块的DEBUG输出。3.3 日志排查的实际案例一次OpenHarmony服务反复重启的根因定位我这里有一个很典型的案例可以分享。有次我拿到一块RK3568板子现象是系统起来后运行几分钟某个系统服务就会崩溃重启再崩溃再重启周而复始。从用户角度看就是系统间歇性卡顿某个功能突然丢失过一会儿又恢复了。排查思路是从hilog的崩溃记录入手。先用hilog -e FATAL抓到崩溃时的完整调用栈发现崩溃发生在foundation进程里再配合addr2line把PC地址翻译成源码行号定位到某个分布式数据管理服务的代码中。顺着代码逻辑继续看发现是数据库打开失败后没有正确释放句柄导致下次重试的时候句柄溢出。但继续深挖就更有意思了。为什么数据库会打开失败到这一步需要查它的依赖条件。通过按域过滤hilog -D查看数据管理域的日志发现它在尝试挂载某个分区时返回了权限错误。再跳回内核日志用dmesg查看定位到是某个存储分区的SELinux标签配置错误导致用户态进程没有权限访问。整个链路串起来就是SELinux标签错误 → 数据库文件无法打开 → 服务初始化失败 → 崩溃重启。单看任何一个模块的日志问题都不完整只有把三层日志联合起来才能还原全貌。这个案例最大的教训就是日志系统的三层结构不是各管各的很多bug的真实根因横跨多个层次要养成假设-验证-跨层关联的排查习惯。4. 第三板斧调试器——深入到内核和应用的内部4.1 内核态调试从printk到KGDB串口和日志帮我们看到了系统的运行状态但有时候状态信息本身就是误导。比如系统死锁了日志里可能什么都看不到进程状态看起来也正常但就是不响应。这时候需要调试器直接介入系统内部看每一个CPU核当前在哪执行、锁被谁持有。OpenHarmony内核态调试最基础的手段是printk它和用户态的日志类似但输出是直接打到内核日志缓冲区的。printk有八个级别从KERN_EMERG到KERN_DEBUG在调试驱动时临时在关键路径上加上printk是定位问题最快的方式。但printk有个硬伤——会改变时序。有些bug对时序极其敏感你加了printk它反而不出现了这时候就需要KGDB这类交互式调试工具。KGDB是内核的调试器通过串口连接工作方式类似gdb。启用KGDB需要在内核配置里打开CONFIG_KGDB和CONFIG_KGDB_SERIAL然后在启动参数里加上kgdbocttyS0,115200。调试时在目标机上先触发中断进入调试状态echo g /proc/sysrq-trigger这条命令会让内核暂停进入KGDB等待模式主机端的gdb通过串口连接上去后可以查看内存、设置断点、单步执行。在调试驱动初始化崩溃时非常有用因为它可以在崩溃点停下来查看所有寄存器和变量状态。比如某次我在调试一个MIPI DSI屏幕驱动时屏幕初始化过程中内核直接死机printk根本没机会打印。用KGDB在初始化函数入口设置断点单步跟进最终定位到是某个延迟函数在关中断环境下被调用导致系统睡死。4.2 用户态调试gdb与core dump的配合内核态调试是少数人的活大多数OpenHarmony开发者日常打交道更多的是用户态应用和系统服务的调试。这时候gdb是主力配合core dump文件可以做到事后复盘。OpenHarmony系统的用户态进程崩溃时如果配置了core dump系统会把崩溃时刻的内存镜像写入文件之后用gdb加载这个core文件就能看到崩溃时的完整调用栈、变量值、寄存器状态跟当时用调试器停下来几乎一样。配置core dump的方法# 设置core文件大小为不限制 ulimit -c unlimited # 查看core文件生成位置 cat /proc/sys/kernel/core_pattern用gdb分析core文件的基本流程gdb /system/bin/your_app /data/core/core.your_app.1234进入gdb之后第一件事是执行bt查看调用栈第二件事是info registers查看寄存器值。调用栈会精确打印出崩溃时的函数调用链通常看到最顶层的那几个函数就是问题所在。如果崩溃发生在第三方应用而你又恰好有源码就可以用带符号表的版本配合源码调试list命令可以直接显示崩溃位置附近的源代码比对着汇编看效率高太多。但绝大多数场景下core dump配合bt命令已经能帮你把问题范围缩小到某个具体函数剩下的就是读代码找逻辑错误。4.3 调试工具链在RK3568开发板上的落地步骤如果你手里正好有一块RK3568系列的OpenHarmony开发板想把这套调试工具链完整跑起来我这里整理了从编译到落地的几步操作。第一步确认内核开启了调试选项。在OpenHarmony内核源码目录执行make ARCHarm64 menuconfig在Kernel hacking菜单里确认Kernel debugging下的Compile-time checks and compiler options、KGDB相关选项处于打开状态。同时确认CONFIG_DEBUG_INFO已经打开这样内核编译时才会生成调试符号和addr2line可用的vmlinux文件。第二步编译时保留调试符号。内核编译完成后vmlinux文件就是带符号的内核镜像要把它保存好。后面用addr2line做地址翻译时需要用到这个文件aarch64-linux-gnu-addr2line -e vmlinux ffffff80081234ac第三步用户态程序的调试需要在编译时加上-g参数。OpenHarmony的构建系统里可以通过在BUILD.gn中设置cflags [ -g ]来为特定模块开启调试信息。注意这会增大二进制体积建议只在debug版本开启。第四步确认开发板的串口调试口已经连通把内核启动参数加上kgdbocttyS0,1500000注意波特率要和你实际串口配置一致。重启开发板后执行echo g /proc/sysrq-trigger系统会暂停串口工具里会出现KGDB的等待提示主机端gdb直接连接串口即可调试。这套工具链在OpenHarmony开发中属于进阶操作第一次配通会有不小的成就感。但我也要提醒一句KGDB依赖串口通信波特率太高可能不稳定如果调试过程中频繁断连适当降低波特率即可。这个细节我自己的调试经历里栽过跟头——一路用1.5M波特率跑KGDB掉线到怀疑人生换成115200之后稳如老狗。5. 三板斧联动一套完整的RK3568实战排错过程5.1 问题场景与初步判断有了前面三个章节的铺垫现在把三样工具合起来走一遍完整的排错流程。这个案例来自我帮一位开发者远程定位的一块RK3568开发板问题。板子预置的是OpenHarmony标准系统启动到桌面完全正常但一旦开始播放视频过不了几秒系统就死机重启没有任何预兆。从现象初步判断这个问题具备几个特征低概率偶发性、触发条件明确播放视频、系统级崩溃。考虑到RK3568的硬解能力本身没问题更可能是某个驱动或服务在特定条件下触发了异常。因为问题能复现就给定位提供了很好的机会。先直接看hilog崩溃日志确认崩溃发生的位置。命令是hilog -e FATAL日志显示崩溃进程是multimedia_service崩溃信号是SIGSEGV出问题的线程名是HdiCodecThread。这说明崩溃不发生在应用层而是多媒体服务调用了硬件编解码接口时出了问题。到这一步用户态这条线已经缩小到多媒体服务调用硬件编解码HAL层这个环节。5.2 三层日志交叉定位接下来用dmesg看内核日志在这一层搜索codec相关输出dmesg | grep -i codec结果发现内核里有几条关于rkvdec的报错显示解码器在某个瞬间报告了bitstream error和fatal error。这说明内核态的编解码驱动确实感知到了异常但驱动自身没有崩溃。问题在于驱动报错之后用户态的服务没有正确处理这个错误继续往硬件里灌数据最终导致系统复位。到这里逻辑链已经比较完整了但还缺一个关键的拼图是什么导致硬件报错这时候需要用到调试器。用KGDB在内核态下一次断点当rkvdec驱动察觉到异常时强制中断查看当前硬件的寄存器状态和驱动内部缓冲区的数据。通过查看驱动里的解码buffer数据发现推送给硬件的数据流中间有一段完全不符合H.264规范的填充数据。正常来说解码器遇到这种数据会返回错误码但此时用户态的调度逻辑已经把后续的帧也推进来了导致硬件状态机错乱最终触发看门狗复位。为了彻底确认根因回到用户态看视频播放流程的hilog日志在multimedia_service的工作线程里确实能看到在崩溃前有一次CodecBufferQueue的空闲buffer数量降至0但服务没有等待buffer回收而是直接继续提交了下一批输入。到这里根因锁定了缓冲管理逻辑缺陷硬件解码速度低于输入速度时没有做流控。5.3 修复方案与验证定位到根因后修复方案就水到渠成了。在多媒体服务的buffer管理模块里为输入队列增加一个水位线检查——当空闲buffer低于阈值时输入线程主动阻塞并等待解码线程消费完至少一枚buffer后再继续提交。这个改动本质上就是给解码链路补上背压机制。修复完成后我建议这位开发者在三个层级分别做验证。第一层是hilog观察播放视频期间multimedia_service不再出现FATAL日志rkvdec的错误计数不再增长。第二层是压力测试连续播放不同码率的视频超过12小时系统不再死机。第三层是回归测试其他多媒体功能音频播放、画面截图、编码推流不受影响。这个案例最值得回味的地方在于三板斧中的每一样都发挥了不可替代的作用。没有hilog你连崩溃发生在多媒体服务都无从知晓没有dmesg你没法把问题从用户态下沉到内核驱动没有KGDB你就看不到硬件报错的根本原因是数据异常。三条线交织在一起才把一条偶发的崩溃链路完整还原出来。6. 让三把斧头更顺手工具链优化与调试习惯养成6.1 日志抓取与自动分析的效率工具手工敲命令式调试在简单场景下够用但项目一复杂日志量一大必须有一套自动化的工具链来承接。我建议每个OpenHarmony开发者都建立一个调试工具箱哪怕刚开始只是一组shell脚本和Python工具。最基础的是一个日志自动抓取脚本在设备上执行按时间戳落盘hilog -x --start -w error -f /data/log/error_$(date %Y%m%d%H%M%S).log 这样即使出现随机崩溃崩溃前一分钟的错误日志大部分能保住。再配合一个定时检查系统关键指标的小工具我在实际项目里用的采集项包括这些内存占用free -m、CPU负载top -n 1、关键进程存活状态ps -ef、内核错误计数cat /proc/interrupts和/proc/meminfo、网络连接状态ip link。这些指标每隔5分钟记录一次崩溃发生后再回看指标时间线往往能发现一些日志里没有体现的环境异常线索。日志分析层面我强烈建议掌握Python对hilog日志做后处理。一条典型的hilog日志行是这样的08-05 14:23:45.678 1234 5678 I C01f00/AbilityManagerService: StartAbility finish, ability: com.example.demo.MainAbility用正则表达式把时间戳、PID、TID、级别、域、标签、消息体拆出来然后就可以按任何维度做聚合统计。比如统计某段时间内ERROR级别日志出现的频率哪个域产生的日志最多哪个进程在崩溃前有异常I/O操作等。对于服务反复重启这类问题写一段脚本统计进程PID变化频率立刻就能判断崩溃周期并缩小触发条件。6.2 不同开发阶段的调试侧重点根据项目所处阶段调试侧重点有所不同这里我梳理了一张速查表方便做方案选型时参考。阶段主要问题首选调试手段辅助手段硬件bring-up板子起不来串口U-Boot日志示波器/万用表内核适配驱动崩溃dmesg KGDB设备树排查系统服务集成服务启动失败hilog按域过滤core dump应用开发应用闪退hilog core dumpgdb attach性能优化卡顿/延迟hilog时间戳 perf内核trace每个阶段之间的切换往往是一个渐进过程。硬件bring-up阶段你会发现串口日志越看越熟练U-Boot里各种命令倒背如流进入内核适配阶段后就很少盯着串口了更多时间花在dmesg和KGDB之间来回切换到了系统集成和应用开发阶段hilog就成为日常主力。很多开发者跳过了硬件bring-up阶段直接用厂商提供的预编译镜像做应用开发。这种情况下如果遇到系统底层问题往往会非常被动因为你对串口日志和内核日志的判断缺乏经验。我始终建议即使你不做硬件适配也至少完整地看一遍自己开发板的串口启动日志知道正常状态长什么样异常出现时才能第一时间察觉。6.3 几条值得长期遵守的调试纪律最后分享几条我自己踩坑总结出来的调试纪律未必全面但对绝大多数项目都适用。第一条是一次只改一个变量。在定位问题阶段每次修改只针对一个可能的根因改完立刻验证。千万不要同时改设备树、换内核版本、调整日志级别那样即使问题消失了你也不知道是哪个改动起了作用。第二条是保留现场再动手。在改动任何东西之前先把当前状态完整记录下来——串口日志、hilog、内核版本、设备树内容、应用版本全部归档。有时候你改了一通发现问题还在回退后想对比新旧环境差异没有存档就只能重新折腾。第三条是善用已知正常的镜像做对照。手上保留一份确认能正常运行的固件标注好版本号和对应的源码commit号。出问题时先刷一份正常固件验证硬件没坏再刷回出问题的固件继续排查能有效隔离硬件故障和软件bug两类因素。第四条是重要日志落盘不要只依赖屏幕。串口工具窗口刷新速度太快日志滚过去就再也找不回来了。写脚本在设备端自动保存日志每天归档等到要复盘时才不会抓瞎。这一点在前面工具链部分提过这里再次强调实在是因为太多人在上面吃过亏。