From 9fdf87f7291fb4aa0fc2705d8f6d6e6bcf581a27 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Wed, 17 Feb 2021 14:54:46 -0600 Subject: [PATCH] panic in debug mode if sleep methods are called in an exception handler (unless PICO_ALLOW_SLEEP_IN_EXCEPTION is set) --- src/common/pico_time/time.c | 5 +++++ src/rp2_common/hardware_irq/irq.c | 1 - src/rp2_common/pico_platform/include/pico/platform.h | 6 ++++++ src/rp2_common/pico_runtime/runtime.c | 4 +--- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/common/pico_time/time.c b/src/common/pico_time/time.c index 32f11e6..33e66a4 100644 --- a/src/common/pico_time/time.c +++ b/src/common/pico_time/time.c @@ -325,6 +325,11 @@ static int64_t sev_callback(__unused alarm_id_t id, __unused void *user_data) { #endif void sleep_until(absolute_time_t t) { +#if PICO_ON_DEVICE && !PICO_ALLOW_SLEEP_IN_EXCEPTION && !defined(NDEBUG) + if (__get_current_exception()) { + panic("Attempted to sleep inside of an exception handler"); + } +#endif #if !PICO_TIME_DEFAULT_ALARM_POOL_DISABLED uint64_t t_us = to_us_since_boot(t); uint64_t t_before_us = t_us - PICO_TIME_SLEEP_OVERHEAD_ADJUST_US; diff --git a/src/rp2_common/hardware_irq/irq.c b/src/rp2_common/hardware_irq/irq.c index 54b1125..e47b68d 100644 --- a/src/rp2_common/hardware_irq/irq.c +++ b/src/rp2_common/hardware_irq/irq.c @@ -13,7 +13,6 @@ #include "pico/assert.h" extern void __unhandled_user_irq(void); -extern uint __get_current_exception(void); static inline irq_handler_t *get_vtable(void) { return (irq_handler_t *) scb_hw->vtor; diff --git a/src/rp2_common/pico_platform/include/pico/platform.h b/src/rp2_common/pico_platform/include/pico/platform.h index ef013d5..7da3103 100644 --- a/src/rp2_common/pico_platform/include/pico/platform.h +++ b/src/rp2_common/pico_platform/include/pico/platform.h @@ -163,6 +163,12 @@ return a; #define __check_type_compatible(type_a, type_b) static_assert(__builtin_types_compatible_p(type_a, type_b), __STRING(type_a) " is not compatible with " __STRING(type_b)); +/** + * Get the current exception level on this core + * \return the exception number if the CPU is handling an exception, or 0 otherwise + */ +extern uint __get_current_exception(void); + #ifdef __cplusplus } #endif diff --git a/src/rp2_common/pico_runtime/runtime.c b/src/rp2_common/pico_runtime/runtime.c index c6a5830..796284e 100644 --- a/src/rp2_common/pico_runtime/runtime.c +++ b/src/rp2_common/pico_runtime/runtime.c @@ -124,9 +124,7 @@ void runtime_init(void) { #endif #ifndef NDEBUG - uint32_t xpsr; - __asm volatile ("mrs %0, XPSR" : "=r" (xpsr)::); - if (xpsr & 0xffu) { + if (__get_current_exception()) { // crap; started in exception handler __asm ("bkpt #0"); }