You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

自定义硬件中断处理问题:Linux下无法捕获Xilinx FPGA中断

Troubleshooting Xilinx FPGA Interrupts in Linux (vs uCOS-II)

Alright, let's walk through this—moving from uCOS-II to Linux for FPGA interrupts has some key differences that are probably tripping you up. Let's start with the extra steps you need beyond just registering the IRQ, then cover how to monitor all interrupt traffic to the CPU.

Extra Steps Beyond register_irq (or request_irq)

uCOS-II is a lightweight RTOS that often maps hardware interrupts directly, but Linux has a more robust interrupt subsystem with extra layers. Here's what you might be missing:

  • Validate the IRQ number mapping
    The hardware interrupt ID 94 you used in uCOS-II might not match the Linux virtual IRQ number. On Xilinx systems (especially ARM with GIC), hardware interrupts (like SPI interrupts) are mapped to Linux IRQs via the interrupt controller. Use cat /proc/interrupts to list registered IRQs, or in your driver, use irq_find_mapping() or platform_get_irq() (if using device tree) to fetch the correct Linux IRQ number instead of hardcoding 94.

  • Explicitly set the interrupt trigger type
    Unlike uCOS-II, Linux requires you to specify the trigger mode when requesting an IRQ. Make sure you pass the correct flags to devm_request_irq() (the modern, resource-managed alternative to register_irq), like IRQF_TRIGGER_RISING, IRQF_TRIGGER_FALLING, or IRQF_TRIGGER_HIGH—this must match how your FPGA is configured to send interrupts. For example:

    devm_request_irq(&pdev->dev, irq, my_interrupt_handler,
                     IRQF_TRIGGER_RISING, "my-fpga-irq", dev_data);
    
  • Enable the interrupt at the hardware level
    uCOS-II might have initialized the FPGA's interrupt controller (or AXI interrupt router) automatically, but Linux expects your driver to handle this. Check your FPGA's register map—you'll likely need to write to a specific MMIO register to unmask/enable the interrupt line leading to the CPU. Don't skip this step!

  • Verify interrupt controller configuration
    If you're on an ARM system with GIC, ensure the GIC has routed the interrupt to your target CPU core. You can check/set interrupt affinity with:

    # Bind IRQ to CPU 0 (replace <linux-irq-number> with the correct value)
    echo 1 > /proc/irq/<linux-irq-number>/smp_affinity
    

    Also, use debugfs (if enabled) to inspect /sys/kernel/debug/irq/<irq-number>/status and confirm the interrupt isn't masked at the controller level.

  • Use the modern IRQ registration API
    register_irq() is deprecated in newer Linux kernels. Switch to devm_request_irq() which handles resource cleanup automatically and reduces bugs. Make sure your interrupt handler follows the correct prototype:

    irqreturn_t my_interrupt_handler(int irq, void *dev_id) {
        // Handle interrupt logic here
        return IRQ_HANDLED;
    }
    

How to Monitor All Interrupts to the CPU (Even Unhandled Ones)

To confirm whether the CPU is receiving the FPGA's interrupt (even if your handler isn't triggering), try these tools:

  • Check /proc/interrupts
    This file shows the count of interrupts received per IRQ and CPU core. If your FPGA is sending interrupts, the count for the corresponding Linux IRQ should increment—even if there's no handler registered (behavior varies slightly by interrupt controller).

  • Use perf for interrupt tracing
    The perf tool can capture all interrupt events, including unhandled ones. Run:

    # Record all interrupt events with call graphs
    perf record -e irq:* -g
    # View the captured report
    perf report
    

    Look for events like irq:irq_entry or irq:irq_exit to see if the CPU is acknowledging the interrupt.

  • Inspect kernel debug logs
    Enable verbose interrupt debugging by adjusting the kernel printk level:

    echo 1 > /proc/sys/kernel/printk
    

    Then watch dmesg -w—if the CPU receives an unhandled interrupt, you might see messages like unhandled interrupt <irq-number> (depending on your kernel's CONFIG_IRQ_DEBUG setting).

  • Use hardware debugging tools
    For Xilinx FPGAs, use Vivado's Integrated Logic Analyzer (ILA) to probe the interrupt output pin of your custom hardware. This confirms whether the FPGA is actually sending the signal before it reaches the CPU. You can also read the GIC's pending registers via MMIO to check if the interrupt is reaching the controller.

  • Check debugfs for interrupt status
    If your kernel has CONFIG_DEBUG_FS enabled, navigate to /sys/kernel/debug/irq/. The irqs file lists all interrupts and their state (pending, active, etc.)—even those without registered handlers.


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

火山引擎 最新活动