stm32/boardctrl: Allow boards to override fatal-error handler.

To override it a board must define MICROPY_BOARD_FATAL_ERROR to a function
that takes a string message and does not return.

Signed-off-by: Damien George <damien@micropython.org>
pull/8873/head
Damien George 2022-07-06 21:26:42 +10:00
rodzic 9f8087b448
commit 9af6a275dd
9 zmienionych plików z 51 dodań i 51 usunięć

Wyświetl plik

@ -24,6 +24,8 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include <string.h>
#include "py/runtime.h" #include "py/runtime.h"
#include "py/objstr.h" #include "py/objstr.h"
#include "py/mphal.h" #include "py/mphal.h"
@ -33,6 +35,26 @@
#include "led.h" #include "led.h"
#include "usrsw.h" #include "usrsw.h"
NORETURN void boardctrl_fatal_error(const char *msg) {
for (volatile uint delay = 0; delay < 10000000; delay++) {
}
led_state(1, 1);
led_state(2, 1);
led_state(3, 1);
led_state(4, 1);
mp_hal_stdout_tx_strn("\nFATAL ERROR:\n", 14);
mp_hal_stdout_tx_strn(msg, strlen(msg));
for (uint i = 0;;) {
led_toggle(((i++) & 3) + 1);
for (volatile uint delay = 0; delay < 10000000; delay++) {
}
if (i >= 16) {
// to conserve power
__WFI();
}
}
}
STATIC void flash_error(int n) { STATIC void flash_error(int n) {
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
led_state(PYB_LED_RED, 1); led_state(PYB_LED_RED, 1);

Wyświetl plik

@ -33,6 +33,10 @@
#define MICROPY_BOARD_PENDSV_ENTRIES #define MICROPY_BOARD_PENDSV_ENTRIES
#endif #endif
#ifndef MICROPY_BOARD_FATAL_ERROR
#define MICROPY_BOARD_FATAL_ERROR boardctrl_fatal_error
#endif
#ifndef MICROPY_BOARD_STARTUP #ifndef MICROPY_BOARD_STARTUP
#define MICROPY_BOARD_STARTUP powerctrl_check_enter_bootloader #define MICROPY_BOARD_STARTUP powerctrl_check_enter_bootloader
#endif #endif
@ -110,6 +114,7 @@ typedef struct _boardctrl_state_t {
bool log_soft_reset; bool log_soft_reset;
} boardctrl_state_t; } boardctrl_state_t;
NORETURN void boardctrl_fatal_error(const char *msg);
void boardctrl_maybe_enter_mboot(size_t n_args, const void *args); void boardctrl_maybe_enter_mboot(size_t n_args, const void *args);
void boardctrl_before_soft_reset_loop(boardctrl_state_t *state); void boardctrl_before_soft_reset_loop(boardctrl_state_t *state);
void boardctrl_top_soft_reset_loop(boardctrl_state_t *state); void boardctrl_top_soft_reset_loop(boardctrl_state_t *state);

Wyświetl plik

@ -97,41 +97,21 @@ STATIC pyb_uart_obj_t pyb_uart_repl_obj;
STATIC uint8_t pyb_uart_repl_rxbuf[MICROPY_HW_UART_REPL_RXBUF]; STATIC uint8_t pyb_uart_repl_rxbuf[MICROPY_HW_UART_REPL_RXBUF];
#endif #endif
void NORETURN __fatal_error(const char *msg) {
for (volatile uint delay = 0; delay < 10000000; delay++) {
}
led_state(1, 1);
led_state(2, 1);
led_state(3, 1);
led_state(4, 1);
mp_hal_stdout_tx_strn("\nFATAL ERROR:\n", 14);
mp_hal_stdout_tx_strn(msg, strlen(msg));
for (uint i = 0;;) {
led_toggle(((i++) & 3) + 1);
for (volatile uint delay = 0; delay < 10000000; delay++) {
}
if (i >= 16) {
// to conserve power
__WFI();
}
}
}
void nlr_jump_fail(void *val) { void nlr_jump_fail(void *val) {
printf("FATAL: uncaught exception %p\n", val); printf("FATAL: uncaught exception %p\n", val);
mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(val)); mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(val));
__fatal_error(""); MICROPY_BOARD_FATAL_ERROR("");
} }
void abort(void) { void abort(void) {
__fatal_error("abort"); MICROPY_BOARD_FATAL_ERROR("abort");
} }
#ifndef NDEBUG #ifndef NDEBUG
void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) { void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) {
(void)func; (void)func;
printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line); printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
__fatal_error(""); MICROPY_BOARD_FATAL_ERROR("");
} }
#endif #endif

