mirror of
https://github.com/raspberrypi/pico-sdk.git
synced 2025-02-05 18:40:21 +00:00
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)
This commit is contained in:
parent
bc7d9ce95a
commit
1ac90374e3
@ -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)
|
||||
|
@ -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. CMake<Lang>Information 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)
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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 ()
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
GCC_Pragma("GCC diagnostic pop") // conversion
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
GCC_Pragma("GCC diagnostic pop") // conversion
|
@ -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
|
||||
|
@ -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];
|
||||
|
@ -5,7 +5,6 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#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
|
||||
|
@ -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) {
|
||||
|
@ -68,9 +68,80 @@
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#if defined __GNUC__
|
||||
#include <sys/cdefs.h>
|
||||
// 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"
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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 $<$<IF:$<STREQUAL:$<TARGET_PROPERTY:PICO_TARGET_BINARY_TYPE>,no_flash>,1,$<AND:$<BOOL:${PICO_NO_FLASH}>,$<STREQUAL:,$<TARGET_PROPERTY:PICO_TARGET_BINARY_TYPE>>>>:-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 $<$<IF:$<STREQUAL:$<TARGET_PROPERTY:PICO_TARGET_BINARY_TYPE>,no_flash>,1,$<AND:$<BOOL:${PICO_NO_FLASH}>,$<STREQUAL:,$<TARGET_PROPERTY:PICO_TARGET_BINARY_TYPE>>>>:-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 $<$<NOT:$<IF:$<STREQUAL:$<TARGET_PROPERTY:PICO_TARGET_BINARY_TYPE>,no_flash>,1,$<AND:$<BOOL:${PICO_NO_FLASH}>,$<STREQUAL:,$<TARGET_PROPERTY:PICO_TARGET_BINARY_TYPE>>>>>:$<IF:$<BOOL:$<TARGET_PROPERTY:PICO_TARGET_BOOT_STAGE2>>,$<TARGET_PROPERTY:PICO_TARGET_BOOT_STAGE2>,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)
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#if !PICO_CXX_DISABLE_ALLOCATION_OVERRIDES // Let user override
|
||||
#include <cstdlib>
|
||||
#include "pico.h"
|
||||
|
||||
void *operator new(std::size_t n) {
|
||||
return std::malloc(n);
|
||||
|
@ -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"
|
||||
:
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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")
|
||||
|
@ -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");
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user