Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
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 /** @}*/
Generated on Tue Jul 12 2022 13:54:34 by
