From 1ac90374e3af56326269acd01829ef682f2c0e76 Mon Sep 17 00:00:00 2001 From: Graham Sanderson Date: Wed, 1 Mar 2023 15:10:18 -0600 Subject: [PATCH] Various small fixes towards building with other compilers (#1285) * Fix various non-GCC warnings (no effect on GCC) * Reduce use of typeof since non GCC compilers may not support it * Introduce PICO_C_COMPILER_IS_GNU, PICO_C_COMPILER_IS_CLANG, PICO_C_COMPILER_IS_IAR to CMake as if (CMAKE_C_COMPILER_ID STREQUAL "xxx") is a bit verbose * Use "unified_asm" macro for all inline asm (it is "volatile __asm" on GNU with a .syntex unified) * Use NOLOAD instead of COPY in linker scripts (arguably more correct anyway) * Use the same style for setting _etext in all 4 linker scripts (to the beginning of .data). Clang aligns .data on a 16 byte boundary. Note ideally we'd add a new symbol __data_source, however that would break backwards compatibility with existing user linker scripts * Use "a" for .stack, .heap sections because clang complains otherwise, and they are explicitly NOLOAD anyway * Avoid duplicating __sev, __wfe, __wfi which Clang sometimes seems to provide as built-ins * Add missing kitchen_sink_blocked_ram binary * Allow build with LLVM Embedded Toolchain Form ARM v 14.0.0 (unsupported atm) --- CMakeLists.txt | 7 ++ cmake/preload/toolchains/pico_arm_clang.cmake | 10 +- .../include/pico/binary_info/code.h | 8 +- src/common/pico_sync/sem.c | 5 + src/common/pico_time/time.c | 4 +- .../pico_util/include/pico/util/queue.h | 2 +- src/rp2_common/boot_stage2/CMakeLists.txt | 4 +- src/rp2_common/hardware_claim/claim.c | 2 +- src/rp2_common/hardware_clocks/clocks.c | 3 +- .../include/hardware/divider.h | 9 +- src/rp2_common/hardware_dma/dma.c | 4 +- src/rp2_common/hardware_flash/flash.c | 2 +- src/rp2_common/hardware_i2c/i2c.c | 4 +- .../hardware_irq/include/hardware/irq.h | 2 +- src/rp2_common/hardware_irq/irq.c | 22 ++--- .../hardware_sync/include/hardware/sync.h | 27 ++++-- src/rp2_common/pico_bootrom/bootrom.c | 4 - .../pico_bootrom/include/pico/bootrom.h | 2 +- .../pico_cyw43_driver/cyw43_bus_pio_spi.c | 2 +- src/rp2_common/pico_double/double_init_rom.c | 2 +- src/rp2_common/pico_double/double_math.c | 26 +++--- .../rp2040_usb_device_enumeration.c | 7 +- src/rp2_common/pico_float/float_init_rom.c | 2 +- src/rp2_common/pico_float/float_math.c | 26 +++--- src/rp2_common/pico_float/float_none.S | 1 - src/rp2_common/pico_i2c_slave/i2c_slave.c | 4 - src/rp2_common/pico_malloc/pico_malloc.c | 25 +++-- src/rp2_common/pico_multicore/multicore.c | 2 +- .../pico_platform/include/pico/platform.h | 93 +++++++++++++++++-- src/rp2_common/pico_platform/platform.c | 4 +- src/rp2_common/pico_printf/printf.c | 39 ++++---- src/rp2_common/pico_runtime/CMakeLists.txt | 6 +- src/rp2_common/pico_runtime/runtime.c | 18 ++-- .../pico_standard_link/CMakeLists.txt | 14 +-- src/rp2_common/pico_standard_link/crt0.S | 4 +- .../pico_standard_link/memmap_blocked_ram.ld | 17 ++-- .../pico_standard_link/memmap_copy_to_ram.ld | 14 +-- .../pico_standard_link/memmap_default.ld | 17 ++-- .../pico_standard_link/memmap_no_flash.ld | 12 +-- .../pico_standard_link/new_delete.cpp | 1 + .../stdio_semihosting.c | 6 +- src/rp2_common/pico_stdio_usb/stdio_usb.c | 6 -- src/rp2_common/tinyusb/CMakeLists.txt | 10 +- test/kitchen_sink/CMakeLists.txt | 15 +++ test/kitchen_sink/kitchen_sink.c | 8 +- .../pico_divider_nesting_test.c | 6 +- test/pico_divider_test/pico_divider_test.c | 10 +- test/pico_float_test/pico_float_test.c | 7 ++ tools/elf2uf2/main.cpp | 2 +- 49 files changed, 315 insertions(+), 212 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e79d04ac..e3f57c82 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,13 @@ if (NOT TARGET _pico_sdk_inclusion_marker) project(pico_sdk C CXX ASM) + string(REGEX MATCH "Clang" PICO_C_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}") + string(REGEX MATCH "GNU" PICO_C_COMPILER_IS_GNU "${CMAKE_C_COMPILER_ID}") + string(REGEX MATCH "IAR" PICO_C_COMPILER_IS_IAR "${CMAKE_C_COMPILER_ID}") + pico_register_common_scope_var(PICO_C_COMPILER_IS_CLANG) + pico_register_common_scope_var(PICO_C_COMPILER_IS_GNU) + pico_register_common_scope_var(PICO_C_COMPILER_IS_IAR) + message("Build type is ${CMAKE_BUILD_TYPE}") if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") if (PICO_DEOPTIMIZED_DEBUG) diff --git a/cmake/preload/toolchains/pico_arm_clang.cmake b/cmake/preload/toolchains/pico_arm_clang.cmake index d06d77ea..2e600c87 100644 --- a/cmake/preload/toolchains/pico_arm_clang.cmake +++ b/cmake/preload/toolchains/pico_arm_clang.cmake @@ -1,4 +1,5 @@ -# NOTE: THIS IS A WIP ONLY PICO_ARM_GCC IS CURRENTLY SUPPORTED +# NOTE: THIS IS A WIP ONLY PICO_ARM_GCC IS CURRENTLY SUPPORTED, however should work with LLVM Embedded Toolchain for ARM +# version 14.0.0 https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/tag/release-14.0.0 # todo there is probably a more "cmake" way of doing this going thru the standard path with our "PICO" platform # i.e. CMakeInformation and whatnot include(${CMAKE_CURRENT_LIST_DIR}/find_compiler.cmake) @@ -37,9 +38,10 @@ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -include_directories(/usr/include/newlib) - option(PICO_DEOPTIMIZED_DEBUG "Build debug builds with -O0" 0) -set(ARM_TOOLCHAIN_COMMON_FLAGS " --target=arm-none-eabi -mcpu=cortex-m0plus -mthumb") +# Oz is preferred for Clang (verses CMake default -Os) see also https://gitlab.kitware.com/cmake/cmake/-/issues/22458 +set(CMAKE_C_FLAGS_MINSIZEREL "-Oz -DNDEBUG") + +set(ARM_TOOLCHAIN_COMMON_FLAGS "--target=armv6m-none-eabi -mfloat-abi=soft -march=armv6m --sysroot ${PICO_COMPILER_DIR}/../lib/clang-runtimes/armv6m_soft_nofp") include(${CMAKE_CURRENT_LIST_DIR}/set_flags.cmake) diff --git a/src/common/pico_binary_info/include/pico/binary_info/code.h b/src/common/pico_binary_info/include/pico/binary_info/code.h index 9478477c..a1b13d95 100644 --- a/src/common/pico_binary_info/include/pico/binary_info/code.h +++ b/src/common/pico_binary_info/include/pico/binary_info/code.h @@ -16,12 +16,12 @@ #include "pico/binary_info/structure.h" #if !PICO_NO_BINARY_INFO -#define __bi_decl(name, bi, section_prefix, attr) static const attr __attribute__((section(section_prefix __STRING(name)))) struct _binary_info_core *name = bi +#define __bi_decl(name, bi, section_prefix, attr) static const attr __attribute__((section(section_prefix __STRING(name)))) struct _binary_info_core *const name = bi #define __bi_lineno_var_name __CONCAT(__bi_, __LINE__) #define __bi_ptr_lineno_var_name __CONCAT(__bi_ptr, __LINE__) #define __bi_enclosure_check_lineno_var_name __CONCAT(_error_bi_is_missing_enclosing_decl_,__LINE__) #define __bi_mark_enclosure static const __unused int __bi_enclosure_check_lineno_var_name=0; -#if !defined(__GNUC__) || __cplusplus || __GNUC__ >= 8 +#if __cplusplus || __GNUC__ >= 8 #define __bi_enclosure_check(x) (x + __bi_enclosure_check_lineno_var_name) #else // skip the version check on older GCC non C++, as it doesn't compile.. this is only here to catch the @@ -39,10 +39,10 @@ * binary information declared this way will also be stripped * \ingroup pico_binary_info */ -#define bi_decl_if_func_used(_decl) ({__bi_mark_enclosure _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.", ); *(volatile uint8_t *)&__bi_ptr_lineno_var_name;}); +#define bi_decl_if_func_used(_decl) ({__bi_mark_enclosure _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.", ); *(const volatile uint8_t *)&__bi_ptr_lineno_var_name;}); #define bi_decl_with_attr(_decl, _attr) __bi_mark_enclosure _attr _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.keep.", __used); -#define bi_decl_if_func_used_with_attr(_decl, _attr) ({__bi_mark_enclosure _attr _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.", ); *(volatile uint8_t *)&__bi_ptr_lineno_var_name;}); +#define bi_decl_if_func_used_with_attr(_decl, _attr) ({__bi_mark_enclosure _attr _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.", ); *(const volatile uint8_t *)&__bi_ptr_lineno_var_name;}); #else #define __bi_decl(bi, name, attr) #define bi_decl_with_attr(_decl, _attr) diff --git a/src/common/pico_sync/sem.c b/src/common/pico_sync/sem.c index ec49fdba..90448170 100644 --- a/src/common/pico_sync/sem.c +++ b/src/common/pico_sync/sem.c @@ -15,7 +15,12 @@ void sem_init(semaphore_t *sem, int16_t initial_permits, int16_t max_permits) { } int __time_critical_func(sem_available)(semaphore_t *sem) { +#ifdef __GNUC__ return *(volatile typeof(sem->permits) *) &sem->permits; +#else + static_assert(sizeof(sem->permits) == 2, ""); + return *(volatile int16_t *) &sem->permits; +#endif } void __time_critical_func(sem_acquire_blocking)(semaphore_t *sem) { diff --git a/src/common/pico_time/time.c b/src/common/pico_time/time.c index a4c0b27e..fa32dd81 100644 --- a/src/common/pico_time/time.c +++ b/src/common/pico_time/time.c @@ -22,7 +22,7 @@ typedef struct alarm_pool_entry { void *user_data; } alarm_pool_entry_t; -typedef struct alarm_pool { +struct alarm_pool { pheap_t *heap; spin_lock_t *lock; alarm_pool_entry_t *entries; @@ -32,7 +32,7 @@ typedef struct alarm_pool { alarm_id_t alarm_in_progress; // this is set during a callback from the IRQ handler... it can be cleared by alarm_cancel to prevent repeats uint8_t hardware_alarm_num; uint8_t core_num; -} alarm_pool_t; +}; #if !PICO_TIME_DEFAULT_ALARM_POOL_DISABLED // To avoid bringing in calloc, we statically allocate the arrays and the heap diff --git a/src/common/pico_util/include/pico/util/queue.h b/src/common/pico_util/include/pico/util/queue.h index e9200099..80e5a927 100644 --- a/src/common/pico_util/include/pico/util/queue.h +++ b/src/common/pico_util/include/pico/util/queue.h @@ -59,7 +59,7 @@ void queue_init_with_spinlock(queue_t *q, uint element_size, uint element_count, * \param element_count Maximum number of entries in the queue */ static inline void queue_init(queue_t *q, uint element_size, uint element_count) { - return queue_init_with_spinlock(q, element_size, element_count, next_striped_spin_lock_num()); + queue_init_with_spinlock(q, element_size, element_count, next_striped_spin_lock_num()); } /*! \brief Destroy the specified queue. diff --git a/src/rp2_common/boot_stage2/CMakeLists.txt b/src/rp2_common/boot_stage2/CMakeLists.txt index a130f413..97c8e012 100644 --- a/src/rp2_common/boot_stage2/CMakeLists.txt +++ b/src/rp2_common/boot_stage2/CMakeLists.txt @@ -40,9 +40,9 @@ function(pico_define_boot_stage2 NAME SOURCES) ) # todo bit of an abstraction failure - revisit for Clang support anyway - if (CMAKE_C_COMPILER_ID STREQUAL "Clang") + if (PICO_C_COMPILER_IS_CLANG) target_link_options(${NAME} PRIVATE "-nostdlib") - else () + elseif (PICO_C_COMPILER_IS_GNU) target_link_options(${NAME} PRIVATE "--specs=nosys.specs") target_link_options(${NAME} PRIVATE "-nostartfiles") endif () diff --git a/src/rp2_common/hardware_claim/claim.c b/src/rp2_common/hardware_claim/claim.c index c96764f5..1636855c 100644 --- a/src/rp2_common/hardware_claim/claim.c +++ b/src/rp2_common/hardware_claim/claim.c @@ -6,7 +6,7 @@ #include "hardware/claim.h" -uint32_t hw_claim_lock() { +uint32_t hw_claim_lock(void) { return spin_lock_blocking(spin_lock_instance(PICO_SPINLOCK_ID_HARDWARE_CLAIM)); } diff --git a/src/rp2_common/hardware_clocks/clocks.c b/src/rp2_common/hardware_clocks/clocks.c index 86c5e8db..75078931 100644 --- a/src/rp2_common/hardware_clocks/clocks.c +++ b/src/rp2_common/hardware_clocks/clocks.c @@ -78,8 +78,7 @@ bool clock_configure(enum clock_index clk_index, uint32_t src, uint32_t auxsrc, // Note XOSC_COUNT is not helpful here because XOSC is not // necessarily running, nor is timer... so, 3 cycles per loop: uint delay_cyc = configured_freq[clk_sys] / configured_freq[clk_index] + 1; - asm volatile ( - ".syntax unified \n\t" + unified_asm ( "1: \n\t" "subs %0, #1 \n\t" "bne 1b" diff --git a/src/rp2_common/hardware_divider/include/hardware/divider.h b/src/rp2_common/hardware_divider/include/hardware/divider.h index 0be2ef81..c5b91dec 100644 --- a/src/rp2_common/hardware_divider/include/hardware/divider.h +++ b/src/rp2_common/hardware_divider/include/hardware/divider.h @@ -85,10 +85,10 @@ static inline void hw_divider_wait_ready(void) { // we use one less register and instruction than gcc which uses a TST instruction uint32_t tmp; // allow compiler to pick scratch register - asm volatile ( + unified_asm ( "hw_divider_result_loop_%=:" "ldr %0, [%1, %2]\n\t" - "lsr %0, #1\n\t" + "lsrs %0, %0, #1\n\t" "bcc hw_divider_result_loop_%=\n\t" : "=&l" (tmp) : "l" (sio_hw), "I" (SIO_DIV_CSR_OFFSET) @@ -105,7 +105,8 @@ static inline void hw_divider_wait_ready(void) { */ static inline divmod_result_t hw_divider_result_nowait(void) { // as ugly as this looks it is actually quite efficient - divmod_result_t rc = (((divmod_result_t) sio_hw->div_remainder) << 32u) | sio_hw->div_quotient; + divmod_result_t rc = ((divmod_result_t) sio_hw->div_remainder) << 32u; + rc |= sio_hw->div_quotient; return rc; } @@ -295,7 +296,7 @@ static inline int32_t hw_divider_remainder_s32(int32_t a, int32_t b) { * \ingroup hardware_divider */ static inline void hw_divider_pause(void) { - asm volatile ( + unified_asm ( "b _1_%=\n" "_1_%=:\n" "b _2_%=\n" diff --git a/src/rp2_common/hardware_dma/dma.c b/src/rp2_common/hardware_dma/dma.c index f142b537..5fec2107 100644 --- a/src/rp2_common/hardware_dma/dma.c +++ b/src/rp2_common/hardware_dma/dma.c @@ -13,8 +13,8 @@ check_hw_size(dma_channel_hw_t, DMA_CHAN_STRIDE); check_hw_layout(dma_hw_t, abort, DMA_CHAN_ABORT_OFFSET); // sanity check -static_assert(__builtin_offsetof(dma_hw_t, ch[0].ctrl_trig) == DMA_CH0_CTRL_TRIG_OFFSET, "hw mismatch"); -static_assert(__builtin_offsetof(dma_hw_t, ch[1].ctrl_trig) == DMA_CH1_CTRL_TRIG_OFFSET, "hw mismatch"); +static_assert(offsetof(dma_hw_t, ch[0].ctrl_trig) == DMA_CH0_CTRL_TRIG_OFFSET, "hw mismatch"); +static_assert(offsetof(dma_hw_t, ch[1].ctrl_trig) == DMA_CH1_CTRL_TRIG_OFFSET, "hw mismatch"); static_assert(NUM_DMA_CHANNELS <= 16, ""); static uint16_t _claimed; diff --git a/src/rp2_common/hardware_flash/flash.c b/src/rp2_common/hardware_flash/flash.c index 56993026..970f0bf0 100644 --- a/src/rp2_common/hardware_flash/flash.c +++ b/src/rp2_common/hardware_flash/flash.c @@ -41,7 +41,7 @@ static void __no_inline_not_in_flash_func(flash_init_boot2_copyout)(void) { } static void __no_inline_not_in_flash_func(flash_enable_xip_via_boot2)(void) { - ((void (*)(void))boot2_copyout+1)(); + ((void (*)(void))((intptr_t)boot2_copyout+1))(); } #else diff --git a/src/rp2_common/hardware_i2c/i2c.c b/src/rp2_common/hardware_i2c/i2c.c index 95bcfea1..c5cdbec3 100644 --- a/src/rp2_common/hardware_i2c/i2c.c +++ b/src/rp2_common/hardware_i2c/i2c.c @@ -27,9 +27,7 @@ static inline void i2c_unreset(i2c_inst_t *i2c) { // Addresses of the form 000 0xxx or 111 1xxx are reserved. No slave should // have these addresses. -static inline bool i2c_reserved_addr(uint8_t addr) { - return (addr & 0x78) == 0 || (addr & 0x78) == 0x78; -} +#define i2c_reserved_addr(addr) (((addr) & 0x78) == 0 || ((addr) & 0x78) == 0x78) uint i2c_init(i2c_inst_t *i2c, uint baudrate) { i2c_reset(i2c); diff --git a/src/rp2_common/hardware_irq/include/hardware/irq.h b/src/rp2_common/hardware_irq/include/hardware/irq.h index 3fca0019..85caf671 100644 --- a/src/rp2_common/hardware_irq/include/hardware/irq.h +++ b/src/rp2_common/hardware_irq/include/hardware/irq.h @@ -10,7 +10,7 @@ // These two config items are also used by assembler, so keeping separate // PICO_CONFIG: PICO_MAX_SHARED_IRQ_HANDLERS, Maximum number of shared IRQ handlers, default=4, advanced=true, group=hardware_irq #ifndef PICO_MAX_SHARED_IRQ_HANDLERS -#define PICO_MAX_SHARED_IRQ_HANDLERS 4u +#define PICO_MAX_SHARED_IRQ_HANDLERS 4 #endif // PICO_CONFIG: PICO_DISABLE_SHARED_IRQ_HANDLERS, Disable shared IRQ handlers, type=bool, default=0, group=hardware_irq diff --git a/src/rp2_common/hardware_irq/irq.c b/src/rp2_common/hardware_irq/irq.c index 12b0dcd8..3e66c189 100644 --- a/src/rp2_common/hardware_irq/irq.c +++ b/src/rp2_common/hardware_irq/irq.c @@ -186,11 +186,11 @@ static inline int8_t slot_diff(struct irq_handler_chain_slot *to, struct irq_han int32_t result = 0xaaaa; // return (to - from); // note this implementation has limited range, but is fine for plenty more than -128->127 result - asm (".syntax unified\n" + unified_asm ( "subs %1, %2\n" "adcs %1, %1\n" // * 2 (and + 1 if negative for rounding) "muls %0, %1\n" - "lsrs %0, 20\n" + "lsrs %0, %0, #20\n" : "+l" (result), "+l" (to) : "l" (from) : @@ -221,9 +221,9 @@ void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_prior // start new chain hard_assert(vtable_handler == __unhandled_user_irq); struct irq_handler_chain_slot slot_data = { - .inst1 = 0xa100, // add r1, pc, #0 - .inst2 = make_branch(&slot->inst2, irq_handler_chain_first_slot), // b irq_handler_chain_first_slot - .inst3 = 0xbd01, // pop {r0, pc} + .inst1 = 0xa100, // add r1, pc, #0 + .inst2 = make_branch(&slot->inst2, (void *) irq_handler_chain_first_slot), // b irq_handler_chain_first_slot + .inst3 = 0xbd01, // pop {r0, pc} .link = -1, .priority = order_priority, .handler = handler @@ -233,7 +233,7 @@ void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_prior } else { assert(!((((uintptr_t)vtable_handler) - ((uintptr_t)irq_handler_chain_slots) - 1)%sizeof(struct irq_handler_chain_slot))); struct irq_handler_chain_slot *prev_slot = NULL; - struct irq_handler_chain_slot *existing_vtable_slot = remove_thumb_bit(vtable_handler); + struct irq_handler_chain_slot *existing_vtable_slot = remove_thumb_bit((void *) vtable_handler); struct irq_handler_chain_slot *cur_slot = existing_vtable_slot; while (cur_slot->priority > order_priority) { prev_slot = cur_slot; @@ -259,9 +259,9 @@ void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_prior } else { // update with new chain head struct irq_handler_chain_slot slot_data = { - .inst1 = 0xa100, // add r1, pc, #0 - .inst2 = make_branch(&slot->inst2, irq_handler_chain_first_slot), // b irq_handler_chain_first_slot - .inst3 = make_branch(&slot->inst3, existing_vtable_slot), // b existing_slot + .inst1 = 0xa100, // add r1, pc, #0 + .inst2 = make_branch(&slot->inst2, (void *) irq_handler_chain_first_slot), // b irq_handler_chain_first_slot + .inst3 = make_branch(&slot->inst3, existing_vtable_slot), // b existing_slot .link = get_slot_index(existing_vtable_slot), .priority = order_priority, .handler = handler @@ -309,7 +309,7 @@ void irq_remove_handler(uint num, irq_handler_t handler) { hard_assert(!exception || exception == num + VTABLE_FIRST_IRQ); struct irq_handler_chain_slot *prev_slot = NULL; - struct irq_handler_chain_slot *existing_vtable_slot = remove_thumb_bit(vtable_handler); + struct irq_handler_chain_slot *existing_vtable_slot = remove_thumb_bit((void *) vtable_handler); struct irq_handler_chain_slot *to_free_slot = existing_vtable_slot; while (to_free_slot->handler != handler) { prev_slot = to_free_slot; @@ -354,7 +354,7 @@ void irq_remove_handler(uint num, irq_handler_t handler) { // it to bl to irq_handler_chain_remove_tail which will remove the slot. // NOTE THAT THIS TRASHES PRIORITY AND LINK SINCE THIS IS A 4 BYTE INSTRUCTION // BUT THEY ARE NOT NEEDED NOW - insert_branch_and_link(&to_free_slot->inst3, irq_handler_chain_remove_tail); + insert_branch_and_link(&to_free_slot->inst3, (void *) irq_handler_chain_remove_tail); } } } else { diff --git a/src/rp2_common/hardware_sync/include/hardware/sync.h b/src/rp2_common/hardware_sync/include/hardware/sync.h index 995b9116..c5715421 100644 --- a/src/rp2_common/hardware_sync/include/hardware/sync.h +++ b/src/rp2_common/hardware_sync/include/hardware/sync.h @@ -114,9 +114,11 @@ typedef volatile uint32_t spin_lock_t; * The SEV (send event) instruction sends an event to both cores. */ +#if !__has_builtin(__sev) __force_inline static void __sev(void) { - __asm volatile ("sev"); + unified_asm ("sev"); } +#endif /*! \brief Insert a WFE instruction in to the code path. * \ingroup hardware_sync @@ -124,18 +126,22 @@ __force_inline static void __sev(void) { * The WFE (wait for event) instruction waits until one of a number of * events occurs, including events signalled by the SEV instruction on either core. */ +#if !__has_builtin(__wfe) __force_inline static void __wfe(void) { - __asm volatile ("wfe"); + unified_asm ("wfe"); } +#endif /*! \brief Insert a WFI instruction in to the code path. * \ingroup hardware_sync * * The WFI (wait for interrupt) instruction waits for a interrupt to wake up the core. */ +#if !__has_builtin(__wfi) __force_inline static void __wfi(void) { - __asm volatile ("wfi"); + unified_asm ("wfi"); } +#endif /*! \brief Insert a DMB instruction in to the code path. * \ingroup hardware_sync @@ -144,7 +150,7 @@ __force_inline static void __wfi(void) { * instruction will be observed before any explicit access after the instruction. */ __force_inline static void __dmb(void) { - __asm volatile ("dmb" : : : "memory"); + unified_asm ("dmb" : : : "memory"); } /*! \brief Insert a DSB instruction in to the code path. @@ -155,7 +161,7 @@ __force_inline static void __dmb(void) { * accesses before this instruction complete. */ __force_inline static void __dsb(void) { - __asm volatile ("dsb" : : : "memory"); + unified_asm ("dsb" : : : "memory"); } /*! \brief Insert a ISB instruction in to the code path. @@ -166,7 +172,7 @@ __force_inline static void __dsb(void) { * the ISB instruction has been completed. */ __force_inline static void __isb(void) { - __asm volatile ("isb"); + unified_asm ("isb"); } /*! \brief Acquire a memory fence @@ -207,8 +213,8 @@ __force_inline static void __mem_fence_release(void) { */ __force_inline static uint32_t save_and_disable_interrupts(void) { uint32_t status; - __asm volatile ("mrs %0, PRIMASK" : "=r" (status)::); - __asm volatile ("cpsid i"); + unified_asm ("mrs %0, PRIMASK" : "=r" (status)::); + unified_asm ("cpsid i"); return status; } @@ -218,7 +224,7 @@ __force_inline static uint32_t save_and_disable_interrupts(void) { * \param status Previous interrupt status from save_and_disable_interrupts() */ __force_inline static void restore_interrupts(uint32_t status) { - __asm volatile ("msr PRIMASK,%0"::"r" (status) : ); + unified_asm ("msr PRIMASK,%0"::"r" (status) : ); } /*! \brief Get HW Spinlock instance from number @@ -389,7 +395,8 @@ int spin_lock_claim_unused(bool required); */ bool spin_lock_is_claimed(uint lock_num); -#define remove_volatile_cast(t, x) ({__mem_fence_acquire(); (t)(x); }) +// no longer use __mem_fence_acquire here, as it is overkill on cortex M0+ +#define remove_volatile_cast(t, x) ({__compiler_memory_barrier(); Clang_Pragma("clang diagnostic push"); Clang_Pragma("clang diagnostic ignored \"-Wcast-qual\""); (t)(x); Clang_Pragma("clang diagnostic pop"); }) #ifdef __cplusplus } diff --git a/src/rp2_common/pico_bootrom/bootrom.c b/src/rp2_common/pico_bootrom/bootrom.c index 5def61a0..01156866 100644 --- a/src/rp2_common/pico_bootrom/bootrom.c +++ b/src/rp2_common/pico_bootrom/bootrom.c @@ -8,10 +8,6 @@ /// \tag::table_lookup[] -// Bootrom function: rom_table_lookup -// Returns the 32 bit pointer into the ROM if found or NULL otherwise. -typedef void *(*rom_table_lookup_fn)(uint16_t *table, uint32_t code); - void *rom_func_lookup(uint32_t code) { return rom_func_lookup_inline(code); } diff --git a/src/rp2_common/pico_bootrom/include/pico/bootrom.h b/src/rp2_common/pico_bootrom/include/pico/bootrom.h index e92207c4..d4796af2 100644 --- a/src/rp2_common/pico_bootrom/include/pico/bootrom.h +++ b/src/rp2_common/pico_bootrom/include/pico/bootrom.h @@ -116,7 +116,7 @@ bool rom_funcs_lookup(uint32_t *table, unsigned int count); // Returns the 32 bit pointer into the ROM if found or NULL otherwise. typedef void *(*rom_table_lookup_fn)(uint16_t *table, uint32_t code); -#if defined(__GNUC__) && (__GNUC__ >= 12) +#if PICO_C_COMPILER_IS_GNU && (__GNUC__ >= 12) // Convert a 16 bit pointer stored at the given rom address into a 32 bit pointer static inline void *rom_hword_as_ptr(uint16_t rom_address) { #pragma GCC diagnostic push diff --git a/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c b/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c index 91ae2427..6976d479 100644 --- a/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c +++ b/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c @@ -63,7 +63,7 @@ static uint32_t counter = 0; //#define SWAP32(A) ((((A) & 0xff000000U) >> 8) | (((A) & 0xff0000U) << 8) | (((A) & 0xff00U) >> 8) | (((A) & 0xffU) << 8)) __force_inline static uint32_t __swap16x2(uint32_t a) { - __asm ("rev16 %0, %0" : "+l" (a) : : ); + unified_asm ("rev16 %0, %0" : "+l" (a) : : ); return a; } #define SWAP32(a) __swap16x2(a) diff --git a/src/rp2_common/pico_double/double_init_rom.c b/src/rp2_common/pico_double/double_init_rom.c index af6f6a2c..eec56c4c 100644 --- a/src/rp2_common/pico_double/double_init_rom.c +++ b/src/rp2_common/pico_double/double_init_rom.c @@ -47,7 +47,7 @@ void __aeabi_double_init(void) { #endif if (rom_version >= 2) { void *rom_table = rom_data_lookup(rom_table_code('S', 'D')); - assert(*((uint8_t *)(((void *)rom_data_lookup(rom_table_code('S', 'F')))-2)) * 4 >= SF_TABLE_V2_SIZE); + assert(*((uint8_t *)rom_data_lookup(rom_table_code('S', 'F'))-2) * 4 >= SF_TABLE_V2_SIZE); memcpy(&sd_table, rom_table, SF_TABLE_V2_SIZE); if (rom_version == 2) { #ifndef NDEBUG diff --git a/src/rp2_common/pico_double/double_math.c b/src/rp2_common/pico_double/double_math.c index 0d8e43c3..6d2a48ec 100644 --- a/src/rp2_common/pico_double/double_math.c +++ b/src/rp2_common/pico_double/double_math.c @@ -8,9 +8,9 @@ #include "pico/double.h" // opened a separate issue https://github.com/raspberrypi/pico-sdk/issues/166 to deal with these warnings if at all -_Pragma("GCC diagnostic push") -_Pragma("GCC diagnostic ignored \"-Wconversion\"") -_Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") +GCC_Pragma("GCC diagnostic push") +GCC_Pragma("GCC diagnostic ignored \"-Wconversion\"") +GCC_Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") typedef uint64_t ui64; typedef uint32_t ui32; @@ -56,13 +56,13 @@ static inline ui64 double2ui64(double d) { return tmp.ix; } +#if PICO_DOUBLE_PROPAGATE_NANS static inline bool disnan(double x) { ui64 ix= double2ui64(x); // checks the top bit of the low 32 bit of the NAN, but it I think that is ok return ((uint32_t)(ix >> 31)) > 0xffe00000u; } -#if PICO_DOUBLE_PROPAGATE_NANS #define check_nan_d1(x) if (disnan((x))) return (x) #define check_nan_d2(x,y) if (disnan((x))) return (x); else if (disnan((y))) return (y); #else @@ -109,8 +109,8 @@ double WRAPPER_FUNC(copysign)(double x, double y) { return dcopysign(x, y); } static inline int diszero(double x) { return dgetexp (x)==0; } -static inline int dispzero(double x) { return dgetsignexp(x)==0; } -static inline int dismzero(double x) { return dgetsignexp(x)==0x800; } +//static inline int dispzero(double x) { return dgetsignexp(x)==0; } +//static inline int dismzero(double x) { return dgetsignexp(x)==0x800; } static inline int disinf(double x) { return dgetexp (x)==0x7ff; } static inline int dispinf(double x) { return dgetsignexp(x)==0x7ff; } static inline int disminf(double x) { return dgetsignexp(x)==0xfff; } @@ -419,10 +419,10 @@ static double dpowint_0(double x,int y) { } double WRAPPER_FUNC(powint)(double x,int y) { - _Pragma("GCC diagnostic push") - _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") + GCC_Like_Pragma("GCC diagnostic push") + GCC_Like_Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") if(x==1.0||y==0) return 1; - _Pragma("GCC diagnostic pop") + GCC_Like_Pragma("GCC diagnostic pop") check_nan_d1(x); if(diszero(x)) { if(y>0) { @@ -468,13 +468,13 @@ static double dpow_0(double x,double y) { } double WRAPPER_FUNC(pow)(double x,double y) { - _Pragma("GCC diagnostic push") - _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") + GCC_Like_Pragma("GCC diagnostic push") + GCC_Like_Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") if(x==1.0||diszero(y)) return 1; check_nan_d2(x, y); if(x==-1.0&&disinf(y)) return 1; - _Pragma("GCC diagnostic pop") + GCC_Like_Pragma("GCC diagnostic pop") if(diszero(x)) { if(!disneg(y)) { @@ -621,4 +621,4 @@ double WRAPPER_FUNC(drem)(double x,double y) { check_nan_d2(x, y); return remquo double WRAPPER_FUNC(remainder)(double x,double y) { check_nan_d2(x, y); return remquo(x,y,0); } -_Pragma("GCC diagnostic pop") // conversion \ No newline at end of file +GCC_Pragma("GCC diagnostic pop") // conversion \ No newline at end of file diff --git a/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c b/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c index 503cd12c..2fefb80c 100644 --- a/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c +++ b/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c @@ -110,8 +110,9 @@ static void hw_enumeration_fix_force_ls_j(void) { gpio_set_inover(dp, GPIO_OVERRIDE_HIGH); // Force PHY pull up to stay before switching away from the phy - hw_set_alias(usb_hw)->phy_direct = USB_USBPHY_DIRECT_DP_PULLUP_EN_BITS; - hw_set_alias(usb_hw)->phy_direct_override = USB_USBPHY_DIRECT_OVERRIDE_DP_PULLUP_EN_OVERRIDE_EN_BITS; + usb_hw_t *usb_hw_set = (usb_hw_t *)hw_set_alias_untyped(usb_hw); + usb_hw_set->phy_direct = USB_USBPHY_DIRECT_DP_PULLUP_EN_BITS; + usb_hw_set->phy_direct_override = USB_USBPHY_DIRECT_OVERRIDE_DP_PULLUP_EN_OVERRIDE_EN_BITS; // Switch to GPIO phy with LS_J forced usb_hw->muxing = USB_USB_MUXING_TO_DIGITAL_PAD_BITS | USB_USB_MUXING_SOFTCON_BITS; @@ -138,7 +139,7 @@ static void hw_enumeration_fix_finish(void) { usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS; // Get rid of DP pullup override - hw_clear_alias(usb_hw)->phy_direct_override = USB_USBPHY_DIRECT_OVERRIDE_DP_PULLUP_EN_OVERRIDE_EN_BITS; + hw_clear_bits(&usb_hw->phy_direct_override, USB_USBPHY_DIRECT_OVERRIDE_DP_PULLUP_EN_OVERRIDE_EN_BITS); // Finally, restore the gpio ctrl value back to GPIO15 iobank0_hw->io[dp].ctrl = gpio_ctrl_prev; diff --git a/src/rp2_common/pico_float/float_init_rom.c b/src/rp2_common/pico_float/float_init_rom.c index 646c0e94..062bfe70 100644 --- a/src/rp2_common/pico_float/float_init_rom.c +++ b/src/rp2_common/pico_float/float_init_rom.c @@ -63,7 +63,7 @@ void __aeabi_float_init(void) { } #endif if (rom_version >= 2) { - assert(*((uint8_t *)(rom_table-2)) * 4 >= SF_TABLE_V2_SIZE); + assert(*((uint8_t *)rom_table-2) * 4 >= SF_TABLE_V2_SIZE); memcpy(&sf_table, rom_table, SF_TABLE_V2_SIZE); } sf_clz_func = rom_func_lookup(ROM_FUNC_CLZ32); diff --git a/src/rp2_common/pico_float/float_math.c b/src/rp2_common/pico_float/float_math.c index d11491cb..93eb01df 100644 --- a/src/rp2_common/pico_float/float_math.c +++ b/src/rp2_common/pico_float/float_math.c @@ -7,9 +7,9 @@ #include "pico/float.h" // opened a separate issue https://github.com/raspberrypi/pico-sdk/issues/166 to deal with these warnings if at all -_Pragma("GCC diagnostic push") -_Pragma("GCC diagnostic ignored \"-Wconversion\"") -_Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") +GCC_Pragma("GCC diagnostic push") +GCC_Pragma("GCC diagnostic ignored \"-Wconversion\"") +GCC_Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") typedef uint32_t ui32; typedef int32_t i32; @@ -54,12 +54,12 @@ static inline ui32 float2ui32(float f) { return tmp.ix; } +#if PICO_FLOAT_PROPAGATE_NANS static inline bool fisnan(float x) { ui32 ix=float2ui32(x); return ix * 2 > 0xff000000u; } -#if PICO_FLOAT_PROPAGATE_NANS #define check_nan_f1(x) if (fisnan((x))) return (x) #define check_nan_f2(x,y) if (fisnan((x))) return (x); else if (fisnan((y))) return (y); #else @@ -106,8 +106,8 @@ float WRAPPER_FUNC(copysignf)(float x, float y) { } static inline int fiszero(float x) { return fgetexp (x)==0; } -static inline int fispzero(float x) { return fgetsignexp(x)==0; } -static inline int fismzero(float x) { return fgetsignexp(x)==0x100; } +//static inline int fispzero(float x) { return fgetsignexp(x)==0; } +//static inline int fismzero(float x) { return fgetsignexp(x)==0x100; } static inline int fisinf(float x) { return fgetexp (x)==0xff; } static inline int fispinf(float x) { return fgetsignexp(x)==0xff; } static inline int fisminf(float x) { return fgetsignexp(x)==0x1ff; } @@ -377,8 +377,8 @@ static float fpowint_0(float x,int y) { } float WRAPPER_FUNC(powintf)(float x,int y) { - _Pragma("GCC diagnostic push") - _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") + GCC_Pragma("GCC diagnostic push") + GCC_Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") if(x==1.0f||y==0) return 1; if(x==0.0f) { if(y>0) { @@ -388,7 +388,7 @@ float WRAPPER_FUNC(powintf)(float x,int y) { if((y&1)) return fcopysign(FPINF,x); return FPINF; } - _Pragma("GCC diagnostic pop") + GCC_Pragma("GCC diagnostic pop") check_nan_f1(x); if(fispinf(x)) { if(y<0) return 0; @@ -426,12 +426,12 @@ static float fpow_0(float x,float y) { } float WRAPPER_FUNC(powf)(float x,float y) { - _Pragma("GCC diagnostic push") - _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") + GCC_Like_Pragma("GCC diagnostic push") + GCC_Like_Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") if(x==1.0f||fiszero(y)) return 1; check_nan_f2(x,y); if(x==-1.0f&&fisinf(y)) return 1; - _Pragma("GCC diagnostic pop") + GCC_Like_Pragma("GCC diagnostic pop") if(fiszero(x)) { if(!fisneg(y)) { if(fisoddint(y)) return x; @@ -579,4 +579,4 @@ float WRAPPER_FUNC(dremf)(float x,float y) { check_nan_f2(x,y); return remquof(x float WRAPPER_FUNC(remainderf)(float x,float y) { check_nan_f2(x,y); return remquof(x,y,0); } -_Pragma("GCC diagnostic pop") // conversion \ No newline at end of file +GCC_Pragma("GCC diagnostic pop") // conversion \ No newline at end of file diff --git a/src/rp2_common/pico_float/float_none.S b/src/rp2_common/pico_float/float_none.S index 55baf290..db8e1268 100644 --- a/src/rp2_common/pico_float/float_none.S +++ b/src/rp2_common/pico_float/float_none.S @@ -29,7 +29,6 @@ wrapper_func __aeabi_i2f wrapper_func __aeabi_l2f wrapper_func __aeabi_ui2f wrapper_func __aeabi_ul2f -wrapper_func __aeabi_i2f wrapper_func __aeabi_f2iz wrapper_func __aeabi_f2lz wrapper_func __aeabi_f2uiz diff --git a/src/rp2_common/pico_i2c_slave/i2c_slave.c b/src/rp2_common/pico_i2c_slave/i2c_slave.c index 74a988ec..12b53014 100644 --- a/src/rp2_common/pico_i2c_slave/i2c_slave.c +++ b/src/rp2_common/pico_i2c_slave/i2c_slave.c @@ -15,10 +15,6 @@ typedef struct i2c_slave { static i2c_slave_t i2c_slaves[2]; -static inline i2c_inst_t *get_hw_instance(const i2c_slave_t *slave) { - return i2c_get_instance(slave - i2c_slaves); -} - static void __isr __not_in_flash_func(i2c_slave_irq_handler)(void) { uint i2c_index = __get_current_exception() - VTABLE_FIRST_IRQ - I2C0_IRQ; i2c_slave_t *slave = &i2c_slaves[i2c_index]; diff --git a/src/rp2_common/pico_malloc/pico_malloc.c b/src/rp2_common/pico_malloc/pico_malloc.c index a0539866..868a455d 100644 --- a/src/rp2_common/pico_malloc/pico_malloc.c +++ b/src/rp2_common/pico_malloc/pico_malloc.c @@ -5,7 +5,6 @@ */ #include -#include #include "pico.h" #include "pico/malloc.h" @@ -14,10 +13,10 @@ auto_init_mutex(malloc_mutex); #endif -extern void *__real_malloc(size_t size); -extern void *__real_calloc(size_t count, size_t size); -extern void *__real_realloc(void *mem, size_t size); -extern void __real_free(void *mem); +extern void *REAL_FUNC(malloc)(size_t size); +extern void *REAL_FUNC(calloc)(size_t count, size_t size); +extern void *REAL_FUNC(realloc)(void *mem, size_t size); +extern void REAL_FUNC(free)(void *mem); extern char __StackLimit; /* Set by linker. */ @@ -29,11 +28,11 @@ static inline void check_alloc(__unused void *mem, __unused uint size) { #endif } -void *__wrap_malloc(size_t size) { +void *WRAPPER_FUNC(malloc)(size_t size) { #if PICO_USE_MALLOC_MUTEX mutex_enter_blocking(&malloc_mutex); #endif - void *rc = __real_malloc(size); + void *rc = REAL_FUNC(malloc)(size); #if PICO_USE_MALLOC_MUTEX mutex_exit(&malloc_mutex); #endif @@ -46,11 +45,11 @@ void *__wrap_malloc(size_t size) { return rc; } -void *__wrap_calloc(size_t count, size_t size) { +void *WRAPPER_FUNC(calloc)(size_t count, size_t size) { #if PICO_USE_MALLOC_MUTEX mutex_enter_blocking(&malloc_mutex); #endif - void *rc = __real_calloc(count, size); + void *rc = REAL_FUNC(calloc)(count, size); #if PICO_USE_MALLOC_MUTEX mutex_exit(&malloc_mutex); #endif @@ -63,11 +62,11 @@ void *__wrap_calloc(size_t count, size_t size) { return rc; } -void *__wrap_realloc(void *mem, size_t size) { +void *WRAPPER_FUNC(realloc)(void *mem, size_t size) { #if PICO_USE_MALLOC_MUTEX mutex_enter_blocking(&malloc_mutex); #endif - void *rc = __real_realloc(mem, size); + void *rc = REAL_FUNC(realloc)(mem, size); #if PICO_USE_MALLOC_MUTEX mutex_exit(&malloc_mutex); #endif @@ -80,11 +79,11 @@ void *__wrap_realloc(void *mem, size_t size) { return rc; } -void __wrap_free(void *mem) { +void WRAPPER_FUNC(free)(void *mem) { #if PICO_USE_MALLOC_MUTEX mutex_enter_blocking(&malloc_mutex); #endif - __real_free(mem); + REAL_FUNC(free)(mem); #if PICO_USE_MALLOC_MUTEX mutex_exit(&malloc_mutex); #endif diff --git a/src/rp2_common/pico_multicore/multicore.c b/src/rp2_common/pico_multicore/multicore.c index 96f50653..1622145e 100644 --- a/src/rp2_common/pico_multicore/multicore.c +++ b/src/rp2_common/pico_multicore/multicore.c @@ -75,7 +75,7 @@ bool multicore_fifo_pop_timeout_us(uint64_t timeout_us, uint32_t *out) { static uint32_t __attribute__((section(".stack1"))) core1_stack[PICO_CORE1_STACK_SIZE / sizeof(uint32_t)]; static void __attribute__ ((naked)) core1_trampoline(void) { - __asm("pop {r0, r1, pc}"); + unified_asm ("pop {r0, r1, pc}"); } int core1_wrapper(int (*entry)(void), void *stack_base) { diff --git a/src/rp2_common/pico_platform/include/pico/platform.h b/src/rp2_common/pico_platform/include/pico/platform.h index 017680b7..91606deb 100644 --- a/src/rp2_common/pico_platform/include/pico/platform.h +++ b/src/rp2_common/pico_platform/include/pico/platform.h @@ -68,9 +68,80 @@ #ifndef __ASSEMBLER__ +#if defined __GNUC__ #include +// note LLVM defines __GNUC__ +#ifdef __clang__ +#define PICO_C_COMPILER_IS_CLANG 1 +#else +#define PICO_C_COMPILER_IS_GNU 1 +#endif +#elif defined __ICCARM__ +#ifndef __aligned +#define __aligned(x) __attribute__((__aligned__(x))) +#endif +#ifndef __always_inline +#define __always_inline __attribute__((__always_inline__)) +#endif +#ifndef __noinline +#define __noinline __attribute__((__noinline__)) +#endif +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif +#ifndef __printflike +#define __printflike(a, b) +#endif +#ifndef __unused +#define __unused __attribute__((__unused__)) +#endif +#ifndef __used +#define __used __attribute__((__used__)) +#endif +#ifndef __CONCAT1 +#define __CONCAT1(a, b) a ## b +#endif +#ifndef __CONCAT +#define __CONCAT(a, b) __CONCAT1(a, b) +#endif +#ifndef __STRING +#define __STRING(a) #a +#endif +/* Compatible definitions of GCC builtins */ + +static inline uint __builtin_ctz(uint x) { + extern uint32_t __ctzsi2(uint32_t); + return __ctzsi2(x); +} +#define __builtin_expect(x, y) (x) +#define __builtin_isnan(x) __iar_isnan(x) +#else +#error Unsupported toolchain +#endif + #include "pico/types.h" +// GCC_Like_Pragma(x) is a pragma on GNUC compatible compilers +#ifdef __GNUC__ +#define GCC_Like_Pragma _Pragma +#else +#define GCC_Like_Pragma(x) +#endif + +// Clang_Pragma(x) is a pragma on Clang only +#ifdef __clang__ +#define Clang_Pragma _Pragma +#else +#define Clang_Pragma(x) +#endif + +// GCC_Pragma(x) is a pragma on GCC only +#if PICO_C_COMPILER_IS_GNU +#define GCC_Pragma _Pragma +#else +#define GCC_Pragma(x) +#endif + #ifdef __cplusplus extern "C" { #endif @@ -236,7 +307,8 @@ extern "C" { * int __force_inline my_function(int x) { * */ -#if defined(__GNUC__) && (__GNUC__ <= 6 || (__GNUC__ == 7 && (__GNUC_MINOR__ < 3 || !defined(__cplusplus)))) + +#if PICO_C_COMPILER_IS_GNU && (__GNUC__ <= 6 || (__GNUC__ == 7 && (__GNUC_MINOR__ < 3 || !defined(__cplusplus)))) #define __force_inline inline __always_inline #else #define __force_inline __always_inline @@ -263,11 +335,13 @@ extern "C" { #define MIN(a, b) ((b)>(a)?(a):(b)) #endif +#define unified_asm(...) __asm volatile (".syntax unified\n" __VA_ARGS__) + /*! \brief Execute a breakpoint instruction * \ingroup pico_platform */ static inline void __breakpoint(void) { - __asm__("bkpt #0"); + unified_asm ("bkpt #0"); } /*! \brief Ensure that the compiler does not move memory access across this method call @@ -283,7 +357,7 @@ static inline void __breakpoint(void) { * might - even above the memory store!) */ __force_inline static void __compiler_memory_barrier(void) { - __asm__ volatile ("" : : : "memory"); + unified_asm ("" : : : "memory"); } /*! \brief Macro for converting memory addresses to 32 bit addresses suitable for DMA @@ -343,10 +417,10 @@ uint8_t rp2040_chip_version(void); * @return the RP2040 rom version number (1 for RP2040-B0, 2 for RP2040-B1, 3 for RP2040-B2) */ static inline uint8_t rp2040_rom_version(void) { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Warray-bounds" +GCC_Pragma("GCC diagnostic push") +GCC_Pragma("GCC diagnostic ignored \"-Warray-bounds\"") return *(uint8_t*)0x13; -#pragma GCC diagnostic pop +GCC_Pragma("GCC diagnostic pop") } /*! \brief No-op function for the body of tight loops @@ -369,7 +443,7 @@ static __force_inline void tight_loop_contents(void) {} * \return a * b */ __force_inline static int32_t __mul_instruction(int32_t a, int32_t b) { - asm ("mul %0, %1" : "+l" (a) : "l" (b) : ); + unified_asm ("muls %0, %1" : "+l" (a) : "l" (b) : ); return a; } @@ -405,7 +479,7 @@ __force_inline static int32_t __mul_instruction(int32_t a, int32_t b) { */ static inline uint __get_current_exception(void) { uint exception; - asm ("mrs %0, ipsr" : "=l" (exception)); + unified_asm ("mrs %0, ipsr" : "=l" (exception)); return exception; } @@ -431,8 +505,7 @@ static inline uint __get_current_exception(void) { * \param minimum_cycles the minimum number of system clock cycles to delay for */ static inline void busy_wait_at_least_cycles(uint32_t minimum_cycles) { - __asm volatile ( - ".syntax unified\n" + unified_asm ( "1: subs %0, #3\n" "bcs 1b\n" : "+r" (minimum_cycles) : : "memory" diff --git a/src/rp2_common/pico_platform/platform.c b/src/rp2_common/pico_platform/platform.c index 9bbcf26e..46e3c88f 100644 --- a/src/rp2_common/pico_platform/platform.c +++ b/src/rp2_common/pico_platform/platform.c @@ -18,7 +18,7 @@ #if !PICO_NO_FPGA_CHECK // Inline stub provided in header if this code is unused (so folding can be // done in each TU instead of relying on LTO) -bool running_on_fpga() { +bool running_on_fpga(void) { return !!((*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_FPGA_BITS); } #endif @@ -26,7 +26,7 @@ bool running_on_fpga() { #define MANUFACTURER_RPI 0x927 #define PART_RP2 0x2 -uint8_t rp2040_chip_version() { +uint8_t rp2040_chip_version(void) { // First register of sysinfo is chip id uint32_t chip_id = *((io_ro_32*)(SYSINFO_BASE + SYSINFO_CHIP_ID_OFFSET)); uint32_t __unused manufacturer = chip_id & SYSINFO_CHIP_ID_MANUFACTURER_BITS; diff --git a/src/rp2_common/pico_printf/printf.c b/src/rp2_common/pico_printf/printf.c index cafdc1b6..7ae526ff 100644 --- a/src/rp2_common/pico_printf/printf.c +++ b/src/rp2_common/pico_printf/printf.c @@ -107,15 +107,6 @@ #endif -/** - * Output a character to a custom device like UART, used by the printf() function - * This function is declared here only. You have to write your custom implementation somewhere - * \param character Character to output - */ -static void _putchar(char character) { - putchar(character); -} - // output function type typedef void (*out_fct_type)(char character, void *buffer, size_t idx, size_t maxlen); @@ -148,17 +139,6 @@ static inline void _out_null(char character, void *buffer, size_t idx, size_t ma (void) maxlen; } -// internal _putchar wrapper -static inline void _out_char(char character, void *buffer, size_t idx, size_t maxlen) { - (void) buffer; - (void) idx; - (void) maxlen; - if (character) { - _putchar(character); - } -} - - // internal output function wrapper static inline void _out_fct(char character, void *buffer, size_t idx, size_t maxlen) { (void) idx; @@ -920,6 +900,25 @@ int vfctprintf(void (*out)(char character, void *arg), void *arg, const char *fo #if LIB_PICO_PRINTF_PICO #if !PICO_PRINTF_ALWAYS_INCLUDED +/** + * Output a character to a custom device like UART, used by the printf() function + * This function is declared here only. You have to write your custom implementation somewhere + * \param character Character to output + */ +static void _putchar(char character) { + putchar(character); +} + +// internal _putchar wrapper +static inline void _out_char(char character, void *buffer, size_t idx, size_t maxlen) { + (void) buffer; + (void) idx; + (void) maxlen; + if (character) { + _putchar(character); + } +} + bool weak_raw_printf(const char *fmt, ...) { va_list va; va_start(va, fmt); diff --git a/src/rp2_common/pico_runtime/CMakeLists.txt b/src/rp2_common/pico_runtime/CMakeLists.txt index 08a9a503..9879ba1d 100644 --- a/src/rp2_common/pico_runtime/CMakeLists.txt +++ b/src/rp2_common/pico_runtime/CMakeLists.txt @@ -40,5 +40,9 @@ if (TARGET pico_standard_link) endif() # todo is this correct/needed? -target_link_options(pico_runtime INTERFACE "--specs=nosys.specs") +if (PICO_C_COMPILER_IS_GNU) + target_link_options(pico_runtime INTERFACE "--specs=nosys.specs") +elseif (PICO_C_COMPILER_IS_CLANG) + # target_link_options(pico_runtime INTERFACE "-nostdlib") +endif() diff --git a/src/rp2_common/pico_runtime/runtime.c b/src/rp2_common/pico_runtime/runtime.c index f9018d0a..b7076172 100644 --- a/src/rp2_common/pico_runtime/runtime.c +++ b/src/rp2_common/pico_runtime/runtime.c @@ -114,8 +114,9 @@ void runtime_init(void) { #if !PICO_IE_26_29_UNCHANGED_ON_RESET // after resetting BANK0 we should disable IE on 26-29 - hw_clear_alias(padsbank0_hw)->io[26] = hw_clear_alias(padsbank0_hw)->io[27] = - hw_clear_alias(padsbank0_hw)->io[28] = hw_clear_alias(padsbank0_hw)->io[29] = PADS_BANK0_GPIO0_IE_BITS; + padsbank0_hw_t *padsbank0_hw_clear = (padsbank0_hw_t *)hw_clear_alias_untyped(padsbank0_hw); + padsbank0_hw_clear->io[26] = padsbank0_hw_clear->io[27] = + padsbank0_hw_clear->io[28] = padsbank0_hw_clear->io[29] = PADS_BANK0_GPIO0_IE_BITS; #endif // this is an array of either mutex_t or recursive_mutex_t (i.e. not necessarily the same size) @@ -150,7 +151,7 @@ void runtime_init(void) { #ifndef NDEBUG if (__get_current_exception()) { // crap; started in exception handler - __asm ("bkpt #0"); + unified_asm ("bkpt #0"); } #endif @@ -260,8 +261,8 @@ void exit(int status) { } // incorrect warning from GCC 6 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wsuggest-attribute=format" +GCC_Pragma("GCC diagnostic push") +GCC_Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=format\"") void __assert_func(const char *file, int line, const char *func, const char *failedexpr) { weak_raw_printf("assertion \"%s\" failed: file \"%s\", line %d%s%s\n", failedexpr, file, line, func ? ", function: " : "", @@ -269,10 +270,9 @@ void __assert_func(const char *file, int line, const char *func, const char *fai _exit(1); } +GCC_Pragma("GCC diagnostic pop") -#pragma GCC diagnostic pop - -void __attribute__((noreturn)) panic_unsupported() { +void __attribute__((noreturn)) panic_unsupported(void) { panic("not supported"); } @@ -286,7 +286,7 @@ extern void __attribute__((noreturn)) __printflike(1, 0) PICO_PANIC_FUNCTION(__u // 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! - __asm ( + unified_asm ( "push {lr}\n" #if !PICO_PANIC_FUNCTION_EMPTY "bl " __XSTRING(PICO_PANIC_FUNCTION) "\n" diff --git a/src/rp2_common/pico_standard_link/CMakeLists.txt b/src/rp2_common/pico_standard_link/CMakeLists.txt index 582b439b..b9282e2d 100644 --- a/src/rp2_common/pico_standard_link/CMakeLists.txt +++ b/src/rp2_common/pico_standard_link/CMakeLists.txt @@ -10,8 +10,8 @@ if (NOT TARGET pico_standard_link) pico_add_map_output(pico_standard_link) # todo revisit when we do Clang - if (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(pico_standard_link INTERFACE "LINKER:-nostdlib") + if (PICO_C_COMPILER_IS_CLANG) +# target_link_options(pico_standard_link INTERFACE "LINKER:-fuse-ld=lld") endif () pico_mirrored_target_link_libraries(pico_standard_link INTERFACE hardware_regs pico_bootrom pico_binary_info) @@ -74,9 +74,11 @@ if (NOT TARGET pico_standard_link) target_compile_definitions(pico_standard_link INTERFACE PICO_DEOPTIMIZED_DEBUG=1) endif() - # todo revisit/recall reasoning for why not -nostartfiles always? - # -nostartfiles will be added if PICO_NO_FLASH would be defined to 1 - target_link_options(pico_standard_link INTERFACE $<$,no_flash>,1,$,$>>>:-nostartfiles>) + # -nostartfiles will be added if not using C++ exceptions (which is the only thing that seems to need it) + if (PICO_C_COMPILER_IS_GNU AND NOT PICO_CXX_ENABLE_EXCEPTIONS) +# target_link_options(pico_standard_link INTERFACE $<$,no_flash>,1,$,$>>>:-nostartfiles>) + target_link_options(pico_standard_link INTERFACE -nostartfiles) + endif() # boot_stage2 will be linked if PICO_NO_FLASH would be defined to 0 target_link_libraries(pico_standard_link INTERFACE $<$,no_flash>,1,$,$>>>>:$>,$,bs2_default>_library>) @@ -96,7 +98,7 @@ if (NOT TARGET pico_standard_link) target_link_options(pico_standard_link INTERFACE "LINKER:--gc-sections") endif() - if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") + if (PICO_C_COMPILER_IS_GNU) # Ignore warnings about rwx segments introduced in binutils 2.39 execute_process(COMMAND ${CMAKE_C_COMPILER} -print-prog-name=ld RESULT_VARIABLE RUN_C_RESULT OUTPUT_VARIABLE FULL_LD_PATH OUTPUT_STRIP_TRAILING_WHITESPACE) diff --git a/src/rp2_common/pico_standard_link/crt0.S b/src/rp2_common/pico_standard_link/crt0.S index d061108d..43b069d0 100644 --- a/src/rp2_common/pico_standard_link/crt0.S +++ b/src/rp2_common/pico_standard_link/crt0.S @@ -325,13 +325,13 @@ hold_non_core0_in_bootrom: // ---------------------------------------------------------------------------- // Stack/heap dummies to set size -.section .stack +.section .stack, "a" // align to allow for memory protection (although this alignment is pretty much ignored by linker script) .align 5 .equ StackSize, PICO_STACK_SIZE .space StackSize -.section .heap +.section .heap, "a" .align 2 .equ HeapSize, PICO_HEAP_SIZE .space HeapSize diff --git a/src/rp2_common/pico_standard_link/memmap_blocked_ram.ld b/src/rp2_common/pico_standard_link/memmap_blocked_ram.ld index 5b0afe65..efe5a407 100644 --- a/src/rp2_common/pico_standard_link/memmap_blocked_ram.ld +++ b/src/rp2_common/pico_standard_link/memmap_blocked_ram.ld @@ -117,10 +117,7 @@ SECTIONS __binary_info_end = .; . = ALIGN(4); - /* End of .text-like segments */ - __etext = .; - - .ram_vector_table (COPY): { + .ram_vector_table (NOLOAD): { *(.ram_vector_table) } > RAM @@ -173,8 +170,10 @@ SECTIONS /* All data end */ __data_end__ = .; } > RAM AT> FLASH + /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ + __etext = LOADADDR(.data); - .uninitialized_data (COPY): { + .uninitialized_data (NOLOAD): { . = ALIGN(4); *(.uninitialized_data*) } > RAM @@ -205,7 +204,7 @@ SECTIONS __bss_end__ = .; } > RAM - .heap (COPY): + .heap (NOLOAD): { __end__ = .; end = __end__; @@ -222,17 +221,17 @@ SECTIONS /* by default we put core 0 stack at the end of scratch Y, so that if core 1 * stack is not used then all of SCRATCH_X is free. */ - .stack1_dummy (COPY): + .stack1_dummy (NOLOAD): { *(.stack1*) } > SCRATCH_X - .stack_dummy (COPY): + .stack_dummy (NOLOAD): { *(.stack*) } > SCRATCH_Y .flash_end : { - __flash_binary_end = .; + PROVIDE(__flash_binary_end = .); } > FLASH /* stack limit is poorly named, but historically is maximum heap ptr */ diff --git a/src/rp2_common/pico_standard_link/memmap_copy_to_ram.ld b/src/rp2_common/pico_standard_link/memmap_copy_to_ram.ld index 90975b59..f149a842 100644 --- a/src/rp2_common/pico_standard_link/memmap_copy_to_ram.ld +++ b/src/rp2_common/pico_standard_link/memmap_copy_to_ram.ld @@ -96,7 +96,7 @@ SECTIONS . = ALIGN(4); /* Vector table goes first in RAM, to avoid large alignment hole */ - .ram_vector_table (COPY): { + .ram_vector_table (NOLOAD): { *(.ram_vector_table) } > RAM @@ -123,7 +123,7 @@ SECTIONS __ram_text_end__ = .; } > RAM AT> FLASH __ram_text_source__ = LOADADDR(.text); - + . = ALIGN(4); .data : { __data_start__ = .; @@ -172,10 +172,10 @@ SECTIONS /* All data end */ __data_end__ = .; } > RAM AT> FLASH - /* __etext is the name of the .data init source pointer (...) */ + /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ __etext = LOADADDR(.data); - .uninitialized_data (COPY): { + .uninitialized_data (NOLOAD): { . = ALIGN(4); *(.uninitialized_data*) } > RAM @@ -206,7 +206,7 @@ SECTIONS __bss_end__ = .; } > RAM - .heap (COPY): + .heap (NOLOAD): { __end__ = .; end = __end__; @@ -223,11 +223,11 @@ SECTIONS /* by default we put core 0 stack at the end of scratch Y, so that if core 1 * stack is not used then all of SCRATCH_X is free. */ - .stack1_dummy (COPY): + .stack1_dummy (NOLOAD): { *(.stack1*) } > SCRATCH_X - .stack_dummy (COPY): + .stack_dummy (NOLOAD): { *(.stack*) } > SCRATCH_Y diff --git a/src/rp2_common/pico_standard_link/memmap_default.ld b/src/rp2_common/pico_standard_link/memmap_default.ld index 07d5812d..638e9947 100644 --- a/src/rp2_common/pico_standard_link/memmap_default.ld +++ b/src/rp2_common/pico_standard_link/memmap_default.ld @@ -117,10 +117,7 @@ SECTIONS __binary_info_end = .; . = ALIGN(4); - /* End of .text-like segments */ - __etext = .; - - .ram_vector_table (COPY): { + .ram_vector_table (NOLOAD): { *(.ram_vector_table) } > RAM @@ -173,8 +170,10 @@ SECTIONS /* All data end */ __data_end__ = .; } > RAM AT> FLASH + /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ + __etext = LOADADDR(.data); - .uninitialized_data (COPY): { + .uninitialized_data (NOLOAD): { . = ALIGN(4); *(.uninitialized_data*) } > RAM @@ -205,7 +204,7 @@ SECTIONS __bss_end__ = .; } > RAM - .heap (COPY): + .heap (NOLOAD): { __end__ = .; end = __end__; @@ -222,17 +221,17 @@ SECTIONS /* by default we put core 0 stack at the end of scratch Y, so that if core 1 * stack is not used then all of SCRATCH_X is free. */ - .stack1_dummy (COPY): + .stack1_dummy (NOLOAD): { *(.stack1*) } > SCRATCH_X - .stack_dummy (COPY): + .stack_dummy (NOLOAD): { *(.stack*) } > SCRATCH_Y .flash_end : { - __flash_binary_end = .; + PROVIDE(__flash_binary_end = .); } > FLASH /* stack limit is poorly named, but historically is maximum heap ptr */ diff --git a/src/rp2_common/pico_standard_link/memmap_no_flash.ld b/src/rp2_common/pico_standard_link/memmap_no_flash.ld index 7a5977fa..6d1aff00 100644 --- a/src/rp2_common/pico_standard_link/memmap_no_flash.ld +++ b/src/rp2_common/pico_standard_link/memmap_no_flash.ld @@ -100,8 +100,6 @@ SECTIONS . = ALIGN(4); .data : { - /* End of .text-like segments */ - __etext = .; __data_start__ = .; *(vtable) *(.data*) @@ -143,10 +141,12 @@ SECTIONS __data_end__ = .; } > RAM - .uninitialized_data (COPY): { + .uninitialized_data (NOLOAD): { . = ALIGN(4); *(.uninitialized_data*) } > RAM + /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ + __etext = LOADADDR(.data); /* Start and end symbols must be word-aligned */ .scratch_x : { @@ -174,7 +174,7 @@ SECTIONS __bss_end__ = .; } > RAM - .heap (COPY): + .heap (NOLOAD): { __end__ = .; end = __end__; @@ -191,11 +191,11 @@ SECTIONS /* by default we put core 0 stack at the end of scratch Y, so that if core 1 * stack is not used then all of SCRATCH_X is free. */ - .stack1_dummy (COPY): + .stack1_dummy (NOLOAD): { *(.stack1*) } > SCRATCH_X - .stack_dummy (COPY): + .stack_dummy (NOLOAD): { *(.stack*) } > SCRATCH_Y diff --git a/src/rp2_common/pico_standard_link/new_delete.cpp b/src/rp2_common/pico_standard_link/new_delete.cpp index 6d632e27..19adddab 100644 --- a/src/rp2_common/pico_standard_link/new_delete.cpp +++ b/src/rp2_common/pico_standard_link/new_delete.cpp @@ -9,6 +9,7 @@ #if !PICO_CXX_DISABLE_ALLOCATION_OVERRIDES // Let user override #include +#include "pico.h" void *operator new(std::size_t n) { return std::malloc(n); diff --git a/src/rp2_common/pico_stdio_semihosting/stdio_semihosting.c b/src/rp2_common/pico_stdio_semihosting/stdio_semihosting.c index 18e90df9..291e9396 100644 --- a/src/rp2_common/pico_stdio_semihosting/stdio_semihosting.c +++ b/src/rp2_common/pico_stdio_semihosting/stdio_semihosting.c @@ -25,11 +25,11 @@ static void stdio_semihosting_out_chars(const char *buf, int length) { args.buf = buf; args.len = length; - __asm ( + unified_asm ( // r1 must contain a pointer to the arguments - "mov r1, %[args]\n" + "movs r1, %[args]\n" // semihosting call number 0x05 = SYS_WRITE - "mov r0, #5\n" + "movs r0, #5\n" // make the semihosting call: https://developer.arm.com/documentation/dui0375/g/What-is-Semihosting-/The-semihosting-interface "bkpt 0xab\n" : diff --git a/src/rp2_common/pico_stdio_usb/stdio_usb.c b/src/rp2_common/pico_stdio_usb/stdio_usb.c index 32f1f332..0dc8d6d9 100644 --- a/src/rp2_common/pico_stdio_usb/stdio_usb.c +++ b/src/rp2_common/pico_stdio_usb/stdio_usb.c @@ -20,9 +20,6 @@ #include "device/usbd_pvt.h" // for usbd_defer_func static mutex_t stdio_usb_mutex; -#ifndef NDEBUG -static uint8_t stdio_usb_core_num; -#endif #if PICO_STDIO_USB_SUPPORT_CHARS_AVAILABLE_CALLBACK static void (*chars_available_callback)(void*); @@ -181,9 +178,6 @@ bool stdio_usb_init(void) { assert(false); return false; } -#ifndef NDEBUG - stdio_usb_core_num = (uint8_t)get_core_num(); -#endif #if !PICO_NO_BI_STDIO_USB bi_decl_if_func_used(bi_program_feature("USB stdin / stdout")); #endif diff --git a/src/rp2_common/tinyusb/CMakeLists.txt b/src/rp2_common/tinyusb/CMakeLists.txt index 8b9e4743..3b931633 100644 --- a/src/rp2_common/tinyusb/CMakeLists.txt +++ b/src/rp2_common/tinyusb/CMakeLists.txt @@ -49,10 +49,12 @@ if (EXISTS ${PICO_TINYUSB_PATH}/${TINYUSB_TEST_PATH}) # Override suppress_tinyusb_warnings to add suppression of (falsely) reported GCC 11.2 warnings function(suppress_tinyusb_warnings) _suppress_tinyusb_warnings() - set_source_files_properties( - ${PICO_TINYUSB_PATH}/src/portable/raspberrypi/rp2040/rp2040_usb.c - PROPERTIES - COMPILE_FLAGS "-Wno-stringop-overflow -Wno-array-bounds") + if (PICO_C_COMPILER_IS_GNU) + set_source_files_properties( + ${PICO_TINYUSB_PATH}/src/portable/raspberrypi/rp2040/rp2040_usb.c + PROPERTIES + COMPILE_FLAGS "-Wno-stringop-overflow -Wno-array-bounds") + endif() endfunction() pico_promote_common_scope_vars() diff --git a/test/kitchen_sink/CMakeLists.txt b/test/kitchen_sink/CMakeLists.txt index 22564b9b..807ec47a 100644 --- a/test/kitchen_sink/CMakeLists.txt +++ b/test/kitchen_sink/CMakeLists.txt @@ -80,6 +80,14 @@ target_compile_options(kitchen_sink_options INTERFACE #-Wundef ) +if (PICO_C_COMPILER_IS_CLANG) + # todo fix up clang warnings + target_compile_options(kitchen_sink_options INTERFACE + -Wno-cast-qual + -Wno-unused-function + -Wno-format) +endif() + target_compile_definitions(kitchen_sink_libs INTERFACE PARAM_ASSERTIONS_ENABLE_ALL=1 # want to check all the assertions for compilation warnings PICO_AUDIO_DMA_IRQ=1 @@ -97,6 +105,8 @@ if (COMMAND suppress_tinyusb_warnings) # TinyUSB itself, so we have to guard against TinyUSB not being present with the above if suppress_tinyusb_warnings() endif() +target_compile_definitions(kitchen_sink_extra_stdio PRIVATE + TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX=1) if (TARGET pico_lwip) set_source_files_properties( ${PICO_LWIP_PATH}/src/core/ipv4/ip4_frag.c @@ -119,6 +129,11 @@ pico_set_binary_type(kitchen_sink_no_flash no_flash) target_link_libraries(kitchen_sink_no_flash kitchen_sink_libs kitchen_sink_options) pico_add_extra_outputs(kitchen_sink_no_flash) +add_executable(kitchen_sink_blocked_ram ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) +pico_set_binary_type(kitchen_sink_blocked_ram blocked_ram) +target_link_libraries(kitchen_sink_blocked_ram kitchen_sink_libs kitchen_sink_options) +pico_add_extra_outputs(kitchen_sink_blocked_ram) + add_executable(kitchen_sink_cpp ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink_cpp.cpp) target_link_libraries(kitchen_sink_cpp kitchen_sink_libs kitchen_sink_options) pico_set_program_name(kitchen_sink_cpp "Wombat tentacles CPP") diff --git a/test/kitchen_sink/kitchen_sink.c b/test/kitchen_sink/kitchen_sink.c index c030a769..ab6118f1 100644 --- a/test/kitchen_sink/kitchen_sink.c +++ b/test/kitchen_sink/kitchen_sink.c @@ -100,9 +100,6 @@ bi_decl(bi_block_device( BINARY_INFO_BLOCK_DEV_FLAG_READ | BINARY_INFO_BLOCK_DEV_FLAG_WRITE | BINARY_INFO_BLOCK_DEV_FLAG_PT_UNKNOWN)); -//#pragma GCC push_options -//#pragma GCC optimize ("O3") - uint32_t *foo = (uint32_t *) 200; uint32_t dma_to = 0; @@ -133,11 +130,14 @@ int main(void) { puts("Hello Everything!"); puts("Hello Everything2!"); + printf("main at %p\n", (void *)main); + static uint x[2]; + printf("x[0] = %p, x[1] = %p\n", x, x+1); hard_assert(mutex_try_enter(&mutex, NULL)); hard_assert(!mutex_try_enter(&mutex, NULL)); hard_assert(recursive_mutex_try_enter(&recursive_mutex, NULL)); hard_assert(recursive_mutex_try_enter(&recursive_mutex, NULL)); // this should compile as we are Cortex M0+ - __asm volatile("SVC #3"); + unified_asm ("SVC #3"); } diff --git a/test/pico_divider_test/pico_divider_nesting_test.c b/test/pico_divider_test/pico_divider_nesting_test.c index 3b5a745e..cf1b9500 100644 --- a/test/pico_divider_test/pico_divider_nesting_test.c +++ b/test/pico_divider_test/pico_divider_nesting_test.c @@ -34,16 +34,16 @@ bool timer_callback(repeating_timer_t *t) { FAILED(); } } - float fz = z; + float fz = (float)z; float fa = fz / 11.0f; float fb = fmodf(fz, 11.0f); - if (fabsf(fz - (fa * 11.0 + fb) > 1e-9)) { + if (fabs(fz - (fa * 11.0 + fb)) > 1e-9) { FAILED(); } double dz = z; double da = dz / 11.0; double db = fmod(dz, 11.0); - if (fabsf(dz - (da * 11.0 + db) > 1e-9)) { + if (fabs(dz - (da * 11.0 + db)) > 1e-9) { FAILED(); } diff --git a/test/pico_divider_test/pico_divider_test.c b/test/pico_divider_test/pico_divider_test.c index fc0e9ef8..97936f8d 100644 --- a/test/pico_divider_test/pico_divider_test.c +++ b/test/pico_divider_test/pico_divider_test.c @@ -193,10 +193,9 @@ void test_random() { #endif uint32_t __attribute__((naked)) time_32(uint32_t a, uint32_t b, uint32_t (*func)(uint32_t a, uint32_t b)) { - asm( - ".syntax unified\n" + unified_asm ( "push {r4, r5, lr}\n" - "ldr r4, =#0xe000e018\n" + "ldr r4, =0xe000e018\n" "ldr r5, [r4]\n" "blx r2\n" "ldr r0, [r4]\n" @@ -208,11 +207,10 @@ uint32_t __attribute__((naked)) time_32(uint32_t a, uint32_t b, uint32_t (*func) } uint32_t __attribute__((naked)) time_64(uint64_t a, uint64_t b, uint64_t (*func64)(uint64_t a, uint64_t b)) { - asm( - ".syntax unified\n" + unified_asm ( "push {r4-r6, lr}\n" "ldr r6, [sp, #16]\n" - "ldr r4, =#0xe000e018\n" + "ldr r4, =0xe000e018\n" "ldr r5, [r4]\n" "blx r6\n" "ldr r0, [r4]\n" diff --git a/test/pico_float_test/pico_float_test.c b/test/pico_float_test/pico_float_test.c index 73dfbc37..6cb034c3 100644 --- a/test/pico_float_test/pico_float_test.c +++ b/test/pico_float_test/pico_float_test.c @@ -398,7 +398,10 @@ int main() { printf("FEXP %10.18f\n", check_close1(expf, x)); printf("FLN %10.18f\n", check_close1(logf, x)); printf("POWF %10.18f\n", check_close2(powf, x, x)); + // todo clang why does this not compile? +#ifndef __clang__ printf("TRUNCF %10.18f\n", check_close1(truncf, x)); +#endif printf("LDEXPF %10.18f\n", check_close2(ldexpf, x, x)); printf("FMODF %10.18f\n", check_close2(fmodf, x, 3.0f)); sincosf(x, &s, &c); @@ -528,6 +531,10 @@ int main() { } for(float x = 4294967296.f * 4294967296.f; x>=0.5f; x/=2.f) { printf("d2i32 %f->%d\n", x, (int32_t)x); +#ifdef __clang__ + // seems to be a bug in clang wgere f2iz(2147483648.f) returns -2147483648 + if (x != 2147483648.f) +#endif check1(__aeabi_f2iz, x); } diff --git a/tools/elf2uf2/main.cpp b/tools/elf2uf2/main.cpp index f8d635e3..6b3c525d 100644 --- a/tools/elf2uf2/main.cpp +++ b/tools/elf2uf2/main.cpp @@ -129,7 +129,7 @@ int check_address_range(const address_ranges& valid_ranges, uint32_t addr, uint3 for(const auto& range : valid_ranges) { if (range.from <= addr && range.to >= addr + size) { if (range.type == address_range::type::NO_CONTENTS && !uninitialized) { - return fail(ERROR_INCOMPATIBLE, "ELF contains memory contents for uninitialized memory at 0x%p", addr); + return fail(ERROR_INCOMPATIBLE, "ELF contains memory contents for uninitialized memory at %p", addr); } ar = range; if (verbose) {