You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌入式Linux不使用设备树设置PL/PS中断的问题求助

解决PL到PS中断捕获失败(request_irq返回-22)的无设备树修改方案

首先,request_irq返回-22(EINVAL)的核心原因是你使用的中断号未被内核GIC控制器识别,或者触发配置与硬件不匹配。以下是无需修改设备树的可行方案:

1. 确定正确的硬件中断号

对于Zynq系列(包括7000和UltraScale+),PL到PS的中断属于GIC的SPI(共享外设中断),硬件中断号的计算规则为:

硬件中断号 = 32 + Vivado中配置的IRQ_F2P编号
你的IRQ_F2P是61,因此对应的硬件中断号为 32 + 61 = 93(此编号适用于Zynq UltraScale+平台,若为Zynq-7000,IRQ_F2P范围仅0-15,你的场景显然属于UltraScale+)。

2. 动态映射中断号(关键步骤)

由于未修改设备树,内核默认不会将该PL中断加入可用中断池,因此需要先通过irq_create_mapping动态完成硬件中断号到内核虚拟中断号的映射:

#include <linux/irqdomain.h>
#include <linux/interrupt.h>

// 硬件中断号,根据你的情况设置为93
#define HW_IRQ_NUM 93

int ret;
unsigned int virq;

// 动态映射硬件中断号到虚拟中断号
virq = irq_create_mapping(NULL, HW_IRQ_NUM);
if (!virq) {
    pr_err("Failed to map hardware interrupt %d\n", HW_IRQ_NUM);
    return -ENODEV;
}

irq_create_mapping会自动查找GIC中断域,完成映射后返回有效的内核虚拟中断号。

3. 使用映射后的虚拟中断号注册中断

用返回的virq替代之前的错误中断号调用request_irq,同时确保触发方式与PL端配置一致(比如PL输出上升沿触发,驱动中就用IRQF_TRIGGER_RISING):

ret = request_irq(virq, your_interrupt_handler, IRQF_TRIGGER_RISING, "pl-irq-driver", NULL);
if (ret) {
    pr_err("Failed to request irq %d, ret = %d\n", virq, ret);
    irq_dispose_mapping(virq); // 映射失败时清理资源
    return ret;
}

4. 额外检查项

  • 确认PL端中断已正确配置:中断输出使能,触发方式(上升沿/下降沿/电平)与驱动中request_irq的参数完全匹配;
  • 查看系统中断状态:通过cat /proc/interrupts或cat /sys/kernel/debug/irq/irqchip/gic-0/spi(GICv2平台)确认映射后的虚拟中断号是否存在;
  • 若仍失败,可先设置触发类型再注册:部分平台默认屏蔽未声明的SPI中断,可先调用irq_set_irq_type(virq, IRQF_TRIGGER_RISING),再执行request_irq。

内容的提问来源于stack exchange,提问作者Boune

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 11:43:20