0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

RK806中断处理流程深度解析:从架构到调试实战

jf_44130326 来源:Linux1024 2026-02-05 13:46 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

RK806作为瑞芯微主流PMIC电源管理芯片),其中断机制是实现电源键响应、电压异常保护、休眠唤醒、watchdog超时处理等核心功能的基础。Linux驱动基于regmap_irq框架设计,屏蔽了底层寄存器操作细节,但调试时若不理解中断流程,往往会陷入现象找不到根源的困境。

本文将从架构基础全流程拆解典型调试实例三层展开,既讲清中断如何工作,又教你遇到问题怎么修,结合核心代码与实操命令,让底层逻辑落地可查、可复现。

wKgZO2kajEeANMZ2AAFZhyckgp0783.png

一、先懂基础:RK806中断的硬件与驱动架构

在分析流程前,需先明确硬件载体驱动框架”——这是定位问题的前提。

1.1硬件中断核心资源(寄存器)

RK806的中断通过2组状态寄存器2组掩码寄存器管理,所有中断事件均映射到这些寄存器的特定bit位,代码中虽未直接定义地址,但通过regmap_irq框架关联:

寄存器类型

框架配置参数

核心作用

关键bit示例(对应中断)

状态寄存器(读)

status_base

存储中断事件状态(读操作自动清0,即ACK

INT_STS00x08bit0PWRON按下;bit4:低电压(VB_LO

状态寄存器(读)

status_base+1

扩展中断状态存储

INT_STS10x0Abit7watchdog超时;bit3SLP1_GPIO唤醒

掩码寄存器(写)

mask_base

启用/禁用中断(1 =禁用,0 =启用)

INT_MSK00x09bit0:禁用PWRON按下中断

掩码寄存器(写)

mask_base+1

扩展中断掩码控制

INT_MSK10x0Bbit7:禁用watchdog中断

注:上述地址为代码隐含逻辑(通过rk806_irq_chipstatus_base=RK806_INT_STS0推导),实际调试需以芯片手册为准。

1.2驱动框架:regmap_irq的核心设计

RK806未直接操作中断寄存器,而是通过Linux内核regmap_irq框架实现寄存器bit→Linux虚拟IRQ”的映射,核心结构如下:

核心结构体/数组

作用

代码示例(rk806-core.c

rk806_irqs数组

定义中断类型寄存器组→bit映射

REGMAP_IRQ_REG(RK806_IRQ_PWRON_FALL, 0, RK806_INT_STS_PWRON_FALL)PWRON按下对应INT_STS0bit0

rk806_irq_chip结构体

描述中断芯片属性

指定名称("rk806")、状态寄存器基地址、掩码寄存器基地址、中断数量(16个)

struct irq_data *

框架句柄,用于后续获取虚拟IRQ、控中断

devm_regmap_add_irq_chip生成,关联regmap与硬件IRQ

设计优势:无需手动读写寄存器,框架自动完成中断检测过滤分发→ACK”,驱动只需关注中断触发后的业务逻辑

二、中断处理全流程:从初始化到清理

RK806的中断处理分为初始化(probe阶段)触发(硬件事件)分发(框架调度)执行(业务逻辑)清理(ACK5个阶段,每个阶段均有明确的代码映射。

中断处理全流程可视化

wKgZO2kajEeAZemnAAHfS6XbN2w774.png

阶段1:中断初始化(probe阶段,核心在rk806_device_init

初始化是中断可用的前提,需完成极性配置框架注册唤醒使能三步:

1.中断极性配置:调用rk806_irq_init,设置中断引脚为低电平有效(避免高电平噪声误触发);

staticvoidrk806_irq_init(struct rk806 *rk806){ // INT_POL字段(0x7b寄存器bit1)写0,配置为低电平有效 rk806_field_write(rk806,INT_POL,RK806_INT_POL_LOW);}

1.注册regmap_irq_chip:将regmapSPI通信层)、硬件IRQ(从设备树获取)与rk806_irq_chip绑定,生成irq_data句柄;

ret =devm_regmap_add_irq_chip(  rk806->dev,  rk806->regmap,    // SPI层初始化的regmap(负责寄存器读写)  rk806->irq,     // 硬件IRQ号(SPI设备的irq属性) IRQF_ONESHOT|IRQF_SHARED, // 中断标志:单次触发(防重入)+ 可共享 0,  &rk806_irq_chip,   // 中断芯片配置  &rk806->irq_data   // 输出:框架句柄,后续用于控中断);

1.启用唤醒中断:调用enable_irq_wake(rk806->irq),将主IRQ标记为唤醒源”——即使系统休眠时禁用主IRQ,该中断仍能唤醒系统;

2.注册特定中断服务函数:对需要自定义逻辑的中断(如VDC电压变化),通过devm_request_threaded_irq注册线程化服务函数(避免中断上下文阻塞);

// 示例:注册VDC上升沿中断(唤醒场景)vdc_irq_rise = regmap_irq_get_virq(rk806->irq_data, RK806_IRQ_VDC_RISE);ret = devm_request_threaded_irq(  rk806->dev,  vdc_irq_rise,  // 虚拟IRQ号(从irq_data获取)  NULL,      // 快速处理函数(无,直接走线程)  rk806_vdc_irq,  // 线程函数(核心逻辑:通知PM唤醒)  IRQF_TRIGGER_HIGH | IRQF_ONESHOT, // 触发方式:高电平+单次  "rk806_vdc_rise",// 中断名称(用于/proc/interrupts)  rk806      // 传递给线程函数的私有数据);enable_irq_wake(vdc_irq_rise); //标记VDC中断为唤醒源

阶段2:中断触发(硬件事件发生)

RK806检测到目标事件,硬件自动完成状态置位引脚电平变化,触发系统IRQ

示例1:用户按下PWRONINT_STS0RK806_INT_STS_PWRON_FALLbit0)置1→中断引脚拉低;

示例2:电池电压低于阈值INT_STS0RK806_INT_STS_VB_LObit4)置1→中断引脚拉低;

示例3:设备插电(VDC恢复)INT_STS0RK806_INT_STS_VDC_RISEbit6)置1→中断引脚拉低。

阶段3:中断分发(regmap_irq框架自动调度)

系统响应硬件IRQ后,框架无需用户干预,自动完成筛选映射触发虚拟IRQ”

1.读状态寄存器:框架读取status_baseINT_STS0)和status_base+1INT_STS1),获取所有未处理中断;

2.过滤已掩码中断:对比mask_baseINT_MSK0/MSK1),排除已禁用的中断(掩码bit=1的中断不处理);

