From f9c5f6a2d698e316d34f5affcfbee0c2bc7b4e68 Mon Sep 17 00:00:00 2001 From: William Vinnicombe Date: Tue, 6 Feb 2024 17:33:59 +0000 Subject: [PATCH] Improve Arm Compiler 6 compatibility --- .../hardware_sync/include/hardware/sync.h | 6 ++++++ .../pico_platform/include/pico/platform.h | 13 +++++++++++-- src/rp2_common/pico_runtime/runtime.c | 6 ++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/rp2_common/hardware_sync/include/hardware/sync.h b/src/rp2_common/hardware_sync/include/hardware/sync.h index b15f36bc4..78e083f8f 100644 --- a/src/rp2_common/hardware_sync/include/hardware/sync.h +++ b/src/rp2_common/hardware_sync/include/hardware/sync.h @@ -149,9 +149,11 @@ __force_inline static void __wfi(void) { * The DMB (data memory barrier) acts as a memory barrier, all memory accesses prior to this * instruction will be observed before any explicit access after the instruction. */ +#ifndef __dmb __force_inline static void __dmb(void) { pico_default_asm_volatile("dmb" : : : "memory"); } +#endif /*! \brief Insert a DSB instruction in to the code path. * \ingroup hardware_sync @@ -160,9 +162,11 @@ __force_inline static void __dmb(void) { * memory barrier (DMB). The DSB operation completes when all explicit memory * accesses before this instruction complete. */ +#ifndef __dsb __force_inline static void __dsb(void) { pico_default_asm_volatile("dsb" : : : "memory"); } +#endif /*! \brief Insert a ISB instruction in to the code path. * \ingroup hardware_sync @@ -171,9 +175,11 @@ __force_inline static void __dsb(void) { * so that all instructions following the ISB are fetched from cache or memory again, after * the ISB instruction has been completed. */ +#ifndef __isb __force_inline static void __isb(void) { pico_default_asm_volatile("isb" ::: "memory"); } +#endif /*! \brief Acquire a memory fence * \ingroup hardware_sync diff --git a/src/rp2_common/pico_platform/include/pico/platform.h b/src/rp2_common/pico_platform/include/pico/platform.h index 64b5e969a..4978aa733 100644 --- a/src/rp2_common/pico_platform/include/pico/platform.h +++ b/src/rp2_common/pico_platform/include/pico/platform.h @@ -297,7 +297,9 @@ extern "C" { */ #define __no_inline_not_in_flash_func(func_name) __noinline __not_in_flash_func(func_name) +#ifndef __packed_aligned #define __packed_aligned __packed __aligned(4) +#endif /*! \brief Attribute to force inlining of a function regardless of optimization level * \ingroup pico_platform @@ -311,8 +313,10 @@ extern "C" { #if PICO_C_COMPILER_IS_GNU && (__GNUC__ <= 6 || (__GNUC__ == 7 && (__GNUC_MINOR__ < 3 || !defined(__cplusplus)))) #define __force_inline inline __always_inline #else +#ifndef __force_inline #define __force_inline __always_inline #endif +#endif /*! \brief Macro to determine the number of elements in an array * \ingroup pico_platform @@ -484,8 +488,13 @@ static __force_inline uint __get_current_exception(void) { return exception; } -#define WRAPPER_FUNC(x) __wrap_ ## x -#define REAL_FUNC(x) __real_ ## x +#if defined(__IS_COMPILER_ARM_COMPILER_6__) + #define WRAPPER_FUNC(__FUNC) $Sub$$##__FUNC + #define REAL_FUNC(__FUNC) $Super$$## __FUNC +#else + #define WRAPPER_FUNC(x) __wrap_ ## x + #define REAL_FUNC(x) __real_ ## x +#endif /*! \brief Helper method to busy-wait for at least the given number of cycles * \ingroup pico_platform diff --git a/src/rp2_common/pico_runtime/runtime.c b/src/rp2_common/pico_runtime/runtime.c index 144ace1bd..f39182e9d 100644 --- a/src/rp2_common/pico_runtime/runtime.c +++ b/src/rp2_common/pico_runtime/runtime.c @@ -90,6 +90,7 @@ void runtime_init(void) { RESETS_RESET_USBCTRL_BITS )); +#ifdef __preinit_array_start // pre-init runs really early since we need it even for memcpy and divide! // (basically anything in aeabi that uses bootrom) @@ -104,6 +105,7 @@ void runtime_init(void) { for (void (**p)(void) = &__preinit_array_start; p < &__preinit_array_end; ++p) { (*p)(); } +#endif // After calling preinit we have enough runtime to do the exciting maths // in clocks_init @@ -165,6 +167,7 @@ void runtime_init(void) { irq_init_priorities(); alarm_pool_init_default(); +#ifdef __init_array_start // Start and end points of the constructor list, // defined by the linker script. extern void (*__init_array_start)(void); @@ -176,6 +179,7 @@ void runtime_init(void) { for (void (**p)(void) = &__init_array_start; p < &__init_array_end; ++p) { (*p)(); } +#endif } @@ -189,6 +193,7 @@ void __attribute__((noreturn)) __attribute__((weak)) _exit(__unused int status) #endif } +#if defined(__clock_t_defined) || defined(_CLOCK_T_DECLARED) __attribute__((weak)) void *_sbrk(int incr) { extern char end; /* Set by linker. */ static char *heap_end; @@ -259,6 +264,7 @@ __attribute((weak)) int _kill(__unused pid_t pid, __unused int sig) { void exit(int status) { _exit(status); } +#endif // incorrect warning from GCC 6 GCC_Pragma("GCC diagnostic push")