1 /* 2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef _PICO_PLATFORM_SECTION_MACROS_H 8 #define _PICO_PLATFORM_SECTION_MACROS_H 9 10 #ifndef __ASSEMBLER__ 11 12 /*! \brief Section attribute macro for placement in RAM after the `.data` section 13 * \ingroup pico_platform 14 * 15 * For example a 400 element `uint32_t` array placed after the .data section 16 * 17 * uint32_t __after_data("my_group_name") a_big_array[400]; 18 * 19 * The section attribute is `.after_data.<group>` 20 * 21 * \param group a string suffix to use in the section name to distinguish groups that can be linker 22 * garbage-collected independently 23 */ 24 #ifndef __after_data 25 #define __after_data(group) __attribute__((section(".after_data." group))) 26 #endif 27 28 /*! \brief Section attribute macro for placement not in flash (i.e in RAM) 29 * \ingroup pico_platform 30 * 31 * For example a 3 element `uint32_t` array placed in RAM (even though it is `static const`) 32 * 33 * static const uint32_t __not_in_flash("my_group_name") an_array[3]; 34 * 35 * The section attribute is `.time_critical.<group>` 36 * 37 * \param group a string suffix to use in the section name to distinguish groups that can be linker 38 * garbage-collected independently 39 */ 40 #ifndef __not_in_flash 41 #define __not_in_flash(group) __attribute__((section(".time_critical." group))) 42 #endif 43 44 /*! \brief Section attribute macro for placement in the SRAM bank 4 (known as "scratch X") 45 * \ingroup pico_platform 46 * 47 * Scratch X is commonly used for critical data and functions accessed only by one core (when only 48 * one core is accessing the RAM bank, there is no opportunity for stalls) 49 * 50 * For example a `uint32_t` variable placed in "scratch X" 51 * 52 * uint32_t __scratch_x("my_group_name") foo = 23; 53 * 54 * The section attribute is `.scratch_x.<group>` 55 * 56 * \param group a string suffix to use in the section name to distinguish groups that can be linker 57 * garbage-collected independently 58 */ 59 #ifndef __scratch_x 60 #define __scratch_x(group) __attribute__((section(".scratch_x." group))) 61 #endif 62 63 /*! \brief Section attribute macro for placement in the SRAM bank 5 (known as "scratch Y") 64 * \ingroup pico_platform 65 * 66 * Scratch Y is commonly used for critical data and functions accessed only by one core (when only 67 * one core is accessing the RAM bank, there is no opportunity for stalls) 68 * 69 * For example a `uint32_t` variable placed in "scratch Y" 70 * 71 * uint32_t __scratch_y("my_group_name") foo = 23; 72 * 73 * The section attribute is `.scratch_y.<group>` 74 * 75 * \param group a string suffix to use in the section name to distinguish groups that can be linker 76 * garbage-collected independently 77 */ 78 #ifndef __scratch_y 79 #define __scratch_y(group) __attribute__((section(".scratch_y." group))) 80 #endif 81 82 /*! \brief Section attribute macro for data that is to be left uninitialized 83 * \ingroup pico_platform 84 * 85 * Data marked this way will retain its value across a reset (normally uninitialized data - in the .bss 86 * section) is initialized to zero during runtime initialization 87 * 88 * For example a `uint32_t` foo that will retain its value if the program is restarted by reset. 89 * 90 * uint32_t __uninitialized_ram(foo); 91 * 92 * The section attribute is `.uninitialized_data.<group>` 93 * 94 * \param group a string suffix to use in the section name to distinguish groups that can be linker 95 * garbage-collected independently 96 */ 97 #ifndef __uninitialized_ram 98 #define __uninitialized_ram(group) __attribute__((section(".uninitialized_data." #group))) group 99 #endif 100 101 /*! \brief Section attribute macro for placement in flash even in a COPY_TO_RAM binary 102 * \ingroup pico_platform 103 * 104 * For example a `uint32_t` variable explicitly placed in flash (it will hard fault if you attempt to write it!) 105 * 106 * uint32_t __in_flash("my_group_name") foo = 23; 107 * 108 * The section attribute is `.flashdata.<group>` 109 * 110 * \param group a string suffix to use in the section name to distinguish groups that can be linker 111 * garbage-collected independently 112 */ 113 #ifndef __in_flash 114 #define __in_flash(group) __attribute__((section(".flashdata." group))) 115 #endif 116 117 /*! \brief Indicates a function should not be stored in flash 118 * \ingroup pico_platform 119 * 120 * Decorates a function name, such that the function will execute from RAM (assuming it is not inlined 121 * into a flash function by the compiler) 122 * 123 * For example a function called my_func taking an int parameter: 124 * 125 * void __not_in_flash_func(my_func)(int some_arg) { 126 * 127 * The function is placed in the `.time_critical.<func_name>` linker section 128 * 129 * \see __no_inline_not_in_flash_func 130 */ 131 #ifndef __not_in_flash_func 132 #define __not_in_flash_func(func_name) __not_in_flash(__STRING(func_name)) func_name 133 #endif 134 135 /*! \brief Indicates a function is time/latency critical and should not run from flash 136 * \ingroup pico_platform 137 * 138 * Decorates a function name, such that the function will execute from RAM (assuming it is not inlined 139 * into a flash function by the compiler) to avoid possible flash latency. Currently this macro is identical 140 * in implementation to `__not_in_flash_func`, however the semantics are distinct and a `__time_critical_func` 141 * may in the future be treated more specially to reduce the overhead when calling such function from a flash 142 * function. 143 * 144 * For example a function called my_func taking an int parameter: 145 * 146 * void __time_critical_func(my_func)(int some_arg) { 147 * 148 * The function is placed in the `.time_critical.<func_name>` linker section 149 * 150 * \see __not_in_flash_func 151 */ 152 #ifndef __time_critical_func 153 #define __time_critical_func(func_name) __not_in_flash_func(func_name) 154 #endif 155 156 /*! \brief Indicate a function should not be stored in flash and should not be inlined 157 * \ingroup pico_platform 158 * 159 * Decorates a function name, such that the function will execute from RAM, explicitly marking it as 160 * noinline to prevent it being inlined into a flash function by the compiler 161 * 162 * For example a function called my_func taking an int parameter: 163 * 164 * void __no_inline_not_in_flash_func(my_func)(int some_arg) { 165 * 166 * The function is placed in the `.time_critical.<func_name>` linker section 167 */ 168 #ifndef __no_inline_not_in_flash_func 169 #define __no_inline_not_in_flash_func(func_name) __noinline __not_in_flash_func(func_name) 170 #endif 171 172 #else 173 174 #ifndef RAM_SECTION_NAME 175 #define RAM_SECTION_NAME(x) .time_critical.##x 176 #endif 177 178 #ifndef SECTION_NAME 179 #define SECTION_NAME(x) .text.##x 180 #endif 181 182 #endif // !__ASSEMBLER__ 183 184 #endif 185 186