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