Mistake on this page?
Report an issue in GitHub or email us
mbed_toolchain.h
1 
2 /** \addtogroup platform */
3 /** @{*/
4 /**
5  * \defgroup platform_toolchain Toolchain functions
6  * @{
7  */
8 
9 /* mbed Microcontroller Library
10  * Copyright (c) 2006-2013 ARM Limited
11  * SPDX-License-Identifier: Apache-2.0
12  *
13  * Licensed under the Apache License, Version 2.0 (the "License");
14  * you may not use this file except in compliance with the License.
15  * You may obtain a copy of the License at
16  *
17  * http://www.apache.org/licenses/LICENSE-2.0
18  *
19  * Unless required by applicable law or agreed to in writing, software
20  * distributed under the License is distributed on an "AS IS" BASIS,
21  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  * See the License for the specific language governing permissions and
23  * limitations under the License.
24  */
25 #ifndef MBED_TOOLCHAIN_H
26 #define MBED_TOOLCHAIN_H
27 
28 #include "mbed_preprocessor.h"
29 
30 
31 // Warning for unsupported compilers
32 #if !defined(__GNUC__) /* GCC */ \
33  && !defined(__CC_ARM) /* ARMCC */ \
34  && !defined(__clang__) /* LLVM/Clang */ \
35  && !defined(__ICCARM__) /* IAR */
36 #warning "This compiler is not yet supported."
37 #endif
38 
39 
40 // Attributes
41 
42 /** MBED_PACKED
43  * Pack a structure, preventing any padding from being added between fields.
44  *
45  * @code
46  * #include "mbed_toolchain.h"
47  *
48  * MBED_PACKED(struct) foo {
49  * char x;
50  * int y;
51  * };
52  * @endcode
53  */
54 #ifndef MBED_PACKED
55 #if defined(__ICCARM__)
56 #define MBED_PACKED(struct) __packed struct
57 #else
58 #define MBED_PACKED(struct) struct __attribute__((packed))
59 #endif
60 #endif
61 
62 /** MBED_ALIGN(N)
63  * Declare a variable to be aligned on an N-byte boundary.
64  *
65  * @note
66  * IAR does not support alignment greater than word size on the stack
67  *
68  * @code
69  * #include "mbed_toolchain.h"
70  *
71  * MBED_ALIGN(16) char a;
72  * @endcode
73  */
74 #ifndef MBED_ALIGN
75 #if __cplusplus >= 201103 && !defined __CC_ARM
76 #define MBED_ALIGN(N) alignas(N)
77 #elif __STDC_VERSION__ >= 201112 && !defined __CC_ARM
78 #define MBED_ALIGN(N) _Alignas(N)
79 #elif defined(__ICCARM__)
80 #define MBED_ALIGN(N) _Pragma(MBED_STRINGIFY(data_alignment=N))
81 #else
82 #define MBED_ALIGN(N) __attribute__((aligned(N)))
83 #endif
84 #endif
85 
86 /** MBED_UNUSED
87  * Declare a function argument to be unused, suppressing compiler warnings
88  *
89  * @code
90  * #include "mbed_toolchain.h"
91  *
92  * void foo(MBED_UNUSED int arg) {
93  *
94  * }
95  * @endcode
96  */
97 #ifndef MBED_UNUSED
98 #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
99 #define MBED_UNUSED __attribute__((__unused__))
100 #else
101 #define MBED_UNUSED
102 #endif
103 #endif
104 
105 /** MBED_USED
106  * Inform the compiler that a static variable is to be retained in the object file, even if it is unreferenced.
107  *
108  * @code
109  * #include "mbed_toolchain.h"
110  *
111  * MBED_USED int foo;
112  *
113  * @endcode
114  */
115 #ifndef MBED_USED
116 #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
117 #define MBED_USED __attribute__((used))
118 #elif defined(__ICCARM__)
119 #define MBED_USED __root
120 #else
121 #define MBED_USED
122 #endif
123 #endif
124 
125 /** MBED_WEAK
126  * Mark a function as being weak.
127  *
128  * @note
129  * Functions should only be marked as weak in the source file. The header file
130  * should contain a regular function declaration to insure the function is emitted.
131  * A function marked weak will not be emitted if an alternative non-weak
132  * implementation is defined.
133  *
134  * @note
135  * Weak functions are not friendly to making code re-usable, as they can only
136  * be overridden once (and if they are multiply overridden the linker will emit
137  * no warning). You should not normally use weak symbols as part of the API to
138  * re-usable modules.
139  *
140  * @code
141  * #include "mbed_toolchain.h"
142  *
143  * MBED_WEAK void foo() {
144  * // a weak implementation of foo that can be overriden by a definition
145  * // without __weak
146  * }
147  * @endcode
148  */
149 #ifndef MBED_WEAK
150 #if defined(__ICCARM__)
151 #define MBED_WEAK __weak
152 #elif defined(__MINGW32__)
153 #define MBED_WEAK
154 #else
155 #define MBED_WEAK __attribute__((weak))
156 #endif
157 #endif
158 
159 /** MBED_COMPILER_BARRIER
160  * Stop the compiler moving memory accesses.
161  *
162  * The barrier stops memory accesses from being moved from one side of the
163  * barrier to the other for safety against other threads and interrupts.
164  *
165  * This macro should only be used if we know only one CPU is accessing the data,
166  * or we are otherwise synchronising CPUs via acquire/release instructions.
167  * Otherwise, use MBED_BARRIER, which will act as a compiler barrier and also
168  * a CPU barrier if necessary.
169  *
170  * @internal
171  * This is not for use by normal code - it is a building block for the
172  * higher-level functions in mbed_critical.h. Higher-level lock/unlock or
173  * acquire/release APIs always provide ordering semantics, using this if
174  * necessary.
175  *
176  * @code
177  * #include "mbed_toolchain.h"
178  *
179  * void atomic_flag_clear_armv8(atomic_flag *flagPtr)
180  * {
181  * // ARMv8 LDA and STL instructions provide sequential consistency against
182  * // other CPUs, so no CPU barrier is needed. But we still need compiler
183  * // barriers to give us sequentially-consistent release semantics with
184  * // respect to compiler reordering - __STLB does not currently
185  * // include this.
186  * MBED_COMPILER_BARRIER();
187  * __STLB(&flagPtr->_flag, false);
188  * MBED_COMPILER_BARRIER();
189  * }
190  */
191 #ifdef __CC_ARM
192 #define MBED_COMPILER_BARRIER() __memory_changed()
193 #elif defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
194 #define MBED_COMPILER_BARRIER() asm volatile("" : : : "memory")
195 #else
196 #error "Missing MBED_COMPILER_BARRIER implementation"
197 #endif
198 
199 /** MBED_BARRIER
200  * Stop the compiler, and CPU if SMP, from moving memory accesses.
201  *
202  * The barrier stops memory accesses from being moved from one side of the
203  * barrier to the other for safety against other threads and interrupts,
204  * potentially on other CPUs.
205  *
206  * In a single-CPU system, this is just a compiler barrier.
207  * If we supported multiple CPUs, this would be a DMB (with implied compiler
208  * barrier).
209  *
210  * @internal
211  * This is not for use by normal code - it is a building block for the
212  * higher-level functions in mbed_critical.h. Higher-level lock/unlock or
213  * acquire/release APIs always provide ordering semantics, using this if
214  * necessary.
215  * @code
216  * #include "mbed_toolchain.h"
217  *
218  * void atomic_flag_clear_armv7(atomic_flag *flagPtr)
219  * {
220  * // ARMv7 LDR and STR instructions do not provide any ordering
221  * // consistency against other CPUs, so explicit barrier DMBs are needed
222  * // for a multi-CPU system, otherwise just compiler barriers for single-CPU.
223  * MBED_BARRIER();
224  * flagPtr->_flag = false;
225  * MBED_BARRIER();
226  * }
227  */
228 #define MBED_BARRIER() MBED_COMPILER_BARRIER()
229 
230 /** MBED_PURE
231  * Hint to the compiler that a function depends only on parameters
232  *
233  * @code
234  * #include "mbed_toolchain.h"
235  *
236  * MBED_PURE int foo(int arg){
237  * // no access to global variables
238  * }
239  * @endcode
240  */
241 #ifndef MBED_PURE
242 #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
243 #define MBED_PURE __attribute__((const))
244 #else
245 #define MBED_PURE
246 #endif
247 #endif
248 
249 /** MBED_NOINLINE
250  * Declare a function that must not be inlined.
251  *
252  * @code
253  * #include "mbed_toolchain.h"
254  *
255  * MBED_NOINLINE void foo() {
256  *
257  * }
258  * @endcode
259  */
260 #ifndef MBED_NOINLINE
261 #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
262 #define MBED_NOINLINE __attribute__((noinline))
263 #elif defined(__ICCARM__)
264 #define MBED_NOINLINE _Pragma("inline=never")
265 #else
266 #define MBED_NOINLINE
267 #endif
268 #endif
269 
270 /** MBED_FORCEINLINE
271  * Declare a function that must always be inlined. Failure to inline
272  * such a function will result in an error.
273  *
274  * @code
275  * #include "mbed_toolchain.h"
276  *
277  * MBED_FORCEINLINE void foo() {
278  *
279  * }
280  * @endcode
281  */
282 #ifndef MBED_FORCEINLINE
283 #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
284 #define MBED_FORCEINLINE inline __attribute__((always_inline))
285 #elif defined(__ICCARM__)
286 #define MBED_FORCEINLINE _Pragma("inline=forced")
287 #else
288 #define MBED_FORCEINLINE inline
289 #endif
290 #endif
291 
292 /** MBED_NORETURN
293  * Declare a function that will never return.
294  *
295  * @code
296  * #include "mbed_toolchain.h"
297  *
298  * MBED_NORETURN void foo() {
299  * // must never return
300  * while (1) {}
301  * }
302  * @endcode
303  */
304 #ifndef MBED_NORETURN
305 #if __cplusplus >= 201103
306 #define MBED_NORETURN [[noreturn]]
307 #elif __STDC_VERSION__ >= 201112
308 #define MBED_NORETURN _Noreturn
309 #elif defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
310 #define MBED_NORETURN __attribute__((noreturn))
311 #elif defined(__ICCARM__)
312 #define MBED_NORETURN __noreturn
313 #else
314 #define MBED_NORETURN
315 #endif
316 #endif
317 
318 /** MBED_UNREACHABLE
319  * An unreachable statement. If the statement is reached,
320  * behavior is undefined. Useful in situations where the compiler
321  * cannot deduce if the code is unreachable.
322  *
323  * @code
324  * #include "mbed_toolchain.h"
325  *
326  * void foo(int arg) {
327  * switch (arg) {
328  * case 1: return 1;
329  * case 2: return 2;
330  * ...
331  * }
332  * MBED_UNREACHABLE;
333  * }
334  * @endcode
335  */
336 #ifndef MBED_UNREACHABLE
337 #if (defined(__GNUC__) || defined(__clang__)) && !defined(__CC_ARM)
338 #define MBED_UNREACHABLE __builtin_unreachable()
339 #else
340 #define MBED_UNREACHABLE while (1)
341 #endif
342 #endif
343 
344 /** MBED_DEPRECATED("message string")
345  * Mark a function declaration as deprecated, if it used then a warning will be
346  * issued by the compiler possibly including the provided message. Note that not
347  * all compilers are able to display the message.
348  *
349  * @code
350  * #include "mbed_toolchain.h"
351  *
352  * MBED_DEPRECATED("don't foo any more, bar instead")
353  * void foo(int arg);
354  * @endcode
355  */
356 #ifndef MBED_DEPRECATED
357 #if defined(__CC_ARM)
358 #define MBED_DEPRECATED(M) __attribute__((deprecated))
359 #elif defined(__GNUC__) || defined(__clang__)
360 #define MBED_DEPRECATED(M) __attribute__((deprecated(M)))
361 #else
362 #define MBED_DEPRECATED(M)
363 #endif
364 #endif
365 
366 /** MBED_DEPRECATED_SINCE("version", "message string")
367  * Mark a function declaration as deprecated, noting that the declaration was
368  * deprecated on the specified version. If the function is used then a warning
369  * will be issued by the compiler possibly including the provided message.
370  * Note that not all compilers are able to display this message.
371  *
372  * @code
373  * #include "mbed_toolchain.h"
374  *
375  * MBED_DEPRECATED_SINCE("mbed-os-5.1", "don't foo any more, bar instead")
376  * void foo(int arg);
377  * @endcode
378  */
379 #define MBED_DEPRECATED_SINCE(D, M) MBED_DEPRECATED(M " [since " D "]")
380 
381 /** MBED_CALLER_ADDR()
382  * Returns the caller of the current function.
383  *
384  * @note
385  * This macro is only implemented for GCC and ARMCC.
386  *
387  * @code
388  * #include "mbed_toolchain.h"
389  *
390  * printf("This function was called from %p", MBED_CALLER_ADDR());
391  * @endcode
392  *
393  * @return Address of the calling function
394  */
395 #ifndef MBED_CALLER_ADDR
396 #if (defined(__GNUC__) || defined(__clang__)) && !defined(__CC_ARM)
397 #define MBED_CALLER_ADDR() __builtin_extract_return_addr(__builtin_return_address(0))
398 #elif defined(__CC_ARM)
399 #define MBED_CALLER_ADDR() __builtin_return_address(0)
400 #else
401 #define MBED_CALLER_ADDR() (NULL)
402 #endif
403 #endif
404 
405 #ifndef MBED_SECTION
406 #if (defined(__GNUC__) || defined(__clang__)) || defined(__CC_ARM)
407 #define MBED_SECTION(name) __attribute__ ((section (name)))
408 #elif defined(__ICCARM__)
409 #define MBED_SECTION(name) _Pragma(MBED_STRINGIFY(location=name))
410 #else
411 #error "Missing MBED_SECTION directive"
412 #endif
413 #endif
414 
415 /**
416  * Macro expanding to a string literal of the enclosing function name.
417  *
418  * The string returned takes into account language specificity and yield human
419  * readable content.
420  *
421  * As an example, if the macro is used within a C++ function then the string
422  * literal containing the function name will contain the complete signature of
423  * the function - including template parameters - and namespace qualifications.
424  */
425 #ifndef MBED_PRETTY_FUNCTION
426 #define MBED_PRETTY_FUNCTION __PRETTY_FUNCTION__
427 #endif
428 
429 #ifndef MBED_PRINTF
430 #if defined(__GNUC__) || defined(__CC_ARM)
431 #define MBED_PRINTF(format_idx, first_param_idx) __attribute__ ((__format__(__printf__, format_idx, first_param_idx)))
432 #else
433 #define MBED_PRINTF(format_idx, first_param_idx)
434 #endif
435 #endif
436 
437 #ifndef MBED_PRINTF_METHOD
438 #if defined(__GNUC__) || defined(__CC_ARM)
439 #define MBED_PRINTF_METHOD(format_idx, first_param_idx) __attribute__ ((__format__(__printf__, format_idx+1, first_param_idx == 0 ? 0 : first_param_idx+1)))
440 #else
441 #define MBED_PRINTF_METHOD(format_idx, first_param_idx)
442 #endif
443 #endif
444 
445 #ifndef MBED_SCANF
446 #if defined(__GNUC__) || defined(__CC_ARM)
447 #define MBED_SCANF(format_idx, first_param_idx) __attribute__ ((__format__(__scanf__, format_idx, first_param_idx)))
448 #else
449 #define MBED_SCANF(format_idx, first_param_idx)
450 #endif
451 #endif
452 
453 #ifndef MBED_SCANF_METHOD
454 #if defined(__GNUC__) || defined(__CC_ARM)
455 #define MBED_SCANF_METHOD(format_idx, first_param_idx) __attribute__ ((__format__(__scanf__, format_idx+1, first_param_idx == 0 ? 0 : first_param_idx+1)))
456 #else
457 #define MBED_SCANF_METHOD(format_idx, first_param_idx)
458 #endif
459 #endif
460 
461 // Macro containing the filename part of the value of __FILE__. Defined as
462 // string literal.
463 #ifndef MBED_FILENAME
464 #if defined(__CC_ARM)
465 #define MBED_FILENAME __MODULE__
466 #elif defined(__GNUC__)
467 #define MBED_FILENAME (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __builtin_strrchr(__FILE__, '\\') ? __builtin_strrchr(__FILE__, '\\') + 1 : __FILE__)
468 #elif defined(__ICCARM__)
469 #define MBED_FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
470 #else
471 #define MBED_FILENAME __FILE__
472 #endif
473 #endif // #ifndef MBED_FILENAME
474 
475 // FILEHANDLE declaration
476 #if defined(TOOLCHAIN_ARM)
477 #include <rt_sys.h>
478 #endif
479 
480 #ifndef FILEHANDLE
481 typedef int FILEHANDLE;
482 #endif
483 
484 // Backwards compatibility
485 #ifndef WEAK
486 #define WEAK MBED_WEAK
487 #endif
488 
489 #ifndef PACKED
490 #define PACKED MBED_PACKED()
491 #endif
492 
493 #ifndef EXTERN
494 #define EXTERN extern
495 #endif
496 
497 /** MBED_NONSECURE_ENTRY
498  * Declare a function that can be called from non-secure world or secure world
499  *
500  * @code
501  * #include "mbed_toolchain.h"
502  *
503  * MBED_NONSECURE_ENTRY void foo() {
504  *
505  * }
506  * @endcode
507  */
508 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3L)
509 #if defined (__ICCARM__)
510 #define MBED_NONSECURE_ENTRY __cmse_nonsecure_entry
511 #else
512 #define MBED_NONSECURE_ENTRY __attribute__((cmse_nonsecure_entry))
513 #endif
514 #else
515 #define MBED_NONSECURE_ENTRY
516 #endif
517 
518 #endif
519 
520 /** @}*/
521 /** @}*/
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.