1 /* USER CODE BEGIN Header */ 2 /** 3 ****************************************************************************** 4 * @file compiler.h 5 * @author GPM WBL Application Team 6 * @brief Compiler-dependent macros. 7 ****************************************************************************** 8 * @attention 9 * 10 * Copyright (c) 2024 STMicroelectronics. 11 * All rights reserved. 12 * 13 * This software is licensed under terms that can be found in the LICENSE file 14 * in the root directory of this software component. 15 * If no LICENSE file comes with this software, it is provided AS-IS. 16 * 17 ****************************************************************************** 18 */ 19 /* USER CODE END Header */ 20 21 /* Define to prevent recursive inclusion -------------------------------------*/ 22 23 #ifndef __COMPILER_H__ 24 #define __COMPILER_H__ 25 26 #ifndef DOXYGEN_SHOULD_SKIP_THIS 27 28 #define QUOTEME(a) #a 29 30 #define FUNCTION_PROTOTYPE(func_name, ret_type, ...) ret_type func_name(__VA_ARGS__); 31 32 /** @addtogroup compiler_macros compiler macros 33 * @{ 34 */ 35 36 /** @addtogroup IAR_toolchain_macros IAR toolchain macros 37 * @{ 38 */ 39 40 /** 41 * @brief This is the section dedicated to IAR toolchain 42 */ 43 #if defined(__ICCARM__) || defined(__IAR_SYSTEMS_ASM__) 44 45 /** 46 * @brief PACKED 47 * Use the PACKED macro for variables that needs to be packed. 48 * Usage: PACKED(struct) myStruct_s 49 * PACKED(union) myStruct_s 50 */ 51 #define PACKED(decl) __packed decl 52 53 /** 54 * @brief REQUIRED 55 * Use the REQUIRED macro for variables that must be always included. 56 * Usage: REQUIRED(static uint8_t my_array[16]) 57 * REQUIRED(static int my_int) 58 */ 59 #define REQUIRED(decl) __root decl 60 61 /** 62 * @brief NORETURN_FUNCTION 63 * Use the NORETURN_FUNCTION macro to declare a no return function. 64 * Usage: NORETURN_FUNCTION(void my_noretrun_function(void)) 65 */ 66 #define NORETURN_FUNCTION(function) __noreturn function 67 68 /** 69 * @brief NOSTACK_FUNCTION 70 * Use the NOSTACK_FUNCTION macro to indicate that function should not use any stack. 71 * Typical usage is for hard fault handler, to avoid altering the value of the stack pointer. 72 * Usage: NOSTACK_FUNCTION(void my_noretrun_function(void)) 73 */ 74 #define NOSTACK_FUNCTION(function) __stackless function 75 76 /** 77 * @brief SECTION 78 * Use the SECTION macro to assign data or code in a specific section. 79 * Usage: SECTION(".my_section") 80 */ 81 #define SECTION(name) _Pragma(QUOTEME(location=name)) 82 83 /** 84 * @brief ALIGN 85 * Use the ALIGN macro to specify the alignment of a variable. 86 * Usage: ALIGN(4) 87 */ 88 #define ALIGN(v) _Pragma(QUOTEME(data_alignment=v)) 89 90 /** 91 * @brief WEAK_FUNCTION 92 * Use the WEAK_FUNCTION macro to declare a weak function. 93 * Usage: WEAK_FUNCTION(int my_weak_function(void)) 94 */ 95 #define WEAK_FUNCTION(function) __weak function 96 97 /** 98 * @brief WEAK_ALIAS_FUNCTION 99 * Use the WEAK_ALIAS_FUNCTION macro to declare a weak alias of a function. 100 * Usage: WEAK_ALIAS_FUNCTION(my_weak_alias_function, my_function, <return_type>, <args...>) 101 */ 102 #define WEAK_ALIAS_FUNCTION(new_name, old_name, ...) _Pragma(QUOTEME(weak new_name=old_name)) 103 104 /** 105 * @brief NO_INIT 106 * Use the NO_INIT macro to declare a not initialized variable in RAM 107 * Usage: NO_INIT(int my_no_init_var) 108 * Usage: NO_INIT(uint16_t my_no_init_array[10]) 109 */ 110 #define NO_INIT(var) __no_init var 111 112 /** 113 * @brief NO_INIT_SECTION 114 * Use the NO_INIT_SECTION macro to declare a not initialized variable in RAM in 115 * in a specific section. 116 * Usage: NO_INIT_SECTION(int my_no_init_var, "MySection") 117 * Usage: NO_INIT_SECTION(uint16_t my_no_init_array[10], "MySection") 118 */ 119 #define NO_INIT_SECTION(var, sect) SECTION(sect) __no_init var 120 121 /** 122 * @brief NO_INLINE 123 * This function attribute suppresses the inlining of a function at the call points of the function. 124 * Usage: NO_INLINE(void my_noinline_function(void)) 125 */ 126 #define NO_INLINE(function) _Pragma(QUOTEME(optimize=no_inline)) function 127 128 #define VARIABLE_SIZE 0 129 #pragma segment = "CSTACK" 130 #define _INITIAL_SP __sfe( "CSTACK" ) /* Stack address */ 131 extern void __iar_program_start(void); 132 #define RESET_HANDLER __iar_program_start 133 134 /** 135 * @} 136 */ 137 138 /** @addtogroup Keil_toolchain_macros Keil toolchain macros 139 * @{ 140 */ 141 142 /** 143 * @brief This is the section dedicated to Keil toolchain 144 */ 145 #else 146 #if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)) 147 148 /** 149 * @brief PACKED 150 * Use the PACKED macro for variables that needs to be packed. 151 * Usage: PACKED(struct) myStruct_s 152 * PACKED(union) myStruct_s 153 */ 154 #define PACKED(decl) decl __attribute__((packed)) 155 156 /** 157 * @brief REQUIRED 158 * Use the REQUIRED macro for variables that must be always included. 159 * Usage: REQUIRED(static uint8_t my_array[16]) 160 * REQUIRED(static int my_int) 161 */ 162 #ifndef REQUIRED 163 #define REQUIRED(decl) decl __attribute__((used)) 164 #endif 165 166 /** 167 * @brief SECTION 168 * Use the SECTION macro to assign data or code in a specific section. 169 * Usage: SECTION(".my_section") 170 */ 171 #define SECTION(name) __attribute__((section(name))) 172 173 /** 174 * @brief ALIGN 175 * Use the ALIGN macro to specify the alignment of a variable. 176 * Usage: ALIGN(4) 177 */ 178 #define ALIGN(N) __attribute__((aligned(N))) 179 180 /** 181 * @brief WEAK_ALIAS_FUNCTION 182 * Use the WEAK_ALIAS_FUNCTION macro to declare a weak alias of a function. 183 * Usage: WEAK_ALIAS_FUNCTION(my_weak_alias_function, my_function, <return_type>, <args...>) 184 */ 185 #define WEAK_ALIAS_FUNCTION(new_name, old_name, ...) \ 186 __attribute__((weak, alias(QUOTEME(old_name)))) FUNCTION_PROTOTYPE(new_name, __VA_ARGS__) 187 188 /** 189 * @brief NORETURN_FUNCTION 190 * Use the NORETURN_FUNCTION macro to declare a no return function. 191 * Usage: NORETURN_FUNCTION(void my_noretrun_function(void)) 192 */ 193 #define NORETURN_FUNCTION(function) __attribute__((noreturn)) function 194 195 /** 196 * @brief NOSTACK_FUNCTION 197 * Use the NOSTACK_FUNCTION macro to indicate that function should not use any stack. 198 * Typical usage is for hard fault handler, to avoid altering the value of the stack pointer. 199 * In keil this is a dummy implementation since no equivalent function is available 200 * Usage: NOSTACK_FUNCTION(void my_noretrun_function(void)) 201 */ 202 #define NOSTACK_FUNCTION(function) function 203 204 /** 205 * @brief NO_INLINE 206 * This function attribute suppresses the inlining of a function at the call points of the function. 207 * Usage: NO_INLINE(void my_noinline_function(void)) 208 */ 209 #define NO_INLINE(function) __attribute__((noinline)) function 210 211 #if defined(__CC_ARM) 212 /** 213 * @brief WEAK_FUNCTION 214 * Use the WEAK_FUNCTION macro to declare a weak function. 215 * Usage: WEAK_FUNCTION(int my_weak_function(void)) 216 */ 217 #define WEAK_FUNCTION(function) __weak function 218 219 /** 220 * @brief NO_INIT 221 * Use the NO_INIT macro to declare a not initialized variable. 222 * Usage: NO_INIT(int my_no_init_var) 223 * Usage: NO_INIT(uint16_t my_no_init_array[10]) 224 */ 225 #define NO_INIT(var) var __attribute__((section( ".noinit.data" ), zero_init)) 226 227 /** 228 * @brief NO_INIT_SECTION 229 * Use the NO_INIT_SECTION macro to declare a not initialized variable that should be placed in a specific section. 230 * Linker script is in charge of placing that section in RAM. 231 * Usage: NO_INIT_SECTION(int my_no_init_var, "MySection") 232 * Usage: NO_INIT_SECTION(uint16_t my_no_init_array[10], "MySection") 233 */ 234 #define NO_INIT_SECTION(var, sect) var __attribute__((section( sect ), zero_init)) 235 #elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) 236 /** 237 * @brief WEAK_FUNCTION 238 * Use the WEAK_FUNCTION macro to declare a weak function. 239 * Usage: WEAK_FUNCTION(int my_weak_function(void)) 240 */ 241 #define WEAK_FUNCTION(function) __attribute__((weak)) function 242 243 /** 244 * @brief NO_INIT 245 * Use the NO_INIT macro to declare a not initialized variable. 246 * Usage: NO_INIT(int my_no_init_var) 247 * Usage: NO_INIT(uint16_t my_no_init_array[10]) 248 */ 249 #define NO_INIT(var) var __attribute__((section(".bss.noinit.data"))) 250 251 /** 252 * @brief NO_INIT_SECTION 253 * Use the NO_INIT_SECTION macro to declare a not initialized variable that should be placed in a specific section. 254 * Linker script is in charge of placing that section in RAM. 255 * Usage: NO_INIT_SECTION(int my_no_init_var, "MySection") 256 * Usage: NO_INIT_SECTION(uint16_t my_no_init_array[10], "MySection") 257 */ 258 #define NO_INIT_SECTION(var, sect) var __attribute__((section(".bss" sect))) 259 260 #endif 261 262 extern void __main(void); 263 extern int main(void); 264 extern unsigned int Image$$ARM_LIB_STACK$$ZI$$Limit; 265 #define _INITIAL_SP (void(*)(void))&Image$$ARM_LIB_STACK$$ZI$$Limit /* Stack address */ 266 #define VARIABLE_SIZE 1 267 268 /** 269 * @} 270 */ 271 272 /** @addtogroup GCC_toolchain_macros GCC toolchain macros 273 * @{ 274 */ 275 276 /** 277 * @brief This is the section dedicated to GCC toolchain 278 */ 279 #else 280 #ifdef __GNUC__ 281 282 /** 283 * @brief PACKED 284 * Use the PACKED macro for variables that needs to be packed. 285 * Usage: PACKED(struct) myStruct_s 286 * PACKED(union) myStruct_s 287 */ 288 #define PACKED(decl) decl __attribute__((packed)) 289 290 /** 291 * @brief REQUIRED 292 * Use the REQUIRED macro for variables that must be always included. 293 * Usage: REQUIRED(static uint8_t my_array[16]) 294 * REQUIRED(static int my_int) 295 */ 296 #define REQUIRED(var) var __attribute__((used)) 297 298 /** 299 * @brief SECTION 300 * Use the SECTION macro to assign data or code in a specific section. 301 * Usage: SECTION(".my_section") 302 */ 303 #define SECTION(name) __attribute__((section(name))) 304 305 /** 306 * @brief ALIGN 307 * Use the ALIGN macro to specify the alignment of a variable. 308 * Usage: ALIGN(4) 309 */ 310 #define ALIGN(N) __attribute__((aligned(N))) 311 312 /** 313 * @brief WEAK_FUNCTION 314 * Use the WEAK_FUNCTION macro to declare a weak function. 315 * Usage: WEAK_FUNCTION(int my_weak_function(void)) 316 */ 317 #define WEAK_FUNCTION(function) __attribute__((weak)) function 318 319 /** 320 * @brief WEAK_ALIAS_FUNCTION 321 * Use the WEAK_ALIAS_FUNCTION macro to declare a weak alias of a function. 322 * Usage: WEAK_ALIAS_FUNCTION(my_weak_alias_function, my_function, <return_type>, <args...>) 323 */ 324 #define WEAK_ALIAS_FUNCTION(new_name, old_name, ...) \ 325 __attribute__((weak, alias(QUOTEME(old_name)))) FUNCTION_PROTOTYPE(new_name, __VA_ARGS__) 326 327 /** 328 * @brief NORETURN_FUNCTION 329 * Use the NORETURN_FUNCTION macro to declare a no return function. 330 * Usage: NORETURN_FUNCTION(void my_noretrun_function(void)) 331 */ 332 #define NORETURN_FUNCTION(function) __attribute__((noreturn)) function 333 334 /** 335 * @brief NOSTACK_FUNCTION 336 * Use the NOSTACK_FUNCTION macro to indicate that function should not use any stack. 337 * Typical usage is for hard fault handler, to avoid altering the value of the stack pointer. 338 * In keil this is a dummy implementation since no equivalent function is available 339 * Usage: NOSTACK_FUNCTION(void my_noretrun_function(void)) 340 */ 341 #define NOSTACK_FUNCTION(function) function 342 343 /** 344 * @brief NO_INIT 345 * Use the NO_INIT macro to declare a not initialized variable placed in RAM 346 * Linker script has to make sure that section ".noinit" is not initialized 347 * Usage: NO_INIT(int my_no_init_var) 348 * Usage: NO_INIT(uint16_t my_no_init_array[10]) 349 */ 350 #define NO_INIT(var) var __attribute__((section(".noinit"))) 351 352 /** 353 * @brief NO_INIT_SECTION 354 * Use the NO_INIT_SECTION macro to declare a not initialized variable. 355 * In order to work properly this macro should be aligned with the linker file. 356 * Usage: NO_INIT_SECTION(int my_no_init_var, "MySection") 357 * Usage: NO_INIT_SECTION(uint16_t my_no_init_array[10], "MySection") 358 */ 359 #define NO_INIT_SECTION(var, sect) var __attribute__((section(sect))) 360 361 /** 362 * @brief NO_INLINE 363 * This function attribute suppresses the inlining of a function at the call points of the function. 364 * Usage: NO_INIT_SECTION(void my_noinline_function(void)) 365 */ 366 #define NO_INLINE(function) __attribute__((noinline)) function 367 368 #define _INITIAL_SP (void(*)(void))(&_estack) 369 #define VARIABLE_SIZE 0 370 371 #else 372 373 #error Neither ICCARM, CC ARM nor GNUC C detected. Define your macros. 374 375 #endif 376 #endif 377 #endif 378 379 /** 380 * @} 381 */ 382 383 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 384 #endif /* __COMPILER_H__ */ 385