news 2026/10/18 6:32:52

RK3562+RK817充电关机后无法开机:PMIC电源状态分支的排查与修复

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RK3562+RK817充电关机后无法开机:PMIC电源状态分支的排查与修复

前阵子调一块 RK3562 + RK817 的带电池主板,遇到一个特别折磨人的现象:插着充电器的时候系统能正常关机,但关机后马上按电源键,整机就像彻底断电一样,串口一个字符都没有,U-Boot 完全没有跑起来。拔掉充电器再按,一切又恢复正常。一开始我以为是哪颗料虚焊了,拿示波器翻来覆去量了半天,最后发现根本不是硬件问题,而是关机时 PMIC 的电源状态分支搞错了。

这块板子的电源方案是 RK3562 主控配 RK817 PMIC,电池供电,支持边充边用。问题稳定复现,影响面却不小:只要用户插着充电器关机,下次按键就无法开机,只能靠拔充电器或者按复位键救回来。对量产设备来说这就是妥妥的售后问题。这篇文章把整个排查过程和修复方案完整写出来,适合正在做 RK3562、RK817 相关 BSP、底层驱动或者整机电源设计的工程师参考。如果你还没遇到这个 bug,也建议收藏一下,这类“充电时关机后无法启动”的问题在带电池 Linux 设备上非常典型,早晚会碰上。

1. 问题现象与故障复现分析

1.1 复现条件:只有“充电时关机”会触发

先说现场。设备跑的是标准 Linux 系统,内核里已经注册了电源管理相关驱动,串口可以在 U-Boot 和内核阶段正常输出。触发路径非常简单:

  1. 设备电量保持在 50% 以上,插入原装充电器,系统正常进入桌面或命令行。
  2. 正常执行关机,例如poweroff或者通过上层设置里的“关机”入口。
  3. 等待屏幕完全熄灭,电源指示灯常亮,说明 PMIC 还在工作。
  4. 按一下电源键,或者长按电源键,屏幕不亮,串口没有任何输出,U-Boot 没有任何启动打印。
  5. 拔掉充电器,再按电源键,设备正常开机,U-Boot 打印、内核启动全都正常。

这个现象我连续复现了好几次,不是偶发。最初怀疑过 U-Boot 镜像损坏、eMMC 启动分区异常、按键 GPIO 配置错误,但“拔掉充电器就能开机”这一条基本把这些问题全排除了——如果 U-Boot 被写坏或者 eMMC 引导有问题,不可能拔掉充电器就恢复。

另一个值得注意的细节是:充电状态下关机后,如果按的不是电源键,而是复位键(板上预留的 reset 测试点),设备也能正常开机。这说明 SoC、DDR、eMMC 以及 U-Boot 本身都是好的,问题是出在“按键开机”这条电源唤醒路径上。

1.2 RK3562 与 RK817 的电源链路回顾

要理解这个问题,得先把 RK3562 和 RK817 的电源关系捋清楚。RK817 是一颗集成了充放电管理、多路 DCDC/LDO 输出的 PMIC,在很多带电池的嵌入式设备上都能看到它的身影。它承担了两件关键事情:

  • 充电管理:适配器的 VBUS 输入到 RK817 内部的充电器路径,给电池充电,同时电池也会通过 RK817 输出给系统供电。
  • 系统供电:RK817 输出多路电源轨,包括给 SoC 核心供电的 VCC_SYS、DDR 供电、IO 供电、RTC 供电等。电源按键(PWRON)也直接接在 RK817 上,由 PMIC 负责检测。

正常开机流程是:按下电源键 → RK817 检测到 PWRON 事件 → 打开各路 DCDC/LDO 输出 → 等待电源稳定后释放 SoC 的复位信号 → RK3562 开始执行 BootROM → 加载 U-Boot。也就是说,U-Boot 能不能跑,前提是 PMIC 先把电供上、把复位时序走完。

