From 192080f6d37e8c4903a4e7f6290cde64bd855636 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 10 Mar 2026 13:29:24 -1000 Subject: [PATCH] Add references for HardFault handler asm pattern --- esphome/components/rp2040/crash_handler.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/esphome/components/rp2040/crash_handler.cpp b/esphome/components/rp2040/crash_handler.cpp index 34268ab6f09..13e07a5de6a 100644 --- a/esphome/components/rp2040/crash_handler.cpp +++ b/esphome/components/rp2040/crash_handler.cpp @@ -133,6 +133,17 @@ static void __attribute__((used)) hard_fault_handler_c(uint32_t *frame, uint32_t // Naked asm wrapper - Cortex-M0+ compatible (no ITE/conditional execution). // Determines active stack pointer and branches to C handler. // Uses literal pool (.word) for addresses since M0+ has limited immediate encoding. +// +// Based on the standard Cortex-M0+ HardFault handler pattern described in: +// - ARM Application Note AN209: "Using Cortex-M3/M4/M7 Fault Exceptions" +// (adapted for M0+ which lacks conditional execution instructions) +// - Memfault: "How to debug a HardFault on an ARM Cortex-M MCU" +// https://interrupt.memfault.com/blog/cortex-m-hardfault-debug +// - Raspberry Pi Forums: "Cortex-M0+ Hard Fault handler porting" +// https://www.eevblog.com/forum/microcontrollers/cortex-m0-hard-fault-handler-porting/ +// +// The key M0+ adaptation: replaces ITE/MRSEQ/MRSNE (Cortex-M3+) with +// MOVS+TST+BEQ branch sequence, and uses a literal pool for the C handler address. extern "C" void __attribute__((naked, used)) isr_hardfault() { __asm volatile("movs r0, #4 \n" // Prepare bit 2 mask "mov r1, lr \n" // r1 = EXC_RETURN