4、中断丢失现象:屏幕无显示、画面撕裂、系统卡死、中断计数不增长

在龙芯HDMI调试过程中,中断丢失是最常见且最难定位的问题之一。当中断信号未能被CPU正确捕获或处理时,显示驱动将无法获得帧同步、DMA完成或热插拔等关键事件通知,进而引发一系列连锁故障。本章系统梳理中断丢失的四种典型表现,帮助调试人员快速建立现象与根因之间的映射关系。

核心判断依据: 中断丢失的最终确认手段是读取 /proc/interrupts 中对应HDMI中断号的计数值。若在预期触发事件(如帧切换、分辨率变更)发生后计数不增长,即可判定中断丢失。

4.1 四种典型现象与根因对照

现象 用户/系统表现 直接原因 常见根因层级
屏幕无显示 HDMI输出黑屏,显示器无信号 VSYNC/HSYNC中断丢失,帧缓冲未更新 中断控制器配置、时钟门控
画面撕裂 屏幕出现水平分割、上下帧错位 VBLANK中断丢失,双缓冲切换不同步 中断优先级、CPU负载
系统卡死 内核日志停止输出,鼠标键盘无响应 中断丢失导致DMA超时,驱动自旋锁死锁 中断共享、中断线电平
中断计数不增长 /proc/interrupts 数值冻结 中断信号未到达CPU或未注册 设备树、中断控制器掩码
调试提示: 四种现象往往不是孤立出现。例如,屏幕无显示 持续一段时间后可能演变为 系统卡死,因为驱动在等待中断时进入无限循环。建议在首次出现异常时立即检查中断计数,避免现象叠加后增加排查难度。

4.2 中断丢失的传播路径与故障链

中断丢失并非瞬间发生,而是沿着硬件→固件→内核→驱动的路径逐级传播。理解这条故障链,有助于在调试时快速定位断点。

中断丢失故障传播链 HDMI控制器 中断控制器(INTC) CPU核 中断处理函数 中断丢失可能发生在以上任意一个环节 屏幕无显示 画面撕裂 系统卡死 计数不增长 排查策略:从右向左逆向追溯 先确认中断计数 → 再检查中断处理函数注册 → 最后排查硬件信号

4.3 中断计数不增长的排查步骤

当怀疑中断丢失时,应按照以下步骤系统化排查,避免盲目修改代码。

  1. 确认中断号与设备树匹配
    # 查看设备树中HDMI节点的中断配置
    cat /proc/device-tree/soc/hdmi@.../interrupts
    # 输出示例:<0 37 4>  (中断控制器0,中断号37,触发类型4=高电平)
  2. 检查中断控制器掩码状态
    # 读取中断控制器寄存器,确认HDMI中断未被屏蔽
    devmem 0x1fe00000 32   # 以龙芯3A5000为例,INTC基地址
    # 检查对应bit位是否为0(0=使能,1=屏蔽)
  3. 验证中断处理函数注册
    # 查看/proc/interrupts中对应中断号的驱动名称
    cat /proc/interrupts | grep hdmi
    # 若显示为"none"或空,说明驱动未成功注册中断
  4. 使用gpio-int-poll测试中断信号
    # 若硬件支持GPIO中断,可临时将HDMI中断线映射到GPIO进行轮询测试
    echo 37 > /sys/class/gpio/export
    cat /sys/class/gpio/gpio37/value   # 观察电平变化
  5. 添加内核调试打印
    // 在中断处理函数入口添加打印,确认是否被调用
    static irqreturn_t hdmi_irq_handler(int irq, void *dev_id)
    {
        printk(KERN_DEBUG "[HDMI] IRQ %d triggered at jiffies %lu\n",
               irq, jiffies);
        // ... 原有处理逻辑
        return IRQ_HANDLED;
    }
常见陷阱: 龙芯平台的中断控制器可能存在 中断线共享 的情况。例如,HDMI与某个SATA控制器共用同一中断线。此时即使HDMI中断正常,也可能因其他设备的中断处理函数耗时过长导致HDMI中断被延迟或丢失。务必检查 /proc/interrupts 中同一中断号下是否挂载了多个设备。

4.4 中断丢失的硬件级排查

当软件层面确认中断注册和掩码均正常,但计数仍不增长时,问题可能出在硬件信号路径上。以下为硬件级排查清单:

排查点 检查方法 正常状态 异常处理
HDMI控制器中断输出引脚 示波器测量中断引脚电平 帧同步时产生脉冲 检查控制器时钟与复位
中断控制器输入引脚 示波器测量INTC输入 与HDMI输出波形一致 检查PCB走线、电平转换
中断控制器输出到CPU 读取INTC状态寄存器 中断挂起位有效 检查INTC配置寄存器
CPU中断输入 读取CPU Cause寄存器 对应IP位为1 检查CPU中断使能(IE)
硬件中断信号路径与测量点 HDMI控制器 P1 中断控制器 P2 CPU核 P3 中断处理 测量点说明 P1:HDMI控制器中断输出引脚 — 确认控制器是否产生中断脉冲 P2:中断控制器输入引脚 — 确认信号是否到达INTC P3:CPU中断输入引脚 / Cause寄存器 — 确认CPU是否收到中断 若P1有信号而P2无信号,问题在PCB走线或电平转换;若P2有而P3无,问题在INTC配置

4.5 中断丢失的软件级快速诊断脚本

以下脚本可一键收集中断相关关键信息,适用于现场快速诊断:

#!/bin/sh
# hdmi_irq_diag.sh - HDMI中断丢失快速诊断脚本
# 用法:在HDMI输出异常时执行

echo "=== HDMI中断诊断报告 ==="
echo "时间: $(date)"
echo ""

echo "--- 1. /proc/interrupts 中HDMI相关中断 ---"
grep -E "hdmi|drm|gpu|37" /proc/interrupts 2>/dev/null || echo "未找到HDMI中断条目"

echo ""
echo "--- 2. 中断控制器寄存器状态 ---"
# 龙芯3A5000 INTC基地址0x1fe00000,偏移0x00=中断状态,0x04=中断掩码
devmem 0x1fe00000 32 2>/dev/null && echo "INTC状态寄存器: $(devmem 0x1fe00000 32)"
devmem 0x1fe00004 32 2>/dev/null && echo "INTC掩码寄存器: $(devmem 0x1fe00004 32)"

echo ""
echo "--- 3. CPU中断状态 ---"
# 读取CP0 Cause寄存器
echo "CP0 Cause: $(echo 'mfc0 $t0, $13; nop' | gdb -q -batch -n -ex 'set $t0=0' -ex 'stepi' 2>/dev/null || echo '无法读取')"

echo ""
echo "--- 4. 内核dmesg最近20条中断相关日志 ---"
dmesg | grep -iE "irq|interrupt|hdmi" | tail -20

echo ""
echo "=== 诊断结束 ==="
使用建议: 将上述脚本保存为 /usr/local/bin/hdmi_irq_diag.sh 并赋予执行权限。在出现屏幕无显示或画面撕裂时立即运行,输出结果可帮助判断中断丢失发生在哪个环节。建议同时保存一份正常状态下的输出作为基线对比。