Skip to content
Snippets Groups Projects
Commit 1b52e22d authored by dx's avatar dx
Browse files

Merge 'Add a panic() function'

See merge request !326
parents a9e1b238 0e5c6243
No related branches found
No related tags found
No related merge requests found
#ifndef FREERTOS_CONFIG_H #ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H
#define MXC_ASSERT_ENABLE
#include "mxc_assert.h"
#include "max32665.h" #include "max32665.h"
#include <assert.h>
/* CMSIS keeps a global updated with current system clock in Hz */ /* CMSIS keeps a global updated with current system clock in Hz */
#define configCPU_CLOCK_HZ ((unsigned long)96000000) #define configCPU_CLOCK_HZ ((unsigned long)96000000)
...@@ -69,7 +68,7 @@ ...@@ -69,7 +68,7 @@
#define xPortSysTickHandler SysTick_Handler #define xPortSysTickHandler SysTick_Handler
/* Assert */ /* Assert */
#define configASSERT(x) MXC_ASSERT(x) #define configASSERT(x) assert(x)
/* Tickless idle hooks */ /* Tickless idle hooks */
typedef uint32_t TickType_t; typedef uint32_t TickType_t;
......
...@@ -64,8 +64,7 @@ int main(void) ...@@ -64,8 +64,7 @@ int main(void)
NULL, NULL,
tskIDLE_PRIORITY + 3, tskIDLE_PRIORITY + 3,
NULL) != pdPASS) { NULL) != pdPASS) {
LOG_CRIT("startup", "Failed to create %s task!", "Serial"); panic("Failed to create %s task!", "Serial");
abort();
} }
/* PMIC */ /* PMIC */
...@@ -76,8 +75,7 @@ int main(void) ...@@ -76,8 +75,7 @@ int main(void)
NULL, NULL,
tskIDLE_PRIORITY + 4, tskIDLE_PRIORITY + 4,
NULL) != pdPASS) { NULL) != pdPASS) {
LOG_CRIT("startup", "Failed to create %s task!", "PMIC"); panic("Failed to create %s task!", "PMIC");
abort();
} }
/* BHI160 */ /* BHI160 */
...@@ -88,8 +86,7 @@ int main(void) ...@@ -88,8 +86,7 @@ int main(void)
NULL, NULL,
tskIDLE_PRIORITY + 1, tskIDLE_PRIORITY + 1,
NULL) != pdPASS) { NULL) != pdPASS) {
LOG_CRIT("startup", "Failed to create %s task!", "BHI160"); panic("Failed to create %s task!", "BHI160");
abort();
} }
/* MAX30001 */ /* MAX30001 */
...@@ -100,8 +97,7 @@ int main(void) ...@@ -100,8 +97,7 @@ int main(void)
NULL, NULL,
tskIDLE_PRIORITY + 1, tskIDLE_PRIORITY + 1,
NULL) != pdPASS) { NULL) != pdPASS) {
LOG_CRIT("startup", "Failed to create %s task!", "MAX30001"); panic("Failed to create %s task!", "MAX30001");
abort();
} }
/* API */ /* API */
if (xTaskCreate( if (xTaskCreate(
...@@ -111,12 +107,7 @@ int main(void) ...@@ -111,12 +107,7 @@ int main(void)
NULL, NULL,
tskIDLE_PRIORITY + 2, tskIDLE_PRIORITY + 2,
&dispatcher_task_id) != pdPASS) { &dispatcher_task_id) != pdPASS) {
LOG_CRIT( panic("Failed to create %s task!", "API Dispatcher");
"startup",
"Failed to create %s task!",
"API Dispatcher"
);
abort();
} }
/* BLE */ /* BLE */
...@@ -128,8 +119,7 @@ int main(void) ...@@ -128,8 +119,7 @@ int main(void)
NULL, NULL,
tskIDLE_PRIORITY + 3, tskIDLE_PRIORITY + 3,
NULL) != pdPASS) { NULL) != pdPASS) {
LOG_CRIT("startup", "Failed to create %s task!", "BLE"); panic("Failed to create %s task!", "BLE");
abort();
} }
} }
...@@ -141,8 +131,7 @@ int main(void) ...@@ -141,8 +131,7 @@ int main(void)
NULL, NULL,
tskIDLE_PRIORITY + 1, tskIDLE_PRIORITY + 1,
NULL) != pdPASS) { NULL) != pdPASS) {
LOG_CRIT("startup", "Failed to create %s task!", "LED"); panic("Failed to create %s task!", "LED");
abort();
} }
/* Lifecycle */ /* Lifecycle */
...@@ -153,8 +142,7 @@ int main(void) ...@@ -153,8 +142,7 @@ int main(void)
NULL, NULL,
tskIDLE_PRIORITY + 3, tskIDLE_PRIORITY + 3,
NULL) != pdPASS) { NULL) != pdPASS) {
LOG_CRIT("startup", "Failed to create %s task!", "Lifecycle"); panic("Failed to create %s task!", "Lifecycle");
abort();
} }
/* /*
...@@ -165,6 +153,5 @@ int main(void) ...@@ -165,6 +153,5 @@ int main(void)
LOG_DEBUG("startup", "Starting FreeRTOS ..."); LOG_DEBUG("startup", "Starting FreeRTOS ...");
vTaskStartScheduler(); vTaskStartScheduler();
LOG_CRIT("startup", "FreeRTOS did not start due to unknown error!"); panic("FreeRTOS did not start due to unknown error!");
abort();
} }
#include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
...@@ -259,14 +260,14 @@ bhi160_handle_packet(bhy_data_type_t data_type, bhy_data_generic_t *sensor_data) ...@@ -259,14 +260,14 @@ bhi160_handle_packet(bhy_data_type_t data_type, bhy_data_generic_t *sensor_data)
wakeup = true; wakeup = true;
/* fall through */ /* fall through */
case VS_ID_TIMESTAMP_MSW: 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; timestamp = sensor_data->data_scalar_u16.data << 16;
break; break;
case VS_ID_TIMESTAMP_LSW_WAKEUP: case VS_ID_TIMESTAMP_LSW_WAKEUP:
wakeup = true; wakeup = true;
/* fall through */ /* fall through */
case VS_ID_TIMESTAMP_LSW: 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) | timestamp = (timestamp & 0xFFFF0000) |
sensor_data->data_scalar_u16.data; sensor_data->data_scalar_u16.data;
break; break;
...@@ -303,7 +304,7 @@ bhi160_handle_packet(bhy_data_type_t data_type, bhy_data_generic_t *sensor_data) ...@@ -303,7 +304,7 @@ bhi160_handle_packet(bhy_data_type_t data_type, bhy_data_generic_t *sensor_data)
break; break;
} }
MXC_ASSERT(data_type == BHY_DATA_TYPE_VECTOR); assert(data_type == BHY_DATA_TYPE_VECTOR);
if (bhi160_streams[sensor_type].queue == NULL) { if (bhi160_streams[sensor_type].queue == NULL) {
break; break;
} }
......
...@@ -364,10 +364,7 @@ void vLifecycleTask(void *pvParameters) ...@@ -364,10 +364,7 @@ void vLifecycleTask(void *pvParameters)
core1_mutex = xSemaphoreCreateMutexStatic(&core1_mutex_data); core1_mutex = xSemaphoreCreateMutexStatic(&core1_mutex_data);
if (xSemaphoreTake(core1_mutex, 0) != pdTRUE) { if (xSemaphoreTake(core1_mutex, 0) != pdTRUE) {
LOG_CRIT( panic("lifecycle: Failed to acquire mutex after creation.");
"lifecycle", "Failed to acquire mutex after creation."
);
vTaskDelay(portMAX_DELAY);
} }
LOG_DEBUG("lifecycle", "Booting core 1 ..."); LOG_DEBUG("lifecycle", "Booting core 1 ...");
......
...@@ -14,6 +14,7 @@ module_sources = files( ...@@ -14,6 +14,7 @@ module_sources = files(
'light_sensor.c', 'light_sensor.c',
'log.c', 'log.c',
'max30001.c', 'max30001.c',
'panic.c',
'personal_state.c', 'personal_state.c',
'pmic.c', 'pmic.c',
'rtc.c', 'rtc.c',
......
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
/* ---------- Panic -------------------------------------------------------- */
void panic(const char *format, ...)
__attribute__((noreturn, format(printf, 1, 2)));
/* ---------- Dispatcher --------------------------------------------------- */ /* ---------- Dispatcher --------------------------------------------------- */
void vApiDispatcher(void *pvParameters); void vApiDispatcher(void *pvParameters);
void dispatcher_mutex_init(void); void dispatcher_mutex_init(void);
...@@ -31,6 +35,8 @@ void vSerialTask(void *pvParameters); ...@@ -31,6 +35,8 @@ void vSerialTask(void *pvParameters);
void serial_enqueue_char(char chr); void serial_enqueue_char(char chr);
void serial_flush(void); void serial_flush(void);
extern TaskHandle_t serial_task_id; 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 // For the eSetBit xTaskNotify task semaphore trigger
enum serial_notify{ enum serial_notify{
......
/*
* 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);
}
...@@ -46,6 +46,11 @@ void serial_init() ...@@ -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 * API-call to write a string. Output goes to both CDCACM and UART
*/ */
......
...@@ -117,5 +117,5 @@ void vApplicationGetTimerTaskMemory( ...@@ -117,5 +117,5 @@ void vApplicationGetTimerTaskMemory(
void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName) void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName)
{ {
LOG_CRIT("rtos", "Task \"%s\" overflowed stack!", pcTaskName); panic("Task \"%s\" overflowed stack!", pcTaskName);
} }
...@@ -224,7 +224,7 @@ void card10_poll(void) ...@@ -224,7 +224,7 @@ void card10_poll(void)
portexpander_poll(); portexpander_poll();
} }
void card10_reset(void) void __attribute__((noreturn)) card10_reset(void)
{ {
printf("Resetting ...\n"); printf("Resetting ...\n");
/* /*
...@@ -235,6 +235,9 @@ void card10_reset(void) ...@@ -235,6 +235,9 @@ void card10_reset(void)
__asm volatile("nop"); __asm volatile("nop");
} }
MXC_GCR->rstr0 = MXC_F_GCR_RSTR0_SYSTEM; MXC_GCR->rstr0 = MXC_F_GCR_RSTR0_SYSTEM;
while (1)
__WFI();
} }
void GPIO0_IRQHandler(void) void GPIO0_IRQHandler(void)
......
...@@ -15,5 +15,5 @@ void core1_start(void *isr); ...@@ -15,5 +15,5 @@ void core1_start(void *isr);
void core1_stop(void); void core1_stop(void);
void card10_poll(void); void card10_poll(void);
void card10_reset(void); void card10_reset(void) __attribute__((noreturn));
#endif #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment