![]() |
RT-Thread RTOS
An open source embedded real-time operating system
|
How RT-Thread turns many interrupt controllers into one global IRQ space drivers can use.
MAX_HANDLERS** (Kconfig, default 256)struct rt_pic_irq** with **irq**, **hwirq**, **pic**, ISR list, optional **parent**Allocation pointer **_pirq_hash_idx**:
| Region | Indices | Purpose |
|---|---|---|
| IPI | 0 … RT_MAX_IPI-1 | SMP inter-processor interrupts |
| PIC domains | _pirq_hash_idx upward | Each **rt_pic_linear_irq** takes a contiguous block |
**rt_pic_config_ipi** uses fixed low indices. Peripheral IRQs come from **rt_pic_config_irq**.
**rt_pic_linear_irq(pic, irq_nr)** (under global lock):
Example (GICv2 with 988 SPIs):
irq_nr = max_irq + 1 - 32** (SGI/PPI handled separately)[RT_MAX_IPI, RT_MAX_IPI + irq_nr)**irq_index = hwirq - 32** for SPI hwirq 32 → index 0| Input | Meaning |
|---|---|
**irq_index** | Offset within this PIC's window |
**hwirq** | Hardware ID in that controller |
| Return value | Global virtual IRQ = **pic->irq_start + irq_index** |
Lookup:
| API | Returns |
|---|---|
**rt_pic_find_irq(pic, irq_index)** | **&pic->pirqs[irq_index]** |
**rt_pic_find_pirq(pic, virtual_irq)** | **pirq** if **virtual_irq** in range |
**irq2pirq(irq)** | Global lookup for **rt_pic_irq_*** wrappers |
| Field | Role |
|---|---|
**irq** | Virtual IRQ (global); **-1** = slot unused |
**hwirq** | Controller-specific line |
**mode** | Edge/level (RT_IRQ_MODE_*) |
**pic** | Owning **struct rt_pic *** |
**parent** | Cascade parent **pirq** |
**children_nodes** | Routed children if **RT_PIC_F_IRQ_ROUTING** |
**isr** | Handler chain |
| IPI | Device IRQ | |
|---|---|---|
| Config | **rt_pic_config_ipi** | **rt_pic_config_irq** or **irq_map** |
| Affinity | All CPUs set in **config_ipi** | Per **irq_set_affinity** |
| Dispatch | GIC trap reads hwirq < 16 → **rt_pic_find_ipi** | hwirq ≥ 32 → **rt_pic_find_irq** |
With MSH: **list_irq** / **list_irq all** ( **pic.c** ) dumps virtual IRQ, PIC name, hwirq, mode, handlers.
**rt_pic_linear_irq** comment: intended for production PIC registration; **rt_pic_cancel_irq** only for failed init teardown.
| Issue | Mitigation |
|---|---|
**MAX_HANDLERS too small** | Sum all PIC **irq_nr** + IPI + headroom |
Use hwirq as **rt_pic_attach_irq argument** | Always use virtual irq from **rt_dm_dev_get_irq** / **irq_map** |
Re-**config_irq** on busy slot | **config_pirq** asserts empty ISR lists if PIC changes |