关机流程正好相反:内核执行pm_power_off→ 系统调用 PMIC 驱动里注册的关机回调 → 通过 I2C 写寄存器,让 RK817 关闭系统电源输出 → SoC 彻底掉电。

问题就出在这个“彻底掉电”和“充电器在线”之间。充电器插着的时候,RK817 检测到外部电源存在,充电通路是活跃的,PMIC 内部逻辑也保持在待机状态。如果关机回调只是简单地执行了一套“纯电池模式”的 PowerOff 命令,PMIC 可能进入了某个既没有完全断电、也没有监听电源键的中间状态。

1.3 用排除法缩小故障范围

现场排查时,我先把能想到的硬件原因全部过了一遍,避免带着错误假设去改软件。

第一组测试:更换充电器和数据线。原装适配器、普通 USB 口、电脑 USB 口都试了,现象一致。排除适配器协议握手异常导致的电源波动。

第二组测试:拆掉电池,只用充电器供电,关机后再开机。这个场景其实很难直接复现,因为很多板子电池拆掉后系统供电路径会变化,不能完全等价。但至少验证了一点:电池本身没有损坏。

第三组测试:不同电量下复现。电量 80%、50%、20% 都试过,只要插着充电器关机,按键都无法开机。电量 5% 的时候更特殊,充电器插入瞬间电压跌落明显,还伴随复位抖动,属于另一个问题,后面会提到。

最终确定一个结论:这个故障和硬件虚焊、U-Boot 镜像损坏无关,是软件在“充电状态下关机”这个分支里没有把 PMIC 配置到正确的状态。排查方向从硬件转向了内核 PMIC 驱动的关机路径。

2. 根因定位:关机时充电器在线带来的状态分支

2.1 为什么充电关机后整机会“假死”

普通关机时拔掉充电器,RK817 没有外部电源,系统一旦关闭所有输出,PMIC 本身也进入低功耗的关机状态。这时候按键,PMIC 从头开始走上电时序,干干净净。

但插着充电器时情况完全不同。RK817 检测到 VBUS 在线,即使 SoC 关机了,PMIC 仍然要保持充电管理功能在工作,内部不少电路是带电的。这种状态其实更接近“充电待机”,而不是真正的 PowerOff。如果关机代码没有把这种情况和纯电池模式区分开,就会出现一个尴尬的局面:

PMIC 有一定输出保持,SoC 却没有完全按照冷启动流程去执行;同时 PMIC 的 PWRON 唤醒功能没有被使能,或者被关机命令覆盖了。于是按键按下去,PMIC 能感应到引脚变化,但它既不会重新打开系统主电源,也不会去拉高 SoC 的复位信号,整机就卡在“半睡半醒”的状态里。

打个比方:普通关机等于把房间配电箱的总闸拉了,按键开机相当于重新合闸,一切从头开始;插充电器关机则像是只关掉了部分灯光,走廊门禁还通着电,但你设定的门禁系统恰好把“开门按钮”给禁用了,所以按按钮没人理你。

2.2 锁定关键嫌疑点:PWRON 唤醒源与 PMIC 工作模式

确定了问题方向后,我去内核源码里翻 RK817 的驱动实现。重点看两个地方:

一是pm_power_off回调。很多 SDK 版本的 RK817 驱动里,关机回调会直接写一个 PowerOff 相关的寄存器位,让 PMIC 进入完全关机模式。这个操作没有区分当前是否有外部充电器输入。

二是 PWRON 唤醒源配置。RK817 的寄存器里通常有控制 PowerKey 是否作为唤醒源的位。正常情况下系统运行时这个位是配好的,但在关机流程里,如果后来又写入了关机命令,或者把部分寄存器恢复成了默认值,这个唤醒源可能就被关掉了。

我当时做了一个很直接的验证:在关机之后,通过调试工具直接往 RK817 的寄存器里写入“使能 PWRON 唤醒 + 进入 Standby 模式”的配置,然后再按键,设备马上就能正常开机。这就基本锁定了问题。

