ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

OpenHarmony I2C 外设调试与排障实战指南

OpenHarmony I2C 外设调试与排障实战指南 I2C 这东西说起来简单两根线一挂设备就能通信。但真到了 OpenHarmony 的板子上你会发现事情远没有想象中那么顺利——扫描不到设备、读写超时、波形畸变、地址冲突随便一个都能让你调上一整天。我在 RK3568 和几款国产 SoC 上做 OpenHarmony 适配的时候I2C 排障花的时间几乎占了外设调试的一半以上。这篇内容就把 I2C 在 OpenHarmony 下的使用方法和排障思路完整梳理一遍从协议基础到设备树配置从内核驱动到用户态 HDF 框架再到逻辑分析仪抓波形的实战技巧尽量把每个环节讲透。不管你是刚接触 OpenHarmony 外设开发的新手还是已经踩过几个坑想系统整理一下的老手应该都能从中找到有用的东西。1. I2C 在 OpenHarmony 外设体系里到底处于什么位置1.1 为什么嵌入式开发绕不开 I2C搞嵌入式的人都有一个共识GPIO 太裸SPI 太快但线多UART 点对点不够灵活。I2C 恰好卡在一个很舒服的位置——两根线SDA 数据线 SCL 时钟线支持多主多从速率从 100kHz 到 3.4MHz 不等挂十几个传感器、EEPROM、触摸屏、PMIC 都不在话下。你在任何一块开发板上找外设大概率都会碰到 I2C 接口的器件。OpenHarmony 作为面向全场景的分布式操作系统外设框架用的是 HDFHardware Driver Foundation。I2C 在 HDF 里被抽象成一种标准总线类型上层应用通过 HDF 提供的 I2C 接口去读写从设备底层则由 SoC 的 I2C 控制器驱动来干活。这个分层设计的好处是你换一块板子只要设备树和控制器驱动适配好了上层业务代码基本不用动。但问题也恰恰出在这个分层上。很多人在应用层调不通 I2C就以为是 HDF 接口用错了实际上根因可能在设备树的引脚复用没配对或者内核里 I2C 控制器根本没起来。所以理解 I2C 在 OpenHarmony 里的完整链路是排障的第一步。1.2 从应用到硬件I2C 的完整调用链路在 OpenHarmony 标准系统里一次 I2C 读写大致经过这么几层应用层通过 HDF 提供的I2cOpen、I2cTransfer等接口发起请求或者通过内核态驱动直接调用 I2C 子系统 API。HDF I2C 框架层负责管理 I2C 控制器实例解析 HCS 配置把请求路由到对应的控制器。Linux I2C 子系统OpenHarmony 标准系统底层用的是 Linux 内核I2C 核心层提供i2c_adapter、i2c_client、i2c_driver等抽象。SoC I2C 控制器驱动具体操作寄存器产生时序波形。硬件层SDA/SCL 两根线加上上拉电阻连到从设备。这条链路上任何一环出问题表现都是读写失败。所以排障的核心思路就是从下往上逐层确认先保证硬件和控制器没问题再查驱动和框架配置最后看应用层调用。很多人一上来就查应用代码这是效率最低的做法。I2C 的问题八成出在设备树和硬件层面应用代码出错的概率反而最小。1.3 OpenHarmony 下 I2C 与 Linux 标准 I2C 的差异虽然 OpenHarmony 标准系统底层是 Linux但它对 I2C 做了一些封装和扩展。最明显的差异在于配置方式标准 Linux 用设备树Device Tree描述 I2C 控制器和从设备而 OpenHarmony 的 HDF 框架额外引入了一套 HCSHDF Configuration Source配置。两者需要配合使用——设备树负责让内核识别控制器和注册i2c_clientHCS 负责让 HDF 框架知道怎么管理这些设备。这就带来一个常见的坑设备树里配好了内核也能看到 I2C 设备但 HDF 层拿不到应用调I2cTransfer直接返回失败。原因往往是 HCS 文件里没有对应的节点配置或者配置的 bus 编号和设备树里的对不上。这个后面会详细讲。另外轻量系统LiteOS-M上的 I2C 实现和标准系统完全不同轻量系统没有 Linux 内核I2C 驱动是直接基于 HDF 写的裸机驱动。本文主要针对标准系统展开轻量系统的思路类似但细节差异较大。2. 协议层面I2C 时序里那些容易忽略的细节2.1 起始、停止与应答三个必须刻在脑子里的信号I2C 协议的核心就三个信号起始条件START、停止条件STOP、应答ACK/NACK。看起来简单但实际调试中很多问题就出在这三个信号的时序上。起始条件SCL 为高电平时SDA 从高变低。停止条件SCL 为高电平时SDA 从低变高。注意这两个条件都要求 SCL 处于高电平如果 SCL 还没拉高就动了 SDA从设备根本不会认为是起始或停止信号。应答信号每传输 8 位数据后第 9 个时钟周期用来传 ACK。主机释放 SDA从设备如果拉低 SDA 就是 ACK保持高就是 NACK。很多读写失败的情况其实就是从设备根本没给出 ACK——要么地址不对要么从设备没上电要么上拉电阻不合适导致电平识别错误。用逻辑分析仪抓波形的时候第一件事就是看起始条件后面跟的地址字节有没有 ACK。如果没有 ACK后面的一切都不用看了先解决从设备响应的问题。2.2 时钟拉伸从设备也会拖后腿时钟拉伸Clock Stretching是 I2C 协议里一个很实用但容易被忽略的机制。当从设备处理不过来的时候它可以把 SCL 拉低强制主机等待。主机必须检测 SCL 的实际电平在从设备释放之前不能继续发时钟。这个机制在读写 EEPROM 的时候特别常见。EEPROM 写完一个页之后需要几毫秒的内部擦写时间这期间它会一直拉低 SCL主机如果不等读出来的就是垃圾数据。在 OpenHarmony 的 I2C 控制器驱动里时钟拉伸通常是硬件自动处理的但有些 SoC 的 I2C 控制器不支持时钟拉伸或者驱动里没使能这个功能。如果你发现读 EEPROM 偶尔失败可以查一下控制器手册确认时钟拉伸是否被支持。RK3568 的 I2C 控制器是支持时钟拉伸的但需要在寄存器里使能。2.3 上拉电阻不是随便放一个就行I2C 的 SDA 和 SCL 都是开漏输出必须外接上拉电阻才能输出高电平。这个电阻的取值不是拍脑袋定的它和总线电容、通信速率直接相关。总线电容越大上升沿越慢上拉电阻就要越小。但电阻太小又会导致功耗增加而且从设备的灌电流能力有限太小可能拉不低。一般经验公式是标准模式100kHz4.7kΩ 到 10kΩ快速模式400kHz2.2kΩ 到 4.7kΩ快速模式1MHz1kΩ 到 2.2kΩ实际取值还要看总线上挂了多少设备、走线多长。我遇到过一块板子I2C 走线拉了将近 20cm上拉用的 10kΩ结果 400kHz 下波形上升沿严重变形降到 100kHz 才能勉强通信。后来把上拉换成 2.2kΩ400kHz 就稳了。用示波器或逻辑分析仪看波形时重点看上升沿是否够陡。如果上升沿占了时钟周期的很大比例说明上拉电阻偏大或者总线电容偏大。2.4 地址冲突7 位地址空间没你想的那么宽I2C 的 7 位地址理论上能挂 128 个设备但实际可用的地址范围要排除保留地址真正能用的也就 112 个左右。而且很多传感器的地址是固定的或者只有一两个可选值。如果你在一条总线上挂了两个地址相同的设备那就直接冲突了。常见的解决办法硬件层面很多器件提供地址选择引脚ADDR可以通过拉高或拉低来改变地址。比如常见的 OLED 驱动 SSD1306ADDR 引脚接 GND 是 0x3C接 VCC 是 0x3D。软件层面用 I2C 多路复用器如 TCA9548A把一条总线扩展成多条每条挂不同地址的设备。分时复用如果两个设备不会同时使用可以通过 GPIO 控制它们的电源或使能引脚分时切换。在 OpenHarmony 的设备树里每个 I2C 从设备节点都要指定reg属性这个值就是设备地址。如果两个节点地址相同内核在注册i2c_client的时候就会报冲突。3. OpenHarmony 设备树与 HCS 配置I2C 适配的主战场3.1 设备树里 I2C 控制器的描述方式在 OpenHarmony 标准系统里SoC 的 I2C 控制器通常在 SoC 级设备树文件如rk3568.dtsi里定义好板级设备树如rk3568-evb.dts只需要引用并覆盖部分属性。一个典型的 I2C 控制器节点长这样i2c1: i2cfe5a0000 { compatible rockchip,rk3568-i2c; reg 0x0 0xfe5a0000 0x0 0x1000; interrupts GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH; clocks cru CLK_I2C1, cru PCLK_I2C1; clock-names i2c, pclk; pinctrl-names default; pinctrl-0 i2c1_xfer; #address-cells 1; #size-cells 0; status disabled; };板级设备树里把它打开并挂上从设备i2c1 { status okay; clock-frequency 400000; gt911: touchscreen5d { compatible goodix,gt911; reg 0x5d; interrupt-parent gpio0; interrupts RK_PB5 IRQ_TYPE_EDGE_FALLING; reset-gpios gpio0 RK_PB6 GPIO_ACTIVE_LOW; irq-gpios gpio0 RK_PB5 GPIO_ACTIVE_HIGH; }; };这里有几个关键点status okay必须写否则控制器不会初始化。clock-frequency指定总线速率不写的话默认 100kHz。pinctrl-0指定引脚复用配置这个必须和实际硬件对应配错了引脚就没有波形。从设备节点的reg就是 I2C 地址compatible要和驱动里的of_match_table匹配。3.2 引脚复用最常见的没波形元凶我见过太多次I2C 读写失败最后查出来是引脚复用没配对。SoC 的引脚通常是多功能的同一个物理引脚可以当 GPIO、UART、I2C、SPI 用。设备树里的pinctrl-0就是告诉引脚控制器把这组引脚切到 I2C 功能。如果pinctrl配错了或者根本没配引脚就停留在默认功能通常是 GPIOI2C 控制器再怎么操作寄存器也不会有波形出来。排查方法很简单用万用表或示波器量一下 SCL 和 SDA 引脚如果一直是高电平或者一直是低电平没有通信时的翻转那基本就是引脚复用的问题。在 RK3568 上I2C1 的引脚复用配置通常在rk3568-pinctrl.dtsi里定义i2c1_xfer: i2c1-xfer { rockchip,pins 0 RK_PB3 1 pcfg_pull_none_smt, 0 RK_PB4 1 pcfg_pull_none_smt; };这里的1就是功能编号表示切到 I2C1 功能。不同 SoC 的功能编号不一样一定要查手册确认。3.3 HCS 配置HDF 框架怎么找到你的 I2C 设备设备树配好之后内核能识别 I2C 控制器和从设备了但 OpenHarmony 的 HDF 框架还需要一份 HCS 配置来管理这些设备。HCS 文件通常放在vendor/厂商名/产品名/hdf_config/目录下I2C 相关的配置在device_info和input等 hcs 文件里。一个典型的 I2C 设备 HCS 配置device_i2c1 :: device { device0 :: deviceNode { policy 2; priority 100; preload 0; permission 0664; moduleName HDF_I2C; serviceName hdf_i2c_1; deviceMatchAttr i2c1_config; }; }然后在i2c_config.hcs里配置具体的总线参数root { i2c_config { i2c1_config { busNum 1; mode 0; speed 400000; }; }; }这里的busNum必须和设备树里的 I2C 控制器编号对应。如果设备树里是i2c1那busNum就应该是 1。对不上的话HDF 层就找不到对应的控制器应用调用直接失败。我踩过的一个坑设备树里 I2C 控制器编号是 1但 HCS 里写成了 0结果应用层一直报 i2c bus not found。查了半天设备树最后才发现是 HCS 配置写错了。所以两边一定要对齐。3.4 设备树调试的实用技巧设备树改完之后怎么确认配置生效了几个常用的方法查看/proc/device-tree/内核启动后会把设备树展开到这个目录你可以直接查看对应节点的属性值。比如cat /proc/device-tree/i2cfe5a0000/status看控制器是否使能。查看/sys/bus/i2c/devices/如果 I2C 从设备注册成功这个目录下会出现对应的设备节点如1-005d表示 bus 1 上地址 0x5d 的设备。用i2cdetect工具如果系统里带了i2c-tools可以直接i2cdetect -y 1扫描 bus 1 上的所有设备地址。能扫到就说明硬件和控制器基本没问题。# 扫描 I2C bus 1 上的设备 i2cdetect -y 1 # 读取地址 0x5d 设备的寄存器 0x00 i2cget -y 1 0x5d 0x00 # 向地址 0x5d 设备的寄存器 0x00 写入 0x01 i2cset -y 1 0x5d 0x00 0x01这几个命令在排障时非常有用能快速定位问题是在硬件层还是软件层。4. 排障实战从读写失败到定位根因的完整链路4.1 第一步确认硬件和波形是否正常I2C 排障的第一原则先看波形再查代码。没有波形代码写得再对也没用。用逻辑分析仪或示波器接上 SCL 和 SDA触发条件设为 SCL 下降沿或者 SDA 边沿。然后发起一次 I2C 读写观察波形完全没有波形控制器没工作或者引脚复用没配对。先查设备树status和pinctrl。有波形但地址字节后没有 ACK从设备没响应。查从设备供电、地址是否正确、上拉电阻是否合适。有 ACK 但数据不对时序问题可能是速率太快、时钟拉伸没处理、或者数据线干扰。波形畸变严重上拉电阻偏大或总线电容偏大降低速率或减小上拉电阻试试。我习惯用逻辑分析仪配合协议解码功能直接看解码出来的地址和数据比人眼看波形快得多。Saleae 的逻辑分析仪自带 I2C 解码国产的 DSLogic 也不错。4.2 第二步用 i2c-tools 快速验证总线如果系统里能跑i2c-tools那排障效率会高很多。i2cdetect能扫描总线上所有响应的地址这一步能快速区分是总线问题还是设备问题。# 列出系统里所有的 I2C 总线 i2cdetect -l # 扫描 bus 1 i2cdetect -y 1如果i2cdetect -l里根本看不到你的总线说明 I2C 控制器驱动没加载或者设备树没使能。如果能看到总线但i2cdetect -y 1扫不到任何设备说明硬件连接或从设备供电有问题。注意i2cdetect的快速扫描模式会发送一些特殊的读写请求有些设备可能不支持导致误判。如果快速扫描扫不到可以试试i2cdetect -y -r 1用读模式扫描。4.3 第三步内核日志里找线索dmesg是排障的好帮手。I2C 相关的错误通常会在内核日志里留下痕迹dmesg | grep -i i2c dmesg | grep -i i2c1常见的错误信息和对应对策日志信息可能原因排查方向i2c i2c-1: bus not busy控制器初始化失败查时钟、引脚复用i2c i2c-1: timeout waiting for bus ready总线被拉低无法释放查从设备是否死锁、上拉是否正常i2c i2c-1: sendbytes: NAK bailout从设备没给 ACK查地址、供电、连接i2c i2c-1: controller not enabled设备树 status 没设为 okay查设备树i2c i2c-1: address 0x5d already in use地址冲突查是否有重复节点这些日志信息能帮你快速缩小排查范围。我一般会先dmesg | grep i2c看一遍心里有个底再动手。4.4 第四步HDF 层的日志和调试如果内核层看起来没问题但应用层还是调不通那就要看 HDF 层的日志了。OpenHarmony 的 HDF 框架有独立的日志系统可以通过hilog查看hilog | grep -i i2c hilog | grep -i hdfHDF 层的常见错误HdfI2cTransfer: invalid bus numberHCS 里配置的 busNum 和设备树对不上。HdfI2cTransfer: open device failedHDF 设备节点没找到查 HCS 配置。HdfI2cTransfer: transfer timeout底层传输超时回到内核层排查。HDF 的 I2C 接口调用示例内核态#include i2c_if.h DevHandle handle I2cOpen(1); // 打开 bus 1 if (handle NULL) { HDF_LOGE(I2cOpen failed); return -1; } struct I2cMsg msgs[2]; uint8_t regAddr 0x00; uint8_t dataBuf[2] {0}; msgs[0].addr 0x5d; msgs[0].buf regAddr; msgs[0].len 1; msgs[0].flags 0; msgs[1].addr 0x5d; msgs[1].buf dataBuf; msgs[1].len 2; msgs[1].flags I2C_FLAG_READ; int32_t ret I2cTransfer(handle, msgs, 2); if (ret ! 2) { HDF_LOGE(I2cTransfer failed, ret %d, ret); } I2cClose(handle);这段代码是典型的写寄存器地址再读数据的操作。注意I2cTransfer的返回值是成功传输的消息数量如果返回的不是 2说明中间有消息失败了。4.5 第五步逻辑分析仪抓波形的高级技巧逻辑分析仪不只是看有没有波形还能帮你分析很多细节问题测量时钟频率实际速率和配置的是否一致。如果配置 400kHz 但实测只有 100kHz可能是时钟分频计算有问题。看起始条件的保持时间起始条件后 SCL 拉低之前SDA 需要保持低电平一段时间Hold Time太短的话从设备可能识别不到。看数据建立和保持时间SDA 的数据必须在 SCL 高电平期间保持稳定变化只能发生在 SCL 低电平期间。如果时序违规从设备可能读到错误数据。看时钟拉伸如果 SCL 被从设备拉低了一段时间说明从设备在处理数据主机需要等待。我遇到过一个案例I2C 读写偶尔失败抓波形发现是数据建立时间不够。SCL 拉高之后 SDA 还在变化从设备采样到了错误的数据。后来在驱动里增加了 SDA 建立时间的配置问题就解决了。5. 典型器件适配案例与常见问题拆解5.1 GT911 触摸屏 I2C 通信失败GT911 是很多开发板上用的触摸屏控制器I2C 地址通常是 0x5D 或 0x14。这个器件的坑比较多我单独拿出来讲。问题一地址不确定。GT911 的 I2C 地址由复位时的 INT 引脚电平决定。复位期间 INT 拉低地址是 0x5DINT 拉高地址是 0x14。如果设备树里地址写错了怎么都通信不上。解决办法是在设备树里正确配置reset-gpios和irq-gpios确保复位时序正确。问题二复位时序不对。GT911 对上电和复位时序有要求RESET 拉低至少 10ms然后拉高INT 引脚在复位释放后的状态决定地址。如果时序不对芯片可能不响应。问题三中断引脚配置错误。GT911 通过中断通知主机有触摸事件如果中断引脚配错触摸功能就不正常。设备树里interrupts和irq-gpios都要配对。gt911: touchscreen5d { compatible goodix,gt911; reg 0x5d; interrupt-parent gpio0; interrupts RK_PB5 IRQ_TYPE_EDGE_FALLING; reset-gpios gpio0 RK_PB6 GPIO_ACTIVE_LOW; irq-gpios gpio0 RK_PB5 GPIO_ACTIVE_HIGH; status okay; };5.2 EEPROM 读写时钟拉伸和页写延迟EEPROM 是 I2C 总线上最经典的器件但读写也有不少讲究。以 AT24C02 为例页写限制AT24C02 一页 8 字节跨页写会回卷覆盖。写数据时要注意不要跨页。写周期延迟每次写操作后EEPROM 需要约 5ms 的内部擦写时间。这期间它不响应任何请求主机如果立刻发下一个请求会收到 NACK。解决办法是写完之后延时 5ms或者用应答轮询ACK Polling——反复发起始条件地址直到收到 ACK 为止。时钟拉伸有些 EEPROM 在写周期内会拉低 SCL 做时钟拉伸主机需要支持这个机制。在 OpenHarmony 下读写 EEPROM 的代码示例DevHandle handle I2cOpen(1); uint8_t writeBuf[3] {0x00, 0xAA, 0xBB}; // 寄存器地址 2字节数据 struct I2cMsg msg; msg.addr 0x50; msg.buf writeBuf; msg.len 3; msg.flags 0; I2cTransfer(handle, msg, 1); OsalMSleep(10); // 等待写周期完成 uint8_t regAddr 0x00; uint8_t readBuf[2] {0}; struct I2cMsg msgs[2]; msgs[0].addr 0x50; msgs[0].buf regAddr; msgs[0].len 1; msgs[0].flags 0; msgs[1].addr 0x50; msgs[1].buf readBuf; msgs[1].len 2; msgs[1].flags I2C_FLAG_READ; I2cTransfer(handle, msgs, 2); I2cClose(handle);5.3 多路复用器 TCA9548A 的配置当总线上设备地址冲突或者需要挂超过总线负载能力的设备时TCA9548A 这类 I2C 多路复用器就派上用场了。它本身也是一个 I2C 从设备地址通常 0x70-0x77通过写寄存器来选择哪一路通道导通。在 OpenHarmony 设备树里TCA9548A 下面的设备需要作为子节点挂在复用器节点下i2c1 { tca9548: mux70 { compatible ti,tca9548; reg 0x70; #address-cells 1; #size-cells 0; channel0: i2c0 { reg 0; #address-cells 1; #size-cells 0; sensor48 { compatible ti,lm75; reg 0x48; }; }; }; };内核的 I2C 复用器框架会自动处理通道切换应用层不需要关心。但要注意复用器切换通道需要时间频繁切换可能影响性能。5.4 常见问题速查表现象可能原因排查方法完全无波形引脚复用未配置、控制器未使能查设备树 pinctrl 和 status有波形无 ACK从设备地址错、未供电、上拉异常用 i2cdetect 扫描、量电压偶尔读写失败时钟拉伸未处理、上拉电阻偏大抓波形看 SCL 是否被拉低读出的数据全 0 或全 FF从设备未响应、寄存器地址错查数据手册确认寄存器映射高速率下不稳定总线电容大、上拉不合适降低速率或减小上拉电阻HDF 层报 bus not foundHCS 配置的 busNum 不对对齐设备树和 HCS 的编号地址冲突报错总线上有重复地址设备用 i2cdetect 扫描确认6. 几个让我印象深刻的踩坑经历6.1 那个被 GPIO 复用了的 I2C 引脚有一次调一块新板子的 I2C设备树配了HCS 也配了i2cdetect就是扫不到任何设备。抓波形发现 SCL 和 SDA 一直是高电平完全没有翻转。查了半天控制器寄存器发现控制器是使能的但引脚没输出。最后翻原理图才发现这两个引脚在另一处设备树节点里被配成了 GPIO而且那个节点先加载把引脚复用抢走了。设备树里引脚复用是有优先级的后配置的会覆盖先配置的。解决办法是在那个 GPIO 节点里把这两个引脚去掉或者调整加载顺序。这个坑教会我一件事设备树里的引脚复用冲突不会报错只会静默地让功能失效。所以改设备树的时候一定要全局搜索一下用到的引脚确认没有其他地方也在配置。6.2 上拉电阻引发的灵异事件还有一次I2C 在实验室里跑得好好的到了现场就频繁失败。拿逻辑分析仪一抓发现波形上升沿特别慢SCL 高电平还没到阈值就被拉低了。现场和实验室的区别是现场的总线走线长了将近 30cm而且旁边有大功率电机干扰。解决办法是把上拉电阻从 10kΩ 换成 2.2kΩ同时在走线上加了屏蔽。换完之后波形明显改善通信稳定了。这件事让我意识到I2C 虽然是低速总线但对硬件环境还是很敏感的实验室能跑不代表现场能跑。6.3 HCS 配置里的一个字母之差前面提过 HCS 里 busNum 写错的问题这里再展开说一下。OpenHarmony 的 HCS 配置是编译进系统的改完之后需要重新编译 HDF 配置并烧录。如果只是改了 HCS 但没重新编译系统里跑的还是旧配置。而且 HCS 的语法比较严格少个分号、多个逗号都会导致解析失败。解析失败的时候HDF 框架可能不会报明显的错误只是设备节点加载不出来。所以改完 HCS 之后一定要确认编译通过并且烧录了新的配置。我现在的习惯是改完 HCS 后先hilog | grep hdf看有没有解析错误再用I2cOpen测试一下能不能打开设备。两步都过了才继续往下调。7. 写给正在调 I2C 的你I2C 排障这件事说到底就是分层确认、逐级缩小范围。硬件层看波形和电压内核层看日志和设备注册框架层看 HCS 配置和 HDF 日志应用层看接口调用和返回值。每一层都有对应的工具和方法关键是不要跳步不要凭感觉猜。我个人的经验是把i2c-tools、逻辑分析仪、dmesg、hilog这四个工具用熟八成以上的 I2C 问题都能定位到。剩下的两成要么是硬件设计问题要么是器件本身的特殊行为需要查手册和反复实验。最后分享一个小技巧调 I2C 的时候先拿一个最简单的器件比如 EEPROM 或者温度传感器验证总线本身没问题再去调复杂的器件比如触摸屏、PMIC。这样能把总线问题和器件问题分开排查效率会高很多。
返回列表