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