From 1536da3497050878d358234ff2a52f6d89ca80b1 Mon Sep 17 00:00:00 2001 From: Rahix <rahix@rahix.de> Date: Fri, 4 Oct 2019 09:58:29 +0200 Subject: [PATCH] feat(epicardium): Add a panic() function In unrecoverable situations we should provide a common way to output the cause of the error and then reset the CPU. The panic() function is mean to be exactly that. It outputs the error-cause, stack-trace, and firmware revision, accompanied by a link to the issue-tracker to encourage people to report the error. After a timeout of ~1.5s it resets the CPU and reboots. Future Work: - Right now, the stack-trace only has a depth of one which is the return address from where panic() was called. In the future it might make sense to provide a deeper stack-trace if a robust implementation is possible. - Integration of @msgctl's faultscreen (!79) so users who don't have the serial console open at all times can also see what happened. Signed-off-by: Rahix <rahix@rahix.de> --- epicardium/modules/meson.build | 1 + epicardium/modules/modules.h | 4 +++ epicardium/modules/panic.c | 63 ++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 epicardium/modules/panic.c diff --git a/epicardium/modules/meson.build b/epicardium/modules/meson.build index 21a04ba5..022397ca 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 465c78a4..bf59566b 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 00000000..e37f3d7a --- /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(); +} -- GitLab