值得多说一句的是,RK817 在不同 SDK 版本里寄存器名称和位定义差异很大,甚至同一颗芯片,Linux 内核里的驱动和 U-Boot 里的初始化代码对“关机模式”的理解都可能不一样。不要死记寄存器地址,关键是把 datasheet 里关于 PowerOff Mode、Standby Mode、PowerKey Wake-Up 的描述吃透,再对照当前 SDK 的实际代码去查。

2.3 用示波器和串口日志确定故障卡在哪一级

排查这类问题时,示波器比日志更可靠。我把探头分别挂到 PWRON、VCC_SYS、SoC 的 RESET 引脚上,复现故障时观察到的波形很典型:

  • 按下电源键,PWRON 引脚确实有正常的按键脉冲,说明按键信号已经送到 PMIC。
  • VCC_SYS 没有任何反应,一直没有爬起来。
  • SoC 的 RESET 引脚也维持在高电平没有任何变化,因为 PMIC 压根没打算触发复位释放时序。

这说明整个故障卡在 PMIC 这一层:电源键事件没有被转换成“打开系统电源 + 释放复位”的信号。SoC 根本没有上电,自然也谈不上执行 BootROM,U-Boot 更不可能打印任何东西。

串口方面也做了一个对照实验:拔掉充电器关机,再按键,串口会先出现一段 BootROM 的早期打印,然后是 U-Boot banner。而在故障状态下,串口从头到尾完全安静。这个对比让我更加确认,问题不在 U-Boot,而在 U-Boot 之前的电源时序。

3. 修复实现:让 PMIC 在充电关机时进入可唤醒 Standby

3.1 修复思路与方案选型:为什么不只改 DTS

明确了根因后,修复方向就很清晰了:关机时如果检测到充电器在线,不能让 PMIC 进入完全 PowerOff,而是应该让它进入“充电 Standby”模式,并且保证 PWRON 是有效的唤醒源;没有充电器时,才走正常的彻底断电流程。

有人可能会说,直接在设备树里把某个寄存器配死不就行了?不行。设备树配置的是初始状态,而“关机时要怎么处理”是一个动态行为,必须根据关机那一刻充电器是否在线来决定。设备树无法表达这种条件分支。

也有人会想,改 U-Boot 里的启动逻辑行不行?可以作为一种临时规避,比如在 U-Boot 阶段强制初始化 PMIC 并打开所有输出,但这样处理不优雅,而且也没有解决 PMIC 在关机状态下的错误配置问题。正确的做法是在内核 PMIC 驱动的关机回调里做判断。

3.2 内核驱动补丁:在 poweroff 回调中按充电状态分支处理

我修改的核心逻辑如下。这段代码没有直接复制某个具体 SDK 的寄存器操作,而是给出一个可参考的框架,实际移植时以你自己用的头文件和 datasheet 为准:

static struct rk817 *g_rk817; static void rk817_power_off(void) { unsigned int val = 0; struct rk817 *rk817 = g_rk817; if (!rk817) return; /* 读取充电器插入状态,具体寄存器位以实际SDK头文件为准 */ regmap_read(rk817->regmap, RK817_CHG_STS, &val); if (val & RK817_CHG_STS_PLUG_IN) { /* * 充电器在线: * 进入可被PowerKey唤醒的Standby模式,而不是完全PowerOff。 */ regmap_update_bits(rk817->regmap, RK817_SYS_CFG, RK817_SYS_CFG_POWER_OFF_EN, RK817_SYS_CFG_STANDBY_EN); /* 使能PWRON作为唤醒源 */ regmap_update_bits(rk817->regmap, RK817_SYS_CFG_WAKEUP, RK817_SYS_CFG_WAKEUP_MASK, RK817_SYS_CFG_WAKEUP_PWRON); } else { /* 无充电器:正常关机,关断所有输出 */ regmap_update_bits(rk817->regmap, RK817_SYS_CFG, RK817_SYS_CFG_POWER_OFF_EN, RK817_SYS_CFG_POWER_OFF_EN); } }