Wyświetl plik

@ -339,8 +339,7 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
if (ret == -MP_EINVAL) { if (ret == -MP_EINVAL) {
mp_raise_ValueError(MP_ERROR_TEXT("invalid freq")); mp_raise_ValueError(MP_ERROR_TEXT("invalid freq"));
} else if (ret < 0) { } else if (ret < 0) {
void NORETURN __fatal_error(const char *msg); MICROPY_BOARD_FATAL_ERROR("can't change freq");
__fatal_error("can't change freq");
} }
return mp_const_none; return mp_const_none;
#endif #endif

Wyświetl plik

@ -28,6 +28,7 @@
#include <stdio.h> #include <stdio.h>
#include "py/obj.h" #include "py/obj.h"
#include "boardctrl.h"
#include "gccollect.h" #include "gccollect.h"
#include "irq.h" #include "irq.h"
#include "pybthread.h" #include "pybthread.h"
@ -42,8 +43,6 @@
#define RAISE_IRQ_PRI() raise_irq_pri(IRQ_PRI_PENDSV) #define RAISE_IRQ_PRI() raise_irq_pri(IRQ_PRI_PENDSV)
#define RESTORE_IRQ_PRI(state) restore_irq_pri(state) #define RESTORE_IRQ_PRI(state) restore_irq_pri(state)
extern void __fatal_error(const char *);
volatile int pyb_thread_enabled; volatile int pyb_thread_enabled;
pyb_thread_t *volatile pyb_thread_all; pyb_thread_t *volatile pyb_thread_all;
pyb_thread_t *volatile pyb_thread_cur; pyb_thread_t *volatile pyb_thread_cur;
@ -57,7 +56,7 @@ static inline void pyb_thread_add_to_runable(pyb_thread_t *thread) {
static inline void pyb_thread_remove_from_runable(pyb_thread_t *thread) { static inline void pyb_thread_remove_from_runable(pyb_thread_t *thread) {
if (thread->run_next == thread) { if (thread->run_next == thread) {
__fatal_error("deadlock"); MICROPY_BOARD_FATAL_ERROR("deadlock");
} }
thread->run_prev->run_next = thread->run_next; thread->run_prev->run_next = thread->run_next;
thread->run_next->run_prev = thread->run_prev; thread->run_next->run_prev = thread->run_prev;
@ -112,7 +111,7 @@ STATIC void pyb_thread_terminate(void) {
SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
enable_irq(irq_state); enable_irq(irq_state);
// should not return // should not return
__fatal_error("could not terminate"); MICROPY_BOARD_FATAL_ERROR("could not terminate");
} }
uint32_t pyb_thread_new(pyb_thread_t *thread, void *stack, size_t stack_len, void *entry, void *arg) { uint32_t pyb_thread_new(pyb_thread_t *thread, void *stack, size_t stack_len, void *entry, void *arg) {

Wyświetl plik

@ -50,7 +50,6 @@
#ifdef FMC_SDRAM_BANK #ifdef FMC_SDRAM_BANK
static void sdram_init_seq(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *command); static void sdram_init_seq(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *command);
extern void __fatal_error(const char *msg);
bool sdram_init(void) { bool sdram_init(void) {
SDRAM_HandleTypeDef hsdram; SDRAM_HandleTypeDef hsdram;
@ -325,7 +324,7 @@ bool __attribute__((optimize("Os"))) sdram_test(bool exhaustive) {
snprintf(error_buffer, sizeof(error_buffer), snprintf(error_buffer, sizeof(error_buffer),
"Data bus test failed at 0x%p expected 0x%x found 0x%lx", "Data bus test failed at 0x%p expected 0x%x found 0x%lx",
&mem_base[0], (1 << i), ((volatile uint32_t *)mem_base)[0]); &mem_base[0], (1 << i), ((volatile uint32_t *)mem_base)[0]);
__fatal_error(error_buffer); MICROPY_BOARD_FATAL_ERROR(error_buffer);
#endif #endif
return false; return false;
} }
@ -340,7 +339,7 @@ bool __attribute__((optimize("Os"))) sdram_test(bool exhaustive) {
snprintf(error_buffer, sizeof(error_buffer), snprintf(error_buffer, sizeof(error_buffer),
"Address bus test failed at 0x%p expected 0x%x found 0x%x", "Address bus test failed at 0x%p expected 0x%x found 0x%x",
&mem_base[i], pattern, mem_base[i]); &mem_base[i], pattern, mem_base[i]);
__fatal_error(error_buffer); MICROPY_BOARD_FATAL_ERROR(error_buffer);
#endif #endif
return false; return false;
} }
@ -355,7 +354,7 @@ bool __attribute__((optimize("Os"))) sdram_test(bool exhaustive) {
snprintf(error_buffer, sizeof(error_buffer), snprintf(error_buffer, sizeof(error_buffer),
"Address bus overlap at 0x%p expected 0x%x found 0x%x", "Address bus overlap at 0x%p expected 0x%x found 0x%x",
&mem_base[i], pattern, mem_base[i]); &mem_base[i], pattern, mem_base[i]);
__fatal_error(error_buffer); MICROPY_BOARD_FATAL_ERROR(error_buffer);
#endif #endif
return false; return false;
} }
@ -376,7 +375,7 @@ bool __attribute__((optimize("Os"))) sdram_test(bool exhaustive) {
snprintf(error_buffer, sizeof(error_buffer), snprintf(error_buffer, sizeof(error_buffer),
"Address bus slow test failed at 0x%p expected 0x%x found 0x%x", "Address bus slow test failed at 0x%p expected 0x%x found 0x%x",
&mem_base[i], ((i % 2) ? pattern : antipattern), mem_base[i]); &mem_base[i], ((i % 2) ? pattern : antipattern), mem_base[i]);
__fatal_error(error_buffer); MICROPY_BOARD_FATAL_ERROR(error_buffer);
#endif #endif
return false; return false;
} }

Wyświetl plik

@ -83,7 +83,6 @@
#include "i2c.h" #include "i2c.h"
#include "usb.h" #include "usb.h"
extern void __fatal_error(const char *);
#if defined(MICROPY_HW_USB_FS) #if defined(MICROPY_HW_USB_FS)
extern PCD_HandleTypeDef pcd_fs_handle; extern PCD_HandleTypeDef pcd_fs_handle;
#endif #endif
@ -192,7 +191,7 @@ void HardFault_C_Handler(ExceptionRegisters_t *regs) {
/* Go to infinite loop when Hard Fault exception occurs */ /* Go to infinite loop when Hard Fault exception occurs */
while (1) { while (1) {
__fatal_error("HardFault"); MICROPY_BOARD_FATAL_ERROR("HardFault");
} }
} }
@ -246,7 +245,7 @@ void NMI_Handler(void) {
void MemManage_Handler(void) { void MemManage_Handler(void) {
/* Go to infinite loop when Memory Manage exception occurs */ /* Go to infinite loop when Memory Manage exception occurs */
while (1) { while (1) {
__fatal_error("MemManage"); MICROPY_BOARD_FATAL_ERROR("MemManage");
} }
} }
@ -258,7 +257,7 @@ void MemManage_Handler(void) {
void BusFault_Handler(void) { void BusFault_Handler(void) {
/* Go to infinite loop when Bus Fault exception occurs */ /* Go to infinite loop when Bus Fault exception occurs */
while (1) { while (1) {
__fatal_error("BusFault"); MICROPY_BOARD_FATAL_ERROR("BusFault");
} }
} }
@ -270,7 +269,7 @@ void BusFault_Handler(void) {
void UsageFault_Handler(void) { void UsageFault_Handler(void) {
/* Go to infinite loop when Usage Fault exception occurs */ /* Go to infinite loop when Usage Fault exception occurs */
while (1) { while (1) {
__fatal_error("UsageFault"); MICROPY_BOARD_FATAL_ERROR("UsageFault");
} }
} }

Wyświetl plik

@ -76,12 +76,11 @@
*/ */
#include "py/mphal.h" #include "py/mphal.h"
#include "boardctrl.h"
#include "powerctrl.h" #include "powerctrl.h"
#if defined(STM32F4) || defined(STM32F7) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) #if defined(STM32F4) || defined(STM32F7) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4)
void __fatal_error(const char *msg);
/** /**
* @brief System Clock Configuration * @brief System Clock Configuration
* *
@ -390,7 +389,7 @@ MP_WEAK void SystemClock_Config(void) {
#endif #endif
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
__fatal_error("HAL_RCC_OscConfig"); MICROPY_BOARD_FATAL_ERROR("HAL_RCC_OscConfig");
} }
#if defined(MICROPY_HW_CLK_PLL2M) #if defined(MICROPY_HW_CLK_PLL2M)
@ -478,20 +477,20 @@ MP_WEAK void SystemClock_Config(void) {
#endif #endif
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
__fatal_error("HAL_RCCEx_PeriphCLKConfig"); MICROPY_BOARD_FATAL_ERROR("HAL_RCCEx_PeriphCLKConfig");
} }
#endif // defined(STM32H7) #endif // defined(STM32H7)
#if defined(STM32F7) #if defined(STM32F7)
/* Activate the OverDrive to reach the 200 MHz Frequency */ /* Activate the OverDrive to reach the 200 MHz Frequency */
if (HAL_PWREx_EnableOverDrive() != HAL_OK) { if (HAL_PWREx_EnableOverDrive() != HAL_OK) {
__fatal_error("HAL_PWREx_EnableOverDrive"); MICROPY_BOARD_FATAL_ERROR("HAL_PWREx_EnableOverDrive");
} }
#endif #endif
#if defined(STM32G4) #if defined(STM32G4)
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_8) != HAL_OK) { if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_8) != HAL_OK) {
__fatal_error("HAL_RCC_ClockConfig"); MICROPY_BOARD_FATAL_ERROR("HAL_RCC_ClockConfig");
} }
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_LPUART1 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_LPUART1
| RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC12 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC12
@ -503,14 +502,14 @@ MP_WEAK void SystemClock_Config(void) {
PeriphClkInitStruct.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK; PeriphClkInitStruct.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
__fatal_error("HAL_RCCEx_PeriphCLKConfig"); MICROPY_BOARD_FATAL_ERROR("HAL_RCCEx_PeriphCLKConfig");
} }
#else #else
uint32_t vco_out = RCC_OscInitStruct.PLL.PLLN * (MICROPY_HW_CLK_VALUE / 1000000) / RCC_OscInitStruct.PLL.PLLM; uint32_t vco_out = RCC_OscInitStruct.PLL.PLLN * (MICROPY_HW_CLK_VALUE / 1000000) / RCC_OscInitStruct.PLL.PLLM;
uint32_t sysclk_mhz = vco_out / RCC_OscInitStruct.PLL.PLLP; uint32_t sysclk_mhz = vco_out / RCC_OscInitStruct.PLL.PLLP;
bool need_pll48 = vco_out % 48 != 0; bool need_pll48 = vco_out % 48 != 0;
if (powerctrl_rcc_clock_config_pll(&RCC_ClkInitStruct, sysclk_mhz, need_pll48) != 0) { if (powerctrl_rcc_clock_config_pll(&RCC_ClkInitStruct, sysclk_mhz, need_pll48) != 0) {
__fatal_error("HAL_RCC_ClockConfig"); MICROPY_BOARD_FATAL_ERROR("HAL_RCC_ClockConfig");
} }
#endif #endif
@ -572,7 +571,7 @@ MP_WEAK void SystemClock_Config(void) {
| RCC_PLLSAI1_ADC1CLK; | RCC_PLLSAI1_ADC1CLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
__fatal_error("HAL_RCCEx_PeriphCLKConfig"); MICROPY_BOARD_FATAL_ERROR("HAL_RCCEx_PeriphCLKConfig");
} }
__PWR_CLK_ENABLE(); __PWR_CLK_ENABLE();

Wyświetl plik

@ -112,8 +112,6 @@
#endif #endif
extern void NORETURN __fatal_error(const char *msg);
typedef struct _pyb_uart_irq_map_t { typedef struct _pyb_uart_irq_map_t {
uint16_t irq_en; uint16_t irq_en;
uint16_t flag; uint16_t flag;
@ -152,7 +150,7 @@ void uart_init0(void) {
RCC_PeriphClkInit.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2; RCC_PeriphClkInit.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;
RCC_PeriphClkInit.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1; RCC_PeriphClkInit.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != HAL_OK) { if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != HAL_OK) {
__fatal_error("HAL_RCCEx_PeriphCLKConfig"); MICROPY_BOARD_FATAL_ERROR("HAL_RCCEx_PeriphCLKConfig");
} }
#endif #endif
} }