3.映射虚拟IRQ:遍历rk806_irqs数组,将寄存器bit”转换为Linux虚拟IRQ号(如INT_STS0bit0→RK806_IRQ_PWRON_FALL);

4.触发服务函数:调用generic_handle_irq(virq),调度对应虚拟IRQ的服务函数(如PWRON中断rk805-pwrkey子设备的服务函数)。

阶段4:中断执行(业务逻辑处理)

不同中断的处理逻辑不同,驱动通过子设备接管自定义线程函数实现,以下是2个核心场景:

场景AVDC电压变化中断(唤醒系统)

VDC中断用于检测外部电压恢复(如插电),触发系统从休眠唤醒,线程函数rk806_vdc_irq逻辑简单:

staticirqreturn_trk806_vdc_irq(intirq,void*data){ structrk806*rk806 = data; // 通知PM子系统:保持唤醒状态2秒(避免系统未就绪就再次休眠) pm_wakeup_dev_event(rk806->dev,2000,false); returnIRQ_HANDLED; // 标记中断已处理}

场景BPWRON按键中断(电源控制)

PWRON中断(按下/松开)由rk805-pwrkey子设备接管(在rk806_cells中定义),处理逻辑与系统电源状态联动:

休眠时短按:触发pm_wakeup唤醒系统;

工作时长按:调用rk806_regulator_shutdown执行关机序列;

工作时短按:发送KEY_POWER事件给上层(如亮屏/锁屏)。

阶段5:中断清理(ACK,框架自动完成)

中断处理完成后,需清除INT_STSx寄存器的对应bit(避免框架反复触发),regmap_irq框架通过以下逻辑自动完成:

1.读取status_base寄存器(触发ACK的硬件机制);

2.硬件检测到读操作后,自动清0已处理的中断bit

3.框架无需用户手动写寄存器(rk806_irq_chip.ack_base = RK806_INT_STS0已配置)。

关键联动:中断与休眠唤醒的配合

RK806的中断需适配低功耗场景,核心逻辑在rk806_core_suspend/resume中,流程如下:

三、调试实战:4个典型中断问题的定位与解决

理解流程后,遇到中断相关问题可按现象关联流程实操验证三步定位,以下是工程师最常遇到的4个场景。

场景1:电源键按下无响应(PWRON中断失效)

现象

按下电源键,系统无任何反应(既不唤醒也不触发关机);

万用表PWRON引脚电平有变化(排除硬件按键故障)。

定位逻辑(关联流程)

问题出在中断初始化分发子设备接管环节,可能原因:

1.中断极性配置错误(高电平有效,与硬件引脚电平变化不匹配);

2.PWRON中断被掩码(INT_MSK0bit0=1,禁用中断);

3.rk805-pwrkey子设备未加载(无人处理PWRON中断);

4.中断计数未增长(硬件未触发中断)。

调试操作(分步验证)

1.检查中断极性:读0x7b寄存器(GPIO_INT_CONFIG)的INT_POL字段(bit1),确认低电平有效(0):

# 利用rk806的sysfs调试节点(core.c中创建)读寄存器echo"r 0x7b"> /sys/rk806single/debug# 预期输出:0x7b 0x02(bit1=0);若为0x03(bit1=1),执行以下命令修正:echo"w 0x7b 0x02"> /sys/rk806single/debug

1.检查PWRON中断掩码:读0x09寄存器(INT_MSK0)的bit0,确认启用(0):

echo"r 0x09"> /sys/rk806single/debug# 若bit0=1(禁用),执行命令启用:echo"w 0x09$((0xff ^ (1<<0)))"> /sys/rk806single/debug # 0xfe,bit0置0

1.查看中断计数:按下电源键后,查/proc/interruptsRK806_IRQ_PWRON_FALL的计数是否增长:

cat/proc/interrupts | grep -E"rk806|RK806_IRQ_PWRON_FALL"# 预期:按下键后计数+1;若计数不变→硬件中断未触发(查引脚连接);若增长→子设备未加载

1.验证子设备加载:检查rk805-pwrkey子设备是否存在:

ls/sys/bus/platform/devices/ | grep rk805-pwrkey# 若无→检查mfd_add_devices是否成功(core.c中devm_mfd_add_devices调用)

场景2:休眠后无法唤醒(唤醒中断失效)

现象

系统执行suspendecho mem > /sys/power/state)后休眠,但触发唤醒源(插电/按电源键)无反应;

