mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-09-10 06:29:32 +00:00
machine: avoid sync.Once during ESP32 startup
UART initialization runs before the scheduler has a current task. Once.Do uses defer, which requires a current task when panic recovery is enabled. Use an interrupt-protected flag for this unicore initialization path instead.
This commit is contained in:
@@ -478,7 +478,7 @@ var (
|
|||||||
rtsctsSignal: 199,
|
rtsctsSignal: 199,
|
||||||
}
|
}
|
||||||
|
|
||||||
onceUart = sync.Once{}
|
uartInterruptConfigured bool
|
||||||
)
|
)
|
||||||
|
|
||||||
// CPU interrupt line used for all UART peripherals.
|
// CPU interrupt line used for all UART peripherals.
|
||||||
@@ -588,11 +588,13 @@ func (uart *UART) configureInterrupt() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Register the ISR only once (shared across all UARTs on the same CPU int).
|
// Register the ISR only once (shared across all UARTs on the same CPU int).
|
||||||
// interrupt.New is a compiler intrinsic and requires a plain (non-capturing)
|
// Avoid sync.Once here because serial is initialized before a task exists.
|
||||||
// handler function, so we use a named package-level function.
|
state := interrupt.Disable()
|
||||||
onceUart.Do(func() {
|
if !uartInterruptConfigured {
|
||||||
_ = interrupt.New(cpuInterruptFromUART, handleUARTInterrupt).Enable()
|
_ = interrupt.New(cpuInterruptFromUART, handleUARTInterrupt).Enable()
|
||||||
})
|
uartInterruptConfigured = true
|
||||||
|
}
|
||||||
|
interrupt.Restore(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleUARTInterrupt is the shared UART interrupt handler. It must be a plain
|
// handleUARTInterrupt is the shared UART interrupt handler. It must be a plain
|
||||||
|
|||||||
Reference in New Issue
Block a user