diff --git a/core/lib/assert.c b/core/lib/assert.c index fcbed9743e..e8b27723d8 100644 --- a/core/lib/assert.c +++ b/core/lib/assert.c @@ -18,6 +18,7 @@ #include "assert.h" #include "architecture.h" #include "cpu.h" +#include "debug.h" #include "panic.h" #if IS_USED(MODULE_BACKTRACE) #include "backtrace.h" @@ -30,6 +31,7 @@ __NORETURN void _assert_failure(const char *file, unsigned line) printf("failed assertion. Backtrace:\n"); backtrace_print(); #endif + DEBUG_BREAKPOINT(1); core_panic(PANIC_ASSERT_FAIL, "FAILED ASSERTION."); } @@ -39,6 +41,7 @@ __NORETURN void _assert_panic(void) #if IS_USED(MODULE_BACKTRACE) backtrace_print(); #endif + DEBUG_BREAKPOINT(1); core_panic(PANIC_ASSERT_FAIL, "FAILED ASSERTION."); } diff --git a/core/lib/include/debug.h b/core/lib/include/debug.h index 4d93e3eee6..7c67b26155 100644 --- a/core/lib/include/debug.h +++ b/core/lib/include/debug.h @@ -59,6 +59,27 @@ extern "C" { #define DEBUG_PRINT(...) printf(__VA_ARGS__) #endif +/** + * @def DEBUG_BREAKPOINT + * + * @brief Set a debug breakpoint + * + * When `DEVELHELP` is enabled, this traps the CPU and allows to debug the + * program with e.g. `gdb`. + * Without `DEVELHELP` this turns into a no-op. + * + * @warning If no Debugger is attached, the CPU might get stuck here + * and consume a lot of power until reset. + * + * @param val Breakpoint context for debugger, usually ignored. + */ +#ifdef DEVELHELP +#include "architecture.h" +#define DEBUG_BREAKPOINT(val) ARCHITECTURE_BREAKPOINT(val) +#else +#define DEBUG_BREAKPOINT(val) (void)0 +#endif + /** * @name Debugging defines * @{ diff --git a/cpu/cortexm_common/include/architecture_arch.h b/cpu/cortexm_common/include/architecture_arch.h index a393f6db6b..8bb8897691 100644 --- a/cpu/cortexm_common/include/architecture_arch.h +++ b/cpu/cortexm_common/include/architecture_arch.h @@ -26,7 +26,8 @@ extern "C" { /* Doc is provided centrally in architecture.h, hide this from Doxygen */ #ifndef DOXYGEN -#define ARCHITECTURE_WORD_BITS (32U) +#define ARCHITECTURE_WORD_BITS (32U) +#define ARCHITECTURE_BREAKPOINT(value) __BKPT(value) #endif /* DOXYGEN */ #ifdef __cplusplus diff --git a/cpu/native/include/architecture_arch.h b/cpu/native/include/architecture_arch.h index ef3ebf2fa5..1a9f7ae06d 100644 --- a/cpu/native/include/architecture_arch.h +++ b/cpu/native/include/architecture_arch.h @@ -24,9 +24,17 @@ extern "C" { #endif +/** + * @brief raise SIGTRAP + * + * We must not include signal.h directly into RIOT application namespace. + */ +void native_breakpoint(void); + /* Doc is provided centrally in architecture.h, hide this from Doxygen */ #ifndef DOXYGEN #define ARCHITECTURE_WORD_BITS (32U) +#define ARCHITECTURE_BREAKPOINT(v) native_breakpoint() #endif /* DOXYGEN */ #ifdef __cplusplus diff --git a/cpu/native/native_cpu.c b/cpu/native/native_cpu.c index 7e0cf5aaa5..5e9e96875a 100644 --- a/cpu/native/native_cpu.c +++ b/cpu/native/native_cpu.c @@ -99,6 +99,11 @@ int thread_isr_stack_usage(void) return -1; } +void native_breakpoint(void) +{ + raise(SIGTRAP); +} + static inline void *align_stack(uintptr_t start, int *stacksize) { const size_t alignment = sizeof(uintptr_t); diff --git a/cpu/stm32/periph/dac.c b/cpu/stm32/periph/dac.c index 468bfa6c4a..c043269711 100644 --- a/cpu/stm32/periph/dac.c +++ b/cpu/stm32/periph/dac.c @@ -73,18 +73,15 @@ void dac_set(dac_t line, uint16_t value) { assert(line < DAC_NUMOF); - /* scale set value to 12-bit */ - value = (value >> 4); - -#ifdef DAC_DHR12R2_DACC2DHR +#ifdef DAC_DHR12L2_DACC2DHR if (dac_config[line].chan & 0x01) { - dev(line)->DHR12R2 = value; + dev(line)->DHR12L2 = value; } else { - dev(line)->DHR12R1 = value; + dev(line)->DHR12L1 = value; } #else - dev(line)->DHR12R1 = value; + dev(line)->DHR12L1 = value; #endif } diff --git a/sys/include/architecture.h b/sys/include/architecture.h index ebd7ce1c31..90f9febd6d 100644 --- a/sys/include/architecture.h +++ b/sys/include/architecture.h @@ -33,6 +33,19 @@ extern "C" { #endif +/** + * @brief Set a breakpoint + * @warning If no Debugger is attached, the CPU might get stuck here + * and consume a lot of power until reset. + * @param[in] value Context value for debugger, usually ignored. + */ +#ifndef ARCHITECTURE_BREAKPOINT +/* If no breakpoint instruction is defined, busy wait for debugger + * to attach and break to ease backtrace + */ +#define ARCHITECTURE_BREAKPOINT(value) do {} while (1) +#endif + /* Provide doxygen doc centrally, instead of in every architecture_arch.h */ #ifdef DOXYGEN /** diff --git a/tests/unittests/Makefile b/tests/unittests/Makefile index ea1caca504..2d3fb7472f 100644 --- a/tests/unittests/Makefile +++ b/tests/unittests/Makefile @@ -3,12 +3,14 @@ include ../Makefile.tests_common USEMODULE += embunit -ifeq (, $(filter tests-%, $(MAKECMDGOALS))) - # the $(dir) Makefile function leaves a trailing slash after the directory - # name, therefore we use patsubst instead. - UNIT_TESTS := $(patsubst %/Makefile,%,$(wildcard tests-*/Makefile)) -else - UNIT_TESTS := $(filter tests-%, $(MAKECMDGOALS)) +ifeq (, $(UNIT_TESTS)) + ifeq (, $(filter tests-%, $(MAKECMDGOALS))) + # the $(dir) Makefile function leaves a trailing slash after the directory + # name, therefore we use patsubst instead. + UNIT_TESTS := $(patsubst %/Makefile,%,$(wildcard tests-*/Makefile)) + else + UNIT_TESTS := $(filter tests-%, $(MAKECMDGOALS)) + endif endif DISABLE_MODULE += auto_init auto_init_%