mbed_toolchain.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /** \addtogroup platform */
  2. /** @{*/
  3. /**
  4. * \defgroup platform_toolchain Toolchain functions
  5. * @{
  6. */
  7. /* mbed Microcontroller Library
  8. * Copyright (c) 2006-2013 ARM Limited
  9. *
  10. * Licensed under the Apache License, Version 2.0 (the "License");
  11. * you may not use this file except in compliance with the License.
  12. * You may obtain a copy of the License at
  13. *
  14. * http://www.apache.org/licenses/LICENSE-2.0
  15. *
  16. * Unless required by applicable law or agreed to in writing, software
  17. * distributed under the License is distributed on an "AS IS" BASIS,
  18. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. * See the License for the specific language governing permissions and
  20. * limitations under the License.
  21. */
  22. #ifndef MBED_TOOLCHAIN_H
  23. #define MBED_TOOLCHAIN_H
  24. #include "mbed_preprocessor.h"
  25. // Warning for unsupported compilers
  26. #if !defined(__GNUC__) /* GCC */ \
  27. && !defined(__CC_ARM) /* ARMCC */ \
  28. && !defined(__clang__) /* LLVM/Clang */ \
  29. && !defined(__ICCARM__) /* IAR */
  30. #warning "This compiler is not yet supported."
  31. #endif
  32. // Attributes
  33. /** MBED_PACKED
  34. * Pack a structure, preventing any padding from being added between fields.
  35. *
  36. * @code
  37. * #include "mbed_toolchain.h"
  38. *
  39. * MBED_PACKED(struct) foo {
  40. * char x;
  41. * int y;
  42. * };
  43. * @endcode
  44. */
  45. #ifndef MBED_PACKED
  46. #if defined(__ICCARM__)
  47. #define MBED_PACKED(struct) __packed struct
  48. #else
  49. #define MBED_PACKED(struct) struct __attribute__((packed))
  50. #endif
  51. #endif
  52. /** MBED_ALIGN(N)
  53. * Declare a variable to be aligned on an N-byte boundary.
  54. *
  55. * @note
  56. * IAR does not support alignment greater than word size on the stack
  57. *
  58. * @code
  59. * #include "mbed_toolchain.h"
  60. *
  61. * MBED_ALIGN(16) char a;
  62. * @endcode
  63. */
  64. #ifndef MBED_ALIGN
  65. #if defined(__ICCARM__)
  66. #define MBED_ALIGN(N) _Pragma(MBED_STRINGIFY(data_alignment=N))
  67. #else
  68. #define MBED_ALIGN(N) __attribute__((aligned(N)))
  69. #endif
  70. #endif
  71. /** MBED_UNUSED
  72. * Declare a function argument to be unused, suppressing compiler warnings
  73. *
  74. * @code
  75. * #include "mbed_toolchain.h"
  76. *
  77. * void foo(MBED_UNUSED int arg) {
  78. *
  79. * }
  80. * @endcode
  81. */
  82. #ifndef MBED_UNUSED
  83. #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
  84. #define MBED_UNUSED __attribute__((__unused__))
  85. #else
  86. #define MBED_UNUSED
  87. #endif
  88. #endif
  89. /** MBED_USED
  90. * Inform the compiler that a static variable is to be retained in the object file, even if it is unreferenced.
  91. *
  92. * @code
  93. * #include "mbed_toolchain.h"
  94. *
  95. * MBED_USED int foo;
  96. *
  97. * @endcode
  98. */
  99. #ifndef MBED_USED
  100. #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
  101. #define MBED_USED __attribute__((used))
  102. #elif defined(__ICCARM__)
  103. #define MBED_USED __root
  104. #else
  105. #define MBED_USED
  106. #endif
  107. #endif
  108. /** MBED_WEAK
  109. * Mark a function as being weak.
  110. *
  111. * @note
  112. * Functions should only be marked as weak in the source file. The header file
  113. * should contain a regular function declaration to insure the function is emitted.
  114. * A function marked weak will not be emitted if an alternative non-weak
  115. * implementation is defined.
  116. *
  117. * @note
  118. * Weak functions are not friendly to making code re-usable, as they can only
  119. * be overridden once (and if they are multiply overridden the linker will emit
  120. * no warning). You should not normally use weak symbols as part of the API to
  121. * re-usable modules.
  122. *
  123. * @code
  124. * #include "mbed_toolchain.h"
  125. *
  126. * MBED_WEAK void foo() {
  127. * // a weak implementation of foo that can be overriden by a definition
  128. * // without __weak
  129. * }
  130. * @endcode
  131. */
  132. #ifndef MBED_WEAK
  133. #if defined(__ICCARM__)
  134. #define MBED_WEAK __weak
  135. #else
  136. #define MBED_WEAK __attribute__((weak))
  137. #endif
  138. #endif
  139. /** MBED_PURE
  140. * Hint to the compiler that a function depends only on parameters
  141. *
  142. * @code
  143. * #include "mbed_toolchain.h"
  144. *
  145. * MBED_PURE int foo(int arg){
  146. * // no access to global variables
  147. * }
  148. * @endcode
  149. */
  150. #ifndef MBED_PURE
  151. #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
  152. #define MBED_PURE __attribute__((const))
  153. #else
  154. #define MBED_PURE
  155. #endif
  156. #endif
  157. /** MBED_NOINLINE
  158. * Declare a function that must not be inlined.
  159. *
  160. * @code
  161. * #include "mbed_toolchain.h"
  162. *
  163. * MBED_NOINLINE void foo() {
  164. *
  165. * }
  166. * @endcode
  167. */
  168. #ifndef MBED_NOINLINE
  169. #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
  170. #define MBED_NOINLINE __attribute__((noinline))
  171. #elif defined(__ICCARM__)
  172. #define MBED_NOINLINE _Pragma("inline=never")
  173. #else
  174. #define MBED_NOINLINE
  175. #endif
  176. #endif
  177. /** MBED_FORCEINLINE
  178. * Declare a function that must always be inlined. Failure to inline
  179. * such a function will result in an error.
  180. *
  181. * @code
  182. * #include "mbed_toolchain.h"
  183. *
  184. * MBED_FORCEINLINE void foo() {
  185. *
  186. * }
  187. * @endcode
  188. */
  189. #ifndef MBED_FORCEINLINE
  190. #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
  191. #define MBED_FORCEINLINE static inline __attribute__((always_inline))
  192. #elif defined(__ICCARM__)
  193. #define MBED_FORCEINLINE _Pragma("inline=forced") static
  194. #else
  195. #define MBED_FORCEINLINE static inline
  196. #endif
  197. #endif
  198. /** MBED_NORETURN
  199. * Declare a function that will never return.
  200. *
  201. * @code
  202. * #include "mbed_toolchain.h"
  203. *
  204. * MBED_NORETURN void foo() {
  205. * // must never return
  206. * while (1) {}
  207. * }
  208. * @endcode
  209. */
  210. #ifndef MBED_NORETURN
  211. #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
  212. #define MBED_NORETURN __attribute__((noreturn))
  213. #elif defined(__ICCARM__)
  214. #define MBED_NORETURN __noreturn
  215. #else
  216. #define MBED_NORETURN
  217. #endif
  218. #endif
  219. /** MBED_UNREACHABLE
  220. * An unreachable statement. If the statement is reached,
  221. * behaviour is undefined. Useful in situations where the compiler
  222. * cannot deduce the unreachability of code.
  223. *
  224. * @code
  225. * #include "mbed_toolchain.h"
  226. *
  227. * void foo(int arg) {
  228. * switch (arg) {
  229. * case 1: return 1;
  230. * case 2: return 2;
  231. * ...
  232. * }
  233. * MBED_UNREACHABLE;
  234. * }
  235. * @endcode
  236. */
  237. #ifndef MBED_UNREACHABLE
  238. #if (defined(__GNUC__) || defined(__clang__)) && !defined(__CC_ARM)
  239. #define MBED_UNREACHABLE __builtin_unreachable()
  240. #else
  241. #define MBED_UNREACHABLE while (1)
  242. #endif
  243. #endif
  244. /** MBED_DEPRECATED("message string")
  245. * Mark a function declaration as deprecated, if it used then a warning will be
  246. * issued by the compiler possibly including the provided message. Note that not
  247. * all compilers are able to display the message.
  248. *
  249. * @code
  250. * #include "mbed_toolchain.h"
  251. *
  252. * MBED_DEPRECATED("don't foo any more, bar instead")
  253. * void foo(int arg);
  254. * @endcode
  255. */
  256. #ifndef MBED_DEPRECATED
  257. #if defined(__CC_ARM)
  258. #define MBED_DEPRECATED(M) __attribute__((deprecated))
  259. #elif defined(__GNUC__) || defined(__clang__)
  260. #define MBED_DEPRECATED(M) __attribute__((deprecated(M)))
  261. #else
  262. #define MBED_DEPRECATED(M)
  263. #endif
  264. #endif
  265. /** MBED_DEPRECATED_SINCE("version", "message string")
  266. * Mark a function declaration as deprecated, noting that the declaration was
  267. * deprecated on the specified version. If the function is used then a warning
  268. * will be issued by the compiler possibly including the provided message.
  269. * Note that not all compilers are able to display this message.
  270. *
  271. * @code
  272. * #include "mbed_toolchain.h"
  273. *
  274. * MBED_DEPRECATED_SINCE("mbed-os-5.1", "don't foo any more, bar instead")
  275. * void foo(int arg);
  276. * @endcode
  277. */
  278. #define MBED_DEPRECATED_SINCE(D, M) MBED_DEPRECATED(M " [since " D "]")
  279. /** MBED_CALLER_ADDR()
  280. * Returns the caller of the current function.
  281. *
  282. * @note
  283. * This macro is only implemented for GCC and ARMCC.
  284. *
  285. * @code
  286. * #include "mbed_toolchain.h"
  287. *
  288. * printf("This function was called from %p", MBED_CALLER_ADDR());
  289. * @endcode
  290. *
  291. * @return Address of the calling function
  292. */
  293. #ifndef MBED_CALLER_ADDR
  294. #if (defined(__GNUC__) || defined(__clang__)) && !defined(__CC_ARM)
  295. #define MBED_CALLER_ADDR() __builtin_extract_return_addr(__builtin_return_address(0))
  296. #elif defined(__CC_ARM)
  297. #define MBED_CALLER_ADDR() __builtin_return_address(0)
  298. #else
  299. #define MBED_CALLER_ADDR() (NULL)
  300. #endif
  301. #endif
  302. #ifndef MBED_SECTION
  303. #if (defined(__GNUC__) || defined(__clang__)) || defined(__CC_ARM)
  304. #define MBED_SECTION(name) __attribute__ ((section (name)))
  305. #elif defined(__ICCARM__)
  306. #define MBED_SECTION(name) _Pragma(MBED_STRINGIFY(location=name))
  307. #else
  308. #error "Missing MBED_SECTION directive"
  309. #endif
  310. #endif
  311. /**
  312. * Macro expanding to a string literal of the enclosing function name.
  313. *
  314. * The string returned takes into account language specificity and yield human
  315. * readable content.
  316. *
  317. * As an example, if the macro is used within a C++ function then the string
  318. * literal containing the function name will contain the complete signature of
  319. * the function - including template parameters - and namespace qualifications.
  320. */
  321. #ifndef MBED_PRETTY_FUNCTION
  322. #define MBED_PRETTY_FUNCTION __PRETTY_FUNCTION__
  323. #endif
  324. #ifndef MBED_PRINTF
  325. #if defined(__GNUC__) || defined(__CC_ARM)
  326. #define MBED_PRINTF(format_idx, first_param_idx) __attribute__ ((__format__(__printf__, format_idx, first_param_idx)))
  327. #else
  328. #define MBED_PRINTF(format_idx, first_param_idx)
  329. #endif
  330. #endif
  331. #ifndef MBED_PRINTF_METHOD
  332. #if defined(__GNUC__) || defined(__CC_ARM)
  333. #define MBED_PRINTF_METHOD(format_idx, first_param_idx) __attribute__ ((__format__(__printf__, format_idx+1, first_param_idx+1)))
  334. #else
  335. #define MBED_PRINTF_METHOD(format_idx, first_param_idx)
  336. #endif
  337. #endif
  338. #ifndef MBED_SCANF
  339. #if defined(__GNUC__) || defined(__CC_ARM)
  340. #define MBED_SCANF(format_idx, first_param_idx) __attribute__ ((__format__(__scanf__, format_idx, first_param_idx)))
  341. #else
  342. #define MBED_SCANF(format_idx, first_param_idx)
  343. #endif
  344. #endif
  345. #ifndef MBED_SCANF_METHOD
  346. #if defined(__GNUC__) || defined(__CC_ARM)
  347. #define MBED_SCANF_METHOD(format_idx, first_param_idx) __attribute__ ((__format__(__scanf__, format_idx+1, first_param_idx+1)))
  348. #else
  349. #define MBED_SCANF_METHOD(format_idx, first_param_idx)
  350. #endif
  351. #endif
  352. // Macro containing the filename part of the value of __FILE__. Defined as
  353. // string literal.
  354. #ifndef MBED_FILENAME
  355. #if defined(__CC_ARM)
  356. #define MBED_FILENAME __MODULE__
  357. #elif defined(__GNUC__)
  358. #define MBED_FILENAME (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __builtin_strrchr(__FILE__, '\\') ? __builtin_strrchr(__FILE__, '\\') + 1 : __FILE__)
  359. #elif defined(__ICCARM__)
  360. #define MBED_FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
  361. #else
  362. #define MBED_FILENAME __FILE__
  363. #endif
  364. #endif // #ifndef MBED_FILENAME
  365. // FILEHANDLE declaration
  366. #if defined(TOOLCHAIN_ARM)
  367. #include <rt_sys.h>
  368. #endif
  369. #ifndef FILEHANDLE
  370. typedef int FILEHANDLE;
  371. #endif
  372. // Backwards compatibility
  373. #ifndef WEAK
  374. #define WEAK MBED_WEAK
  375. #endif
  376. #ifndef PACKED
  377. #define PACKED MBED_PACKED()
  378. #endif
  379. #ifndef EXTERN
  380. #define EXTERN extern
  381. #endif
  382. /** MBED_NONSECURE_ENTRY
  383. * Declare a function that can be called from non-secure world or secure world
  384. *
  385. * @code
  386. * #include "mbed_toolchain.h"
  387. *
  388. * MBED_NONSECURE_ENTRY void foo() {
  389. *
  390. * }
  391. * @endcode
  392. */
  393. #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3L)
  394. #if defined (__ICCARM__)
  395. #define MBED_NONSECURE_ENTRY __cmse_nonsecure_entry
  396. #else
  397. #define MBED_NONSECURE_ENTRY __attribute__((cmse_nonsecure_entry))
  398. #endif
  399. #else
  400. #define MBED_NONSECURE_ENTRY
  401. #endif
  402. #endif
  403. /** @}*/
  404. /** @}*/