几个实现细节值得展开:

第一,g_rk817这个全局指针要在驱动 probe 成功时保存,然后在关机回调里使用。不要在关机回调里重新去i2c_get_clientdata或者到处找全局引用,否则在系统关机阶段搞不好会拿到一个已经被释放的资源。

第二,充电器在线状态尽量复用充电子驱动已有的接口,比如通过power_supply_get_property查询在线状态,而不是在关机回调里再直接读寄存器。这样既不会和充电驱动内部的缓存状态冲突,也方便维护。如果你们内核版本比较老,充电驱动没有导出方便的查询接口,那直接读一次寄存器也可以,但要注意寄存器地址要和驱动里其它地方保持一致。

第三,驱动里原本可能已经有一个pm_power_off赋值点,比如在 probe 函数尾部:

static int rk817_i2c_probe(struct i2c_client *client) { ... g_rk817 = rk817; pm_power_off = rk817_power_off; ... }

要确认没有其它驱动在后面覆盖这个指针。我曾经遇到过一个问题:主板上的另一颗 RTC 芯片驱动也注册了pm_power_off,把 PMIC 的覆盖掉了,导致我改的关机回调根本没被调用。排查方法是在关机回调里加一条早期打印,如果关机时串口看不到这条打印,就说明回调没生效。

3.3 U-Boot 与设备树的配套调整

修改完内核,我还顺手检查了设备树和 U-Boot 侧,确保整条链路是通的。

设备树方面,RK817 节点通常需要声明为系统的 power controller,这样内核才会在关机时调用它的回调。具体属性名称各 SDK 有差异,常见的是system-power-controller或者rockchip,system-power-controller。如果没有这个属性,内核心想调用 PMIC 关机回调也没法把这个设备和电源管理框架关联起来。

U-Boot 方面,重点确认了两点:

一是 U-Boot 早期 I2C 访问 RK817 是否正常。U-Boot 启动时通常会在power_init_board或者类似函数里初始化 PMIC 寄存器。如果 I2C 通信失败,启动会直接卡在前面,表现为串口有早期打印但无法继续。我在这块板子上没遇到这个问题,但对于量产板维修场景来说,这是一个很容易踩的坑。

二是我在 U-Boot 的 PMIC 初始化代码里临时加了一条打印,把 RK817 的充电状态寄存器打出来,方便判断上电时 PMIC 到底处于什么状态。这样每次按键开机,可以从串口直接看到当时的场景:

/* U-Boot 调试代码,打印充电状态寄存器 */ printf("RK817 CHG_STS = 0x%02x\n", read_reg(RK817_CHG_STS));

有了这条打印,缩 root cause 的速度会快很多。正式版本里可以去掉。

另外,如果你们的产品有“关机充电显示”功能,也就是关机后插充电器会亮一个充电图标,需要格外小心。这个功能通常也依赖 RK817 在关机状态下的充电通路和唤醒逻辑,如果和 PowerKey 唤醒源配置冲突,就会出现“插充电器显示充电,但一按电源键就死机”的现象。我这次没有开启这个功能,所以没有和它叠加测试,如果你们项目里有,建议把两者放在一起验证。

3.4 编译、烧录与完整验证矩阵

修改完成后重新编译内核和 dtb,烧录到设备,然后按照下面的验证矩阵逐项测试:

场景操作预期结果
充电关机插充电器状态下正常关机,2秒后按电源键能进入 U-Boot,正常启动系统
非充电关机拔掉充电器,正常关机,按电源键能正常启动,与修改前一致
充电关机后拔充电器插充电器关机,拔掉充电器,按电源键能正常启动
关机后插充电器无充电器关机,插上充电器,按电源键能正常启动
电量100%满电充电状态,关机后按键能正常启动
电量20%低电量充电状态,关机后按键能正常启动
短按/长按短按一下、长按2秒,各自测试都能进入 U-Boot
连续开关机重复20次充电关机再开机全部成功
插拔充电器关机状态下反复插拔充电器,再按键按键能正常唤醒,不会自动开机

