@web-font-path: "roboto-debian.css";
v2.2.0 (RP2040)
Loading...
Searching...
No Matches
pico_platform

Macros and definitions (and functions when included by non assembly code) for the RP2 family device / architecture to provide a common abstraction over low level compiler / platform specifics. More...

## Files

file | common.h
| Macros and definitions common to all rp2 platforms but not specific to any library.
file | compiler.h
| Macros and definitions (and functions when included by non assembly code) to adapt for different compilers.

## Macros

#define | __fast_mul(a, b)
| multiply two integer values using the fastest method possible
#define | __isr
| Marker for an interrupt handler.
#define | __force_inline __always_inline
| Attribute to force inlining of a function regardless of optimization level.
#define | count_of(a)
| Macro to determine the number of elements in an array.
#define | MAX(a, b)
| Macro to return the maximum of two comparable values.
#define | MIN(a, b)
| Macro to return the minimum of two comparable values.
#define | __check_type_compatible(type_a, type_b)
| Utility macro to assert two types are equivalent.
#define | __after_data(group)
| Section attribute macro for placement in RAM after the .data section.
#define | __scratch_x(group)
| Section attribute macro for placement not in flash (i.e in RAM).
#define | __scratch_y(group)
| Section attribute macro for placement in the SRAM bank 5 (known as "scratch Y").
#define | __uninitialized_ram(group)
| Section attribute macro for data that is to be left uninitialized.
#define | __in_flash(group)
| Section attribute macro for placement in flash even in a COPY_TO_RAM binary.
#define | __no_inline_not_in_flash_func(func_name)
| Indicates a function should not be stored in flash.

## Functions

static void | busy_wait_at_least_cycles (uint32_t minimum_cycles)
| Helper method to busy-wait for at least the given number of cycles.
static __force_inline void | __breakpoint (void)
| Execute a breakpoint instruction.
static __force_inline uint | get_core_num (void)
| Get the current core number.
static __force_inline uint | __get_current_exception (void)
| Get the current exception level on this core.
uint8_t | rp2040_chip_version (void)
| Returns the RP2040 chip revision number.
static uint8_t | rp2040_rom_version (void)
| Returns the RP2040 rom version number.
static __force_inline int32_t | __mul_instruction (int32_t a, int32_t b)
| Multiply two integers using an assembly MUL instruction.
static __force_inline void | tight_loop_contents (void)
| No-op function for the body of tight loops.
static __always_inline void | __compiler_memory_barrier (void)
| Ensure that the compiler does not move memory access across this method call.
void | panic_unsupported (void)
| Panics with the message "Unsupported".
void | panic (const char *fmt,...)
| Displays a panic message and halts execution.

## Detailed Description

Macros and definitions (and functions when included by non assembly code) for the RP2 family device / architecture to provide a common abstraction over low level compiler / platform specifics.

Macros and definitions for accessing the CPU registers.

This header may be included by assembly code

## Macro Definition Documentation

## __after_data

#define __after_data | ( |  | group | ) |

Value:
__attribute__((section(".after_data." group)))

Section attribute macro for placement in RAM after the .data section.

For example a 400 element uint32_t array placed after the .data section

    uint32_t __after_data("my_group_name") a_big_array[400];

The section attribute is .after_data.<group>

Parameters

  group | a string suffix to use in the section name to distinguish groups that can be linker garbage-collected independently

## __check_type_compatible

#define __check_type_compatible | ( |  | type_a,
|  |  | type_b )

Value:
static_assert(__builtin_types_compatible_p(type_a, type_b), __STRING(type_a) " is not compatible with " __STRING(type_b));

Utility macro to assert two types are equivalent.

This macro can be useful in other macros along with typeof to assert that two parameters are of equivalent type (or that a single parameter is of an expected type)

## __fast_mul

#define __fast_mul | ( |  | a,
|  |  | b )

Value:
__builtin_choose_expr(__builtin_constant_p(b) && !__builtin_constant_p(a), \
(__builtin_popcount(b) >= 2 ? __mul_instruction(a,b) : (a)*(b)), \
(a)*(b))
__mul_instruction
static __force_inline int32_t __mul_instruction(int32_t a, int32_t b)
Multiply two integers using an assembly MUL instruction.
Definition platform.h:164

multiply two integer values using the fastest method possible

Efficiently multiplies value a by possibly constant value b.

