Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CThunk.h Source File

CThunk.h

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