diff --git a/epicardium/modules/meson.build b/epicardium/modules/meson.build index 21a04ba5ec8464979127f1572b56a979ba34f08b..022397ca26e3866ef9a72472a7621e4cd6dbfec2 100644 --- a/epicardium/modules/meson.build +++ b/epicardium/modules/meson.build @@ -14,6 +14,7 @@ module_sources = files( 'light_sensor.c', 'log.c', 'max30001.c', + 'panic.c', 'personal_state.c', 'pmic.c', 'rtc.c', diff --git a/epicardium/modules/modules.h b/epicardium/modules/modules.h index 465c78a4bda915927a10faafc90df911784f8574..bf59566b3e7ef168977ccf7606d55f445961da86 100644 --- a/epicardium/modules/modules.h +++ b/epicardium/modules/modules.h @@ -8,6 +8,10 @@ #include <stdint.h> #include <stdbool.h> +/* ---------- Panic -------------------------------------------------------- */ +void panic(const char *format, ...) + __attribute__((noreturn, format(printf, 1, 2))); + /* ---------- Dispatcher --------------------------------------------------- */ void vApiDispatcher(void *pvParameters); void dispatcher_mutex_init(void); diff --git a/epicardium/modules/panic.c b/epicardium/modules/panic.c new file mode 100644 index 0000000000000000000000000000000000000000..e37f3d7a408eb40e5bbe4581339f1c38c53c6146 --- /dev/null +++ b/epicardium/modules/panic.c @@ -0,0 +1,63 @@ +/* + * Panic + * ===== + * + * Under some conditions the firmware should crash and reboot automatically. + * This module provides the necessary facilities to do so. + * + * Note that a panic should indicate **only** logic-errors in the firmware or + * unrecoverable hardware conditions. + */ + +#include "modules/log.h" +#include "modules/modules.h" + +#include "card10.h" +#include "card10-version.h" + +#include <stdio.h> +#include <stdarg.h> + +void __attribute__((noreturn)) panic(const char *format, ...) +{ + /* Turn off interrupts. We won't get back from here anyway. */ + __asm volatile("cpsid i" ::: "memory"); + + /* + * Turn off asynchronous printing because that won't ever work from + * here ... + */ + serial_return_to_synchronous(); + + printf("\x1b[31;1m --- SYSTEM PANIC ---\n" + "\x1b[0;31m --- ---\n" + " --- ---\n" + "\x1b[0m A fatal error occured:\n \x1b[1m"); + + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + + printf("\n" + "\x1b[0m\n" + " Firmware Version:\n" + "\x1b[35m %s\n", + CARD10_VERSION); + + printf("\x1b[0m\n" + " Stack Trace:\n" + "\x1b[36m %p\n", + __builtin_return_address(0)); + + printf("\x1b[33m\n" + " Please report this error to the card10 firmware team!\n" + "\x1b[0m -> https://git.card10.badge.events.ccc.de/card10/firmware/issues/new?issue <-\n" + "\x1b[31m --- ====== ===== ---\x1b[0m\n"); + + for (int i = 0; i < 96000000; i++) { + __asm volatile("nop"); + } + + card10_reset(); +}