唤醒源硬件正常(VDC电压变化、电源键电平正常)。

定位逻辑(关联流程)

唤醒依赖唤醒IRQ启用休眠时未禁用唤醒IRQ,可能原因:

1.唤醒IRQ未标记enable_irq_wake(休眠时被禁用);

2.休眠时误修改唤醒中断掩码(INT_MSK0bit6=1,禁用VDC中断);

3.唤醒中断服务函数未执行(未通知PM子系统)。

调试操作

1.检查唤醒源注册:查/sys/power/wakeup_sources,确认VDC/PWRON唤醒源已激活:

cat/sys/power/wakeup_sources | grep rk806# 预期输出:rk806_vdc_rise 0 0 0(已注册);若无→检查enable_irq_wake调用

1.验证休眠前后的中断掩码:休眠前/后读INT_MSK0bit6VDC中断),确认未被禁用:

# 休眠前读echo"r 0x09"> /sys/rk806single/debug # 记录bit6值(0=启用)# 执行休眠echomem > /sys/power/state# 唤醒后再次读echo"r 0x09"> /sys/rk806single/debug# 若bit6变为1→休眠时被误禁用,需检查rk806_core_suspend是否修改掩码

1.跟踪唤醒中断执行:在rk806_vdc_irq中加调试打印,确认唤醒时是否调用:

