Skip to content

feat(cortex-m3): peripheral IRQ pipeline — C2/C1/C3#4

Closed
Charliechen114514 wants to merge 3 commits into
mainfrom
feat/periph-irq-pipeline
Closed

feat(cortex-m3): peripheral IRQ pipeline — C2/C1/C3#4
Charliechen114514 wants to merge 3 commits into
mainfrom
feat/periph-irq-pipeline

Conversation

@Charliechen114514

Copy link
Copy Markdown
Member

外设中断端到端(06 第二波 C2/C1/C3)

打通外设 → NVIC → handler 的完整中断通道,三个外设(TIM/EXTI/USART)端到端跑通,验证第一波 A 抢占模型在真实外设上成立。

C2 — raise_irq 公共通道 + Timer UIF→IRQ (84c73e6)

  • raise_irq 原为空壳 no-op → 实现为 nvic_->set_pending(irq)。这是所有 MMIO IRQ 的公共入口(SysTick 之前靠独立 sys_tick_irq 绕过)。
  • Timer UIE edge 回调 → raise TIM2(IRQ 28)。

C1 — EXTI 外部中断 + AFIO EXTICR (857fb0e)

  • Stm32f1Exti(IMR/RTSR/FTSR/SWIER/PR)+ AFIO exti_line_port 路由(EXTICR 终于有消费者)。
  • GPIO edge → EXTI(EXTICR 路由 + IMR/RTSR/FTSR)→ raise(线→IRQ 6-10/23/40)。
  • GPIO simulate_input 补 edge emit(外部输入边沿喂 EXTI)。

C3 — USART RX 注入 + RXNEIE (0364f16)

  • USART inject_rx 单字节缓冲 + RXNE;DR read 返回字节 + 清 RXNE(读=RX/写=TX 共享)。
  • RXNEIE → raise USART1(IRQ 37)。TXEIE 跳过(模拟器 TX 即时,TXE 常高会循环 raise)。

验证

  • ctest 301/301 绿(无回归:固件 E2E 3×AC6 + gcc hal_uart / CLI / 中断抢占全过)。
  • raise_irq 三消费者(TIM/EXTI/USART)全通同一通道 —— 以后新外设中断(SPI/DMA/ADC)复用。

细节

  • notes 014/015/016 + 06 实施记录。
  • 坑:MICRO_FORGE_SOURCES 显式 set() 列表(非 DIRECTIVES 说的 GLOB);ARM 异常自动压栈 r0-r3(handler 读结果用 r4+)。

🤖 Generated with Claude Code

raise_irq was a no-op — the entire peripheral→NVIC IRQ channel was never
connected (SysTick bypassed it via sys_tick_irq). Implement it as
nvic_->set_pending(irq); this is the shared entry for all MMIO IRQs
(TIM/USART/EXTI).

Stm32f1Timer gains set_irq_callback (SysTick pattern); tick() raises on
UIF 0→1 edge when DIER.UIE is set. SoC wires TIM2 (kTim2Irqn=28). Add
unit tests (edge/UIE semantics) and TimerUifRoundtrip E2E (coordinator
Apb1 tick → handler entry → BX LR return). ctest 289/289.
Add Stm32f1Exti (IMR/EMR/RTSR/FTSR/SWIER/PR @ 0x40010400). GPIO edges
→ AFIO EXTICR routing (new exti_line_port getter) → IMR+RTSR/FTSR match
→ pending + raise NVIC (line→IRQ: 0-4=6-10, 5-9=23, 10-15=40). Reuses
the raise_irq channel from C2 (EXTI is its second consumer).

GPIO simulate_input now emits edge_signal so external input edges feed
EXTI. SoC wires gpioa/b/c edge_signal → EXTI → raise_irq. Tests: 6 unit
(registers/PR/routing/mask/edge-select) + ExtiGpioEdgeRoundtrip E2E.
ctest 296/296.
USART gains inject_rx(byte): single-slot RX buffer + SR.RXNE, DR read
returns the byte and clears RXNE (read=RX/write=TX shared). RXNEIE (CR1
bit5) + RXNE → raise USART1 (IRQ37) via the raise_irq channel — its third
consumer (TIM/EXTI/USART). TXEIE skipped (instant TX keeps TXE high →
would loop-raise; firmware polling TXE still works).

Tests: 4 unit (RXNE/DR/RXNEIE enabled+disabled) + UsartRxRoundtrip E2E
(inject_rx → handler reads DR via r4, which survives exception return
unlike auto-stacked r0-r3). ctest 301/301.
@Charliechen114514 Charliechen114514 deleted the feat/periph-irq-pipeline branch June 23, 2026 10:24
@Charliechen114514 Charliechen114514 restored the feat/periph-irq-pipeline branch June 23, 2026 10:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant