diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2020-11-24 15:15:11 -0700 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2020-11-24 15:22:42 -0700 |
commit | ecbcb2509f4b811bce0a56e07de9737d14815251 (patch) | |
tree | f96492fb6db5d26c133dc3ab2993a9df3f224ea2 /src | |
parent | 351ff7059a5bacb322664412a8c62ee4640b33bf (diff) | |
download | stm32l4-ecbcb2509f4b811bce0a56e07de9737d14815251.tar.gz stm32l4-ecbcb2509f4b811bce0a56e07de9737d14815251.tar.bz2 stm32l4-ecbcb2509f4b811bce0a56e07de9737d14815251.zip |
Add better logging capabilities, including the ability to panic.
Diffstat (limited to 'src')
-rw-r--r-- | src/kern/init.c | 60 | ||||
-rw-r--r-- | src/kern/log.c | 20 | ||||
-rw-r--r-- | src/kern/mem.c | 18 | ||||
-rw-r--r-- | src/kern/panic.c | 36 |
4 files changed, 113 insertions, 21 deletions
diff --git a/src/kern/init.c b/src/kern/init.c index 8f2d7e8..8885c09 100644 --- a/src/kern/init.c +++ b/src/kern/init.c @@ -20,6 +20,22 @@ extern uint32_t BSS_END; extern void (*INIT_ROUTINES_FLASH_START)(); extern void (*INIT_ROUTINES_FLASH_STOP)(); +extern uint32_t INIT_0_END; +extern uint32_t INIT_1_END; +extern uint32_t INIT_2_END; +extern uint32_t INIT_3_END; +extern uint32_t INIT_4_END; +extern uint32_t INIT_5_END; +extern uint32_t INIT_6_END; +extern uint32_t INIT_7_END; + +static _no_init init_level_t initlevel; + +init_level_t get_system_init_level() +{ + return initlevel; +} + init0() { /* Enable a higher clock speed. This is the first thing we do @@ -58,18 +74,52 @@ init3() SCB.vto_r = 0x08000000; } -/* - * Runs before main. Initializes the data and bss segments by loading them - * into memory. - */ -_Noreturn void on_reset() +void run_init_routines() { + void* init_boundaries[] = { + &INIT_0_END, + &INIT_1_END, + &INIT_2_END, + &INIT_3_END, + &INIT_4_END, + &INIT_5_END, + &INIT_6_END, + &INIT_7_END, + }; + void (**initfn)(); for (initfn = &INIT_ROUTINES_FLASH_START; initfn < &INIT_ROUTINES_FLASH_STOP; ++initfn) { + while (initfn == init_boundaries[initlevel] && initlevel < INIT_LEVEL_7) { + ++initlevel; + + if (initlevel > 2) { + klogf("[init%d]\n", initlevel); + } + } + (*initfn)(); } + while (initlevel < INIT_LEVEL_7) { + ++initlevel; + + klogf("[init%d]\n", initlevel); + } + + klogf("Initialization Routines Complete. Onto main()\n"); +} + +/* + * Runs before main. Initializes the data and bss segments by loading them + * into memory. + */ +_Noreturn void on_reset() +{ + initlevel = INIT_LEVEL_0; + + run_init_routines(); + /* Jump to main. */ main(); diff --git a/src/kern/log.c b/src/kern/log.c index ebc2cbe..c876759 100644 --- a/src/kern/log.c +++ b/src/kern/log.c @@ -26,7 +26,27 @@ void klogf(const char* fmt, ...) va_list l; va_start(l, fmt); + kvlogf(fmt, l); +} + +void kvlogf(const char* fmt, va_list l) +{ + usart_vprintf(&USART2, fmt, l); +} + +void kerr_vlogf(const char* fmt, va_list l) +{ + klogf("\x1b[01;31m[ERROR] "); usart_vprintf(&USART2, fmt, l); + klogf("\x1b[00m"); +} + +void kerr_logf(const char* fmt, ...) +{ + va_list l; + va_start(l, fmt); + + kerr_vlogf(fmt, l); } void setup_usart2(uint32_t baud_rate) diff --git a/src/kern/mem.c b/src/kern/mem.c index ac90f0d..eb4527e 100644 --- a/src/kern/mem.c +++ b/src/kern/mem.c @@ -1,7 +1,9 @@ #include "kern/mem.h" #include "arch.h" + #include "kern/common.h" +#include "kern/panic.h" #ifdef ARCH_STM32L4 /* Provide a definition for memset() when not provided for the @@ -146,22 +148,6 @@ static void coalesce(kalloc_node_t* cur) last_freed->size = ((uint8_t*)next_used - (last_freed->mem)) / 4; } -#ifdef FOR_TESTING -#include <assert.h> -#include <stdio.h> -void panic(const char* x) -{ - fprintf(stderr, "%s\n", x); - assert(0); -} -#else -void panic(const char* x) -{ - for (;;) - ; -} -#endif - void kfree(void* mem) { /* Like normal free(), do nothing on free'ing NULL */ diff --git a/src/kern/panic.c b/src/kern/panic.c new file mode 100644 index 0000000..8708456 --- /dev/null +++ b/src/kern/panic.c @@ -0,0 +1,36 @@ +#include "arch.h" +#include "kern/panic.h" +#include "kern/log.h" +#include "kern/init.h" +#include "arch/stm32l4xxx/peripherals/clock.h" +#include "kern/gpio/sysled.h" +#include "kern/gpio/gpio_manager.h" +#include "kern/delay.h" + +#include <stdarg.h> + +#ifdef ARCH_STM32L4 +_Noreturn void panic(const char* fmt, ...) +{ + + if (get_system_init_level() > INIT_LEVEL_2) { + va_list l; + va_start(l, fmt); + + kerr_logf("** Kernel Panic! **\n"); + kerr_vlogf(fmt, l); + + set_system_clock_MHz(4); /* reduce power usage while we do nothing. */ + for(;;); + } else { + set_system_clock_MHz(4); /* reduce power usage while we do nothing. */ + gpio_reserved_pin_t pin3 = get_sysled(); + for (;;) { + set_gpio_pin_high(pin3); + delay(100000); + set_gpio_pin_low(pin3); + delay(100000); + } + } +} +#endif |