diff --git a/epicardium/FreeRTOSConfig.h b/epicardium/FreeRTOSConfig.h index f1d3aa46915e9c4373d281a1a4ab37707a918bf9..b731f6a9abdee7556f073936d86aba649e72a8d1 100644 --- a/epicardium/FreeRTOSConfig.h +++ b/epicardium/FreeRTOSConfig.h @@ -1,11 +1,10 @@ #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H -#define MXC_ASSERT_ENABLE -#include "mxc_assert.h" - #include "max32665.h" +#include <assert.h> + /* CMSIS keeps a global updated with current system clock in Hz */ #define configCPU_CLOCK_HZ ((unsigned long)96000000) @@ -69,7 +68,7 @@ #define xPortSysTickHandler SysTick_Handler /* Assert */ -#define configASSERT(x) MXC_ASSERT(x) +#define configASSERT(x) assert(x) /* Tickless idle hooks */ typedef uint32_t TickType_t; diff --git a/epicardium/main.c b/epicardium/main.c index 95319203b53b33b0c099d0b7ecaa50f3ea3e50d8..3dbd4bbf5a0ac00f0712bfca66854c8d682c3f81 100644 --- a/epicardium/main.c +++ b/epicardium/main.c @@ -64,8 +64,7 @@ int main(void) NULL, tskIDLE_PRIORITY + 3, NULL) != pdPASS) { - LOG_CRIT("startup", "Failed to create %s task!", "Serial"); - abort(); + panic("Failed to create %s task!", "Serial"); } /* PMIC */ @@ -76,8 +75,7 @@ int main(void) NULL, tskIDLE_PRIORITY + 4, NULL) != pdPASS) { - LOG_CRIT("startup", "Failed to create %s task!", "PMIC"); - abort(); + panic("Failed to create %s task!", "PMIC"); } /* BHI160 */ @@ -88,8 +86,7 @@ int main(void) NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) { - LOG_CRIT("startup", "Failed to create %s task!", "BHI160"); - abort(); + panic("Failed to create %s task!", "BHI160"); } /* MAX30001 */ @@ -100,8 +97,7 @@ int main(void) NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) { - LOG_CRIT("startup", "Failed to create %s task!", "MAX30001"); - abort(); + panic("Failed to create %s task!", "MAX30001"); } /* API */ if (xTaskCreate( @@ -111,12 +107,7 @@ int main(void) NULL, tskIDLE_PRIORITY + 2, &dispatcher_task_id) != pdPASS) { - LOG_CRIT( - "startup", - "Failed to create %s task!", - "API Dispatcher" - ); - abort(); + panic("Failed to create %s task!", "API Dispatcher"); } /* BLE */ @@ -128,8 +119,7 @@ int main(void) NULL, tskIDLE_PRIORITY + 3, NULL) != pdPASS) { - LOG_CRIT("startup", "Failed to create %s task!", "BLE"); - abort(); + panic("Failed to create %s task!", "BLE"); } } @@ -141,8 +131,7 @@ int main(void) NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) { - LOG_CRIT("startup", "Failed to create %s task!", "LED"); - abort(); + panic("Failed to create %s task!", "LED"); } /* Lifecycle */ @@ -153,8 +142,7 @@ int main(void) NULL, tskIDLE_PRIORITY + 3, NULL) != pdPASS) { - LOG_CRIT("startup", "Failed to create %s task!", "Lifecycle"); - abort(); + panic("Failed to create %s task!", "Lifecycle"); } /* @@ -165,6 +153,5 @@ int main(void) LOG_DEBUG("startup", "Starting FreeRTOS ..."); vTaskStartScheduler(); - LOG_CRIT("startup", "FreeRTOS did not start due to unknown error!"); - abort(); + panic("FreeRTOS did not start due to unknown error!"); } diff --git a/epicardium/modules/bhi.c b/epicardium/modules/bhi.c index a40a73eb64a6503d47319c9bc25603f766e822cd..b88e1dc217d087e93d286a488a81ccef3cac619c 100644 --- a/epicardium/modules/bhi.c +++ b/epicardium/modules/bhi.c @@ -1,3 +1,4 @@ +#include <assert.h> #include <stdio.h> #include <string.h> @@ -259,14 +260,14 @@ bhi160_handle_packet(bhy_data_type_t data_type, bhy_data_generic_t *sensor_data) wakeup = true; /* fall through */ case VS_ID_TIMESTAMP_MSW: - MXC_ASSERT(data_type == BHY_DATA_TYPE_SCALAR_U16); + assert(data_type == BHY_DATA_TYPE_SCALAR_U16); timestamp = sensor_data->data_scalar_u16.data << 16; break; case VS_ID_TIMESTAMP_LSW_WAKEUP: wakeup = true; /* fall through */ case VS_ID_TIMESTAMP_LSW: - MXC_ASSERT(data_type == BHY_DATA_TYPE_SCALAR_U16); + assert(data_type == BHY_DATA_TYPE_SCALAR_U16); timestamp = (timestamp & 0xFFFF0000) | sensor_data->data_scalar_u16.data; break; @@ -303,7 +304,7 @@ bhi160_handle_packet(bhy_data_type_t data_type, bhy_data_generic_t *sensor_data) break; } - MXC_ASSERT(data_type == BHY_DATA_TYPE_VECTOR); + assert(data_type == BHY_DATA_TYPE_VECTOR); if (bhi160_streams[sensor_type].queue == NULL) { break; } diff --git a/epicardium/modules/lifecycle.c b/epicardium/modules/lifecycle.c index 650664d2e97ee15ecbd35199e176ded925a78bfb..a1f8627aa53d648bc67be12455052d6a19352910 100644 --- a/epicardium/modules/lifecycle.c +++ b/epicardium/modules/lifecycle.c @@ -364,10 +364,7 @@ void vLifecycleTask(void *pvParameters) core1_mutex = xSemaphoreCreateMutexStatic(&core1_mutex_data); if (xSemaphoreTake(core1_mutex, 0) != pdTRUE) { - LOG_CRIT( - "lifecycle", "Failed to acquire mutex after creation." - ); - vTaskDelay(portMAX_DELAY); + panic("lifecycle: Failed to acquire mutex after creation."); } LOG_DEBUG("lifecycle", "Booting core 1 ..."); 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 d5087864ae30ea1e4797abb106ba634b58280d4f..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); @@ -31,6 +35,8 @@ void vSerialTask(void *pvParameters); void serial_enqueue_char(char chr); void serial_flush(void); extern TaskHandle_t serial_task_id; +/* Turn off the print queue and do prints synchroneous from now on. */ +void serial_return_to_synchronous(); // For the eSetBit xTaskNotify task semaphore trigger enum serial_notify{ diff --git a/epicardium/modules/panic.c b/epicardium/modules/panic.c new file mode 100644 index 0000000000000000000000000000000000000000..aa27b4de5ae7a856ed6beee6e8cc29cdab43e1bf --- /dev/null +++ b/epicardium/modules/panic.c @@ -0,0 +1,76 @@ +/* + * 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(); +} + +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); +} diff --git a/epicardium/modules/serial.c b/epicardium/modules/serial.c index 396d628dba562d8017600d23ec57df7ffaa64ea4..ef5b65edda24b9ce828afcec18cb84f2ff7f27ef 100644 --- a/epicardium/modules/serial.c +++ b/epicardium/modules/serial.c @@ -46,6 +46,11 @@ void serial_init() ); } +void serial_return_to_synchronous() +{ + write_stream_buffer = NULL; +} + /* * API-call to write a string. Output goes to both CDCACM and UART */ diff --git a/epicardium/support.c b/epicardium/support.c index e6925203767dc84ddc44e7c56c9e932f8464f4a1..ac58cf03170eb09b1dc96b0a66b036a155bdc73f 100644 --- a/epicardium/support.c +++ b/epicardium/support.c @@ -117,5 +117,5 @@ void vApplicationGetTimerTaskMemory( void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName) { - LOG_CRIT("rtos", "Task \"%s\" overflowed stack!", pcTaskName); + panic("Task \"%s\" overflowed stack!", pcTaskName); } diff --git a/lib/card10/card10.c b/lib/card10/card10.c index 09cc44ff293b8001d7121be3b22b8939bc9fd0e8..43361ef06fbf76323516b68e5fdead7f7b9febd9 100644 --- a/lib/card10/card10.c +++ b/lib/card10/card10.c @@ -224,7 +224,7 @@ void card10_poll(void) portexpander_poll(); } -void card10_reset(void) +void __attribute__((noreturn)) card10_reset(void) { printf("Resetting ...\n"); /* @@ -235,6 +235,9 @@ void card10_reset(void) __asm volatile("nop"); } MXC_GCR->rstr0 = MXC_F_GCR_RSTR0_SYSTEM; + + while (1) + __WFI(); } void GPIO0_IRQHandler(void) diff --git a/lib/card10/card10.h b/lib/card10/card10.h index fc90fe67f47527cbdbcf2a0b30a9c9d53d70d3df..192058f02a76361323e10c50d2e20f6a5a26f427 100644 --- a/lib/card10/card10.h +++ b/lib/card10/card10.h @@ -15,5 +15,5 @@ void core1_start(void *isr); void core1_stop(void); void card10_poll(void); -void card10_reset(void); +void card10_reset(void) __attribute__((noreturn)); #endif