staticirqreturn_trk806_vdc_irq(intirq,void*data){ pr_info("[RK806] VDC wakeup irq triggered!n"); // 新增打印 pm_wakeup_dev_event(rk806->dev,2000,false); returnIRQ_HANDLED;}

重新编译驱动后,唤醒时查看dmesg

dmesg| grep"VDC wakeup irq triggered"# 有打印→执行正常;无打印→中断未分发(查regmap_irq映射)

场景3:低电压不触发关机(VB_LO中断失效)

现象

电池电压低于配置阈值(如3.0V < 预设3.4V),但系统未自动关机;

SYS_STS0x5D)寄存器,VB_LO_STSbit4=1(硬件已检测到低电压)。

定位逻辑(关联流程)

低电压关机依赖RK806_IRQ_VB_LO中断,问题可能:

1.VB_LO中断被掩码(INT_MSK0bit4=1);

2.VB_LO_ACT配置为仅通知中断VB_LO_ACT_INT=1),而非自动关机VB_LO_ACT_SD=0);

3.中断服务函数未调用rk806_vb_force_shutdown_init(未执行关机序列)。

调试操作

1.启用VB_LO中断:读INT_MSK00x09bit4,确认启用(0):

echo"r 0x09"> /sys/rk806single/debug# 若bit4=1→执行命令启用:echo"w 0x09$((0xff ^ (1<<4)))"> /sys/rk806single/debug # 0xef,bit4置0

1.配置VB_LO_ACT为关机:读SYS_CFG00x5Ebit3VB_LO_ACT),确认配置为0SD):

echo"r 0x5e"> /sys/rk806single/debug# 若bit3=1(INT)→改为SD:echo"w 0x5e$((0xff ^ (1<<3)))"> /sys/rk806single/debug # 0xf7,bit3置0

1.验证关机函数调用:在rk806_vb_force_shutdown_init加打印,确认低电压时触发:

staticvoidrk806_vb_force_shutdown_init(struct rk806 *rk806){ pr_info("[RK806] Low voltage detected, start force shutdown!n"); // 原有关机序列配置逻辑...}

低电压时查看dmesg,若有打印执行正常;若无中断未分发(查rk806_irqs数组是否包含RK806_IRQ_VB_LO)。

场景4:中断频繁触发(如VDC中断狂跳)

现象

dmesg中频繁打印“VDC irq handled”,每秒数百次;

无实际电压变化,/proc/interruptsRK806_IRQ_VDC_RISE计数持续增长。

定位逻辑(关联流程)

中断狂跳多因触发方式不匹配硬件信号噪声

1.中断配置为电平触发IRQF_TRIGGER_HIGH),而VDC引脚信号持续为高;

2.中断未正确ACKINT_STSxbit未清0,框架反复触发);

3.VDC检测引脚接触不良,存在高频噪声。

调试操作

1.修正中断触发方式:将电平触发改为边沿触发(仅电压变化时触发):

// 错误配置(电平触发)ret = devm_request_threaded_irq(..., IRQF_TRIGGER_HIGH | IRQF_ONESHOT, ...);//正确配置(上升沿触发,仅电压从低变高时触发)ret = devm_request_threaded_irq(..., IRQF_TRIGGER_RISING | IRQF_ONESHOT, ...);

