mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CThunk.h Source File

CThunk.h

00001 
00002 /** \addtogroup platform */
00003 /** @{*/
00004 /**
00005  * \defgroup platform_CThunk CThunk class
00006  * @{
00007  */
00008 /* General C++ Object Thunking class
00009  *
00010  * - allows direct callbacks to non-static C++ class functions
00011  * - keeps track for the corresponding class instance
00012  * - supports an optional context parameter for the called function
00013  * - ideally suited for class object receiving interrupts (NVIC_SetVector)
00014  *
00015  * Copyright (c) 2014-2015 ARM Limited
00016  * SPDX-License-Identifier: Apache-2.0
00017  *
00018  * Licensed under the Apache License, Version 2.0 (the "License");
00019  * you may not use this file except in compliance with the License.
00020  * You may obtain a copy of the License at
00021  *
00022  *     http://www.apache.org/licenses/LICENSE-2.0
00023  *
00024  * Unless required by applicable law or agreed to in writing, software
00025  * distributed under the License is distributed on an "AS IS" BASIS,
00026  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00027  * See the License for the specific language governing permissions and
00028  * limitations under the License.
00029  */
00030 
00031 /* General C++ Object Thunking class
00032  *
00033  * - allows direct callbacks to non-static C++ class functions
00034  * - keeps track for the corresponding class instance
00035  * - supports an optional context parameter for the called function
00036  * - ideally suited for class object receiving interrupts (NVIC_SetVector)
00037  */
00038 
00039 #ifndef __CTHUNK_H__
00040 #define __CTHUNK_H__
00041 
00042 #include "CThunkBase.h"
00043 
00044 /**
00045  * Class for created a pointer with data bound to it
00046  *
00047  * @note Synchronization level: Not protected
00048  */
00049 template<class T>
00050 class CThunk: public CThunkBase {
00051 public:
00052     typedef void (T::*CCallbackSimple)(void);
00053     typedef void (T::*CCallback)(void *context);
00054 
00055     inline CThunk(T *instance)
00056     {
00057         init(instance, NULL, NULL);
00058     }
00059 
00060     inline CThunk(T *instance, CCallback callback)
00061     {
00062         init(instance, callback, NULL);
00063     }
00064 
00065     ~CThunk()
00066     {
00067         cthunk_free(_entry);
00068         _entry = NULL;
00069     }
00070 
00071     inline CThunk(T *instance, CCallbackSimple callback)
00072     {
00073         init(instance, (CCallback)callback, NULL);
00074     }
00075 
00076     inline CThunk(T &instance, CCallback callback)
00077     {
00078         init(instance, callback, NULL);
00079     }
00080 
00081     inline CThunk(T &instance, CCallbackSimple callback)
00082     {
00083         init(instance, (CCallback)callback, NULL);
00084     }
00085 
00086     inline CThunk(T &instance, CCallback callback, void *context)
00087     {
00088         init(instance, callback, context);
00089     }
00090 
00091     inline void callback(CCallback callback)
00092     {
00093         _callback = callback;
00094     }
00095 
00096     inline void callback(CCallbackSimple callback)
00097     {
00098         _callback_simple = callback;
00099     }
00100 
00101     inline void context(void *context)
00102     {
00103         _context = context;
00104     }
00105 
00106     inline void context(uint32_t context)
00107     {
00108         _context = (void *)context;
00109     }
00110 
00111     inline uint32_t entry(void)
00112     {
00113         if (_entry == NULL) {
00114             _entry = cthunk_alloc(this);
00115         }
00116         return (uint32_t)_entry;
00117     }
00118 
00119     /* get thunk entry point for connecting rhunk to an IRQ table */
00120     inline operator CThunkEntry(void)
00121     {
00122         return (CThunkEntry)entry();
00123     }
00124 
00125     /* get thunk entry point for connecting rhunk to an IRQ table */
00126     inline operator uint32_t(void)
00127     {
00128         return entry();
00129     }
00130 
00131     /* simple test function */
00132     inline void call(void)
00133     {
00134         (((CThunkEntry)(entry()))());
00135     }
00136 
00137 private:
00138     T *_instance;
00139     void *_context;
00140     union {
00141         CCallbackSimple _callback_simple;
00142         CCallback _callback;
00143     };
00144 
00145     CThunkEntry _entry;
00146 
00147     static void trampoline(CThunkBase *base)
00148     {
00149         CThunk<T> *self = static_cast<CThunk<T>*>(base);
00150         T *instance = self->_instance;
00151         void *context = self->_context;
00152         CCallback callback = self->_callback;
00153 
00154         if (instance && callback) {
00155             (instance->*callback)(context);
00156         }
00157     }
00158 
00159     inline void init(T *instance, CCallback callback, void *context)
00160     {
00161         _instance = instance;
00162         _context = context;
00163         _callback = callback;
00164         _trampoline = &trampoline;
00165         _entry = 0;
00166     }
00167 };
00168 
00169 /**@}*/
00170 
00171 /**@}*/
00172 
00173 #endif/*__CTHUNK_H__*/
00174