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

ARM架构下无DTS时硬件中断映射VIRQ及虚拟设备分配软件触发SPI方法

ARM架构无设备树时硬件中断映射到虚拟中断(VIRQ)
  • 静态定义硬件中断资源:在平台设备初始化代码中,通过struct resource指定硬件中断号(HWIRQ),将其绑定到平台设备上:
static struct resource my_device_resources[] = {
    {
        .start = 32,  // 目标硬件中断号
        .end = 32,
        .flags = IORESOURCE_IRQ,
    },
};

static struct platform_device my_platform_dev = {
    .name = "my-custom-device",
    .id = -1,
    .num_resources = ARRAY_SIZE(my_device_resources),
    .resource = my_device_resources,
};

static int __init my_dev_init(void) {
    return platform_device_register(&my_platform_dev);
}
module_init(my_dev_init);
  • 驱动中完成映射与中断申请:在驱动probe函数里,提取平台设备的中断资源,根据架构需求完成HWIRQ到VIRQ的映射,再申请中断:
static irqreturn_t my_irq_handler(int irq, void *dev_id) {
    // 中断处理逻辑
    return IRQ_HANDLED;
}

static int my_driver_probe(struct platform_device *pdev) {
    struct resource *irq_res;
    int virq, ret;

    irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
    if (!irq_res) return -ENODEV;

    // 部分ARM架构(如带GIC的ARMv7)可省略手动映射,直接用platform_get_irq获取VIRQ
    virq = irq_create_mapping(NULL, irq_res->start);
    if (!virq) return -EINVAL;

    ret = request_irq(virq, my_irq_handler, IRQF_TRIGGER_RISING, "my-dev-irq", pdev);
    if (ret) {
        irq_dispose_mapping(virq);
        return ret;
    }
    return 0;
}
虚拟设备无设备树节点时分配软件触发的共享处理器中断(SPI)
  • 确认GIC支持:确保系统使用的GIC版本为v2及以上,这类GIC原生支持软件触发SPI,SPI的HWIRQ范围通常为32~1019(具体以GIC配置为准)。
  • 动态分配SPI中断号:调用内核API分配可用的SPI中断:
int virq = irq_alloc_descs(-1, 32, 1, 0);
if (virq <= 0) {
    pr_err("Failed to allocate SPI IRQ\n");
    return virq;
}
  • 配置为软件触发模式:通过GIC芯片操作设置中断触发类型为软件触发:
struct irq_chip *gic_chip = irq_get_chip(virq);
if (!gic_chip) {
    irq_free_desc(virq);
    return -ENODEV;
}

irq_set_status_flags(virq, IRQ_LEVEL);
irq_set_chip_and_handler(virq, gic_chip, handle_level_irq);

// 设置触发类型为上升沿(软件触发常用配置)
if (gic_chip->irq_set_type) {
    gic_chip->irq_set_type(virq, IRQ_TYPE_EDGE_RISING);
}
  • 申请与触发中断:在虚拟设备中申请该中断,之后可通过内核API手动触发:
static irqreturn_t virtual_irq_handler(int irq, void *dev_id) {
    // 虚拟设备中断处理逻辑
    return IRQ_HANDLED;
}

// 申请中断
int ret = request_irq(virq, virtual_irq_handler, IRQF_SHARED, "virtual-spi-irq", my_virtual_dev);
if (ret) {
    irq_free_desc(virq);
    return ret;
}

// 软件触发中断
irq_set_irqchip_state(virq, IRQCHIP_STATE_PENDING, true);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 22:15:35