1.验证中断ACK:读INT_STS00x08bit6,确认中断处理后清0

# 1. 读当前状态(记录bit6值)echo"r 0x08"> /sys/rk806single/debug# 2. 等待1秒后再次读sleep1 &&echo"r 0x08"> /sys/rk806single/debug# 若bit6持续为1→硬件未支持“读清”,需修改rk806_irq_chip.ack_type为REGMAP_IRQ_ACK_WRITE(手动写0清位)

1.排查硬件噪声:用示波器VDC检测引脚(如VDC_IN),若存在高频波动,需在硬件上添加RC滤波电路(1kΩ电阻+ 100nF电容),稳定信号后中断狂跳问题会消失。

四、总结:中断流程的调试价值

掌握RK806中断流程,本质是掌握从现象到根源的定位链路,核心价值体现在三点:

1.分层定位:中断问题无非初始化触发分发执行清理某环节失效,按流程排查可避免盲目试错;

2.工具结合:善用/proc/interrupts(计数)、sysfs debug(寄存器读写)、dmesg(打印),让底层状态可视化;

3.代码映射:快速关联问题与代码(如唤醒失败enable_irq_wake,按键无响应rk805-pwrkey子设备)。

对于嵌入式工程师而言,PMIC中断调试是底层能力的试金石——吃透本文流程与实例,不仅能解决RK806的问题,更能触类旁通理解其他PMIC(如RK817RK809)的中断逻辑,提升底层问题的攻坚效率。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    88

    文章

    11821

    浏览量

    219594
  • 中断处理
    +关注

    关注

    0

    文章

    96

    浏览量

    11506
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    开关电源pcb设计实例 分析RK806电源方案的PCB设计

    模块峰值电流表进行知悉,供PCB Layout时评估线宽作用,如下表值得注意的是,不能简单的全部加起来算成SOC的峰值电流,要评估散热方案,根据实际场景的工作平均电流进行,表格参数值仅供参考。 本篇内容以RK806电源方案的PCB设计
    的头像 发表于 08-02 08:41 3625次阅读
    开关电源pcb设计实例 分析<b class='flag-5'>RK806</b>电源方案的PCB设计

    RK3588 EVB开发板原理图讲解【三】

    RK3588 电源管理 ——RK806 介绍 一、RK806 典型应用图 二、RK806 特征 输入范围:2.7V - 5.5V。 待机电流:极低,仅为 10μA 。 通信协议支持
    发表于 02-14 16:13

    RK3588 EVB开发板原理图讲解【七】

    流程◦ Power Key 开机流程◦ 关机方式1. RK3588 实际板型开机电路描述2. 长按强制关机和复位的区别探讨RK3588 方案
    发表于 02-28 08:51

    RK3128 Android 7.1 进入深度休眠流程分析

    RK3128 Android 7.1 进入深度休眠流程分析RK3128是瑞芯微电子推出的一款低功耗四核Cortex-A7处理器,运行Andr
    发表于 07-22 10:45

    AUTOSAR架构深度解析 精选资料推荐

    AUTOSAR架构深度解析本文转载于:AUTOSAR架构深度解析目录AUTOSAR
    发表于 07-28 07:40

    AUTOSAR架构深度解析 精选资料分享

    AUTOSAR架构深度解析本文转载于:AUTOSAR架构深度解析AUTOSAR的分层式设计,用于
    发表于 07-28 07:02

    8253中断服务程序流程

    8253中断服务程序流程图 希望发电机P =
    发表于 05-03 00:12 5207次阅读
    8253<b class='flag-5'>中断</b>服务程序<b class='flag-5'>流程</b>图

    STM32中断系统的工作流程

    一、前言 在之前的STM32的中断系统理论基础知识之基本原理及NVIC,分别中断的基本原理,中断的管理机制和中断
    的头像 发表于 06-22 09:17 4401次阅读
    STM32<b class='flag-5'>中断</b>系统的工作<b class='flag-5'>流程</b>

    RK806电源方案的PCB设计注意事项

    的太远,摆放方向时,尽量优先考虑 RK806的BUCK1、BUCK2、BUCK3、BUCK4这些输出电流比较大的电源RK3588的信号流向是顺畅的。 图1 整体电源方案图 RK806
    的头像 发表于 09-23 07:40 2563次阅读
    <b class='flag-5'>RK806</b>电源方案的PCB设计注意事项

    stm32中断怎么处理

    STM32是一款非常强大的微控制器系列,具有丰富的外设和功能。中断是STM32非常重要的部分,能够帮助我们提高系统的响应速度和效率。本文将详细介绍STM32中断处理方法。 一、
    的头像 发表于 01-02 17:35 4110次阅读

    解决RK806+RK3588休眠异常!硬件特性软件优化的完整方案

    在嵌入式开发,电源管理的稳定性直接决定了设备的可靠性。近期,RK3588 平台搭配 RK806 电源管理芯片(PMIC)时,出现了二次休眠异常的问题 —— 第一次休眠唤醒正常,再次休眠后
    的头像 发表于 02-09 16:46 968次阅读
    解决<b class='flag-5'>RK806+RK</b>3588休眠异常!<b class='flag-5'>从</b>硬件特性<b class='flag-5'>到</b>软件优化的完整方案

    深度拆解RK806 PMIC电源处理流程SPI通信到DVS动态调压

    在嵌入式设备,PMIC(电源管理集成电路)是 “能源管家”—— 它不仅为 CPU、内存、外设提供稳定电压,还需处理休眠唤醒、异常保护、动态调压等核心逻辑。瑞芯微 RK806 作为一款高集成度
    的头像 发表于 02-05 13:47 2756次阅读
    <b class='flag-5'>深度</b>拆解<b class='flag-5'>RK806</b> PMIC电源<b class='flag-5'>处理</b><b class='flag-5'>流程</b>:<b class='flag-5'>从</b>SPI通信到DVS动态调压

    RK 平台 USB 摄像头成像调试指南:信号画质的全流程优化

    信号调试画质优化的实操方案,助力开发者快速解决成像难题。 一、先搞懂:成像差的核心诱因 USB 摄像头成像模糊、卡顿、连等问题,本质是 “信号传输” 与 “硬件适配” 双重问题: •信号层面:USB 眼图指标不达标、枚举失败
    的头像 发表于 11-26 07:05 1290次阅读
    <b class='flag-5'>RK</b> 平台 USB 摄像头成像<b class='flag-5'>调试</b>指南:<b class='flag-5'>从</b>信号<b class='flag-5'>到</b>画质的全<b class='flag-5'>流程</b>优化

    RK3506 MIPI转HDMI显示开发实战硬件驱动全解析

    0 入门 Linux 嵌入式开发!RK3506 开发板实战教程系列开篇 在嵌入式设备开发,MIPI DSI接口(移动行业处理器接口)广
    的头像 发表于 01-06 07:09 1153次阅读
    <b class='flag-5'>RK</b>3506 MIPI转HDMI显示开发<b class='flag-5'>实战</b>:<b class='flag-5'>从</b>硬件<b class='flag-5'>到</b>驱动全<b class='flag-5'>解析</b>

    深度剖析U-Boot ADC Uclass:架构实战的全维度解析

    在嵌入式开发,ADC(模数转换)是连接模拟世界与数字系统的关键桥梁,而 U-Boot 作为嵌入式领域的经典引导程序,其 ADC 子系统的设计堪称分层架构与通用化设计的典范。本文将从架构流程
    的头像 发表于 04-26 07:08 42次阅读
    <b class='flag-5'>深度</b>剖析U-Boot ADC Uclass:<b class='flag-5'>从</b><b class='flag-5'>架构</b><b class='flag-5'>到</b><b class='flag-5'>实战</b>的全维度<b class='flag-5'>解析</b>