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