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
assert.hpp
Go to the documentation of this file.
1#ifndef SBL_COMMON_ASSERT_HPP_
2#define SBL_COMMON_ASSERT_HPP_
3
4/**
5 * @file assert.hpp
6 * @brief Assert and panic for embedded firmware
7 *
8 * Provides SBL_ASSERT(cond) and SBL_PANIC(msg) macros that output
9 * diagnostic info and halt the processor. Output goes through the
10 * same sink as the logging system (SBL_LOG_OUTPUT).
11 *
12 * This header is pure library code — no hardware dependencies.
13 * For HardFault register dumps, also include <sbl/common/fault.hpp>.
14 *
15 * Usage:
16 * #include <sbl/common/assert.hpp>
17 *
18 * void process(float* buf, uint16_t frames) {
19 * SBL_ASSERT(buf != nullptr);
20 * SBL_ASSERT(frames <= 48);
21 * // ...
22 * }
23 *
24 * if (something_unrecoverable) {
25 * SBL_PANIC("DMA config failed");
26 * }
27 *
28 * Configuration:
29 * SBL_ASSERT_ENABLED - 1 (default) to enable, 0 to compile out
30 * SBL_FAULT_OUTPUT - output sink class (defaults to SBL_LOG_OUTPUT)
31 */
32
33#include <cstdint>
35
36// ============================================================================
37// Output sink resolution
38// ============================================================================
39
40// If the user defined a dedicated fault output, use it.
41// Otherwise, use polling UART (works with interrupts disabled).
42// NOTE: Fault handlers run after cpsid i — interrupt-driven output
43// (ring buffer + ISR) will never drain. Must use polling writes.
44#ifndef SBL_FAULT_OUTPUT
46
47 #if SBL_LOG_HW_DEFAULTS_AVAILABLE
48 #define SBL_FAULT_OUTPUT sbl::log::UartFaultOutput
49 #else
50 // No output available — fault still halts, just silently.
53 static void write(const char*) {}
54 };
55 }
56 #define SBL_FAULT_OUTPUT sbl::fault::detail::NullFaultOutput
57 #endif
58#endif
59
60namespace sbl::fault {
61
62/**
63 * @brief Halt with a diagnostic message. Does not return.
64 *
65 * Disables interrupts, formats the message with file/line info,
66 * outputs it, then enters an infinite loop with a debug breakpoint.
67 *
68 * Safe to call from any context (main loop, ISR, fault handler).
69 */
70[[noreturn]] inline void panic(const char* msg, const char* file, int line) {
71 __asm volatile("cpsid i"); // __disable_irq()
72
73 char buf[128];
74 sbl::log::format(buf, sizeof(buf), "\r\n!!! %s\r\n at %s:%d\r\n", msg, file, line);
75 SBL_FAULT_OUTPUT::write(buf);
76
77 while (true) {
78 __asm volatile("bkpt #0");
79 }
80}
81
82} // namespace sbl::fault
83
84// ============================================================================
85// Macros
86// ============================================================================
87
88#define SBL_PANIC(msg) sbl::fault::panic("PANIC: " msg, __FILE__, __LINE__)
89
90#ifndef SBL_ASSERT_ENABLED
91 #define SBL_ASSERT_ENABLED 1
92#endif
93
94#if SBL_ASSERT_ENABLED
95 #define SBL_ASSERT(cond) \
96 do { \
97 if (!(cond)) { \
98 sbl::fault::panic("ASSERT FAILED: " #cond, __FILE__, __LINE__); \
99 } \
100 } while (0)
101#else
102 #define SBL_ASSERT(cond) ((void)0)
103#endif
104
105#endif // SBL_COMMON_ASSERT_HPP_
Default logger output sink and timestamp provider.
Minimal safe string formatting for embedded systems.
Faults and assertions.
Definition assert.hpp:51
void panic(const char *msg, const char *file, int line)
Halt with a diagnostic message. Does not return.
Definition assert.hpp:70
int format(char *buf, size_t size, const char *fmt,...)
Format a string into a buffer (snprintf-style)
Definition format.hpp:265
static void write(const char *)
Definition assert.hpp:53