Skip to content

Commit bc6a0a5

Browse files
committed
device/arm: clear pending interrupts before enabling them
Without this change, a pending interrupt would spuriously trigger immediately after enabling. This happens if an interrupt is triggered during flashing (e.g. by DMA), which survives the subsequent reset. This behaviour matches e.g. `machine.irqSet` in machine_rp2_rp2350.go. See 7f970a4, whose symptoms were likely caused by spurious interrupts.
1 parent 120d17c commit bc6a0a5

File tree

3 files changed

+10
-2
lines changed

3 files changed

+10
-2
lines changed

builder/sizes_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ func TestBinarySize(t *testing.T) {
4343
tests := []sizeTest{
4444
// microcontrollers
4545
{"hifive1b", "examples/echo", 4560, 280, 0, 2268},
46-
{"microbit", "examples/serial", 2916, 388, 8, 2272},
47-
{"wioterminal", "examples/pininterrupt", 7359, 1489, 116, 6912},
46+
{"microbit", "examples/serial", 2924, 388, 8, 2272},
47+
{"wioterminal", "examples/pininterrupt", 7383, 1489, 116, 6912},
4848

4949
// TODO: also check wasm. Right now this is difficult, because
5050
// wasm binaries are run through wasm-opt and therefore the

src/device/arm/arm.go

+5
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@ const (
146146
SYST_CALIB_NOREF = 0x80000000 // Bit NOREF.
147147
)
148148

149+
// ClearPendingIRQ clears the pending status of the interrupt.
150+
func ClearPendingIRQ(irq uint32) {
151+
NVIC.ICPR[irq>>5].Set(1 << (irq & 0x1F))
152+
}
153+
149154
// Enable the given interrupt number.
150155
func EnableIRQ(irq uint32) {
151156
NVIC.ISER[irq>>5].Set(1 << (irq & 0x1F))

src/runtime/interrupt/interrupt_cortexm.go

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import (
99
// Enable enables this interrupt. Right after calling this function, the
1010
// interrupt may be invoked if it was already pending.
1111
func (irq Interrupt) Enable() {
12+
// Clear the ARM pending bit, an asserting device may still
13+
// trigger the interrupt once enabled.
14+
arm.ClearPendingIRQ(uint32(irq.num))
1215
arm.EnableIRQ(uint32(irq.num))
1316
}
1417

0 commit comments

Comments
 (0)