Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mbed_toolchain.h Source File

mbed_toolchain.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2019 ARM Limited
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 #ifndef MBED_TOOLCHAIN_H
00018 #define MBED_TOOLCHAIN_H
00019 
00020 #include "platform/mbed_preprocessor.h"
00021 
00022 
00023 // Warning for unsupported compilers
00024 #if !defined(__GNUC__)   /* GCC        */ \
00025  && !defined(__CC_ARM)   /* ARMCC      */ \
00026  && !defined(__clang__)  /* LLVM/Clang */ \
00027  && !defined(__ICCARM__) /* IAR        */
00028 #warning "This compiler is not yet supported."
00029 #endif
00030 
00031 /** \addtogroup platform-public-api */
00032 /** @{*/
00033 
00034 /**
00035  * \defgroup platform_toolchain Toolchain functions
00036  * @{
00037  */
00038 
00039 // Attributes
00040 
00041 /** MBED_PACKED
00042  *  Pack a structure, preventing any padding from being added between fields.
00043  *
00044  *  @code
00045  *  #include "mbed_toolchain.h"
00046  *
00047  *  MBED_PACKED(struct) foo {
00048  *      char x;
00049  *      int y;
00050  *  };
00051  *  @endcode
00052  */
00053 #ifndef MBED_PACKED
00054 #if defined(__ICCARM__)
00055 #define MBED_PACKED(struct) __packed struct
00056 #else
00057 #define MBED_PACKED(struct) struct __attribute__((packed))
00058 #endif
00059 #endif
00060 
00061 /** MBED_ALIGN(N)
00062  *  Declare a variable to be aligned on an N-byte boundary.
00063  *
00064  *  @note
00065  *  IAR does not support alignment greater than word size on the stack
00066  *
00067  *  @code
00068  *  #include "mbed_toolchain.h"
00069  *
00070  *  MBED_ALIGN(16) char a;
00071  *  @endcode
00072  */
00073 #ifndef MBED_ALIGN
00074 #if __cplusplus >= 201103 && !defined __CC_ARM
00075 #define MBED_ALIGN(N) alignas(N)
00076 #elif __STDC_VERSION__ >= 201112 && !defined __CC_ARM
00077 #define MBED_ALIGN(N) _Alignas(N)
00078 #elif defined(__ICCARM__)
00079 #define MBED_ALIGN(N) _Pragma(MBED_STRINGIFY(data_alignment=N))
00080 #else
00081 #define MBED_ALIGN(N) __attribute__((aligned(N)))
00082 #endif
00083 #endif
00084 
00085 /** MBED_UNUSED
00086  *  Declare a function argument to be unused, suppressing compiler warnings
00087  *
00088  *  @code
00089  *  #include "mbed_toolchain.h"
00090  *
00091  *  void foo(MBED_UNUSED int arg) {
00092  *
00093  *  }
00094  *  @endcode
00095  */
00096 #ifndef MBED_UNUSED
00097 #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
00098 #define MBED_UNUSED __attribute__((__unused__))
00099 #else
00100 #define MBED_UNUSED
00101 #endif
00102 #endif
00103 
00104 /** MBED_USED
00105  *  Inform the compiler that a static variable is to be retained in the object file, even if it is unreferenced.
00106  *
00107  *  @code
00108  *  #include "mbed_toolchain.h"
00109  *
00110  *  MBED_USED int foo;
00111  *
00112  *  @endcode
00113  */
00114 #ifndef MBED_USED
00115 #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
00116 #define MBED_USED __attribute__((used))
00117 #elif defined(__ICCARM__)
00118 #define MBED_USED __root
00119 #else
00120 #define MBED_USED
00121 #endif
00122 #endif
00123 
00124 /** MBED_WEAK
00125  *  Mark a function as being weak.
00126  *
00127  *  @note
00128  *  Functions should only be marked as weak in the source file. The header file
00129  *  should contain a regular function declaration to insure the function is emitted.
00130  *  A function marked weak will not be emitted if an alternative non-weak
00131  *  implementation is defined.
00132  *
00133  *  @note
00134  *  Weak functions are not friendly to making code re-usable, as they can only
00135  *  be overridden once (and if they are multiply overridden the linker will emit
00136  *  no warning). You should not normally use weak symbols as part of the API to
00137  *  re-usable modules.
00138  *
00139  *  @code
00140  *  #include "mbed_toolchain.h"
00141  *
00142  *  MBED_WEAK void foo() {
00143  *      // a weak implementation of foo that can be overriden by a definition
00144  *      // without  __weak
00145  *  }
00146  *  @endcode
00147  */
00148 #ifndef MBED_WEAK
00149 #if defined(__ICCARM__)
00150 #define MBED_WEAK __weak
00151 #elif defined(__MINGW32__)
00152 #define MBED_WEAK
00153 #else
00154 #define MBED_WEAK __attribute__((weak))
00155 #endif
00156 #endif
00157 
00158 /** MBED_COMPILER_BARRIER
00159  * Stop the compiler moving memory accesses.
00160  *
00161  * The barrier stops memory accesses from being moved from one side of the
00162  * barrier to the other for safety against other threads and interrupts.
00163  *
00164  * This macro should only be used if we know only one CPU is accessing the data,
00165  * or we are otherwise synchronising CPUs via acquire/release instructions.
00166  * Otherwise, use MBED_BARRIER, which will act as a compiler barrier and also
00167  * a CPU barrier if necessary.
00168  *
00169  * @internal
00170  * This is not for use by normal code - it is a building block for the
00171  * higher-level functions in mbed_critical.h. Higher-level lock/unlock or
00172  * acquire/release APIs always provide ordering semantics, using this if
00173  * necessary.
00174  *
00175  * @code
00176  *  #include "mbed_toolchain.h"
00177  *
00178  *  void atomic_flag_clear_armv8(atomic_flag *flagPtr)
00179  *  {
00180  *      // ARMv8 LDA and STL instructions provide sequential consistency against
00181  *      // other CPUs, so no CPU barrier is needed. But we still need compiler
00182  *      // barriers to give us sequentially-consistent release semantics with
00183  *      // respect to compiler reordering - __STLB does not currently
00184  *      // include this.
00185  *      MBED_COMPILER_BARRIER();
00186  *      __STLB(&flagPtr->_flag, false);
00187  *      MBED_COMPILER_BARRIER();
00188  *  }
00189  */
00190 #ifdef __CC_ARM
00191 #define MBED_COMPILER_BARRIER() __memory_changed()
00192 #elif defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
00193 #define MBED_COMPILER_BARRIER() asm volatile("" : : : "memory")
00194 #else
00195 #error "Missing MBED_COMPILER_BARRIER implementation"
00196 #endif
00197 
00198 /** MBED_BARRIER
00199  * Stop the compiler, and CPU if SMP, from moving memory accesses.
00200  *
00201  * The barrier stops memory accesses from being moved from one side of the
00202  * barrier to the other for safety against other threads and interrupts,
00203  * potentially on other CPUs.
00204  *
00205  * In a single-CPU system, this is just a compiler barrier.
00206  * If we supported multiple CPUs, this would be a DMB (with implied compiler
00207  * barrier).
00208  *
00209  * @internal
00210  * This is not for use by normal code - it is a building block for the
00211  * higher-level functions in mbed_critical.h. Higher-level lock/unlock or
00212  * acquire/release APIs always provide ordering semantics, using this if
00213  * necessary.
00214  * @code
00215  *  #include "mbed_toolchain.h"
00216  *
00217  *  void atomic_flag_clear_armv7(atomic_flag *flagPtr)
00218  *  {
00219  *      // ARMv7 LDR and STR instructions do not provide any ordering
00220  *      // consistency against other CPUs, so explicit barrier DMBs are needed
00221  *      // for a multi-CPU system, otherwise just compiler barriers for single-CPU.
00222  *      MBED_BARRIER();
00223  *      flagPtr->_flag = false;
00224  *      MBED_BARRIER();
00225  *  }
00226  */
00227 #define MBED_BARRIER() MBED_COMPILER_BARRIER()
00228 
00229 /** MBED_PURE
00230  *  Hint to the compiler that a function depends only on parameters
00231  *
00232  *  @code
00233  *  #include "mbed_toolchain.h"
00234  *
00235  *  MBED_PURE int foo(int arg){
00236  *      // no access to global variables
00237  *  }
00238  *  @endcode
00239  */
00240 #ifndef MBED_PURE
00241 #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
00242 #define MBED_PURE __attribute__((const))
00243 #else
00244 #define MBED_PURE
00245 #endif
00246 #endif
00247 
00248 /** MBED_NOINLINE
00249  *  Declare a function that must not be inlined.
00250  *
00251  *  @code
00252  *  #include "mbed_toolchain.h"
00253  *
00254  *  MBED_NOINLINE void foo() {
00255  *
00256  *  }
00257  *  @endcode
00258  */
00259 #ifndef MBED_NOINLINE
00260 #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
00261 #define MBED_NOINLINE __attribute__((noinline))
00262 #elif defined(__ICCARM__)
00263 #define MBED_NOINLINE _Pragma("inline=never")
00264 #else
00265 #define MBED_NOINLINE
00266 #endif
00267 #endif
00268 
00269 /** MBED_FORCEINLINE
00270  *  Declare a function that must always be inlined. Failure to inline
00271  *  such a function will result in an error.
00272  *
00273  *  @code
00274  *  #include "mbed_toolchain.h"
00275  *
00276  *  MBED_FORCEINLINE void foo() {
00277  *
00278  *  }
00279  *  @endcode
00280  */
00281 #ifndef MBED_FORCEINLINE
00282 #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
00283 #define MBED_FORCEINLINE inline __attribute__((always_inline))
00284 #elif defined(__ICCARM__)
00285 #define MBED_FORCEINLINE _Pragma("inline=forced")
00286 #else
00287 #define MBED_FORCEINLINE inline
00288 #endif
00289 #endif
00290 
00291 /** MBED_NORETURN
00292  *  Declare a function that will never return.
00293  *
00294  *  @code
00295  *  #include "mbed_toolchain.h"
00296  *
00297  *  MBED_NORETURN void foo() {
00298  *      // must never return
00299  *      while (1) {}
00300  *  }
00301  *  @endcode
00302  */
00303 #ifndef MBED_NORETURN
00304 #if __cplusplus >= 201103
00305 #define MBED_NORETURN [[noreturn]]
00306 #elif __STDC_VERSION__ >= 201112
00307 #define MBED_NORETURN _Noreturn
00308 #elif defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
00309 #define MBED_NORETURN __attribute__((noreturn))
00310 #elif defined(__ICCARM__)
00311 #define MBED_NORETURN __noreturn
00312 #else
00313 #define MBED_NORETURN
00314 #endif
00315 #endif
00316 
00317 /** MBED_UNREACHABLE
00318  *  An unreachable statement. If the statement is reached,
00319  *  behavior is undefined. Useful in situations where the compiler
00320  *  cannot deduce if the code is unreachable.
00321  *
00322  *  @code
00323  *  #include "mbed_toolchain.h"
00324  *
00325  *  void foo(int arg) {
00326  *      switch (arg) {
00327  *          case 1: return 1;
00328  *          case 2: return 2;
00329  *          ...
00330  *      }
00331  *      MBED_UNREACHABLE;
00332  *  }
00333  *  @endcode
00334  */
00335 #ifndef MBED_UNREACHABLE
00336 #if (defined(__GNUC__) || defined(__clang__)) && !defined(__CC_ARM)
00337 #define MBED_UNREACHABLE __builtin_unreachable()
00338 #else
00339 #define MBED_UNREACHABLE while (1)
00340 #endif
00341 #endif
00342 
00343 /** MBED_FALLTHROUGH
00344  *  Marks a point in a switch statement where fallthrough can occur.
00345  *  Should be placed as the last statement before a label.
00346  *
00347  *  @code
00348  *  #include "mbed_toolchain.h"
00349  *
00350  *  int foo(int arg) {
00351  *      switch (arg) {
00352  *          case 1:
00353  *          case 2:
00354  *          case 3:
00355  *              arg *= 2;
00356  *              MBED_FALLTHROUGH;
00357  *          default:
00358  *              return arg;
00359  *      }
00360  *  }
00361  *  @endcode
00362  */
00363 #ifndef MBED_FALLTHROUGH
00364 #if __cplusplus >= 201703
00365 #define MBED_FALLTHROUGH [[fallthrough]]
00366 #elif defined(__clang__)
00367 #if __cplusplus >= 201103
00368 #define MBED_FALLTHROUGH [[clang::fallthrough]]
00369 #elif __has_attribute(fallthrough)
00370 #define MBED_FALLTHROUGH __attribute__((fallthrough))
00371 #else
00372 #define MBED_FALLTHROUGH
00373 #endif
00374 #elif defined (__GNUC__) && !defined(__CC_ARM)
00375 #define MBED_FALLTHROUGH __attribute__((fallthrough))
00376 #else
00377 #define MBED_FALLTHROUGH
00378 #endif
00379 #endif
00380 
00381 /** MBED_DEPRECATED("message string")
00382  *  Mark a function declaration as deprecated, if it used then a warning will be
00383  *  issued by the compiler possibly including the provided message. Note that not
00384  *  all compilers are able to display the message.
00385  *
00386  *  @code
00387  *  #include "mbed_toolchain.h"
00388  *
00389  *  MBED_DEPRECATED("don't foo any more, bar instead")
00390  *  void foo(int arg);
00391  *  @endcode
00392  */
00393 #ifndef MBED_DEPRECATED
00394 #if defined(__CC_ARM)
00395 #define MBED_DEPRECATED(M) __attribute__((deprecated))
00396 #elif defined(__GNUC__) || defined(__clang__)
00397 #define MBED_DEPRECATED(M) __attribute__((deprecated(M)))
00398 #else
00399 #define MBED_DEPRECATED(M)
00400 #endif
00401 #endif
00402 
00403 /** MBED_DEPRECATED_SINCE("version", "message string")
00404  *  Mark a function declaration as deprecated, noting that the declaration was
00405  *  deprecated on the specified version. If the function is used then a warning
00406  *  will be issued by the compiler possibly including the provided message.
00407  *  Note that not all compilers are able to display this message.
00408  *
00409  *  @code
00410  *  #include "mbed_toolchain.h"
00411  *
00412  *  MBED_DEPRECATED_SINCE("mbed-os-5.1", "don't foo any more, bar instead")
00413  *  void foo(int arg);
00414  *  @endcode
00415  */
00416 #define MBED_DEPRECATED_SINCE(D, M) MBED_DEPRECATED(M " [since " D "]")
00417 
00418 /** MBED_CALLER_ADDR()
00419  * Returns the caller of the current function.
00420  *
00421  * @note
00422  * This macro is only implemented for GCC and ARMCC.
00423  *
00424  * @code
00425  * #include "mbed_toolchain.h"
00426  *
00427  * printf("This function was called from %p", MBED_CALLER_ADDR());
00428  * @endcode
00429  *
00430  * @return Address of the calling function
00431  */
00432 #ifndef MBED_CALLER_ADDR
00433 #if (defined(__GNUC__) || defined(__clang__)) && !defined(__CC_ARM)
00434 #define MBED_CALLER_ADDR() __builtin_extract_return_addr(__builtin_return_address(0))
00435 #elif defined(__CC_ARM)
00436 #define MBED_CALLER_ADDR() __builtin_return_address(0)
00437 #else
00438 #define MBED_CALLER_ADDR() (NULL)
00439 #endif
00440 #endif
00441 
00442 #ifndef MBED_SECTION
00443 #if (defined(__GNUC__) || defined(__clang__)) || defined(__CC_ARM)
00444 #define MBED_SECTION(name) __attribute__ ((section (name)))
00445 #elif defined(__ICCARM__)
00446 #define MBED_SECTION(name) _Pragma(MBED_STRINGIFY(location=name))
00447 #else
00448 #error "Missing MBED_SECTION directive"
00449 #endif
00450 #endif
00451 
00452 /**
00453  * Macro expanding to a string literal of the enclosing function name.
00454  *
00455  * The string returned takes into account language specificity and yield human
00456  * readable content.
00457  *
00458  * As an example, if the macro is used within a C++ function then the string
00459  * literal containing the function name will contain the complete signature of
00460  * the function - including template parameters - and namespace qualifications.
00461  */
00462 #ifndef MBED_PRETTY_FUNCTION
00463 #define MBED_PRETTY_FUNCTION __PRETTY_FUNCTION__
00464 #endif
00465 
00466 #ifndef MBED_PRINTF
00467 #if defined(__GNUC__) || defined(__CC_ARM)
00468 #define MBED_PRINTF(format_idx, first_param_idx) __attribute__ ((__format__(__printf__, format_idx, first_param_idx)))
00469 #else
00470 #define MBED_PRINTF(format_idx, first_param_idx)
00471 #endif
00472 #endif
00473 
00474 #ifndef MBED_PRINTF_METHOD
00475 #if defined(__GNUC__) || defined(__CC_ARM)
00476 #define MBED_PRINTF_METHOD(format_idx, first_param_idx) __attribute__ ((__format__(__printf__, format_idx+1, first_param_idx == 0 ? 0 : first_param_idx+1)))
00477 #else
00478 #define MBED_PRINTF_METHOD(format_idx, first_param_idx)
00479 #endif
00480 #endif
00481 
00482 #ifndef MBED_SCANF
00483 #if defined(__GNUC__) || defined(__CC_ARM)
00484 #define MBED_SCANF(format_idx, first_param_idx) __attribute__ ((__format__(__scanf__, format_idx, first_param_idx)))
00485 #else
00486 #define MBED_SCANF(format_idx, first_param_idx)
00487 #endif
00488 #endif
00489 
00490 #ifndef MBED_SCANF_METHOD
00491 #if defined(__GNUC__) || defined(__CC_ARM)
00492 #define MBED_SCANF_METHOD(format_idx, first_param_idx) __attribute__ ((__format__(__scanf__, format_idx+1, first_param_idx == 0 ? 0 : first_param_idx+1)))
00493 #else
00494 #define MBED_SCANF_METHOD(format_idx, first_param_idx)
00495 #endif
00496 #endif
00497 
00498 // Macro containing the filename part of the value of __FILE__. Defined as
00499 // string literal.
00500 #ifndef MBED_FILENAME
00501 #if defined(__CC_ARM)
00502 #define MBED_FILENAME __MODULE__
00503 #elif defined(__GNUC__)
00504 #define MBED_FILENAME (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __builtin_strrchr(__FILE__, '\\') ? __builtin_strrchr(__FILE__, '\\') + 1 : __FILE__)
00505 #elif defined(__ICCARM__)
00506 #define MBED_FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
00507 #else
00508 #define MBED_FILENAME __FILE__
00509 #endif
00510 #endif // #ifndef MBED_FILENAME
00511 
00512 // FILEHANDLE declaration
00513 #if defined(TOOLCHAIN_ARM)
00514 #include <rt_sys.h>
00515 #endif
00516 
00517 #ifndef FILEHANDLE
00518 typedef int FILEHANDLE;
00519 #endif
00520 
00521 // Backwards compatibility
00522 #ifndef WEAK
00523 #define WEAK MBED_WEAK
00524 #endif
00525 
00526 #ifndef PACKED
00527 #define PACKED MBED_PACKED()
00528 #endif
00529 
00530 #ifndef EXTERN
00531 #define EXTERN extern
00532 #endif
00533 
00534 /** MBED_NONSECURE_ENTRY
00535  *  Declare a function that can be called from non-secure world or secure world
00536  *
00537  *  @code
00538  *  #include "mbed_toolchain.h"
00539  *
00540  *  MBED_NONSECURE_ENTRY void foo() {
00541  *
00542  *  }
00543  *  @endcode
00544  */
00545 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3L)
00546 #if defined (__ICCARM__)
00547 #define MBED_NONSECURE_ENTRY       __cmse_nonsecure_entry
00548 #else
00549 #define MBED_NONSECURE_ENTRY       __attribute__((cmse_nonsecure_entry))
00550 #endif
00551 #else
00552 #define MBED_NONSECURE_ENTRY
00553 #endif
00554 
00555 #endif
00556 
00557 /** @}*/
00558 /** @}*/