@web-font-path: "roboto-debian.css";
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. | |
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
| #define __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>
| group | a string suffix to use in the section name to distinguish groups that can be linker garbage-collected independently |
| #define __check_type_compatible | ( | type_a, | |
| 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)
| #define __fast_mul | ( | a, | |
| b ) |
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
| a | the first operand |
| b | the second operand |
| #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) {
| #define __in_flash | ( | 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>
| group | a string suffix to use in the section name to distinguish groups that can be linker garbage-collected independently |
| #define __isr | ( | void | ) |
Marker for an interrupt handler.
For example an IRQ handler function called my_interrupt_handler:
void __isr my_interrupt_handler(void) {
| #define __no_inline_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
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
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
| #define __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>
| 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>
| group | a string suffix to use in the section name to distinguish groups that can be linker garbage-collected independently |
| #define __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>
| group | a string suffix to use in the section name to distinguish groups that can be linker garbage-collected independently |
| #define __uninitialized_ram | ( | 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>
| group | a string suffix to use in the section name to distinguish groups that can be linker garbage-collected independently |
| #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.
|
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!)
|
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.
|
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.
| a | the first operand |
| b | the second operand |
|
inlinestatic |
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.
| minimum_cycles | the minimum number of system clock cycles to delay for |
|
static |
Get the current core number.
| 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.
| fmt | format string (printf-like) |
| ... | printf-like arguments |
| void panic_unsupported | ( | void | ) |
Panics with the message "Unsupported".
| uint8_t rp2040_chip_version | ( | void | ) |
Returns the RP2040 chip revision number.
|
inlinestatic |
Returns the RP2040 rom version number.
|
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