If b is known to be constant and not zero or a power of 2, then a mul instruction is used rather than gcc's default which is often a slow combination of shifts and adds. If b is a power of 2 then a single shift is of course preferable and will be used

Parameters

  a | the first operand
  b | the second operand

Returns
  a * b

## __force_inline

#define __force_inline __always_inline

Attribute to force inlining of a function regardless of optimization level.

For example my_function here will always be inlined:

    int __force_inline my_function(int x) {

## __in_flash

#define __in_flash | ( |  | group | ) |

Value:
__attribute__((section(".flashdata." group)))

Section attribute macro for placement in flash even in a COPY_TO_RAM binary.

For example a uint32_t variable explicitly placed in flash (it will hard fault if you attempt to write it!)

    uint32_t __in_flash("my_group_name") foo = 23;

The section attribute is .flashdata.<group>

Parameters

  group | a string suffix to use in the section name to distinguish groups that can be linker garbage-collected independently

## __isr

#define __isr | ( |  | void | ) |

Marker for an interrupt handler.

For example an IRQ handler function called my_interrupt_handler:

    void __isr my_interrupt_handler(void) {

## __no_inline_not_in_flash_func

#define __no_inline_not_in_flash_func | ( |  | func_name | ) |

Value:
__noinline __not_in_flash_func(func_name)

Indicates a function should not be stored in flash.

Decorates a function name, such that the function will execute from RAM (assuming it is not inlined into a flash function by the compiler)

For example a function called my_func taking an int parameter:

    void __not_in_flash_func(my_func)(int some_arg) {

The function is placed in the .time_critical.<func_name> linker section

See also
  __no_inline_not_in_flash_func

Indicates a function is time/latency critical and should not run from flash

Decorates a function name, such that the function will execute from RAM (assuming it is not inlined into a flash function by the compiler) to avoid possible flash latency. Currently this macro is identical in implementation to __not_in_flash_func, however the semantics are distinct and a __time_critical_func may in the future be treated more specially to reduce the overhead when calling such function from a flash function.

For example a function called my_func taking an int parameter:

    void __time_critical_func(my_func)(int some_arg) {

The function is placed in the .time_critical.<func_name> linker section

See also
  __not_in_flash_func

Indicate a function should not be stored in flash and should not be inlined

Decorates a function name, such that the function will execute from RAM, explicitly marking it as noinline to prevent it being inlined into a flash function by the compiler

For example a function called my_func taking an int parameter:

    void __no_inline_not_in_flash_func(my_func)(int some_arg) {

The function is placed in the .time_critical.<func_name> linker section

## __scratch_x

#define __scratch_x | ( |  | group | ) |

Value:
__attribute__((section(".scratch_x." group)))

Section attribute macro for placement not in flash (i.e in RAM).

For example a 3 element uint32_t array placed in RAM (even though it is static const)

    static const uint32_t __not_in_flash("my_group_name") an_array[3];

The section attribute is .time_critical.<group>

Parameters

  group | a string suffix to use in the section name to distinguish groups that can be linker garbage-collected independently

Section attribute macro for placement in the SRAM bank 4 (known as "scratch X")

Scratch X is commonly used for critical data and functions accessed only by one core (when only one core is accessing the RAM bank, there is no opportunity for stalls)

For example a uint32_t variable placed in "scratch X"

    uint32_t __scratch_x("my_group_name") foo = 23;

The section attribute is .scratch_x.<group>

Parameters

  group | a string suffix to use in the section name to distinguish groups that can be linker garbage-collected independently

## __scratch_y

#define __scratch_y | ( |  | group | ) |

Value:
__attribute__((section(".scratch_y." group)))

Section attribute macro for placement in the SRAM bank 5 (known as "scratch Y").

Scratch Y is commonly used for critical data and functions accessed only by one core (when only one core is accessing the RAM bank, there is no opportunity for stalls)

For example a uint32_t variable placed in "scratch Y"

    uint32_t __scratch_y("my_group_name") foo = 23;

The section attribute is .scratch_y.<group>

Parameters

  group | a string suffix to use in the section name to distinguish groups that can be linker garbage-collected independently

## __uninitialized_ram

#define __uninitialized_ram | ( |  | group | ) |

Value:
__attribute__((section(".uninitialized_data." #group))) group

Section attribute macro for data that is to be left uninitialized.

Data marked this way will retain its value across a reset (normally uninitialized data - in the .bss section) is initialized to zero during runtime initialization

For example a uint32_t foo that will retain its value if the program is restarted by reset.

    uint32_t __uninitialized_ram(foo);

The section attribute is .uninitialized_data.<group>

Parameters

  group | a string suffix to use in the section name to distinguish groups that can be linker garbage-collected independently

## count_of

#define count_of | ( |  | a | ) |

Value:
(sizeof(a)/sizeof((a)[0]))

Macro to determine the number of elements in an array.

## MAX

#define MAX | ( |  | a,
|  |  | b )

Value:
((a)>(b)?(a):(b))

Macro to return the maximum of two comparable values.

## MIN

#define MIN | ( |  | a,
|  |  | b )

Value:
((b)>(a)?(a):(b))

Macro to return the minimum of two comparable values.

## Function Documentation

## __compiler_memory_barrier()

__always_inline void __compiler_memory_barrier | ( | void |  | ) |

static

Ensure that the compiler does not move memory access across this method call.

For example in the following code:

    *some_memory_location = var_a;
    __compiler_memory_barrier();
    uint32_t var_b = *some_other_memory_location

The compiler will not move the load from some_other_memory_location above the memory barrier (which it otherwise might - even above the memory store!)

## __get_current_exception()

__force_inline uint __get_current_exception | ( | void |  | ) |

static

Get the current exception level on this core.

On Cortex-M this is the exception number defined in the architecture reference, which is equal to VTABLE_FIRST_IRQ + irq num if inside an interrupt handler. (VTABLE_FIRST_IRQ is defined in platform_defs.h).

On Hazard3, this function returns VTABLE_FIRST_IRQ + irq num if inside of an external IRQ handler (or a fault from such a handler), and 0 otherwise, generally aligning with the Cortex-M values.

Returns
  the exception number if the CPU is handling an exception, or 0 otherwise

## __mul_instruction()

__force_inline int32_t __mul_instruction | ( | int32_t | a,
|  | int32_t | b )

static

Multiply two integers using an assembly MUL instruction.

This multiplies a by b using multiply instruction using the ARM mul instruction regardless of values (the compiler might otherwise choose to perform shifts/adds), i.e. this is a 1 cycle operation.

Parameters

  a | the first operand
  b | the second operand

Returns
  a * b

## busy_wait_at_least_cycles()

void busy_wait_at_least_cycles | ( | uint32_t | minimum_cycles | ) |

inline static

Helper method to busy-wait for at least the given number of cycles.

This method is useful for introducing very short delays.

This method busy-waits in a tight loop for the given number of system clock cycles. The total wait time is only accurate to within 2 cycles, and this method uses a loop counter rather than a hardware timer, so the method will always take longer than expected if an interrupt is handled on the calling core during the busy-wait; you can of course disable interrupts to prevent this.

You can use clock_get_hz(clk_sys) to determine the number of clock cycles per second if you want to convert an actual time duration to a number of cycles.

Parameters

  minimum_cycles | the minimum number of system clock cycles to delay for

## get_core_num()

__force_inline uint get_core_num | ( | void |  | ) |

static

Get the current core number.

Returns
  The core number the call was made from

## panic()

void panic | ( | const char * | fmt,
|  |  | ... )

Displays a panic message and halts execution.

An attempt is made to output the message to all registered STDOUT drivers after which this method executes a BKPT instruction.

Parameters

  fmt | format string (printf-like)
  ... | printf-like arguments

## panic_unsupported()

void panic_unsupported | ( | void |  | ) |

Panics with the message "Unsupported".

See also
  panic

## rp2040_chip_version()

uint8_t rp2040_chip_version | ( | void |  | ) |

Returns the RP2040 chip revision number.

Returns
  the RP2040 chip revision number (1 for B0/B1, 2 for B2)

## rp2040_rom_version()

uint8_t rp2040_rom_version | ( | void |  | ) |

inline static

Returns the RP2040 rom version number.

Returns
  the RP2040 rom version number (1 for RP2040-B0, 2 for RP2040-B1, 3 for RP2040-B2)

## tight_loop_contents()

__force_inline void tight_loop_contents | ( | void |  | ) |

static

No-op function for the body of tight loops.

No-op function intended to be called by any tight hardware polling loop. Using this ubiquitously makes it much easier to find tight loops, but also in the future #ifdef-ed support for lockup debugging might be added