mirror of
https://github.com/raspberrypi/pico-sdk.git
synced 2025-12-10 07:14:36 +01:00
84 lines
2.4 KiB
C
84 lines
2.4 KiB
C
/*
|
|
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <sys/cdefs.h>
|
|
#include <unistd.h>
|
|
#include "pico.h"
|
|
|
|
#if LIB_PICO_PRINTF_PICO
|
|
#include "pico/printf.h"
|
|
#else
|
|
#define weak_raw_printf printf
|
|
#define weak_raw_vprintf vprintf
|
|
#endif
|
|
|
|
void __attribute__((noreturn)) panic_unsupported(void) {
|
|
panic("not supported");
|
|
}
|
|
|
|
// PICO_CONFIG: PICO_PANIC_FUNCTION, Name of a function to use in place of the stock panic function or empty string to simply breakpoint on panic, group=pico_runtime
|
|
// note the default is not "panic" it is undefined
|
|
#ifdef PICO_PANIC_FUNCTION
|
|
#define PICO_PANIC_FUNCTION_EMPTY (__CONCAT(PICO_PANIC_FUNCTION, 1) == 1)
|
|
#if !PICO_PANIC_FUNCTION_EMPTY
|
|
extern void __attribute__((noreturn)) __printflike(1, 0) PICO_PANIC_FUNCTION(__unused const char *fmt, ...);
|
|
#endif
|
|
// Use a forwarding method here as it is a little simpler than renaming the symbol as it is used from assembler
|
|
void __attribute__((naked, noreturn)) __printflike(1, 0) panic(__unused const char *fmt, ...) {
|
|
// if you get an undefined reference here, you didn't define your PICO_PANIC_FUNCTION!
|
|
pico_default_asm (
|
|
#ifdef __riscv
|
|
|
|
#if !PICO_PANIC_FUNCTION_EMPTY
|
|
"jal " __XSTRING(PICO_PANIC_FUNCTION) "\n"
|
|
#endif
|
|
"1: ebreak\n"
|
|
"j 1b\n"
|
|
|
|
#else
|
|
|
|
"push {lr}\n"
|
|
#if !PICO_PANIC_FUNCTION_EMPTY
|
|
"bl " __XSTRING(PICO_PANIC_FUNCTION) "\n"
|
|
#endif
|
|
"1: bkpt #0\n"
|
|
"b 1b\n" // loop for ever as we are no return
|
|
|
|
#endif
|
|
:
|
|
:
|
|
:
|
|
);
|
|
}
|
|
#else
|
|
// todo consider making this try harder to output if we panic early
|
|
// right now, print mutex may be uninitialised (in which case it deadlocks - although after printing "PANIC")
|
|
// more importantly there may be no stdout/UART initialized yet
|
|
// todo we may want to think about where we print panic messages to; writing to USB appears to work
|
|
// though it doesn't seem like we can expect it to... fine for now
|
|
void __attribute__((noreturn)) __printflike(1, 0) panic(const char *fmt, ...) {
|
|
puts("\n*** PANIC ***\n");
|
|
if (fmt) {
|
|
#if LIB_PICO_PRINTF_NONE
|
|
puts(fmt);
|
|
#else
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
#if PICO_PRINTF_ALWAYS_INCLUDED
|
|
vprintf(fmt, args);
|
|
#else
|
|
weak_raw_vprintf(fmt, args);
|
|
#endif
|
|
va_end(args);
|
|
puts("\n");
|
|
#endif
|
|
}
|
|
|
|
_exit(1);
|
|
}
|
|
#endif
|