Sound Byte Libs 0.5.1-121-g3358a44
C++ firmware library for audio applications on 32-bit ARM Cortex-M processors
Loading...
Searching...
No Matches
fault.hpp
Go to the documentation of this file.
1#ifndef SBL_COMMON_FAULT_HPP_
2#define SBL_COMMON_FAULT_HPP_
3
4/**
5 * @file fault.hpp
6 * @brief HardFault handler with register dump
7 *
8 * Bridge between the MCU's HardFault vector (in sbl-hardware startup.cpp)
9 * and the library's diagnostic output. Including this header provides:
10 *
11 * 1. sbl::fault::on_hard_fault() — formats the Cortex-M exception frame
12 * 2. sbl_on_hard_fault() — strong C symbol that overrides the weak default
13 * in startup.cpp, connecting the vector to the formatter
14 *
15 * The startup.cpp in sbl-hardware declares a weak sbl_on_hard_fault() that
16 * just hits a breakpoint. When this header is included in the application,
17 * the strong symbol here wins, giving formatted register output on any fault.
18 *
19 * Usage:
20 * // Include once in your main.cpp (or any single TU)
21 * #include <sbl/common/fault.hpp>
22 *
23 * // That's it. HardFaults now dump registers to your log output.
24 *
25 * The output sink is shared with assert.hpp (SBL_FAULT_OUTPUT).
26 * See assert.hpp for sink configuration.
27 */
28
29#include <sbl/common/assert.hpp> // For SBL_FAULT_OUTPUT and sbl::log::format
30
31namespace sbl::fault {
32
33/**
34 * @brief Format and output the Cortex-M exception stack frame.
35 *
36 * The Cortex-M exception entry pushes these registers onto the
37 * active stack (MSP or PSP):
38 * [0] R0 [1] R1 [2] R2 [3] R3
39 * [4] R12 [5] LR [6] PC [7] xPSR
40 *
41 * The faulting instruction address is frame[6] (stacked PC).
42 * frame[5] (stacked LR) shows where the faulting function would
43 * have returned to.
44 *
45 * @param frame Pointer to the exception stack frame
46 */
47[[noreturn]] inline void on_hard_fault(const uint32_t* frame) {
48 __asm volatile("cpsid i");
49
50 char buf[256];
51 int pos = 0;
52
53 pos += sbl::log::format(buf + pos, sizeof(buf) - pos,
54 "\r\n!!! HARD FAULT\r\n"
55 " PC = 0x%08lX (faulting instruction)\r\n"
56 " LR = 0x%08lX (return address)\r\n"
57 " PSR = 0x%08lX\r\n",
58 frame[6], frame[5], frame[7]);
59
60 pos += sbl::log::format(buf + pos, sizeof(buf) - pos,
61 " R0 = 0x%08lX R1 = 0x%08lX\r\n"
62 " R2 = 0x%08lX R3 = 0x%08lX\r\n"
63 " R12 = 0x%08lX\r\n",
64 frame[0], frame[1], frame[2], frame[3], frame[4]);
65
66 SBL_FAULT_OUTPUT::write(buf);
67
68 while (true) {
69 __asm volatile("bkpt #1");
70 }
71}
72
73} // namespace sbl::fault
74
75// ============================================================================
76// HardFault handler override
77// ============================================================================
78// This strong symbol overrides the weak default in startup.cpp,
79// connecting the MCU's HardFault vector to the formatted output above.
80//
81// __attribute__((used)) forces the compiler to emit the symbol even
82// though nothing in C++ calls it directly — the call comes from the
83// HardFault assembly stub in startup.cpp via the vector table.
84
85extern "C" [[noreturn]] __attribute__((used))
86inline void sbl_on_hard_fault(const uint32_t* frame) {
88}
89
90#endif // SBL_COMMON_FAULT_HPP_
Assert and panic for embedded firmware.
__attribute__((used)) inline void sbl_on_hard_fault(const uint32_t *frame)
Definition fault.hpp:85
Faults and assertions.
Definition assert.hpp:51
void on_hard_fault(const uint32_t *frame)
Format and output the Cortex-M exception stack frame.
Definition fault.hpp:47
int format(char *buf, size_t size, const char *fmt,...)
Format a string into a buffer (snprintf-style)
Definition format.hpp:265