mirror of https://github.com/ARMmbed/mbed-os.git
296 lines
6.9 KiB
C
296 lines
6.9 KiB
C
|
|
/** \addtogroup platform */
|
|
/** @{*/
|
|
/* mbed Microcontroller Library
|
|
* Copyright (c) 2006-2013 ARM Limited
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#ifndef MBED_TOOLCHAIN_H
|
|
#define MBED_TOOLCHAIN_H
|
|
|
|
#include "mbed_preprocessor.h"
|
|
|
|
|
|
// Warning for unsupported compilers
|
|
#if !defined(__GNUC__) /* GCC */ \
|
|
&& !defined(__CC_ARM) /* ARMCC */ \
|
|
&& !defined(__clang__) /* LLVM/Clang */ \
|
|
&& !defined(__ICCARM__) /* IAR */
|
|
#warning "This compiler is not yet supported."
|
|
#endif
|
|
|
|
|
|
// Attributes
|
|
|
|
/** MBED_PACKED
|
|
* Pack a structure, preventing any padding from being added between fields.
|
|
*
|
|
* @code
|
|
* #include "toolchain.h"
|
|
*
|
|
* MBED_PACKED(struct) foo {
|
|
* char x;
|
|
* int y;
|
|
* };
|
|
* @endcode
|
|
*/
|
|
#ifndef MBED_PACKED
|
|
#if defined(__ICCARM__)
|
|
#define MBED_PACKED(struct) __packed struct
|
|
#else
|
|
#define MBED_PACKED(struct) struct __attribute__((packed))
|
|
#endif
|
|
#endif
|
|
|
|
/** MBED_ALIGN(N)
|
|
* Declare a variable to be aligned on an N-byte boundary.
|
|
*
|
|
* @note
|
|
* IAR does not support alignment greater than word size on the stack
|
|
*
|
|
* @code
|
|
* #include "toolchain.h"
|
|
*
|
|
* MBED_ALIGN(16) char a;
|
|
* @endcode
|
|
*/
|
|
#ifndef MBED_ALIGN
|
|
#if defined(__ICCARM__)
|
|
#define MBED_ALIGN(N) _Pragma(MBED_STRINGIFY(data_alignment=N))
|
|
#else
|
|
#define MBED_ALIGN(N) __attribute__((aligned(N)))
|
|
#endif
|
|
#endif
|
|
|
|
/** MBED_UNUSED
|
|
* Declare a function argument to be unused, suppressing compiler warnings
|
|
*
|
|
* @code
|
|
* #include "toolchain.h"
|
|
*
|
|
* void foo(MBED_UNUSED int arg) {
|
|
*
|
|
* }
|
|
* @endcode
|
|
*/
|
|
#ifndef MBED_UNUSED
|
|
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
|
|
#define MBED_UNUSED __attribute__((__unused__))
|
|
#else
|
|
#define MBED_UNUSED
|
|
#endif
|
|
#endif
|
|
|
|
/** MBED_WEAK
|
|
* Mark a function as being weak.
|
|
*
|
|
* @note
|
|
* weak functions are not friendly to making code re-usable, as they can only
|
|
* be overridden once (and if they are multiply overridden the linker will emit
|
|
* no warning). You should not normally use weak symbols as part of the API to
|
|
* re-usable modules.
|
|
*
|
|
* @code
|
|
* #include "toolchain.h"
|
|
*
|
|
* MBED_WEAK void foo() {
|
|
* // a weak implementation of foo that can be overriden by a definition
|
|
* // without __weak
|
|
* }
|
|
* @endcode
|
|
*/
|
|
#ifndef MBED_WEAK
|
|
#if defined(__ICCARM__)
|
|
#define MBED_WEAK __weak
|
|
#else
|
|
#define MBED_WEAK __attribute__((weak))
|
|
#endif
|
|
#endif
|
|
|
|
/** MBED_PURE
|
|
* Hint to the compiler that a function depends only on parameters
|
|
*
|
|
* @code
|
|
* #include "toolchain.h"
|
|
*
|
|
* MBED_PURE int foo(int arg){
|
|
* // no access to global variables
|
|
* }
|
|
* @endcode
|
|
*/
|
|
#ifndef MBED_PURE
|
|
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
|
|
#define MBED_PURE __attribute__((const))
|
|
#else
|
|
#define MBED_PURE
|
|
#endif
|
|
#endif
|
|
|
|
/** MBED_FORCEINLINE
|
|
* Declare a function that must always be inlined. Failure to inline
|
|
* such a function will result in an error.
|
|
*
|
|
* @code
|
|
* #include "toolchain.h"
|
|
*
|
|
* MBED_FORCEINLINE void foo() {
|
|
*
|
|
* }
|
|
* @endcode
|
|
*/
|
|
#ifndef MBED_FORCEINLINE
|
|
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
|
|
#define MBED_FORCEINLINE static inline __attribute__((always_inline))
|
|
#elif defined(__ICCARM__)
|
|
#define MBED_FORCEINLINE _Pragma("inline=forced") static
|
|
#else
|
|
#define MBED_FORCEINLINE static inline
|
|
#endif
|
|
#endif
|
|
|
|
/** MBED_NORETURN
|
|
* Declare a function that will never return.
|
|
*
|
|
* @code
|
|
* #include "toolchain.h"
|
|
*
|
|
* MBED_NORETURN void foo() {
|
|
* // must never return
|
|
* while (1) {}
|
|
* }
|
|
* @endcode
|
|
*/
|
|
#ifndef MBED_NORETURN
|
|
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
|
|
#define MBED_NORETURN __attribute__((noreturn))
|
|
#elif defined(__ICCARM__)
|
|
#define MBED_NORETURN __noreturn
|
|
#else
|
|
#define MBED_NORETURN
|
|
#endif
|
|
#endif
|
|
|
|
/** MBED_UNREACHABLE
|
|
* An unreachable statement. If the statement is reached,
|
|
* behaviour is undefined. Useful in situations where the compiler
|
|
* cannot deduce the unreachability of code.
|
|
*
|
|
* @code
|
|
* #include "toolchain.h"
|
|
*
|
|
* void foo(int arg) {
|
|
* switch (arg) {
|
|
* case 1: return 1;
|
|
* case 2: return 2;
|
|
* ...
|
|
* }
|
|
* MBED_UNREACHABLE;
|
|
* }
|
|
* @endcode
|
|
*/
|
|
#ifndef MBED_UNREACHABLE
|
|
#if (defined(__GNUC__) || defined(__clang__)) && !defined(__CC_ARM)
|
|
#define MBED_UNREACHABLE __builtin_unreachable()
|
|
#else
|
|
#define MBED_UNREACHABLE while (1)
|
|
#endif
|
|
#endif
|
|
|
|
/** MBED_DEPRECATED("message string")
|
|
* Mark a function declaration as deprecated, if it used then a warning will be
|
|
* issued by the compiler possibly including the provided message. Note that not
|
|
* all compilers are able to display the message.
|
|
*
|
|
* @code
|
|
* #include "toolchain.h"
|
|
*
|
|
* MBED_DEPRECATED("don't foo any more, bar instead")
|
|
* void foo(int arg);
|
|
* @endcode
|
|
*/
|
|
#ifndef MBED_DEPRECATED
|
|
#if defined(__CC_ARM)
|
|
#define MBED_DEPRECATED(M) __attribute__((deprecated))
|
|
#elif defined(__GNUC__) || defined(__clang__)
|
|
#define MBED_DEPRECATED(M) __attribute__((deprecated(M)))
|
|
#else
|
|
#define MBED_DEPRECATED(M)
|
|
#endif
|
|
#endif
|
|
|
|
/** MBED_DEPRECATED_SINCE("version", "message string")
|
|
* Mark a function declaration as deprecated, noting that the declaration was
|
|
* deprecated on the specified version. If the function is used then a warning
|
|
* will be issued by the compiler possibly including the provided message.
|
|
* Note that not all compilers are able to display this message.
|
|
*
|
|
* @code
|
|
* #include "toolchain.h"
|
|
*
|
|
* MBED_DEPRECATED_SINCE("mbed-os-5.1", "don't foo any more, bar instead")
|
|
* void foo(int arg);
|
|
* @endcode
|
|
*/
|
|
#define MBED_DEPRECATED_SINCE(D, M) MBED_DEPRECATED(M " [since " D "]")
|
|
|
|
/** MBED_CALLER_ADDR()
|
|
* Returns the caller of the current function.
|
|
*
|
|
* @note
|
|
* This macro is only implemented for GCC and ARMCC.
|
|
*
|
|
* @code
|
|
* #include "toolchain.h"
|
|
*
|
|
* printf("This function was called from %p", MBED_CALLER_ADDR());
|
|
* @endcode
|
|
*
|
|
* @return Address of the calling function
|
|
*/
|
|
#ifndef MBED_CALLER_ADDR
|
|
#if (defined(__GNUC__) || defined(__clang__)) && !defined(__CC_ARM)
|
|
#define MBED_CALLER_ADDR() __builtin_extract_return_addr(__builtin_return_address(0))
|
|
#elif defined(__CC_ARM)
|
|
#define MBED_CALLER_ADDR() __builtin_return_address(0)
|
|
#else
|
|
#define MBED_CALLER_ADDR() (NULL)
|
|
#endif
|
|
#endif
|
|
|
|
// FILEHANDLE declaration
|
|
#if defined(TOOLCHAIN_ARM)
|
|
#include <rt_sys.h>
|
|
#endif
|
|
|
|
#ifndef FILEHANDLE
|
|
typedef int FILEHANDLE;
|
|
#endif
|
|
|
|
// Backwards compatibility
|
|
#ifndef WEAK
|
|
#define WEAK MBED_WEAK
|
|
#endif
|
|
|
|
#ifndef PACKED
|
|
#define PACKED MBED_PACKED()
|
|
#endif
|
|
|
|
#ifndef EXTERN
|
|
#define EXTERN extern
|
|
#endif
|
|
|
|
#endif
|
|
|
|
/** @}*/
|