这个矩阵里每一行我都实际跑过。最花时间的是最后一项“连续开关机”,因为每次都要等系统完全关掉再按键开机、等 U-Boot 起来、等内核起来再关机,一轮循环就要半分钟,20次就是十分钟上下,中间还得盯着串口看有没有一次异常。这也是我长期养成的习惯:改动电源相关代码,验证次数一定要够多,不能看一两次正常就收工。

4. 排坑实录与长期维护经验

4.1 调试过程中遇到的其他坑

第一个坑:误伤电池模式关机。第一次改代码时,我在分支判断里把“充电器不在线”的 else 分支写成了同样进入 Standby 模式,结果电池供电状态下关机后系统并没有彻底断电,功耗明显异常,一晚上掉电很多。后来重新检查逻辑,把 else 分支改回完全 PowerOff,问题消失。

第二个坑:充电器在线状态读错了寄存器。RK817 的充电状态寄存器里有好几个位,分别是 VBUS 存在、USB 枚举状态、ACIN 状态等。一开始我读的是 USB 枚举完成标志位,结果用普通充电器(不走 USB 协议枚举)测试时,这个位一直是 0,导致关机回调走了 else 分支,故障依旧。后来改为读取 VBUS 在线状态位,才算真正命中条件。

第三个坑:按键唤醒后设备偶发复位。修改后大部分场景正常了,但偶尔按键开机后跑一会儿又重启。用示波器抓了一遍,发现是 DDR 电源轨的爬升时序跟不上 SoC 复位释放的节奏,VCC_SYS 已经稳定了,DDR 供电还在慢慢爬,SoC 初始化 DDR 的时候电压不够,直接挂掉。这个问题的修复方式和 PMIC 关机回调无关,是在设备树里调整对应 DCDC regulator 的上升沿时间参数,让电源轨按顺序配合好。这也提醒我:充电关机后再开机,属于一种特殊的冷启动路径,它和正常按按键开机的时序不完全一样,不能只看 PMIC 是否输出,还要看各条电源轨之间的相对时序。

4.2 问题速查表与一次定位模板

把这次的经验整理成一个速查表,遇到类似“无法进入 U-Boot”的问题时可以直接对照:

现象可能原因排查手段
插充电器关机后按键完全无反应关机回调让 PMIC 进入了无法监听 PowerKey 的状态检查 PMIC 驱动 poweroff 分支和唤醒源配置
串口完全无打印,但按键能看到 PWRON 波形SoC 没有上电或没有脱离复位示波器抓 VCC_SYS、RESET,确认电源时序
U-Boot 早期有打印,随后卡住I2C 访问 PMIC 失败或 DDR 初始化异常检查 U-Boot 里 PMIC 初始化、DDR 电源爬升
按键后反复重启各路电源轨建立顺序不对调整 regulator ramp delay,观察波形
不插充电器关机后也无法开机PMIC 关机配置被其它驱动覆盖或寄存器被误写确认pm_power_off最终生效者,对比出厂配置
电量很低时失败概率高充电建立导致欠压复位或预充条件不满足抓 VBUS/VBAT 波形,检查预充/涓流参数

这套排查思路可以抽象成一个通用定位模板,不再局限于某颗芯片:

  1. 先看串口有没有任何输出,有输出说明 SoC 已经跑起来了,问题在执行层面;没有输出则基本是电源或复位问题。
  2. 示波器同时抓 PWRON、系统主电源、RESET,还原一整个按键上电过程。
  3. 查看 PMIC 在关机后处于哪种模式:完全 PowerOff、Standby、还是充电待机。
  4. 确认 PowerKey 唤醒源有没有被使能,有没有被后续写入的寄存器覆盖。
  5. 确认所有关键电源轨是否按顺序建立,特别是 DDR 和 IO 电源。

