summaryrefslogtreecommitdiffstats
path: root/mbed/platform
diff options
context:
space:
mode:
authorYann Herklotz <ymherklotz@gmail.com>2017-05-10 13:17:31 +0100
committerYann Herklotz <ymherklotz@gmail.com>2017-05-10 13:17:31 +0100
commitaa30a51f3e2d9120aa819c1bc8162793662ccf32 (patch)
treee7659204b1ecf3f65fae106c12b096fd552c2d8d /mbed/platform
downloadWaveGenerator-aa30a51f3e2d9120aa819c1bc8162793662ccf32.tar.gz
WaveGenerator-aa30a51f3e2d9120aa819c1bc8162793662ccf32.zip
Adding initial files
Diffstat (limited to 'mbed/platform')
-rw-r--r--mbed/platform/CThunk.h245
-rw-r--r--mbed/platform/CallChain.h192
-rw-r--r--mbed/platform/Callback.h4654
-rw-r--r--mbed/platform/CircularBuffer.h119
-rw-r--r--mbed/platform/FunctionPointer.h100
-rw-r--r--mbed/platform/PlatformMutex.h51
-rw-r--r--mbed/platform/SingletonPtr.h110
-rw-r--r--mbed/platform/Transaction.h79
-rw-r--r--mbed/platform/critical.h24
-rw-r--r--mbed/platform/mbed_application.h50
-rw-r--r--mbed/platform/mbed_assert.h113
-rw-r--r--mbed/platform/mbed_critical.h359
-rw-r--r--mbed/platform/mbed_debug.h71
-rw-r--r--mbed/platform/mbed_error.h71
-rw-r--r--mbed/platform/mbed_interface.h135
-rw-r--r--mbed/platform/mbed_mem_trace.h143
-rw-r--r--mbed/platform/mbed_preprocessor.h53
-rw-r--r--mbed/platform/mbed_retarget.h191
-rw-r--r--mbed/platform/mbed_rtc_time.h92
-rw-r--r--mbed/platform/mbed_semihost_api.h98
-rw-r--r--mbed/platform/mbed_sleep.h85
-rw-r--r--mbed/platform/mbed_stats.h75
-rw-r--r--mbed/platform/mbed_toolchain.h305
-rw-r--r--mbed/platform/mbed_wait_api.h71
-rw-r--r--mbed/platform/platform.h35
-rw-r--r--mbed/platform/rtc_time.h24
-rw-r--r--mbed/platform/semihost_api.h24
-rw-r--r--mbed/platform/sleep.h24
-rw-r--r--mbed/platform/toolchain.h26
-rw-r--r--mbed/platform/wait_api.h24
30 files changed, 7643 insertions, 0 deletions
diff --git a/mbed/platform/CThunk.h b/mbed/platform/CThunk.h
new file mode 100644
index 0000000..53cfffc
--- /dev/null
+++ b/mbed/platform/CThunk.h
@@ -0,0 +1,245 @@
+
+/** \addtogroup platform */
+/** @{*/
+/* General C++ Object Thunking class
+ *
+ * - allows direct callbacks to non-static C++ class functions
+ * - keeps track for the corresponding class instance
+ * - supports an optional context parameter for the called function
+ * - ideally suited for class object receiving interrupts (NVIC_SetVector)
+ *
+ * Copyright (c) 2014-2015 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.
+ */
+
+/* General C++ Object Thunking class
+ *
+ * - allows direct callbacks to non-static C++ class functions
+ * - keeps track for the corresponding class instance
+ * - supports an optional context parameter for the called function
+ * - ideally suited for class object receiving interrupts (NVIC_SetVector)
+ */
+
+#ifndef __CTHUNK_H__
+#define __CTHUNK_H__
+
+#define CTHUNK_ADDRESS 1
+#define CTHUNK_VARIABLES volatile uint32_t code[2]
+
+#if (defined(__CORTEX_M3) || defined(__CORTEX_M4) || defined(__CORTEX_M7) || defined(__CORTEX_A9))
+/**
+* CTHUNK disassembly for Cortex-M3/M4/M7/A9 (thumb2):
+* * adr r0, #4
+* * ldm r0, {r0, r1, r2, pc}
+*
+* This instruction loads the arguments for the static thunking function to r0-r2, and
+* branches to that function by loading its address into PC.
+*
+* This is safe for both regular calling and interrupt calling, since it only touches scratch registers
+* which should be saved by the caller, and are automatically saved as part of the IRQ context switch.
+*/
+#define CTHUNK_ASSIGMENT do { \
+ m_thunk.code[0] = 0xE890A001; \
+ m_thunk.code[1] = 0x00008007; \
+ } while (0)
+
+#elif (defined(__CORTEX_M0PLUS) || defined(__CORTEX_M0))
+/*
+* CTHUNK disassembly for Cortex M0/M0+ (thumb):
+* * adr r0, #4
+* * ldm r0, {r0, r1, r2, r3}
+* * bx r3
+*/
+#define CTHUNK_ASSIGMENT do { \
+ m_thunk.code[0] = 0xC80FA001; \
+ m_thunk.code[1] = 0x00004718; \
+ } while (0)
+
+#else
+#error "Target is not currently suported."
+#endif
+
+/* IRQ/Exception compatible thunk entry function */
+typedef void (*CThunkEntry)(void);
+
+/**
+ * Class for created a pointer with data bound to it
+ *
+ * @Note Synchronization level: Not protected
+ */
+template<class T>
+class CThunk
+{
+ public:
+ typedef void (T::*CCallbackSimple)(void);
+ typedef void (T::*CCallback)(void* context);
+
+ inline CThunk(T *instance)
+ {
+ init(instance, NULL, NULL);
+ }
+
+ inline CThunk(T *instance, CCallback callback)
+ {
+ init(instance, callback, NULL);
+ }
+
+ ~CThunk() {
+
+ }
+
+ inline CThunk(T *instance, CCallbackSimple callback)
+ {
+ init(instance, (CCallback)callback, NULL);
+ }
+
+ inline CThunk(T &instance, CCallback callback)
+ {
+ init(instance, callback, NULL);
+ }
+
+ inline CThunk(T &instance, CCallbackSimple callback)
+ {
+ init(instance, (CCallback)callback, NULL);
+ }
+
+ inline CThunk(T &instance, CCallback callback, void* context)
+ {
+ init(instance, callback, context);
+ }
+
+ inline void callback(CCallback callback)
+ {
+ m_callback = callback;
+ }
+
+ inline void callback(CCallbackSimple callback)
+ {
+ m_callback = (CCallback)callback;
+ }
+
+ inline void context(void* context)
+ {
+ m_thunk.context = (uint32_t)context;
+ }
+
+ inline void context(uint32_t context)
+ {
+ m_thunk.context = context;
+ }
+
+ inline uint32_t entry(void)
+ {
+ return (((uint32_t)&m_thunk)|CTHUNK_ADDRESS);
+ }
+
+ /* get thunk entry point for connecting rhunk to an IRQ table */
+ inline operator CThunkEntry(void)
+ {
+ return (CThunkEntry)entry();
+ }
+
+ /* get thunk entry point for connecting rhunk to an IRQ table */
+ inline operator uint32_t(void)
+ {
+ return entry();
+ }
+
+ /* simple test function */
+ inline void call(void)
+ {
+ (((CThunkEntry)(entry()))());
+ }
+
+ private:
+ T* m_instance;
+ volatile CCallback m_callback;
+
+// TODO: this needs proper fix, to refactor toolchain header file and all its use
+// PACKED there is not defined properly for IAR
+#if defined (__ICCARM__)
+ typedef __packed struct
+ {
+ CTHUNK_VARIABLES;
+ volatile uint32_t instance;
+ volatile uint32_t context;
+ volatile uint32_t callback;
+ volatile uint32_t trampoline;
+ } CThunkTrampoline;
+#else
+ typedef struct
+ {
+ CTHUNK_VARIABLES;
+ volatile uint32_t instance;
+ volatile uint32_t context;
+ volatile uint32_t callback;
+ volatile uint32_t trampoline;
+ } __attribute__((__packed__)) CThunkTrampoline;
+#endif
+
+ static void trampoline(T* instance, void* context, CCallback* callback)
+ {
+ if(instance && *callback) {
+ (static_cast<T*>(instance)->**callback)(context);
+ }
+ }
+
+ volatile CThunkTrampoline m_thunk;
+
+ inline void init(T *instance, CCallback callback, void* context)
+ {
+ /* remember callback - need to add this level of redirection
+ as pointer size for member functions differs between platforms */
+ m_callback = callback;
+
+ /* populate thunking trampoline */
+ CTHUNK_ASSIGMENT;
+ m_thunk.context = (uint32_t)context;
+ m_thunk.instance = (uint32_t)instance;
+ m_thunk.callback = (uint32_t)&m_callback;
+ m_thunk.trampoline = (uint32_t)&trampoline;
+
+#if defined(__CORTEX_A9)
+ /* Data cache clean */
+ /* Cache control */
+ {
+ uint32_t start_addr = (uint32_t)&m_thunk & 0xFFFFFFE0;
+ uint32_t end_addr = (uint32_t)&m_thunk + sizeof(m_thunk);
+ uint32_t addr;
+
+ /* Data cache clean and invalid */
+ for (addr = start_addr; addr < end_addr; addr += 0x20) {
+ __v7_clean_inv_dcache_mva((void *)addr);
+ }
+ /* Instruction cache invalid */
+ __v7_inv_icache_all();
+ __ca9u_inv_tlb_all();
+ __v7_inv_btac();
+ }
+#endif
+#if defined(__CORTEX_M7)
+ /* Data cache clean and invalid */
+ SCB_CleanInvalidateDCache();
+
+ /* Instruction cache invalid */
+ SCB_InvalidateICache();
+#endif
+ __ISB();
+ __DSB();
+ }
+};
+
+#endif/*__CTHUNK_H__*/
+
+/** @}*/
diff --git a/mbed/platform/CallChain.h b/mbed/platform/CallChain.h
new file mode 100644
index 0000000..f014ed4
--- /dev/null
+++ b/mbed/platform/CallChain.h
@@ -0,0 +1,192 @@
+/* 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_CALLCHAIN_H
+#define MBED_CALLCHAIN_H
+
+#include "platform/Callback.h"
+#include "platform/mbed_toolchain.h"
+#include <string.h>
+
+namespace mbed {
+/** \addtogroup platform */
+/** @{*/
+
+/** Group one or more functions in an instance of a CallChain, then call them in
+ * sequence using CallChain::call(). Used mostly by the interrupt chaining code,
+ * but can be used for other purposes.
+ *
+ * @Note Synchronization level: Not protected
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ *
+ * CallChain chain;
+ *
+ * void first(void) {
+ * printf("'first' function.\n");
+ * }
+ *
+ * void second(void) {
+ * printf("'second' function.\n");
+ * }
+ *
+ * class Test {
+ * public:
+ * void f(void) {
+ * printf("A::f (class member).\n");
+ * }
+ * };
+ *
+ * int main() {
+ * Test test;
+ *
+ * chain.add(second);
+ * chain.add_front(first);
+ * chain.add(&test, &Test::f);
+ * chain.call();
+ * }
+ * @endcode
+ */
+
+typedef Callback<void()> *pFunctionPointer_t;
+class CallChainLink;
+
+class CallChain {
+public:
+ /** Create an empty chain
+ *
+ * @param size (optional) Initial size of the chain
+ */
+ CallChain(int size = 4);
+ virtual ~CallChain();
+
+ /** Add a function at the end of the chain
+ *
+ * @param func A pointer to a void function
+ *
+ * @returns
+ * The function object created for 'func'
+ */
+ pFunctionPointer_t add(Callback<void()> func);
+
+ /** Add a function at the end of the chain
+ *
+ * @param obj pointer to the object to call the member function on
+ * @param method pointer to the member function to be called
+ *
+ * @returns
+ * The function object created for 'obj' and 'method'
+ *
+ * @deprecated
+ * The add function does not support cv-qualifiers. Replaced by
+ * add(callback(obj, method)).
+ */
+ template<typename T, typename M>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "The add function does not support cv-qualifiers. Replaced by "
+ "add(callback(obj, method)).")
+ pFunctionPointer_t add(T *obj, M method) {
+ return add(callback(obj, method));
+ }
+
+ /** Add a function at the beginning of the chain
+ *
+ * @param func A pointer to a void function
+ *
+ * @returns
+ * The function object created for 'func'
+ */
+ pFunctionPointer_t add_front(Callback<void()> func);
+
+ /** Add a function at the beginning of the chain
+ *
+ * @param tptr pointer to the object to call the member function on
+ * @param mptr pointer to the member function to be called
+ *
+ * @returns
+ * The function object created for 'tptr' and 'mptr'
+ *
+ * @deprecated
+ * The add_front function does not support cv-qualifiers. Replaced by
+ * add_front(callback(obj, method)).
+ */
+ template<typename T, typename M>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "The add_front function does not support cv-qualifiers. Replaced by "
+ "add_front(callback(obj, method)).")
+ pFunctionPointer_t add_front(T *obj, M method) {
+ return add_front(callback(obj, method));
+ }
+
+ /** Get the number of functions in the chain
+ */
+ int size() const;
+
+ /** Get a function object from the chain
+ *
+ * @param i function object index
+ *
+ * @returns
+ * The function object at position 'i' in the chain
+ */
+ pFunctionPointer_t get(int i) const;
+
+ /** Look for a function object in the call chain
+ *
+ * @param f the function object to search
+ *
+ * @returns
+ * The index of the function object if found, -1 otherwise.
+ */
+ int find(pFunctionPointer_t f) const;
+
+ /** Clear the call chain (remove all functions in the chain).
+ */
+ void clear();
+
+ /** Remove a function object from the chain
+ *
+ * @arg f the function object to remove
+ *
+ * @returns
+ * true if the function object was found and removed, false otherwise.
+ */
+ bool remove(pFunctionPointer_t f);
+
+ /** Call all the functions in the chain in sequence
+ */
+ void call();
+
+ void operator ()(void) {
+ call();
+ }
+ pFunctionPointer_t operator [](int i) const {
+ return get(i);
+ }
+
+ /* disallow copy constructor and assignment operators */
+private:
+ CallChain(const CallChain&);
+ CallChain & operator = (const CallChain&);
+ CallChainLink *_chain;
+};
+
+} // namespace mbed
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/Callback.h b/mbed/platform/Callback.h
new file mode 100644
index 0000000..a303b40
--- /dev/null
+++ b/mbed/platform/Callback.h
@@ -0,0 +1,4654 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 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_CALLBACK_H
+#define MBED_CALLBACK_H
+
+#include <string.h>
+#include <stdint.h>
+#include <new>
+#include "platform/mbed_assert.h"
+#include "platform/mbed_toolchain.h"
+
+namespace mbed {
+/** \addtogroup platform */
+/** @{*/
+
+
+/** Callback class based on template specialization
+ *
+ * @Note Synchronization level: Not protected
+ */
+template <typename F>
+class Callback;
+
+// Internal sfinae declarations
+//
+// These are used to eliminate overloads based on type attributes
+// 1. Does a function object have a call operator
+// 2. Does a function object fit in the available storage
+//
+// These eliminations are handled cleanly by the compiler and avoid
+// massive and misleading error messages when confronted with an
+// invalid type (or worse, runtime failures)
+namespace detail {
+ struct nil {};
+
+ template <bool B, typename R = nil>
+ struct enable_if { typedef R type; };
+
+ template <typename R>
+ struct enable_if<false, R> {};
+
+ template <typename M, M>
+ struct is_type {
+ static const bool value = true;
+ };
+}
+
+/** Callback class based on template specialization
+ *
+ * @Note Synchronization level: Not protected
+ */
+template <typename R>
+class Callback<R()> {
+public:
+ /** Create a Callback with a static function
+ * @param func Static function to attach
+ */
+ Callback(R (*func)() = 0) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R()> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)()) {
+ generate(method_context<T, R (T::*)()>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)() const) {
+ generate(method_context<const T, R (T::*)() const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)() volatile) {
+ generate(method_context<volatile T, R (T::*)() volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)() const volatile) {
+ generate(method_context<const volatile T, R (T::*)() const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*), U *arg) {
+ generate(function_context<R (*)(T*), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*), const U *arg) {
+ generate(function_context<R (*)(const T*), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(), &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, typename detail::enable_if<
+ detail::is_type<R (F::*)() const, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)() volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)() const volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(U *obj, R (*func)(T*)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(const U *obj, R (*func)(const T*)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(volatile U *obj, R (*func)(volatile T*)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(const volatile U *obj, R (*func)(const volatile T*)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)()) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const Callback<R()> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(U *obj, R (T::*method)()) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const U *obj, R (T::*method)() const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(volatile U *obj, R (T::*method)() volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const volatile U *obj, R (T::*method)() const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(T*), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(const T*), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(volatile T*), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(const volatile T*), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(), &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const F f, typename detail::enable_if<
+ detail::is_type<R (F::*)() const, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)() volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)() const volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(U *obj, R (*func)(T*)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(const U *obj, R (*func)(const T*)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(volatile U *obj, R (*func)(volatile T*)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(const volatile U *obj, R (*func)(const volatile T*)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call() const {
+ MBED_ASSERT(_ops);
+ return _ops->call(this);
+ }
+
+ /** Call the attached function
+ */
+ R operator()() const {
+ return call();
+ }
+
+ /** Test if function has been attached
+ */
+ operator bool() const {
+ return _ops;
+ }
+
+ /** Test for equality
+ */
+ friend bool operator==(const Callback &l, const Callback &r) {
+ return memcmp(&l, &r, sizeof(Callback)) == 0;
+ }
+
+ /** Test for inequality
+ */
+ friend bool operator!=(const Callback &l, const Callback &r) {
+ return !(l == r);
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Callback to call passed as void pointer
+ */
+ static R thunk(void *func) {
+ return static_cast<Callback*>(func)->call();
+ }
+
+private:
+ // Stored as pointer to function and pointer to optional object
+ // Function pointer is stored as union of possible function types
+ // to garuntee proper size and alignment
+ struct _class;
+ union {
+ void (*_staticfunc)();
+ void (*_boundfunc)(_class*);
+ void (_class::*_methodfunc)();
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+
+ MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
+ "Type F must not exceed the size of the Callback class");
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p) {
+ return (*(F*)p)();
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()() const {
+ return (obj->*method)();
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()() const {
+ return func(arg);
+ }
+ };
+};
+
+/** Callback class based on template specialization
+ *
+ * @Note Synchronization level: Not protected
+ */
+template <typename R, typename A0>
+class Callback<R(A0)> {
+public:
+ /** Create a Callback with a static function
+ * @param func Static function to attach
+ */
+ Callback(R (*func)(A0) = 0) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R(A0)> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)(A0)) {
+ generate(method_context<T, R (T::*)(A0)>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)(A0) const) {
+ generate(method_context<const T, R (T::*)(A0) const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)(A0) volatile) {
+ generate(method_context<volatile T, R (T::*)(A0) volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)(A0) const volatile) {
+ generate(method_context<const volatile T, R (T::*)(A0) const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*, A0), U *arg) {
+ generate(function_context<R (*)(T*, A0), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*, A0), const U *arg) {
+ generate(function_context<R (*)(const T*, A0), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*, A0), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*, A0), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*, A0), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*, A0), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0), &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0) const, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0) volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0) const volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(U *obj, R (*func)(T*, A0)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(const U *obj, R (*func)(const T*, A0)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(volatile U *obj, R (*func)(volatile T*, A0)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(const volatile U *obj, R (*func)(const volatile T*, A0)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(A0)) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const Callback<R(A0)> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(U *obj, R (T::*method)(A0)) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const U *obj, R (T::*method)(A0) const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(volatile U *obj, R (T::*method)(A0) volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const volatile U *obj, R (T::*method)(A0) const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(T*, A0), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(const T*, A0), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(volatile T*, A0), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(const volatile T*, A0), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0), &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0) const, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0) volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0) const volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(U *obj, R (*func)(T*, A0)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(const U *obj, R (*func)(const T*, A0)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(volatile U *obj, R (*func)(volatile T*, A0)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(const volatile U *obj, R (*func)(const volatile T*, A0)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call(A0 a0) const {
+ MBED_ASSERT(_ops);
+ return _ops->call(this, a0);
+ }
+
+ /** Call the attached function
+ */
+ R operator()(A0 a0) const {
+ return call(a0);
+ }
+
+ /** Test if function has been attached
+ */
+ operator bool() const {
+ return _ops;
+ }
+
+ /** Test for equality
+ */
+ friend bool operator==(const Callback &l, const Callback &r) {
+ return memcmp(&l, &r, sizeof(Callback)) == 0;
+ }
+
+ /** Test for inequality
+ */
+ friend bool operator!=(const Callback &l, const Callback &r) {
+ return !(l == r);
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Callback to call passed as void pointer
+ */
+ static R thunk(void *func, A0 a0) {
+ return static_cast<Callback*>(func)->call(a0);
+ }
+
+private:
+ // Stored as pointer to function and pointer to optional object
+ // Function pointer is stored as union of possible function types
+ // to garuntee proper size and alignment
+ struct _class;
+ union {
+ void (*_staticfunc)(A0);
+ void (*_boundfunc)(_class*, A0);
+ void (_class::*_methodfunc)(A0);
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*, A0);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+
+ MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
+ "Type F must not exceed the size of the Callback class");
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p, A0 a0) {
+ return (*(F*)p)(a0);
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()(A0 a0) const {
+ return (obj->*method)(a0);
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()(A0 a0) const {
+ return func(arg, a0);
+ }
+ };
+};
+
+/** Callback class based on template specialization
+ *
+ * @Note Synchronization level: Not protected
+ */
+template <typename R, typename A0, typename A1>
+class Callback<R(A0, A1)> {
+public:
+ /** Create a Callback with a static function
+ * @param func Static function to attach
+ */
+ Callback(R (*func)(A0, A1) = 0) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R(A0, A1)> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)(A0, A1)) {
+ generate(method_context<T, R (T::*)(A0, A1)>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)(A0, A1) const) {
+ generate(method_context<const T, R (T::*)(A0, A1) const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)(A0, A1) volatile) {
+ generate(method_context<volatile T, R (T::*)(A0, A1) volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)(A0, A1) const volatile) {
+ generate(method_context<const volatile T, R (T::*)(A0, A1) const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*, A0, A1), U *arg) {
+ generate(function_context<R (*)(T*, A0, A1), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*, A0, A1), const U *arg) {
+ generate(function_context<R (*)(const T*, A0, A1), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*, A0, A1), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*, A0, A1), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*, A0, A1), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*, A0, A1), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1), &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1) const, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1) volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1) const volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(U *obj, R (*func)(T*, A0, A1)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(const U *obj, R (*func)(const T*, A0, A1)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(volatile U *obj, R (*func)(volatile T*, A0, A1)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(A0, A1)) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const Callback<R(A0, A1)> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(U *obj, R (T::*method)(A0, A1)) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const U *obj, R (T::*method)(A0, A1) const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(volatile U *obj, R (T::*method)(A0, A1) volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const volatile U *obj, R (T::*method)(A0, A1) const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(T*, A0, A1), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(const T*, A0, A1), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(volatile T*, A0, A1), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(const volatile T*, A0, A1), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1), &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1) const, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1) volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1) const volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(U *obj, R (*func)(T*, A0, A1)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(const U *obj, R (*func)(const T*, A0, A1)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(volatile U *obj, R (*func)(volatile T*, A0, A1)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call(A0 a0, A1 a1) const {
+ MBED_ASSERT(_ops);
+ return _ops->call(this, a0, a1);
+ }
+
+ /** Call the attached function
+ */
+ R operator()(A0 a0, A1 a1) const {
+ return call(a0, a1);
+ }
+
+ /** Test if function has been attached
+ */
+ operator bool() const {
+ return _ops;
+ }
+
+ /** Test for equality
+ */
+ friend bool operator==(const Callback &l, const Callback &r) {
+ return memcmp(&l, &r, sizeof(Callback)) == 0;
+ }
+
+ /** Test for inequality
+ */
+ friend bool operator!=(const Callback &l, const Callback &r) {
+ return !(l == r);
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Callback to call passed as void pointer
+ */
+ static R thunk(void *func, A0 a0, A1 a1) {
+ return static_cast<Callback*>(func)->call(a0, a1);
+ }
+
+private:
+ // Stored as pointer to function and pointer to optional object
+ // Function pointer is stored as union of possible function types
+ // to garuntee proper size and alignment
+ struct _class;
+ union {
+ void (*_staticfunc)(A0, A1);
+ void (*_boundfunc)(_class*, A0, A1);
+ void (_class::*_methodfunc)(A0, A1);
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*, A0, A1);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+
+ MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
+ "Type F must not exceed the size of the Callback class");
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p, A0 a0, A1 a1) {
+ return (*(F*)p)(a0, a1);
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()(A0 a0, A1 a1) const {
+ return (obj->*method)(a0, a1);
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()(A0 a0, A1 a1) const {
+ return func(arg, a0, a1);
+ }
+ };
+};
+
+/** Callback class based on template specialization
+ *
+ * @Note Synchronization level: Not protected
+ */
+template <typename R, typename A0, typename A1, typename A2>
+class Callback<R(A0, A1, A2)> {
+public:
+ /** Create a Callback with a static function
+ * @param func Static function to attach
+ */
+ Callback(R (*func)(A0, A1, A2) = 0) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R(A0, A1, A2)> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)(A0, A1, A2)) {
+ generate(method_context<T, R (T::*)(A0, A1, A2)>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)(A0, A1, A2) const) {
+ generate(method_context<const T, R (T::*)(A0, A1, A2) const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)(A0, A1, A2) volatile) {
+ generate(method_context<volatile T, R (T::*)(A0, A1, A2) volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)(A0, A1, A2) const volatile) {
+ generate(method_context<const volatile T, R (T::*)(A0, A1, A2) const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*, A0, A1, A2), U *arg) {
+ generate(function_context<R (*)(T*, A0, A1, A2), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*, A0, A1, A2), const U *arg) {
+ generate(function_context<R (*)(const T*, A0, A1, A2), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*, A0, A1, A2), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*, A0, A1, A2), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*, A0, A1, A2), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*, A0, A1, A2), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2), &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2) const, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2) volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2) const volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(U *obj, R (*func)(T*, A0, A1, A2)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(const U *obj, R (*func)(const T*, A0, A1, A2)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const Callback<R(A0, A1, A2)> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(U *obj, R (T::*method)(A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const U *obj, R (T::*method)(A0, A1, A2) const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(volatile U *obj, R (T::*method)(A0, A1, A2) volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const volatile U *obj, R (T::*method)(A0, A1, A2) const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(T*, A0, A1, A2), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(const T*, A0, A1, A2), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(volatile T*, A0, A1, A2), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(const volatile T*, A0, A1, A2), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2), &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2) const, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2) volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2) const volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(U *obj, R (*func)(T*, A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(const U *obj, R (*func)(const T*, A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(volatile U *obj, R (*func)(volatile T*, A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call(A0 a0, A1 a1, A2 a2) const {
+ MBED_ASSERT(_ops);
+ return _ops->call(this, a0, a1, a2);
+ }
+
+ /** Call the attached function
+ */
+ R operator()(A0 a0, A1 a1, A2 a2) const {
+ return call(a0, a1, a2);
+ }
+
+ /** Test if function has been attached
+ */
+ operator bool() const {
+ return _ops;
+ }
+
+ /** Test for equality
+ */
+ friend bool operator==(const Callback &l, const Callback &r) {
+ return memcmp(&l, &r, sizeof(Callback)) == 0;
+ }
+
+ /** Test for inequality
+ */
+ friend bool operator!=(const Callback &l, const Callback &r) {
+ return !(l == r);
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Callback to call passed as void pointer
+ */
+ static R thunk(void *func, A0 a0, A1 a1, A2 a2) {
+ return static_cast<Callback*>(func)->call(a0, a1, a2);
+ }
+
+private:
+ // Stored as pointer to function and pointer to optional object
+ // Function pointer is stored as union of possible function types
+ // to garuntee proper size and alignment
+ struct _class;
+ union {
+ void (*_staticfunc)(A0, A1, A2);
+ void (*_boundfunc)(_class*, A0, A1, A2);
+ void (_class::*_methodfunc)(A0, A1, A2);
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*, A0, A1, A2);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+
+ MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
+ "Type F must not exceed the size of the Callback class");
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p, A0 a0, A1 a1, A2 a2) {
+ return (*(F*)p)(a0, a1, a2);
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2) const {
+ return (obj->*method)(a0, a1, a2);
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2) const {
+ return func(arg, a0, a1, a2);
+ }
+ };
+};
+
+/** Callback class based on template specialization
+ *
+ * @Note Synchronization level: Not protected
+ */
+template <typename R, typename A0, typename A1, typename A2, typename A3>
+class Callback<R(A0, A1, A2, A3)> {
+public:
+ /** Create a Callback with a static function
+ * @param func Static function to attach
+ */
+ Callback(R (*func)(A0, A1, A2, A3) = 0) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R(A0, A1, A2, A3)> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)(A0, A1, A2, A3)) {
+ generate(method_context<T, R (T::*)(A0, A1, A2, A3)>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)(A0, A1, A2, A3) const) {
+ generate(method_context<const T, R (T::*)(A0, A1, A2, A3) const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
+ generate(method_context<volatile T, R (T::*)(A0, A1, A2, A3) volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
+ generate(method_context<const volatile T, R (T::*)(A0, A1, A2, A3) const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*, A0, A1, A2, A3), U *arg) {
+ generate(function_context<R (*)(T*, A0, A1, A2, A3), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*, A0, A1, A2, A3), const U *arg) {
+ generate(function_context<R (*)(const T*, A0, A1, A2, A3), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*, A0, A1, A2, A3), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*, A0, A1, A2, A3), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*, A0, A1, A2, A3), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2, A3), &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2, A3) const, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2, A3) volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2, A3) const volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(U *obj, R (*func)(T*, A0, A1, A2, A3)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const Callback<R(A0, A1, A2, A3)> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(U *obj, R (T::*method)(A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const U *obj, R (T::*method)(A0, A1, A2, A3) const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(volatile U *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const volatile U *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(T*, A0, A1, A2, A3), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(const T*, A0, A1, A2, A3), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(volatile T*, A0, A1, A2, A3), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2, A3), &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2, A3) const, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2, A3) volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2, A3) const volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(U *obj, R (*func)(T*, A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(const U *obj, R (*func)(const T*, A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call(A0 a0, A1 a1, A2 a2, A3 a3) const {
+ MBED_ASSERT(_ops);
+ return _ops->call(this, a0, a1, a2, a3);
+ }
+
+ /** Call the attached function
+ */
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
+ return call(a0, a1, a2, a3);
+ }
+
+ /** Test if function has been attached
+ */
+ operator bool() const {
+ return _ops;
+ }
+
+ /** Test for equality
+ */
+ friend bool operator==(const Callback &l, const Callback &r) {
+ return memcmp(&l, &r, sizeof(Callback)) == 0;
+ }
+
+ /** Test for inequality
+ */
+ friend bool operator!=(const Callback &l, const Callback &r) {
+ return !(l == r);
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Callback to call passed as void pointer
+ */
+ static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
+ return static_cast<Callback*>(func)->call(a0, a1, a2, a3);
+ }
+
+private:
+ // Stored as pointer to function and pointer to optional object
+ // Function pointer is stored as union of possible function types
+ // to garuntee proper size and alignment
+ struct _class;
+ union {
+ void (*_staticfunc)(A0, A1, A2, A3);
+ void (*_boundfunc)(_class*, A0, A1, A2, A3);
+ void (_class::*_methodfunc)(A0, A1, A2, A3);
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*, A0, A1, A2, A3);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+
+ MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
+ "Type F must not exceed the size of the Callback class");
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3) {
+ return (*(F*)p)(a0, a1, a2, a3);
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
+ return (obj->*method)(a0, a1, a2, a3);
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
+ return func(arg, a0, a1, a2, a3);
+ }
+ };
+};
+
+/** Callback class based on template specialization
+ *
+ * @Note Synchronization level: Not protected
+ */
+template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+class Callback<R(A0, A1, A2, A3, A4)> {
+public:
+ /** Create a Callback with a static function
+ * @param func Static function to attach
+ */
+ Callback(R (*func)(A0, A1, A2, A3, A4) = 0) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R(A0, A1, A2, A3, A4)> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
+ generate(method_context<T, R (T::*)(A0, A1, A2, A3, A4)>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
+ generate(method_context<const T, R (T::*)(A0, A1, A2, A3, A4) const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
+ generate(method_context<volatile T, R (T::*)(A0, A1, A2, A3, A4) volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
+ generate(method_context<const volatile T, R (T::*)(A0, A1, A2, A3, A4) const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*, A0, A1, A2, A3, A4), U *arg) {
+ generate(function_context<R (*)(T*, A0, A1, A2, A3, A4), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*, A0, A1, A2, A3, A4), const U *arg) {
+ generate(function_context<R (*)(const T*, A0, A1, A2, A3, A4), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*, A0, A1, A2, A3, A4), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*, A0, A1, A2, A3, A4), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2, A3, A4), &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2, A3, A4) const, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2, A3, A4) volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2, A3, A4) const volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ generate(f);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(U *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to Callback(func, arg)")
+ Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const Callback<R(A0, A1, A2, A3, A4)> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(U *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const U *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(T*, A0, A1, A2, A3, A4), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(const T*, A0, A1, A2, A3, A4), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2, A3, A4), &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2, A3, A4) const, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2, A3, A4) volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param func Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ MBED_DEPRECATED_SINCE("mbed-os-5.4",
+ "Replaced by simple assignment 'Callback cb = func")
+ void attach(const volatile F f, typename detail::enable_if<
+ detail::is_type<R (F::*)(A0, A1, A2, A3, A4) const volatile, &F::operator()>::value &&
+ sizeof(F) <= sizeof(uintptr_t)
+ >::type = detail::nil()) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(U *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(const U *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to attach(func, arg)")
+ void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
+ MBED_ASSERT(_ops);
+ return _ops->call(this, a0, a1, a2, a3, a4);
+ }
+
+ /** Call the attached function
+ */
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
+ return call(a0, a1, a2, a3, a4);
+ }
+
+ /** Test if function has been attached
+ */
+ operator bool() const {
+ return _ops;
+ }
+
+ /** Test for equality
+ */
+ friend bool operator==(const Callback &l, const Callback &r) {
+ return memcmp(&l, &r, sizeof(Callback)) == 0;
+ }
+
+ /** Test for inequality
+ */
+ friend bool operator!=(const Callback &l, const Callback &r) {
+ return !(l == r);
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Callback to call passed as void pointer
+ */
+ static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
+ return static_cast<Callback*>(func)->call(a0, a1, a2, a3, a4);
+ }
+
+private:
+ // Stored as pointer to function and pointer to optional object
+ // Function pointer is stored as union of possible function types
+ // to garuntee proper size and alignment
+ struct _class;
+ union {
+ void (*_staticfunc)(A0, A1, A2, A3, A4);
+ void (*_boundfunc)(_class*, A0, A1, A2, A3, A4);
+ void (_class::*_methodfunc)(A0, A1, A2, A3, A4);
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*, A0, A1, A2, A3, A4);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+
+ MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
+ "Type F must not exceed the size of the Callback class");
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
+ return (*(F*)p)(a0, a1, a2, a3, a4);
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
+ return (obj->*method)(a0, a1, a2, a3, a4);
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
+ return func(arg, a0, a1, a2, a3, a4);
+ }
+ };
+};
+
+// Internally used event type
+typedef Callback<void(int)> event_callback_t;
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R>
+Callback<R()> callback(R (*func)() = 0) {
+ return Callback<R()>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R>
+Callback<R()> callback(const Callback<R()> &func) {
+ return Callback<R()>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R>
+Callback<R()> callback(U *obj, R (T::*method)()) {
+ return Callback<R()>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R>
+Callback<R()> callback(const U *obj, R (T::*method)() const) {
+ return Callback<R()>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R>
+Callback<R()> callback(volatile U *obj, R (T::*method)() volatile) {
+ return Callback<R()>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R>
+Callback<R()> callback(const volatile U *obj, R (T::*method)() const volatile) {
+ return Callback<R()>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(R (*func)(T*), U *arg) {
+ return Callback<R()>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(R (*func)(const T*), const U *arg) {
+ return Callback<R()>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(R (*func)(volatile T*), volatile U *arg) {
+ return Callback<R()>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(R (*func)(const volatile T*), const volatile U *arg) {
+ return Callback<R()>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R()> callback(U *obj, R (*func)(T*)) {
+ return Callback<R()>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R()> callback(const U *obj, R (*func)(const T*)) {
+ return Callback<R()>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R()> callback(volatile U *obj, R (*func)(volatile T*)) {
+ return Callback<R()>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R()> callback(const volatile U *obj, R (*func)(const volatile T*)) {
+ return Callback<R()>(func, obj);
+}
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0>
+Callback<R(A0)> callback(R (*func)(A0) = 0) {
+ return Callback<R(A0)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0>
+Callback<R(A0)> callback(const Callback<R(A0)> &func) {
+ return Callback<R(A0)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(U *obj, R (T::*method)(A0)) {
+ return Callback<R(A0)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(const U *obj, R (T::*method)(A0) const) {
+ return Callback<R(A0)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(volatile U *obj, R (T::*method)(A0) volatile) {
+ return Callback<R(A0)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(const volatile U *obj, R (T::*method)(A0) const volatile) {
+ return Callback<R(A0)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(R (*func)(T*, A0), U *arg) {
+ return Callback<R(A0)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(R (*func)(const T*, A0), const U *arg) {
+ return Callback<R(A0)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(R (*func)(volatile T*, A0), volatile U *arg) {
+ return Callback<R(A0)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(R (*func)(const volatile T*, A0), const volatile U *arg) {
+ return Callback<R(A0)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0)> callback(U *obj, R (*func)(T*, A0)) {
+ return Callback<R(A0)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0)> callback(const U *obj, R (*func)(const T*, A0)) {
+ return Callback<R(A0)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0)> callback(volatile U *obj, R (*func)(volatile T*, A0)) {
+ return Callback<R(A0)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0)> callback(const volatile U *obj, R (*func)(const volatile T*, A0)) {
+ return Callback<R(A0)>(func, obj);
+}
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(R (*func)(A0, A1) = 0) {
+ return Callback<R(A0, A1)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(const Callback<R(A0, A1)> &func) {
+ return Callback<R(A0, A1)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(U *obj, R (T::*method)(A0, A1)) {
+ return Callback<R(A0, A1)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(const U *obj, R (T::*method)(A0, A1) const) {
+ return Callback<R(A0, A1)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(volatile U *obj, R (T::*method)(A0, A1) volatile) {
+ return Callback<R(A0, A1)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(const volatile U *obj, R (T::*method)(A0, A1) const volatile) {
+ return Callback<R(A0, A1)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(R (*func)(T*, A0, A1), U *arg) {
+ return Callback<R(A0, A1)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(R (*func)(const T*, A0, A1), const U *arg) {
+ return Callback<R(A0, A1)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(R (*func)(volatile T*, A0, A1), volatile U *arg) {
+ return Callback<R(A0, A1)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(R (*func)(const volatile T*, A0, A1), const volatile U *arg) {
+ return Callback<R(A0, A1)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0, A1)> callback(U *obj, R (*func)(T*, A0, A1)) {
+ return Callback<R(A0, A1)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0, A1)> callback(const U *obj, R (*func)(const T*, A0, A1)) {
+ return Callback<R(A0, A1)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0, A1)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1)) {
+ return Callback<R(A0, A1)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0, A1)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1)) {
+ return Callback<R(A0, A1)>(func, obj);
+}
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(R (*func)(A0, A1, A2) = 0) {
+ return Callback<R(A0, A1, A2)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(const Callback<R(A0, A1, A2)> &func) {
+ return Callback<R(A0, A1, A2)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(U *obj, R (T::*method)(A0, A1, A2)) {
+ return Callback<R(A0, A1, A2)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(const U *obj, R (T::*method)(A0, A1, A2) const) {
+ return Callback<R(A0, A1, A2)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(volatile U *obj, R (T::*method)(A0, A1, A2) volatile) {
+ return Callback<R(A0, A1, A2)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(const volatile U *obj, R (T::*method)(A0, A1, A2) const volatile) {
+ return Callback<R(A0, A1, A2)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(R (*func)(T*, A0, A1, A2), U *arg) {
+ return Callback<R(A0, A1, A2)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(R (*func)(const T*, A0, A1, A2), const U *arg) {
+ return Callback<R(A0, A1, A2)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(R (*func)(volatile T*, A0, A1, A2), volatile U *arg) {
+ return Callback<R(A0, A1, A2)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(R (*func)(const volatile T*, A0, A1, A2), const volatile U *arg) {
+ return Callback<R(A0, A1, A2)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0, A1, A2)> callback(U *obj, R (*func)(T*, A0, A1, A2)) {
+ return Callback<R(A0, A1, A2)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0, A1, A2)> callback(const U *obj, R (*func)(const T*, A0, A1, A2)) {
+ return Callback<R(A0, A1, A2)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0, A1, A2)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2)) {
+ return Callback<R(A0, A1, A2)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0, A1, A2)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2)) {
+ return Callback<R(A0, A1, A2)>(func, obj);
+}
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(R (*func)(A0, A1, A2, A3) = 0) {
+ return Callback<R(A0, A1, A2, A3)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(const Callback<R(A0, A1, A2, A3)> &func) {
+ return Callback<R(A0, A1, A2, A3)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(U *obj, R (T::*method)(A0, A1, A2, A3)) {
+ return Callback<R(A0, A1, A2, A3)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(const U *obj, R (T::*method)(A0, A1, A2, A3) const) {
+ return Callback<R(A0, A1, A2, A3)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
+ return Callback<R(A0, A1, A2, A3)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
+ return Callback<R(A0, A1, A2, A3)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(R (*func)(T*, A0, A1, A2, A3), U *arg) {
+ return Callback<R(A0, A1, A2, A3)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(R (*func)(const T*, A0, A1, A2, A3), const U *arg) {
+ return Callback<R(A0, A1, A2, A3)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(R (*func)(volatile T*, A0, A1, A2, A3), volatile U *arg) {
+ return Callback<R(A0, A1, A2, A3)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile U *arg) {
+ return Callback<R(A0, A1, A2, A3)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0, A1, A2, A3)> callback(U *obj, R (*func)(T*, A0, A1, A2, A3)) {
+ return Callback<R(A0, A1, A2, A3)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0, A1, A2, A3)> callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3)) {
+ return Callback<R(A0, A1, A2, A3)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0, A1, A2, A3)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
+ return Callback<R(A0, A1, A2, A3)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0, A1, A2, A3)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
+ return Callback<R(A0, A1, A2, A3)>(func, obj);
+}
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(A0, A1, A2, A3, A4) = 0) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(const Callback<R(A0, A1, A2, A3, A4)> &func) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(U *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
+ return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(const U *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
+ return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
+ return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
+ return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(T*, A0, A1, A2, A3, A4), U *arg) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(const T*, A0, A1, A2, A3, A4), const U *arg) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile U *arg) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile U *arg) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0, A1, A2, A3, A4)> callback(U *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0, A1, A2, A3, A4)> callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0, A1, A2, A3, A4)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "Arguments to callback have been reordered to callback(func, arg)")
+Callback<R(A0, A1, A2, A3, A4)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
+}
+
+
+} // namespace mbed
+
+#endif
+
+
+/** @}*/
diff --git a/mbed/platform/CircularBuffer.h b/mbed/platform/CircularBuffer.h
new file mode 100644
index 0000000..b7973c0
--- /dev/null
+++ b/mbed/platform/CircularBuffer.h
@@ -0,0 +1,119 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 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_CIRCULARBUFFER_H
+#define MBED_CIRCULARBUFFER_H
+
+#include "platform/mbed_critical.h"
+
+namespace mbed {
+/** \addtogroup platform */
+/** @{*/
+
+/** Templated Circular buffer class
+ *
+ * @Note Synchronization level: Interrupt safe
+ */
+template<typename T, uint32_t BufferSize, typename CounterType = uint32_t>
+class CircularBuffer {
+public:
+ CircularBuffer() : _head(0), _tail(0), _full(false) {
+ }
+
+ ~CircularBuffer() {
+ }
+
+ /** Push the transaction to the buffer. This overwrites the buffer if it's
+ * full
+ *
+ * @param data Data to be pushed to the buffer
+ */
+ void push(const T& data) {
+ core_util_critical_section_enter();
+ if (full()) {
+ _tail++;
+ _tail %= BufferSize;
+ }
+ _pool[_head++] = data;
+ _head %= BufferSize;
+ if (_head == _tail) {
+ _full = true;
+ }
+ core_util_critical_section_exit();
+ }
+
+ /** Pop the transaction from the buffer
+ *
+ * @param data Data to be pushed to the buffer
+ * @return True if the buffer is not empty and data contains a transaction, false otherwise
+ */
+ bool pop(T& data) {
+ bool data_popped = false;
+ core_util_critical_section_enter();
+ if (!empty()) {
+ data = _pool[_tail++];
+ _tail %= BufferSize;
+ _full = false;
+ data_popped = true;
+ }
+ core_util_critical_section_exit();
+ return data_popped;
+ }
+
+ /** Check if the buffer is empty
+ *
+ * @return True if the buffer is empty, false if not
+ */
+ bool empty() {
+ core_util_critical_section_enter();
+ bool is_empty = (_head == _tail) && !_full;
+ core_util_critical_section_exit();
+ return is_empty;
+ }
+
+ /** Check if the buffer is full
+ *
+ * @return True if the buffer is full, false if not
+ */
+ bool full() {
+ core_util_critical_section_enter();
+ bool full = _full;
+ core_util_critical_section_exit();
+ return full;
+ }
+
+ /** Reset the buffer
+ *
+ */
+ void reset() {
+ core_util_critical_section_enter();
+ _head = 0;
+ _tail = 0;
+ _full = false;
+ core_util_critical_section_exit();
+ }
+
+private:
+ T _pool[BufferSize];
+ volatile CounterType _head;
+ volatile CounterType _tail;
+ volatile bool _full;
+};
+
+}
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/FunctionPointer.h b/mbed/platform/FunctionPointer.h
new file mode 100644
index 0000000..8ee3b5a
--- /dev/null
+++ b/mbed/platform/FunctionPointer.h
@@ -0,0 +1,100 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 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_FUNCTIONPOINTER_H
+#define MBED_FUNCTIONPOINTER_H
+
+#include "platform/Callback.h"
+#include "platform/mbed_toolchain.h"
+#include <string.h>
+#include <stdint.h>
+
+namespace mbed {
+/** \addtogroup platform */
+/** @{*/
+
+
+// Declarations for backwards compatibility
+// To be foward compatible, code should adopt the Callback class
+template <typename R, typename A1>
+class FunctionPointerArg1 : public Callback<R(A1)> {
+public:
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "FunctionPointerArg1<R, A> has been replaced by Callback<R(A)>")
+ FunctionPointerArg1(R (*function)(A1) = 0)
+ : Callback<R(A1)>(function) {}
+
+ template<typename T>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "FunctionPointerArg1<R, A> has been replaced by Callback<R(A)>")
+ FunctionPointerArg1(T *object, R (T::*member)(A1))
+ : Callback<R(A1)>(object, member) {}
+
+ R (*get_function())(A1) {
+ return *reinterpret_cast<R (**)(A1)>(this);
+ }
+
+ R call(A1 a1) const {
+ if (!Callback<R(A1)>::operator bool()) {
+ return (R)0;
+ }
+
+ return Callback<R(A1)>::call(a1);
+ }
+
+ R operator()(A1 a1) const {
+ return Callback<R(A1)>::call(a1);
+ }
+};
+
+template <typename R>
+class FunctionPointerArg1<R, void> : public Callback<R()> {
+public:
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "FunctionPointer has been replaced by Callback<void()>")
+ FunctionPointerArg1(R (*function)() = 0)
+ : Callback<R()>(function) {}
+
+ template<typename T>
+ MBED_DEPRECATED_SINCE("mbed-os-5.1",
+ "FunctionPointer has been replaced by Callback<void()>")
+ FunctionPointerArg1(T *object, R (T::*member)())
+ : Callback<R()>(object, member) {}
+
+ R (*get_function())() {
+ return *reinterpret_cast<R (**)()>(this);
+ }
+
+ R call() const {
+ if (!Callback<R()>::operator bool()) {
+ return (R)0;
+ }
+
+ return Callback<R()>::call();
+ }
+
+ R operator()() const {
+ return Callback<R()>::call();
+ }
+};
+
+typedef FunctionPointerArg1<void, void> FunctionPointer;
+
+
+} // namespace mbed
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/PlatformMutex.h b/mbed/platform/PlatformMutex.h
new file mode 100644
index 0000000..57b8e5f
--- /dev/null
+++ b/mbed/platform/PlatformMutex.h
@@ -0,0 +1,51 @@
+
+/** \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 PLATFORM_MUTEX_H
+#define PLATFORM_MUTEX_H
+
+#ifdef MBED_CONF_RTOS_PRESENT
+#include "rtos/Mutex.h"
+typedef rtos::Mutex PlatformMutex;
+#else
+/** A stub mutex for when an RTOS is not present
+*/
+class PlatformMutex {
+public:
+ PlatformMutex() {
+ // Stub
+
+ }
+ ~PlatformMutex() {
+ // Stub
+ }
+
+ void lock() {
+ // Do nothing
+ }
+
+ void unlock() {
+ // Do nothing
+ }
+};
+
+#endif
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/SingletonPtr.h b/mbed/platform/SingletonPtr.h
new file mode 100644
index 0000000..00a396f
--- /dev/null
+++ b/mbed/platform/SingletonPtr.h
@@ -0,0 +1,110 @@
+
+/** \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 SINGLETONPTR_H
+#define SINGLETONPTR_H
+
+#include <stdint.h>
+#include <new>
+#include "platform/mbed_assert.h"
+#ifdef MBED_CONF_RTOS_PRESENT
+#include "cmsis_os.h"
+#endif
+
+#ifdef MBED_CONF_RTOS_PRESENT
+extern osMutexId singleton_mutex_id;
+#endif
+
+/** Lock the singleton mutex
+ *
+ * This function is typically used to provide
+ * exclusive access when initializing a
+ * global object.
+ */
+inline static void singleton_lock(void)
+{
+#ifdef MBED_CONF_RTOS_PRESENT
+ osMutexWait(singleton_mutex_id, osWaitForever);
+#endif
+}
+
+/** Unlock the singleton mutex
+ *
+ * This function is typically used to provide
+ * exclusive access when initializing a
+ * global object.
+ */
+inline static void singleton_unlock(void)
+{
+#ifdef MBED_CONF_RTOS_PRESENT
+ osMutexRelease (singleton_mutex_id);
+#endif
+}
+
+/** Utility class for creating an using a singleton
+ *
+ * @Note Synchronization level: Thread safe
+ *
+ * @Note: This class must only be used in a static context -
+ * this class must never be allocated or created on the
+ * stack.
+ *
+ * @Note: This class is lazily initialized on first use.
+ * This class is a POD type so if it is not used it will
+ * be garbage collected.
+ */
+template <class T>
+struct SingletonPtr {
+
+ /** Get a pointer to the underlying singleton
+ *
+ * @returns
+ * A pointer to the singleton
+ */
+ T* get() {
+ if (NULL == _ptr) {
+ singleton_lock();
+ if (NULL == _ptr) {
+ _ptr = new (_data) T();
+ }
+ singleton_unlock();
+ }
+ // _ptr was not zero initialized or was
+ // corrupted if this assert is hit
+ MBED_ASSERT(_ptr == (T *)&_data);
+ return _ptr;
+ }
+
+ /** Get a pointer to the underlying singleton
+ *
+ * @returns
+ * A pointer to the singleton
+ */
+ T* operator->() {
+ return get();
+ }
+
+ // This is zero initialized when in global scope
+ T *_ptr;
+ // Force data to be 4 byte aligned
+ uint32_t _data[(sizeof(T) + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
+};
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/Transaction.h b/mbed/platform/Transaction.h
new file mode 100644
index 0000000..4064775
--- /dev/null
+++ b/mbed/platform/Transaction.h
@@ -0,0 +1,79 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 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_TRANSACTION_H
+#define MBED_TRANSACTION_H
+
+#include "platform/platform.h"
+#include "platform/FunctionPointer.h"
+
+namespace mbed {
+/** \addtogroup platform */
+/** @{*/
+
+/** Transaction structure
+ */
+typedef struct {
+ void *tx_buffer; /**< Tx buffer */
+ size_t tx_length; /**< Length of Tx buffer*/
+ void *rx_buffer; /**< Rx buffer */
+ size_t rx_length; /**< Length of Rx buffer */
+ uint32_t event; /**< Event for a transaction */
+ event_callback_t callback; /**< User's callback */
+ uint8_t width; /**< Buffer's word width (8, 16, 32, 64) */
+} transaction_t;
+
+/** Transaction class defines a transaction.
+ *
+ * @Note Synchronization level: Not protected
+ */
+template<typename Class>
+class Transaction {
+public:
+ Transaction(Class *tpointer, const transaction_t& transaction) : _obj(tpointer), _data(transaction) {
+ }
+
+ Transaction() : _obj(), _data() {
+ }
+
+ ~Transaction() {
+ }
+
+ /** Get object's instance for the transaction
+ *
+ * @return The object which was stored
+ */
+ Class* get_object() {
+ return _obj;
+ }
+
+ /** Get the transaction
+ *
+ * @return The transaction which was stored
+ */
+ transaction_t* get_transaction() {
+ return &_data;
+ }
+
+private:
+ Class* _obj;
+ transaction_t _data;
+};
+
+}
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/critical.h b/mbed/platform/critical.h
new file mode 100644
index 0000000..19000c1
--- /dev/null
+++ b/mbed/platform/critical.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2015-2016, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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_OLD_CRITICAL_H
+#define MBED_OLD_CRITICAL_H
+
+#warning critical.h has been replaced by mbed_critical.h, please update to mbed_critical.h [since mbed-os-5.3]
+#include "platform/mbed_critical.h"
+
+#endif
diff --git a/mbed/platform/mbed_application.h b/mbed/platform/mbed_application.h
new file mode 100644
index 0000000..b14faac
--- /dev/null
+++ b/mbed/platform/mbed_application.h
@@ -0,0 +1,50 @@
+
+/** \addtogroup platform */
+/** @{*/
+/* mbed Microcontroller Library
+ * Copyright (c) 2017-2017 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_APPLICATION_H
+#define MBED_APPLICATION_H
+
+#include<stdint.h>
+
+#define MBED_APPLICATION_SUPPORT (defined(__CORTEX_M3) || defined(__CORTEX_M4) || defined(__CORTEX_M7))
+#if MBED_APPLICATION_SUPPORT
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Start the application at the given address. This function does
+ * not return. It is the applications responsibility for flushing to
+ * or powering down external components such as filesystems or
+ * socket connections before calling this function. For Cortex-M
+ * devices this function powers down generic system components such as
+ * the NVIC and set the vector table to that of the new image followed
+ * by jumping to the reset handler of the new image.
+ *
+ * @param address Starting address of next application to run
+ */
+void mbed_start_application(uintptr_t address);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/mbed_assert.h b/mbed/platform/mbed_assert.h
new file mode 100644
index 0000000..e71dd77
--- /dev/null
+++ b/mbed/platform/mbed_assert.h
@@ -0,0 +1,113 @@
+
+/** \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_ASSERT_H
+#define MBED_ASSERT_H
+
+#include "mbed_preprocessor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Internal mbed assert function which is invoked when MBED_ASSERT macro failes.
+ * This function is active only if NDEBUG is not defined prior to including this
+ * assert header file.
+ * In case of MBED_ASSERT failing condition, error() is called with the assertation message.
+ * @param expr Expresion to be checked.
+ * @param file File where assertation failed.
+ * @param line Failing assertation line number.
+ */
+void mbed_assert_internal(const char *expr, const char *file, int line);
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef NDEBUG
+#define MBED_ASSERT(expr) ((void)0)
+
+#else
+#define MBED_ASSERT(expr) \
+do { \
+ if (!(expr)) { \
+ mbed_assert_internal(#expr, __FILE__, __LINE__); \
+ } \
+} while (0)
+#endif
+
+
+/** MBED_STATIC_ASSERT
+ * Declare compile-time assertions, results in compile-time error if condition is false
+ *
+ * The assertion acts as a declaration that can be placed at file scope, in a
+ * code block (except after a label), or as a member of a C++ class/struct/union.
+ *
+ * @note
+ * Use of MBED_STATIC_ASSERT as a member of a struct/union is limited:
+ * - In C++, MBED_STATIC_ASSERT is valid in class/struct/union scope.
+ * - In C, MBED_STATIC_ASSERT is not valid in struct/union scope, and
+ * MBED_STRUCT_STATIC_ASSERT is provided as an alternative that is valid
+ * in C and C++ class/struct/union scope.
+ *
+ * @code
+ * MBED_STATIC_ASSERT(MBED_LIBRARY_VERSION >= 120,
+ * "The mbed library must be at least version 120");
+ *
+ * int main() {
+ * MBED_STATIC_ASSERT(sizeof(int) >= sizeof(char),
+ * "An int must be larger than a char");
+ * }
+ * @endcode
+ */
+#if defined(__cplusplus) && (__cplusplus >= 201103L || __cpp_static_assert >= 200410L)
+#define MBED_STATIC_ASSERT(expr, msg) static_assert(expr, msg)
+#elif !defined(__cplusplus) && __STDC_VERSION__ >= 201112L
+#define MBED_STATIC_ASSERT(expr, msg) _Static_assert(expr, msg)
+#elif defined(__cplusplus) && defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) \
+ && (__GNUC__*100 + __GNUC_MINOR__) > 403L
+#define MBED_STATIC_ASSERT(expr, msg) __extension__ static_assert(expr, msg)
+#elif !defined(__cplusplus) && defined(__GNUC__) && !defined(__CC_ARM) \
+ && (__GNUC__*100 + __GNUC_MINOR__) > 406L
+#define MBED_STATIC_ASSERT(expr, msg) __extension__ _Static_assert(expr, msg)
+#elif defined(__ICCARM__)
+#define MBED_STATIC_ASSERT(expr, msg) static_assert(expr, msg)
+#else
+#define MBED_STATIC_ASSERT(expr, msg) \
+ enum {MBED_CONCAT(MBED_ASSERTION_AT_, __LINE__) = sizeof(char[(expr) ? 1 : -1])}
+#endif
+
+/** MBED_STRUCT_STATIC_ASSERT
+ * Declare compile-time assertions, results in compile-time error if condition is false
+ *
+ * Unlike MBED_STATIC_ASSERT, MBED_STRUCT_STATIC_ASSERT can and must be used
+ * as a member of a C/C++ class/struct/union.
+ *
+ * @code
+ * struct thing {
+ * MBED_STATIC_ASSERT(2 + 2 == 4,
+ * "Hopefully the universe is mathematically consistent");
+ * };
+ * @endcode
+ */
+#define MBED_STRUCT_STATIC_ASSERT(expr, msg) int : (expr) ? 0 : -1
+
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/mbed_critical.h b/mbed/platform/mbed_critical.h
new file mode 100644
index 0000000..2556347
--- /dev/null
+++ b/mbed/platform/mbed_critical.h
@@ -0,0 +1,359 @@
+
+/** \addtogroup platform */
+/** @{*/
+/*
+ * Copyright (c) 2015-2016, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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_UTIL_CRITICAL_H__
+#define __MBED_UTIL_CRITICAL_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Determine the current interrupts enabled state
+ *
+ * This function can be called to determine whether or not interrupts are currently enabled.
+ * \note
+ * NOTE:
+ * This function works for both cortex-A and cortex-M, although the underlyng implementation
+ * differs.
+ * @return true if interrupts are enabled, false otherwise
+ */
+bool core_util_are_interrupts_enabled(void);
+
+/** Mark the start of a critical section
+ *
+ * This function should be called to mark the start of a critical section of code.
+ * \note
+ * NOTES:
+ * 1) The use of this style of critical section is targetted at C based implementations.
+ * 2) These critical sections can be nested.
+ * 3) The interrupt enable state on entry to the first critical section (of a nested set, or single
+ * section) will be preserved on exit from the section.
+ * 4) This implementation will currently only work on code running in privileged mode.
+ */
+void core_util_critical_section_enter(void);
+
+/** Mark the end of a critical section
+ *
+ * This function should be called to mark the end of a critical section of code.
+ * \note
+ * NOTES:
+ * 1) The use of this style of critical section is targetted at C based implementations.
+ * 2) These critical sections can be nested.
+ * 3) The interrupt enable state on entry to the first critical section (of a nested set, or single
+ * section) will be preserved on exit from the section.
+ * 4) This implementation will currently only work on code running in privileged mode.
+ */
+void core_util_critical_section_exit(void);
+
+/**
+ * Atomic compare and set. It compares the contents of a memory location to a
+ * given value and, only if they are the same, modifies the contents of that
+ * memory location to a given new value. This is done as a single atomic
+ * operation. The atomicity guarantees that the new value is calculated based on
+ * up-to-date information; if the value had been updated by another thread in
+ * the meantime, the write would fail due to a mismatched expectedCurrentValue.
+ *
+ * Refer to https://en.wikipedia.org/wiki/Compare-and-set [which may redirect
+ * you to the article on compare-and swap].
+ *
+ * @param ptr The target memory location.
+ * @param[in,out] expectedCurrentValue A pointer to some location holding the
+ * expected current value of the data being set atomically.
+ * The computed 'desiredValue' should be a function of this current value.
+ * @Note: This is an in-out parameter. In the
+ * failure case of atomic_cas (where the
+ * destination isn't set), the pointee of expectedCurrentValue is
+ * updated with the current value.
+ * @param[in] desiredValue The new value computed based on '*expectedCurrentValue'.
+ *
+ * @return true if the memory location was atomically
+ * updated with the desired value (after verifying
+ * that it contained the expectedCurrentValue),
+ * false otherwise. In the failure case,
+ * exepctedCurrentValue is updated with the new
+ * value of the target memory location.
+ *
+ * pseudocode:
+ * function cas(p : pointer to int, old : pointer to int, new : int) returns bool {
+ * if *p != *old {
+ * *old = *p
+ * return false
+ * }
+ * *p = new
+ * return true
+ * }
+ *
+ * @Note: In the failure case (where the destination isn't set), the value
+ * pointed to by expectedCurrentValue is still updated with the current value.
+ * This property helps writing concise code for the following incr:
+ *
+ * function incr(p : pointer to int, a : int) returns int {
+ * done = false
+ * value = *p // This fetch operation need not be atomic.
+ * while not done {
+ * done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success
+ * }
+ * return value + a
+ * }
+ */
+bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue);
+
+/**
+ * Atomic compare and set. It compares the contents of a memory location to a
+ * given value and, only if they are the same, modifies the contents of that
+ * memory location to a given new value. This is done as a single atomic
+ * operation. The atomicity guarantees that the new value is calculated based on
+ * up-to-date information; if the value had been updated by another thread in
+ * the meantime, the write would fail due to a mismatched expectedCurrentValue.
+ *
+ * Refer to https://en.wikipedia.org/wiki/Compare-and-set [which may redirect
+ * you to the article on compare-and swap].
+ *
+ * @param ptr The target memory location.
+ * @param[in,out] expectedCurrentValue A pointer to some location holding the
+ * expected current value of the data being set atomically.
+ * The computed 'desiredValue' should be a function of this current value.
+ * @Note: This is an in-out parameter. In the
+ * failure case of atomic_cas (where the
+ * destination isn't set), the pointee of expectedCurrentValue is
+ * updated with the current value.
+ * @param[in] desiredValue The new value computed based on '*expectedCurrentValue'.
+ *
+ * @return true if the memory location was atomically
+ * updated with the desired value (after verifying
+ * that it contained the expectedCurrentValue),
+ * false otherwise. In the failure case,
+ * exepctedCurrentValue is updated with the new
+ * value of the target memory location.
+ *
+ * pseudocode:
+ * function cas(p : pointer to int, old : pointer to int, new : int) returns bool {
+ * if *p != *old {
+ * *old = *p
+ * return false
+ * }
+ * *p = new
+ * return true
+ * }
+ *
+ * @Note: In the failure case (where the destination isn't set), the value
+ * pointed to by expectedCurrentValue is still updated with the current value.
+ * This property helps writing concise code for the following incr:
+ *
+ * function incr(p : pointer to int, a : int) returns int {
+ * done = false
+ * value = *p // This fetch operation need not be atomic.
+ * while not done {
+ * done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success
+ * }
+ * return value + a
+ * }
+ */
+bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue);
+
+/**
+ * Atomic compare and set. It compares the contents of a memory location to a
+ * given value and, only if they are the same, modifies the contents of that
+ * memory location to a given new value. This is done as a single atomic
+ * operation. The atomicity guarantees that the new value is calculated based on
+ * up-to-date information; if the value had been updated by another thread in
+ * the meantime, the write would fail due to a mismatched expectedCurrentValue.
+ *
+ * Refer to https://en.wikipedia.org/wiki/Compare-and-set [which may redirect
+ * you to the article on compare-and swap].
+ *
+ * @param ptr The target memory location.
+ * @param[in,out] expectedCurrentValue A pointer to some location holding the
+ * expected current value of the data being set atomically.
+ * The computed 'desiredValue' should be a function of this current value.
+ * @Note: This is an in-out parameter. In the
+ * failure case of atomic_cas (where the
+ * destination isn't set), the pointee of expectedCurrentValue is
+ * updated with the current value.
+ * @param[in] desiredValue The new value computed based on '*expectedCurrentValue'.
+ *
+ * @return true if the memory location was atomically
+ * updated with the desired value (after verifying
+ * that it contained the expectedCurrentValue),
+ * false otherwise. In the failure case,
+ * exepctedCurrentValue is updated with the new
+ * value of the target memory location.
+ *
+ * pseudocode:
+ * function cas(p : pointer to int, old : pointer to int, new : int) returns bool {
+ * if *p != *old {
+ * *old = *p
+ * return false
+ * }
+ * *p = new
+ * return true
+ * }
+ *
+ * @Note: In the failure case (where the destination isn't set), the value
+ * pointed to by expectedCurrentValue is still updated with the current value.
+ * This property helps writing concise code for the following incr:
+ *
+ * function incr(p : pointer to int, a : int) returns int {
+ * done = false
+ * value = *p // This fetch operation need not be atomic.
+ * while not done {
+ * done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success
+ * }
+ * return value + a
+ * }
+ */
+bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue);
+
+/**
+ * Atomic compare and set. It compares the contents of a memory location to a
+ * given value and, only if they are the same, modifies the contents of that
+ * memory location to a given new value. This is done as a single atomic
+ * operation. The atomicity guarantees that the new value is calculated based on
+ * up-to-date information; if the value had been updated by another thread in
+ * the meantime, the write would fail due to a mismatched expectedCurrentValue.
+ *
+ * Refer to https://en.wikipedia.org/wiki/Compare-and-set [which may redirect
+ * you to the article on compare-and swap].
+ *
+ * @param ptr The target memory location.
+ * @param[in,out] expectedCurrentValue A pointer to some location holding the
+ * expected current value of the data being set atomically.
+ * The computed 'desiredValue' should be a function of this current value.
+ * @Note: This is an in-out parameter. In the
+ * failure case of atomic_cas (where the
+ * destination isn't set), the pointee of expectedCurrentValue is
+ * updated with the current value.
+ * @param[in] desiredValue The new value computed based on '*expectedCurrentValue'.
+ *
+ * @return true if the memory location was atomically
+ * updated with the desired value (after verifying
+ * that it contained the expectedCurrentValue),
+ * false otherwise. In the failure case,
+ * exepctedCurrentValue is updated with the new
+ * value of the target memory location.
+ *
+ * pseudocode:
+ * function cas(p : pointer to int, old : pointer to int, new : int) returns bool {
+ * if *p != *old {
+ * *old = *p
+ * return false
+ * }
+ * *p = new
+ * return true
+ * }
+ *
+ * @Note: In the failure case (where the destination isn't set), the value
+ * pointed to by expectedCurrentValue is still updated with the current value.
+ * This property helps writing concise code for the following incr:
+ *
+ * function incr(p : pointer to int, a : int) returns int {
+ * done = false
+ * value = *p // This fetch operation need not be atomic.
+ * while not done {
+ * done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success
+ * }
+ * return value + a
+ * }
+ */
+bool core_util_atomic_cas_ptr(void **ptr, void **expectedCurrentValue, void *desiredValue);
+
+/**
+ * Atomic increment.
+ * @param valuePtr Target memory location being incremented.
+ * @param delta The amount being incremented.
+ * @return The new incremented value.
+ */
+uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta);
+
+/**
+ * Atomic increment.
+ * @param valuePtr Target memory location being incremented.
+ * @param delta The amount being incremented.
+ * @return The new incremented value.
+ */
+uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta);
+
+/**
+ * Atomic increment.
+ * @param valuePtr Target memory location being incremented.
+ * @param delta The amount being incremented.
+ * @return The new incremented value.
+ */
+uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta);
+
+/**
+ * Atomic increment.
+ * @param valuePtr Target memory location being incremented.
+ * @param delta The amount being incremented in bytes.
+ * @return The new incremented value.
+ *
+ * @note The type of the pointer argument is not taken into account
+ * and the pointer is incremented by bytes.
+ */
+void *core_util_atomic_incr_ptr(void **valuePtr, ptrdiff_t delta);
+
+/**
+ * Atomic decrement.
+ * @param valuePtr Target memory location being decremented.
+ * @param delta The amount being decremented.
+ * @return The new decremented value.
+ */
+uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta);
+
+/**
+ * Atomic decrement.
+ * @param valuePtr Target memory location being decremented.
+ * @param delta The amount being decremented.
+ * @return The new decremented value.
+ */
+uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta);
+
+/**
+ * Atomic decrement.
+ * @param valuePtr Target memory location being decremented.
+ * @param delta The amount being decremented.
+ * @return The new decremented value.
+ */
+uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta);
+
+/**
+ * Atomic decrement.
+ * @param valuePtr Target memory location being decremented.
+ * @param delta The amount being decremented in bytes.
+ * @return The new decremented value.
+ *
+ * @note The type of the pointer argument is not taken into account
+ * and the pointer is decremented by bytes
+ */
+void *core_util_atomic_decr_ptr(void **valuePtr, ptrdiff_t delta);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+#endif // __MBED_UTIL_CRITICAL_H__
+
+/** @}*/
diff --git a/mbed/platform/mbed_debug.h b/mbed/platform/mbed_debug.h
new file mode 100644
index 0000000..38cbecd
--- /dev/null
+++ b/mbed/platform/mbed_debug.h
@@ -0,0 +1,71 @@
+
+/** \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_DEBUG_H
+#define MBED_DEBUG_H
+#include "device.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DEVICE_STDIO_MESSAGES
+#include <stdio.h>
+#include <stdarg.h>
+
+/** Output a debug message
+ *
+ * @param format printf-style format string, followed by variables
+ */
+static inline void debug(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+}
+
+/** Conditionally output a debug message
+ *
+ * NOTE: If the condition is constant false (!= 1) and the compiler optimization
+ * level is greater than 0, then the whole function will be compiled away.
+ *
+ * @param condition output only if condition is true (== 1)
+ * @param format printf-style format string, followed by variables
+ */
+static inline void debug_if(int condition, const char *format, ...) {
+ if (condition == 1) {
+ va_list args;
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+ }
+}
+
+#else
+static inline void debug(const char *format, ...) {}
+static inline void debug_if(int condition, const char *format, ...) {}
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/mbed_error.h b/mbed/platform/mbed_error.h
new file mode 100644
index 0000000..5a3f4fd
--- /dev/null
+++ b/mbed/platform/mbed_error.h
@@ -0,0 +1,71 @@
+
+/** \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_ERROR_H
+#define MBED_ERROR_H
+
+/** To generate a fatal compile-time error, you can use the pre-processor #error directive.
+ *
+ * @code
+ * #error "That shouldn't have happened!"
+ * @endcode
+ *
+ * If the compiler evaluates this line, it will report the error and stop the compile.
+ *
+ * For example, you could use this to check some user-defined compile-time variables:
+ *
+ * @code
+ * #define NUM_PORTS 7
+ * #if (NUM_PORTS > 4)
+ * #error "NUM_PORTS must be less than 4"
+ * #endif
+ * @endcode
+ *
+ * Reporting Run-Time Errors:
+ * To generate a fatal run-time error, you can use the mbed error() function.
+ *
+ * @code
+ * error("That shouldn't have happened!");
+ * @endcode
+ *
+ * If the mbed running the program executes this function, it will print the
+ * message via the USB serial port, and then die with the blue lights of death!
+ *
+ * The message can use printf-style formatting, so you can report variables in the
+ * message too. For example, you could use this to check a run-time condition:
+ *
+ * @code
+ * if(x >= 5) {
+ * error("expected x to be less than 5, but got %d", x);
+ * }
+ * #endcode
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void error(const char* format, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/mbed_interface.h b/mbed/platform/mbed_interface.h
new file mode 100644
index 0000000..1d27e57
--- /dev/null
+++ b/mbed/platform/mbed_interface.h
@@ -0,0 +1,135 @@
+
+/** \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_INTERFACE_H
+#define MBED_INTERFACE_H
+
+#include <stdarg.h>
+
+#include "device.h"
+
+/* Mbed interface mac address
+ * if MBED_MAC_ADD_x are zero, interface uid sets mac address,
+ * otherwise MAC_ADD_x are used.
+ */
+#define MBED_MAC_ADDR_INTERFACE 0x00
+#define MBED_MAC_ADDR_0 MBED_MAC_ADDR_INTERFACE
+#define MBED_MAC_ADDR_1 MBED_MAC_ADDR_INTERFACE
+#define MBED_MAC_ADDR_2 MBED_MAC_ADDR_INTERFACE
+#define MBED_MAC_ADDR_3 MBED_MAC_ADDR_INTERFACE
+#define MBED_MAC_ADDR_4 MBED_MAC_ADDR_INTERFACE
+#define MBED_MAC_ADDR_5 MBED_MAC_ADDR_INTERFACE
+#define MBED_MAC_ADDRESS_SUM (MBED_MAC_ADDR_0 | MBED_MAC_ADDR_1 | MBED_MAC_ADDR_2 | MBED_MAC_ADDR_3 | MBED_MAC_ADDR_4 | MBED_MAC_ADDR_5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DEVICE_SEMIHOST
+
+/** Functions to control the mbed interface
+ *
+ * mbed Microcontrollers have a built-in interface to provide functionality such as
+ * drag-n-drop download, reset, serial-over-usb, and access to the mbed local file
+ * system. These functions provide means to control the interface suing semihost
+ * calls it supports.
+ */
+
+/** Determine whether the mbed interface is connected, based on whether debug is enabled
+ *
+ * @returns
+ * 1 if interface is connected,
+ * 0 otherwise
+ */
+int mbed_interface_connected(void);
+
+/** Instruct the mbed interface to reset, as if the reset button had been pressed
+ *
+ * @returns
+ * 1 if successful,
+ * 0 otherwise (e.g. interface not present)
+ */
+int mbed_interface_reset(void);
+
+/** This will disconnect the debug aspect of the interface, so semihosting will be disabled.
+ * The interface will still support the USB serial aspect
+ *
+ * @returns
+ * 0 if successful,
+ * -1 otherwise (e.g. interface not present)
+ */
+int mbed_interface_disconnect(void);
+
+/** This will disconnect the debug aspect of the interface, and if the USB cable is not
+ * connected, also power down the interface. If the USB cable is connected, the interface
+ * will remain powered up and visible to the host
+ *
+ * @returns
+ * 0 if successful,
+ * -1 otherwise (e.g. interface not present)
+ */
+int mbed_interface_powerdown(void);
+
+/** This returns a string containing the 32-character UID of the mbed interface
+ * This is a weak function that can be overwritten if required
+ *
+ * @param uid A 33-byte array to write the null terminated 32-byte string
+ *
+ * @returns
+ * 0 if successful,
+ * -1 otherwise (e.g. interface not present)
+ */
+int mbed_interface_uid(char *uid);
+
+#endif
+
+/** This returns a unique 6-byte MAC address, based on the interface UID
+ * If the interface is not present, it returns a default fixed MAC address (00:02:F7:F0:00:00)
+ *
+ * This is a weak function that can be overwritten if you want to provide your own mechanism to
+ * provide a MAC address.
+ *
+ * @param mac A 6-byte array to write the MAC address
+ */
+void mbed_mac_address(char *mac);
+
+/** Cause the mbed to flash the BLOD (Blue LEDs Of Death) sequence
+ */
+void mbed_die(void);
+
+/** Print out an error message. This is typically called when
+ * hanlding a crash.
+ *
+ * @Note Synchronization level: Interrupt safe
+ */
+void mbed_error_printf(const char* format, ...);
+
+/** Print out an error message. Similar to mbed_error_printf
+ * but uses a va_list.
+ *
+ * @Note Synchronization level: Interrupt safe
+ */
+void mbed_error_vfprintf(const char * format, va_list arg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/mbed_mem_trace.h b/mbed/platform/mbed_mem_trace.h
new file mode 100644
index 0000000..eebd236
--- /dev/null
+++ b/mbed/platform/mbed_mem_trace.h
@@ -0,0 +1,143 @@
+
+/** \addtogroup platform */
+/** @{*/
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2016 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_MEM_TRACE_H__
+#define __MBED_MEM_TRACE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+
+/* Operation types for tracer */
+enum {
+ MBED_MEM_TRACE_MALLOC,
+ MBED_MEM_TRACE_REALLOC,
+ MBED_MEM_TRACE_CALLOC,
+ MBED_MEM_TRACE_FREE
+};
+
+/* Prefix for the output of the default tracer */
+#define MBED_MEM_DEFAULT_TRACER_PREFIX "#"
+
+/**
+ * Type of the callback used by the memory tracer. This callback is called when a memory
+ * allocation operation (malloc, realloc, calloc, free) is called and tracing is enabled
+ * for that memory allocation function.
+ *
+ * @param op the ID of the operation (MBED_MEM_TRACE_MALLOC, MBED_MEM_TRACE_REALLOC,
+ * MBED_MEM_TRACE_CALLOC or MBED_MEM_TRACE_FREE).
+ * @param res the result that the memory operation returned (NULL for 'free').
+ * @param caller the caller of the memory operation. Note that the value of 'caller' might be
+ * unreliable.
+ *
+ * The rest of the parameters passed 'mbed_mem_trace_cb_t' are the same as the memory operations
+ * that triggered its call (see 'man malloc' for details):
+ *
+ * - for malloc: cb(MBED_MEM_TRACE_MALLOC, res, caller, size).
+ * - for realloc: cb(MBED_MEM_TRACE_REALLOC, res, caller, ptr, size).
+ * - for calloc: cb(MBED_MEM_TRACE_CALLOC, res, caller, nmemb, size).
+ * - for free: cb(MBED_MEM_TRACE_FREE, NULL, caller, ptr).
+ */
+typedef void (*mbed_mem_trace_cb_t)(uint8_t op, void *res, void* caller, ...);
+
+/**
+ * Set the callback used by the memory tracer (use NULL for disable tracing).
+ *
+ * @param cb the callback to call on each memory operation.
+ */
+void mbed_mem_trace_set_callback(mbed_mem_trace_cb_t cb);
+
+/**
+ * Trace a call to 'malloc'.
+ * @param res the result of running 'malloc'.
+ * @param size the 'size' argument given to 'malloc'.
+ * @param caller the caller of the memory operation.
+ * @return 'res' (the first argument).
+ */
+void *mbed_mem_trace_malloc(void *res, size_t size, void *caller);
+
+/**
+ * Trace a call to 'realloc'.
+ * @param res the result of running 'realloc'.
+ * @param ptr the 'ptr' argument given to 'realloc'.
+ * @param size the 'size' argument given to 'realloc'.
+ *
+ * @return 'res' (the first argument).
+ */
+void *mbed_mem_trace_realloc(void *res, void *ptr, size_t size, void *caller);
+
+/**
+ * Trace a call to 'calloc'.
+ * @param res the result of running 'calloc'.
+ * @param nmemb the 'nmemb' argument given to 'calloc'.
+ * @param size the 'size' argument given to 'calloc'.
+ * @param caller the caller of the memory operation.
+ * @Return 'res' (the first argument).
+ */
+void *mbed_mem_trace_calloc(void *res, size_t num, size_t size, void *caller);
+
+/**
+ * Trace a call to 'free'.
+ * @param ptr the 'ptr' argument given to 'free'.
+ * @param caller the caller of the memory operation.
+ */
+void mbed_mem_trace_free(void *ptr, void *caller);
+
+/**
+ * Default memory trace callback. DO NOT CALL DIRECTLY. It is meant to be used
+ * as the second argument of 'mbed_mem_trace_setup'.
+ *
+ * The default callback outputs trace data using 'printf', in a format that's
+ * easily parsable by an external tool. For each memory operation, the callback
+ * outputs a line that begins with '#<op>:<0xresult>;<0xcaller>-':
+ *
+ * - 'op' identifies the memory operation ('m' for 'malloc', 'r' for 'realloc',
+ * 'c' for 'calloc' and 'f' for 'free').
+ * - 'result' (base 16) is the result of the memor operation. This is always NULL
+ * for 'free', since 'free' doesn't return anything.
+ * -'caller' (base 16) is the caller of the memory operation. Note that the value
+ * of 'caller' might be unreliable.
+ *
+ * The rest of the output depends on the operation being traced:
+ *
+ * - for 'malloc': 'size', where 'size' is the original argument to 'malloc'.
+ * - for 'realloc': '0xptr;size', where 'ptr' (base 16) and 'size' are the original arguments to 'realloc'.
+ * - for 'calloc': 'nmemb;size', where 'nmemb' and 'size' are the original arguments to 'calloc'.
+ * - for 'free': '0xptr', where 'ptr' (base 16) is the original argument to 'free'.
+ *
+ * Examples:
+ *
+ * - '#m:0x20003240;0x600d-50' encodes a 'malloc' that returned 0x20003240, was called
+ * by the instruction at 0x600D with a the 'size' argument equal to 50.
+ * - '#f:0x0;0x602f-0x20003240' encodes a 'free' that was called by the instruction at
+ * 0x602f with the 'ptr' argument equal to 0x20003240.
+ */
+void mbed_mem_trace_default_callback(uint8_t op, void *res, void *caller, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif// #ifndef __MBED_MEM_TRACE_H__
+
+
+/** @}*/
diff --git a/mbed/platform/mbed_preprocessor.h b/mbed/platform/mbed_preprocessor.h
new file mode 100644
index 0000000..506f804
--- /dev/null
+++ b/mbed/platform/mbed_preprocessor.h
@@ -0,0 +1,53 @@
+/** \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_PREPROCESSOR_H
+#define MBED_PREPROCESSOR_H
+
+
+/** MBED_CONCAT
+ * Concatenate tokens together
+ *
+ * @note
+ * Expands tokens before concatenation
+ *
+ * @code
+ * // Creates a unique label based on the line number
+ * int MBED_CONCAT(UNIQUE_LABEL_, __LINE__) = 1;
+ * @endcode
+ */
+#define MBED_CONCAT(a, b) MBED_CONCAT_(a, b)
+#define MBED_CONCAT_(a, b) a##b
+
+/** MBED_STRINGIFY
+ * Converts tokens into strings
+ *
+ * @note
+ * Expands tokens before stringification
+ *
+ * @code
+ * // Creates a string based on the parameters
+ * const char *c = MBED_STRINGIFY(This is a ridiculous way to create a string)
+ * @endcode
+ */
+#define MBED_STRINGIFY(a) MBED_STRINGIFY_(a)
+#define MBED_STRINGIFY_(a) #a
+
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/mbed_retarget.h b/mbed/platform/mbed_retarget.h
new file mode 100644
index 0000000..62fcfad
--- /dev/null
+++ b/mbed/platform/mbed_retarget.h
@@ -0,0 +1,191 @@
+/*
+ * mbed Microcontroller Library
+ * Copyright (c) 2006-2016 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 RETARGET_H
+#define RETARGET_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+/* We can get the following standard types from sys/types for gcc, but we
+ * need to define the types ourselves for the other compilers that normally
+ * target embedded systems */
+#if defined(__ARMCC_VERSION) || defined(__ICCARM__)
+typedef int ssize_t; ///< Signed size type, usually encodes negative errors
+typedef long off_t; ///< Offset in a data stream
+typedef int mode_t; ///< Mode for opening files
+
+#define O_RDONLY 0
+#define O_WRONLY 1
+#define O_RDWR 2
+#define O_CREAT 0x0200
+#define O_TRUNC 0x0400
+#define O_APPEND 0x0008
+
+#define NAME_MAX 255 ///< Maximum size of a name in a file path
+
+#else
+#include <sys/fcntl.h>
+#include <sys/types.h>
+#include <sys/syslimits.h>
+#endif
+
+
+/* DIR declarations must also be here */
+#if __cplusplus
+namespace mbed { class Dir; }
+typedef mbed::Dir DIR;
+#else
+typedef struct Dir DIR;
+#endif
+
+#if __cplusplus
+extern "C" {
+#endif
+ DIR *opendir(const char*);
+ struct dirent *readdir(DIR *);
+ int closedir(DIR*);
+ void rewinddir(DIR*);
+ long telldir(DIR*);
+ void seekdir(DIR*, long);
+ int mkdir(const char *name, mode_t n);
+#if __cplusplus
+};
+#endif
+
+
+#if defined(__ARMCC_VERSION) || defined(__ICCARM__)
+/* The intent of this section is to unify the errno error values to match
+ * the POSIX definitions for the GCC_ARM, ARMCC and IAR compilers. This is
+ * necessary because the ARMCC/IAR errno.h, or sys/stat.h are missing some
+ * symbol definitions used by the POSIX filesystem API to return errno codes.
+ * Note also that ARMCC errno.h defines some symbol values differently from
+ * the GCC_ARM/IAR/standard POSIX definitions. The definitions guard against
+ * this and future changes by changing the symbol definition as shown below. */
+#ifdef ENOENT
+#undef ENOENT
+#endif
+#define ENOENT 2 /* No such file or directory. */
+
+#ifdef EIO
+#undef EIO
+#endif
+#define EIO 5 /* I/O error */
+
+#ifdef ENXIO
+#undef ENXIO
+#endif
+#define ENXIO 6 /* No such device or address */
+
+#ifdef ENOEXEC
+#undef ENOEXEC
+#endif
+#define ENOEXEC 8 /* Exec format error */
+
+#ifdef EBADF
+#undef EBADF
+#endif
+#define EBADF 9 /* Bad file number */
+
+#ifdef ENOMEM
+#undef ENOMEM
+#endif
+#define ENOMEM 12 /* Not enough space */
+
+#ifdef EACCES
+#undef EACCES
+#endif
+#define EACCES 13 /* Permission denied */
+
+#ifdef EFAULT
+#undef EFAULT
+#endif
+#define EFAULT 14 /* Bad address */
+
+#ifdef EEXIST
+#undef EEXIST
+#endif
+#define EEXIST 17 /* File exists */
+
+#ifdef EINVAL
+#undef EINVAL
+#endif
+#define EINVAL 22 /* Invalid argument */
+
+#ifdef ENFILE
+#undef ENFILE
+#endif
+#define ENFILE 23 /* Too many open files in system */
+
+#ifdef EMFILE
+#undef EMFILE
+#endif
+#define EMFILE 24 /* File descriptor value too large */
+
+#ifdef ENOSYS
+#undef ENOSYS
+#endif
+#define ENOSYS 38 /* Function not implemented */
+
+/* Missing stat.h defines.
+ * The following are sys/stat.h definitions not currently present in the ARMCC
+ * errno.h. Note, ARMCC errno.h defines some symbol values differing from
+ * GCC_ARM/IAR/standard POSIX definitions. Guard against this and future
+ * changes by changing the symbol definition for filesystem use. */
+#define _IFDIR 0040000 /* directory */
+#define _IFREG 0100000 /* regular */
+
+#define S_IFDIR _IFDIR
+#define S_IFREG _IFREG
+
+#define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
+#define S_IRUSR 0000400 /* read permission, owner */
+#define S_IWUSR 0000200 /* write permission, owner */
+#define S_IXUSR 0000100/* execute/search permission, owner */
+#define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
+#define S_IRGRP 0000040 /* read permission, group */
+#define S_IWGRP 0000020 /* write permission, grougroup */
+#define S_IXGRP 0000010/* execute/search permission, group */
+#define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
+#define S_IROTH 0000004 /* read permission, other */
+#define S_IWOTH 0000002 /* write permission, other */
+#define S_IXOTH 0000001/* execute/search permission, other */
+
+#endif /* defined(__ARMCC_VERSION) || defined(__ICCARM__) */
+
+
+/* The following are dirent.h definitions are declared here to garuntee
+ * consistency where structure may be different with different toolchains */
+struct dirent {
+ char d_name[NAME_MAX+1];
+ uint8_t d_type;
+};
+
+enum {
+ DT_UNKNOWN, // The file type could not be determined.
+ DT_FIFO, // This is a named pipe (FIFO).
+ DT_CHR, // This is a character device.
+ DT_DIR, // This is a directory.
+ DT_BLK, // This is a block device.
+ DT_REG, // This is a regular file.
+ DT_LNK, // This is a symbolic link.
+ DT_SOCK, // This is a UNIX domain socket.
+};
+
+
+#endif /* RETARGET_H */
diff --git a/mbed/platform/mbed_rtc_time.h b/mbed/platform/mbed_rtc_time.h
new file mode 100644
index 0000000..66b2eb2
--- /dev/null
+++ b/mbed/platform/mbed_rtc_time.h
@@ -0,0 +1,92 @@
+
+/** \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.
+ */
+
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Implementation of the C time.h functions
+ *
+ * Provides mechanisms to set and read the current time, based
+ * on the microcontroller Real-Time Clock (RTC), plus some
+ * standard C manipulation and formating functions.
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ *
+ * int main() {
+ * set_time(1256729737); // Set RTC time to Wed, 28 Oct 2009 11:35:37
+ *
+ * while(1) {
+ * time_t seconds = time(NULL);
+ *
+ * printf("Time as seconds since January 1, 1970 = %d\n", seconds);
+ *
+ * printf("Time as a basic string = %s", ctime(&seconds));
+ *
+ * char buffer[32];
+ * strftime(buffer, 32, "%I:%M %p\n", localtime(&seconds));
+ * printf("Time as a custom formatted string = %s", buffer);
+ *
+ * wait(1);
+ * }
+ * }
+ * @endcode
+ */
+
+/** Set the current time
+ *
+ * Initialises and sets the time of the microcontroller Real-Time Clock (RTC)
+ * to the time represented by the number of seconds since January 1, 1970
+ * (the UNIX timestamp).
+ *
+ * @param t Number of seconds since January 1, 1970 (the UNIX timestamp)
+ *
+ * @Note Synchronization level: Thread safe
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ *
+ * int main() {
+ * set_time(1256729737); // Set time to Wed, 28 Oct 2009 11:35:37
+ * }
+ * @endcode
+ */
+void set_time(time_t t);
+
+/** Attach an external RTC to be used for the C time functions
+ *
+ * @Note Synchronization level: Thread safe
+ *
+ * @param read_rtc pointer to function which returns current UNIX timestamp
+ * @param write_rtc pointer to function which sets current UNIX timestamp, can be NULL
+ * @param init_rtc pointer to funtion which initializes RTC, can be NULL
+ * @param isenabled_rtc pointer to function wich returns if the rtc is enabled, can be NULL
+ */
+void attach_rtc(time_t (*read_rtc)(void), void (*write_rtc)(time_t), void (*init_rtc)(void), int (*isenabled_rtc)(void));
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @}*/
diff --git a/mbed/platform/mbed_semihost_api.h b/mbed/platform/mbed_semihost_api.h
new file mode 100644
index 0000000..7b52c9e
--- /dev/null
+++ b/mbed/platform/mbed_semihost_api.h
@@ -0,0 +1,98 @@
+
+/** \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_SEMIHOST_H
+#define MBED_SEMIHOST_H
+
+#include "device.h"
+#include "platform/mbed_toolchain.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DEVICE_SEMIHOST
+
+#ifndef __CC_ARM
+
+#if defined(__ICCARM__)
+static inline int __semihost(int reason, const void *arg) {
+ return __semihosting(reason, (void*)arg);
+}
+#else
+
+#ifdef __thumb__
+# define AngelSWI 0xAB
+# define AngelSWIInsn "bkpt"
+# define AngelSWIAsm bkpt
+#else
+# define AngelSWI 0x123456
+# define AngelSWIInsn "swi"
+# define AngelSWIAsm swi
+#endif
+
+static inline int __semihost(int reason, const void *arg) {
+ int value;
+
+ asm volatile (
+ "mov r0, %1" "\n\t"
+ "mov r1, %2" "\n\t"
+ AngelSWIInsn " %a3" "\n\t"
+ "mov %0, r0"
+ : "=r" (value) /* output operands */
+ : "r" (reason), "r" (arg), "i" (AngelSWI) /* input operands */
+ : "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc" /* list of clobbered registers */
+ );
+
+ return value;
+}
+#endif
+#endif
+
+#if DEVICE_LOCALFILESYSTEM
+FILEHANDLE semihost_open(const char* name, int openmode);
+int semihost_close (FILEHANDLE fh);
+int semihost_read (FILEHANDLE fh, unsigned char* buffer, unsigned int length, int mode);
+int semihost_write (FILEHANDLE fh, const unsigned char* buffer, unsigned int length, int mode);
+int semihost_ensure(FILEHANDLE fh);
+long semihost_flen (FILEHANDLE fh);
+int semihost_seek (FILEHANDLE fh, long position);
+int semihost_istty (FILEHANDLE fh);
+
+int semihost_remove(const char *name);
+int semihost_rename(const char *old_name, const char *new_name);
+#endif
+
+int semihost_uid(char *uid);
+int semihost_reset(void);
+int semihost_vbus(void);
+int semihost_powerdown(void);
+int semihost_exit(void);
+
+int semihost_connected(void);
+int semihost_disabledebug(void);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/mbed_sleep.h b/mbed/platform/mbed_sleep.h
new file mode 100644
index 0000000..1d1f798
--- /dev/null
+++ b/mbed/platform/mbed_sleep.h
@@ -0,0 +1,85 @@
+
+/** \addtogroup platform */
+/** @{*/
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2017 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_SLEEP_H
+#define MBED_SLEEP_H
+
+#include "sleep_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Send the microcontroller to sleep
+ *
+ * @note This function can be a noop if not implemented by the platform.
+ * @note This function will only put device to sleep in release mode (small profile or when NDEBUG is defined).
+ *
+ * The processor is setup ready for sleep, and sent to sleep using __WFI(). In this mode, the
+ * system clock to the core is stopped until a reset or an interrupt occurs. This eliminates
+ * dynamic power used by the processor, memory systems and buses. The processor, peripheral and
+ * memory state are maintained, and the peripherals continue to work and can generate interrupts.
+ *
+ * The processor can be woken up by any internal peripheral interrupt or external pin interrupt.
+ *
+ * @note
+ * The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored.
+ * Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be
+ * able to access the LocalFileSystem
+ */
+__INLINE static void sleep(void)
+{
+#ifdef NDEBUG
+#if DEVICE_SLEEP
+ hal_sleep();
+#endif /* DEVICE_SLEEP */
+#endif /* NDEBUG */
+}
+
+/** Send the microcontroller to deep sleep
+ *
+ * @note This function can be a noop if not implemented by the platform.
+ * @note This function will only put device to sleep in release mode (small profile or when NDEBUG is defined).
+ *
+ * This processor is setup ready for deep sleep, and sent to sleep using __WFI(). This mode
+ * has the same sleep features as sleep plus it powers down peripherals and clocks. All state
+ * is still maintained.
+ *
+ * The processor can only be woken up by an external interrupt on a pin or a watchdog timer.
+ *
+ * @note
+ * The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored.
+ * Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be
+ * able to access the LocalFileSystem
+ */
+__INLINE static void deepsleep(void)
+{
+#ifdef NDEBUG
+#if DEVICE_SLEEP
+ hal_deepsleep();
+#endif /* DEVICE_SLEEP */
+#endif /* NDEBUG */
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/mbed_stats.h b/mbed/platform/mbed_stats.h
new file mode 100644
index 0000000..aa2da58
--- /dev/null
+++ b/mbed/platform/mbed_stats.h
@@ -0,0 +1,75 @@
+
+/** \addtogroup platform */
+/** @{*/
+/* mbed Microcontroller Library
+ * Copyright (c) 2016-2016 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_STATS_H
+#define MBED_STATS_H
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ uint32_t current_size; /**< Bytes allocated currently. */
+ uint32_t max_size; /**< Max bytes allocated at a given time. */
+ uint32_t total_size; /**< Cumulative sum of bytes ever allocated. */
+ uint32_t reserved_size; /**< Current number of bytes allocated for the heap. */
+ uint32_t alloc_cnt; /**< Current number of allocations. */
+ uint32_t alloc_fail_cnt; /**< Number of failed allocations. */
+} mbed_stats_heap_t;
+
+/**
+ * Fill the passed in heap stat structure with heap stats.
+ *
+ * @param stats A pointer to the mbed_stats_heap_t structure to fill
+ */
+void mbed_stats_heap_get(mbed_stats_heap_t *stats);
+
+typedef struct {
+ uint32_t thread_id; /**< Identifier for thread that owns the stack. */
+ uint32_t max_size; /**< Sum of the maximum number of bytes used in each stack. */
+ uint32_t reserved_size; /**< Current number of bytes allocated for all stacks. */
+ uint32_t stack_cnt; /**< Number of stacks currently allocated. */
+} mbed_stats_stack_t;
+
+/**
+ * Fill the passed in structure with stack stats.
+ *
+ * @param stats A pointer to the mbed_stats_stack_t structure to fill
+ */
+void mbed_stats_stack_get(mbed_stats_stack_t *stats);
+
+/**
+ * Fill the passed array of stat structures with the stack stats
+ * for each available stack.
+ *
+ * @param stats A pointer to an array of mbed_stats_stack_t structures to fill
+ * @param count The number of mbed_stats_stack_t structures in the provided array
+ * @return The number of mbed_stats_stack_t structures that have been filled,
+ * this is equal to the number of stacks on the system.
+ */
+size_t mbed_stats_stack_get_each(mbed_stats_stack_t *stats, size_t count);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/mbed_toolchain.h b/mbed/platform/mbed_toolchain.h
new file mode 100644
index 0000000..5afbae7
--- /dev/null
+++ b/mbed/platform/mbed_toolchain.h
@@ -0,0 +1,305 @@
+
+/** \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 "mbed_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 "mbed_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 "mbed_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 "mbed_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 "mbed_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 "mbed_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 "mbed_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 "mbed_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 "mbed_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 "mbed_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 "mbed_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
+
+#ifndef MBED_SECTION
+#if (defined(__GNUC__) || defined(__clang__)) || defined(__CC_ARM)
+#define MBED_SECTION(name) __attribute__ ((section (name)))
+#elif defined(__ICCARM__)
+#define MBED_SECTION(name) _Pragma(MBED_STRINGIFY(location=name))
+#else
+#error "Missing MBED_SECTION directive"
+#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
+
+/** @}*/
diff --git a/mbed/platform/mbed_wait_api.h b/mbed/platform/mbed_wait_api.h
new file mode 100644
index 0000000..65ff92c
--- /dev/null
+++ b/mbed/platform/mbed_wait_api.h
@@ -0,0 +1,71 @@
+
+/** \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_WAIT_API_H
+#define MBED_WAIT_API_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Generic wait functions.
+ *
+ * These provide simple NOP type wait capabilities.
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ *
+ * DigitalOut heartbeat(LED1);
+ *
+ * int main() {
+ * while (1) {
+ * heartbeat = 1;
+ * wait(0.5);
+ * heartbeat = 0;
+ * wait(0.5);
+ * }
+ * }
+ */
+
+/** Waits for a number of seconds, with microsecond resolution (within
+ * the accuracy of single precision floating point).
+ *
+ * @param s number of seconds to wait
+ */
+void wait(float s);
+
+/** Waits a number of milliseconds.
+ *
+ * @param ms the whole number of milliseconds to wait
+ */
+void wait_ms(int ms);
+
+/** Waits a number of microseconds.
+ *
+ * @param us the whole number of microseconds to wait
+ */
+void wait_us(int us);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/platform.h b/mbed/platform/platform.h
new file mode 100644
index 0000000..ea002bd
--- /dev/null
+++ b/mbed/platform/platform.h
@@ -0,0 +1,35 @@
+
+/** \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_PLATFORM_H
+#define MBED_PLATFORM_H
+
+#include <cstddef>
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+
+#include "platform/mbed_retarget.h"
+#include "platform/mbed_toolchain.h"
+#include "device.h"
+#include "PinNames.h"
+#include "PeripheralNames.h"
+
+#endif
+
+/** @}*/
diff --git a/mbed/platform/rtc_time.h b/mbed/platform/rtc_time.h
new file mode 100644
index 0000000..c7df6ba
--- /dev/null
+++ b/mbed/platform/rtc_time.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2015-2016, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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_OLD_RTC_TIME_H
+#define MBED_OLD_RTC_TIME_H
+
+#warning rtc_time.h has been replaced by mbed_rtc_time.h, please update to mbed_rtc_time.h [since mbed-os-5.3]
+#include "platform/mbed_rtc_time.h"
+
+#endif
diff --git a/mbed/platform/semihost_api.h b/mbed/platform/semihost_api.h
new file mode 100644
index 0000000..1661b9c
--- /dev/null
+++ b/mbed/platform/semihost_api.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2015-2016, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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_OLD_SEMIHOST_API_H
+#define MBED_OLD_SEMIHOST_API_H
+
+#warning semihost_api.h has been replaced by mbed_semihost_api.h, please update to mbed_semihost_api.h [since mbed-os-5.3]
+#include "platform/mbed_semihost_api.h"
+
+#endif
diff --git a/mbed/platform/sleep.h b/mbed/platform/sleep.h
new file mode 100644
index 0000000..ea1fb48
--- /dev/null
+++ b/mbed/platform/sleep.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2015-2016, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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_OLD_SLEEP_H
+#define MBED_OLD_SLEEP_H
+
+#warning sleep.h has been replaced by mbed_sleep.h, please update to mbed_sleep.h [since mbed-os-5.3]
+#include "platform/mbed_sleep.h"
+
+#endif
diff --git a/mbed/platform/toolchain.h b/mbed/platform/toolchain.h
new file mode 100644
index 0000000..0b54da5
--- /dev/null
+++ b/mbed/platform/toolchain.h
@@ -0,0 +1,26 @@
+
+/** \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_OLD_TOOLCHAIN_H
+#define MBED_OLD_TOOLCHAIN_H
+
+#warning toolchain.h has been replaced by mbed_toolchain.h, please update to mbed_toolchain.h [since mbed-os-5.3]
+#include "platform/mbed_toolchain.h"
+
+#endif
diff --git a/mbed/platform/wait_api.h b/mbed/platform/wait_api.h
new file mode 100644
index 0000000..9b89071
--- /dev/null
+++ b/mbed/platform/wait_api.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2015-2016, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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_OLD_WAIT_API_H
+#define MBED_OLD_WAIT_API_H
+
+#warning wait_api.h has been replaced by mbed_wait_api.h, please update to mbed_wait_api.h [since mbed-os-5.3]
+#include "platform/mbed_wait_api.h"
+
+#endif