Select Git revision
-
Damien George authoredDamien George authored
panic.c 4.50 KiB
/*
* 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 "gfx.h"
#include "display.h"
#include "LCD_Driver.h"
#include <stdio.h>
#include <stdarg.h>
static void faultsplash(const char *msg);
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 <-\n"
"\x1b[31m --- ====== ===== ---\x1b[0m\n");
char faultsplash_buffer[14 * 4];
va_start(ap, format);
vsnprintf(faultsplash_buffer, sizeof(faultsplash_buffer), format, ap);
va_end(ap);
faultsplash(faultsplash_buffer);
for (int i = 0; i < 96000000; i++) {
__asm volatile("nop");
}
card10_reset();
}
void __attribute__((noreturn)) __assert_func(
const char *file, int line, const char *func, const char *failedexpr
) {
panic("Assertion failure:\n"
" \"%s\"\n"
" failed in \"%s:%d\",\n"
" function: %s()",
failedexpr,
file,
line,
func);
}
static const unsigned char faultsplash_rle[] = {
0x7f, 0x50, 0x83, 0x0f, 0x82, 0x7f, 0x0d, 0x83, 0x0f, 0x82, 0x7f, 0x1d,
0x82, 0x7f, 0x1f, 0x82, 0x7f, 0x1f, 0x82, 0x7f, 0x12, 0x82, 0x09, 0x82,
0x7f, 0x14, 0x82, 0x09, 0x82, 0x7f, 0x09, 0x82, 0x11, 0x83, 0x7f, 0x0b,
0x82, 0x11, 0x83, 0x7f, 0x0f, 0x82, 0x07, 0x82, 0x7f, 0x16, 0x82, 0x07,
0x82, 0x7f, 0x16, 0x82, 0x07, 0x82, 0x7f, 0x1a, 0x83, 0x7f, 0x1e, 0x83,
0x7f, 0x0a, 0x8b, 0x17, 0x82, 0x02, 0x82, 0x02, 0x83, 0x73, 0x8c, 0x16,
0x82, 0x02, 0x82, 0x02, 0x83, 0x72, 0x81, 0x0c, 0x84, 0x07, 0x85, 0x7f,
0x03, 0x82, 0x0c, 0x84, 0x07, 0x86, 0x7f, 0x02, 0x82, 0x0c, 0x84, 0x07,
0x86, 0x7f, 0x82, 0x12, 0x87, 0x7f, 0x06, 0x82, 0x12, 0x87, 0x7f, 0x06,
0x82, 0x24, 0x82, 0x78, 0x82, 0x24, 0x82, 0x78, 0x82, 0x24, 0x82, 0x78,
0x82, 0x16, 0x83, 0x04, 0x82, 0x07, 0x82, 0x76, 0x82, 0x16, 0x83, 0x04,
0x82, 0x07, 0x82, 0x70, 0x8f, 0x0d, 0x82, 0x12, 0x82, 0x6e, 0x8f, 0x0d,
0x82, 0x12, 0x82, 0x6e, 0x8f, 0x0b, 0x82, 0x09, 0x82, 0x0b, 0x82, 0x6c,
0x8f, 0x0b, 0x82, 0x09, 0x82, 0x0b, 0x82, 0x6c, 0x8f, 0x0b, 0x82, 0x09,
0x82, 0x0b, 0x82, 0x6c, 0x8f, 0x7f, 0x12, 0x8f, 0x7f, 0x0d, 0x98, 0x12,
0x82, 0x74, 0x98, 0x12, 0x82, 0x70, 0xa1, 0x7f, 0xa1, 0x7f, 0xa1, 0x7f,
0xa1, 0x7f, 0xa1, 0x7d, 0xa5, 0x7b, 0xa5, 0x7b, 0xa5, 0x7b, 0xa5, 0x7a,
0xa6, 0x78, 0x89, 0x02, 0x9f, 0x76, 0x89, 0x02, 0x9f, 0x76, 0xaa, 0x76,
0xaa, 0x76, 0x87, 0x02, 0xa1, 0x76, 0x87, 0x02, 0xa1, 0x76, 0x87, 0x02,
0xa1, 0x76, 0x87, 0x02, 0xa1, 0x76, 0x87, 0x02, 0xa1, 0x76, 0x87, 0x02,
0xa1, 0x76, 0x87, 0x02, 0xa1, 0x76, 0xaa, 0x76, 0xaa, 0x76, 0xaa, 0x76,
0x89, 0x02, 0x9f, 0x76, 0x89, 0x02, 0x9f, 0x79, 0xa5, 0x7b, 0xa5, 0x7b,
0xa5, 0x7b, 0x8b, 0x02, 0x98, 0x7b, 0x8b, 0x02, 0x98, 0x7d, 0xa1, 0x7f,
0xa1, 0x7f, 0xa1, 0x7f, 0xa1, 0x7f, 0xa1, 0x7f, 0x04, 0x98, 0x7f, 0x09,
0x98, 0x7f, 0x0e, 0x8f, 0x7f, 0x12, 0x8f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
0x7f, 0x06
};
static void faultsplash(const char *msg)
{
LCD_SetBacklight(100);
gfx_copy_region(
&display_screen,
0,
0,
160,
80,
GFX_RLE_MONO,
sizeof(faultsplash_rle),
faultsplash_rle
);
gfx_puts(&Font20, &display_screen, 80, 5, "Panic", 0xf800, 0xf800);
size_t len = strlen(msg);
char buf[15] = { 0 };
int offset = 34;
for (size_t i = 0; i < len; i += 14) {
strncpy(buf, &msg[i], 14);
gfx_puts(
&Font12,
&display_screen,
52,
offset,
buf,
0xc618,
0xc618
);
offset += 12;
}
gfx_update(&display_screen);
}