4.3 平台迁移时如何复用这套排查思路

这次的平台是 RK3562 + RK817,但这类问题的本质其实是通用的:带电池设备在关机状态下仍然有充电通路在跑,只要 PMIC 的关机处理逻辑没有把“充电器在线”当成一种特殊状态,就可能出现按键无法唤醒的隐患。换到别的 SoC 搭配别的 PMIC,排查方法完全一样。

我后来在另一个项目上换过一套平台,PMIC 完全不同。当时也出现了类似的“关机充电后无法开机”,直接用同一个模板去定位:先抓按键波形,再查 PMIC 的关机状态寄存器,然后看唤醒源配置,半小时就定位到了问题。

另外有一个建议:在做量产固件之前,一定把“关机 + 充电器在线 + 按键开机”这种情况写进测试用例。很多产品的出厂测试只关注正常开机、休眠唤醒、关机充电,偏偏漏了“充电时关机再开机”这种组合。用户在实际使用中很容易触发,一旦触发就是完全死机级别的问题,体验非常糟糕。把这个场景纳入常规回归,是很值得的投入。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/18 6:32:39

手机SSH运维实战:uniTerm v1.10打造移动端AI终端新体验

手机能 SSH 运维这件事,我之前一直觉得是“应急凑合”,但 uniTerm v1.10 出来后,我的看法变了。这款开源 AI 终端原本在桌面端就挺好用的,这次安卓版发布,补齐了移动端缺口。手机上跑 SSH 不再只是拿个 Termux 敲两行命…

作者头像 李华
网站建设 2026/10/18 6:32:03

跨学科开题报告写作指南:AI工具如何助力研究方案生成

1. 跨学科开题报告的痛点:想法再多也碰壁1.1 为什么跨学科选题总被导师说“立不住”跨学科研究这几年热度确实高,从“智能医疗”“教育大数据”到“智慧城市治理”,凡是沾了不同学科交叉边的选题,天然就显得前沿、有想象力。但热度…

作者头像 李华
网站建设 2026/10/18 6:30:39

老系统重构实战:从数据库连接池打爆到模块化单体选型复盘

这期节目聊完,我在整理笔记的时候发现,Dirk和Linus两个人聊得最投入、最没有嘉宾包袱的一次,反而是这期讲"旧系统改造"的。原因很简单:他们俩都亲手拆过自己的烂摊子,也都被人用"别动,动了出…

作者头像 李华
网站建设 2026/10/18 6:29:35

自然语言编程实战:从需求描述到可落地代码的完整流程

前几年要在编辑器里让程序做个事,你得先把数据结构和调用关系在脑子里过一遍,再敲上几十行代码。现在圈子里讨论的方向已经变了,很多人开始直接用自然语言去描述"我想要什么效果",让工具去生成、修改甚至调试代码。这种…

作者头像 李华
网站建设 2026/10/18 6:26:15

CEF 3.2357 Windows32 实战指南:C++嵌入网页与NPAPI插件集成

简介:本资源为CEF(Chromium Embedded Framework)3.2357.1271.g8e0674e Windows 32位官方二进制发布包的完整存档,专为C桌面应用开发者、浏览器嵌入式方案研究者及需要NPAPI插件支持的遗留系统维护人员提供。该版本是CEF官方明确终…

作者头像 李华
网站建设 2026/10/18 6:26:09

Ubuntu 18.04上vcpkg安装失败?升级GCC与CMake工具链指南

说个可能让你很意外的情况:在同一台 Ubuntu 18.04 机器上,编译普通的 C 项目一切顺利,可一旦想用 vcpkg 安装第三方库,比如 fmt、spdlog,或者某些对编译器版本要求偏高的库,十有八九都会卡在配置阶段&#…

作者头像 李华