Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
CThunk.h
00001 /* General C++ Object Thunking class 00002 * 00003 * - allows direct callbacks to non-static C++ class functions 00004 * - keeps track for the corresponding class instance 00005 * - supports an optional context parameter for the called function 00006 * - ideally suited for class object receiving interrupts (NVIC_SetVector) 00007 * 00008 * Copyright (c) 2014 ARM Limited 00009 * 00010 * Licensed under the Apache License, Version 2.0 (the "License"); 00011 * you may not use this file except in compliance with the License. 00012 * You may obtain a copy of the License at 00013 * 00014 * http://www.apache.org/licenses/LICENSE-2.0 00015 * 00016 * Unless required by applicable law or agreed to in writing, software 00017 * distributed under the License is distributed on an "AS IS" BASIS, 00018 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00019 * See the License for the specific language governing permissions and 00020 * limitations under the License. 00021 */ 00022 00023 #ifndef __CTHUNK_H__ 00024 #define __CTHUNK_H__ 00025 00026 #if defined(__CORTEX_M3) || defined(__thumb2__) 00027 # define CTHUNK_OPCODE 0x8007E89F; 00028 # define CTHUNK_ADDRESS 1 00029 #else 00030 # error "TODO: add support for non-cortex-m3 trampoline, too" 00031 #endif 00032 00033 /* IRQ/Exception compatible thunk entry function */ 00034 typedef void (*CThunkEntry)(void); 00035 00036 template<class T> 00037 class CThunk 00038 { 00039 public: 00040 typedef void (T::*CCallbackSimple)(void); 00041 typedef void (T::*CCallback)(void* context); 00042 00043 inline CThunk(T *instance) 00044 { 00045 init(instance, NULL, NULL); 00046 } 00047 00048 inline CThunk(T *instance, CCallback callback) 00049 { 00050 init(instance, callback, NULL); 00051 } 00052 00053 inline CThunk(T *instance, CCallbackSimple callback) 00054 { 00055 init(instance, (CCallback)callback, NULL); 00056 } 00057 00058 inline CThunk(T &instance, CCallback callback) 00059 { 00060 init(instance, callback, NULL); 00061 } 00062 00063 inline CThunk(T &instance, CCallbackSimple callback) 00064 { 00065 init(instance, (CCallback)callback, NULL); 00066 } 00067 00068 inline CThunk(T &instance, CCallback callback, void* context) 00069 { 00070 init(instance, callback, context); 00071 } 00072 00073 inline void callback(CCallback callback) 00074 { 00075 m_callback = callback; 00076 } 00077 00078 inline void callback(CCallbackSimple callback) 00079 { 00080 m_callback = (CCallback)callback; 00081 } 00082 00083 inline void context(void* context) 00084 { 00085 m_thunk.context = (uint32_t)context; 00086 } 00087 00088 inline void context(uint32_t context) 00089 { 00090 m_thunk.context = context; 00091 } 00092 00093 inline uint32_t entry(void) 00094 { 00095 return (((uint32_t)&m_thunk)|CTHUNK_ADDRESS); 00096 } 00097 00098 /* get thunk entry point for connecting rhunk to an IRQ table */ 00099 inline operator CThunkEntry(void) 00100 { 00101 return (CThunkEntry)entry(); 00102 } 00103 00104 /* get thunk entry point for connecting rhunk to an IRQ table */ 00105 inline operator uint32_t(void) 00106 { 00107 return entry(); 00108 } 00109 00110 /* simple test function */ 00111 inline void call(void) 00112 { 00113 ((CThunkEntry)(entry())(); 00114 } 00115 00116 private: 00117 T* m_instance; 00118 volatile CCallback m_callback; 00119 00120 typedef struct 00121 { 00122 volatile uint32_t code; 00123 volatile uint32_t instance; 00124 volatile uint32_t context; 00125 volatile uint32_t callback; 00126 volatile uint32_t trampoline; 00127 } __attribute__((packed)) CThunkTrampoline; 00128 00129 static void trampoline(T* instance, void* context, CCallback* callback) 00130 { 00131 if(instance && *callback) 00132 (static_cast<T*>(instance)->**callback)(context); 00133 } 00134 00135 volatile CThunkTrampoline m_thunk; 00136 00137 inline void init(T *instance, CCallback callback, void* context) 00138 { 00139 /* remember callback - need to add this level of redirection 00140 as pointer size for member functions differs between platforms */ 00141 m_callback = callback; 00142 00143 /* populate thunking trampoline */ 00144 m_thunk.code = CTHUNK_OPCODE; 00145 m_thunk.context = (uint32_t)context; 00146 m_thunk.instance = (uint32_t)instance; 00147 m_thunk.callback = (uint32_t)&m_callback; 00148 m_thunk.trampoline = (uint32_t)&trampoline; 00149 00150 __ISB(); 00151 __DSB(); 00152 } 00153 }; 00154 00155 #endif/*__CTHUNK_H__*/
Generated on Tue Jul 19 2022 20:54:42 by
1.7.2