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@2:3197c4a8ba85, 2014-08-15 (annotated)
- Committer:
- meriac
- Date:
- Fri Aug 15 16:03:48 2014 +0000
- Revision:
- 2:3197c4a8ba85
- Parent:
- 1:53a00c956d82
- Child:
- 3:51023d181133
fixed mbed symbols
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| meriac | 0:7de85300ea3a | 1 | /* General C++ Object Thunking class |
| meriac | 0:7de85300ea3a | 2 | * |
| meriac | 0:7de85300ea3a | 3 | * - allows direct callbacks to non-static C++ class functions |
| meriac | 0:7de85300ea3a | 4 | * - keeps track for the corresponding class instance |
| meriac | 0:7de85300ea3a | 5 | * - supports an optional context parameter for the called function |
| meriac | 0:7de85300ea3a | 6 | * - ideally suited for class object receiving interrupts (NVIC_SetVector) |
| meriac | 0:7de85300ea3a | 7 | * |
| meriac | 0:7de85300ea3a | 8 | * Copyright (c) 2014 ARM Limited |
| meriac | 0:7de85300ea3a | 9 | * |
| meriac | 0:7de85300ea3a | 10 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| meriac | 0:7de85300ea3a | 11 | * you may not use this file except in compliance with the License. |
| meriac | 0:7de85300ea3a | 12 | * You may obtain a copy of the License at |
| meriac | 0:7de85300ea3a | 13 | * |
| meriac | 0:7de85300ea3a | 14 | * http://www.apache.org/licenses/LICENSE-2.0 |
| meriac | 0:7de85300ea3a | 15 | * |
| meriac | 0:7de85300ea3a | 16 | * Unless required by applicable law or agreed to in writing, software |
| meriac | 0:7de85300ea3a | 17 | * distributed under the License is distributed on an "AS IS" BASIS, |
| meriac | 0:7de85300ea3a | 18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| meriac | 0:7de85300ea3a | 19 | * See the License for the specific language governing permissions and |
| meriac | 0:7de85300ea3a | 20 | * limitations under the License. |
| meriac | 0:7de85300ea3a | 21 | */ |
| meriac | 0:7de85300ea3a | 22 | |
| meriac | 0:7de85300ea3a | 23 | #ifndef __CTHUNK_H__ |
| meriac | 0:7de85300ea3a | 24 | #define __CTHUNK_H__ |
| meriac | 0:7de85300ea3a | 25 | |
| meriac | 0:7de85300ea3a | 26 | /* IRQ/Exception compatible thunk entry function */ |
| meriac | 0:7de85300ea3a | 27 | typedef void (*CThunkEntry)(void); |
| meriac | 0:7de85300ea3a | 28 | |
| meriac | 0:7de85300ea3a | 29 | template<class T> |
| meriac | 0:7de85300ea3a | 30 | class CThunk |
| meriac | 0:7de85300ea3a | 31 | { |
| meriac | 0:7de85300ea3a | 32 | public: |
| meriac | 0:7de85300ea3a | 33 | typedef void (T::*CCallbackSimple)(void); |
| meriac | 0:7de85300ea3a | 34 | typedef void (T::*CCallback)(void* context); |
| meriac | 0:7de85300ea3a | 35 | |
| meriac | 1:53a00c956d82 | 36 | inline CThunk(T *instance) |
| meriac | 0:7de85300ea3a | 37 | { |
| meriac | 1:53a00c956d82 | 38 | init(*instance, NULL, NULL); |
| meriac | 0:7de85300ea3a | 39 | } |
| meriac | 0:7de85300ea3a | 40 | |
| meriac | 0:7de85300ea3a | 41 | inline CThunk(T &instance) |
| meriac | 0:7de85300ea3a | 42 | { |
| meriac | 0:7de85300ea3a | 43 | init(instance, NULL, NULL); |
| meriac | 0:7de85300ea3a | 44 | } |
| meriac | 0:7de85300ea3a | 45 | |
| meriac | 0:7de85300ea3a | 46 | inline CThunk(T &instance, CCallback callback) |
| meriac | 0:7de85300ea3a | 47 | { |
| meriac | 0:7de85300ea3a | 48 | init(instance, callback, NULL); |
| meriac | 0:7de85300ea3a | 49 | } |
| meriac | 0:7de85300ea3a | 50 | |
| meriac | 0:7de85300ea3a | 51 | inline CThunk(T &instance, CCallbackSimple callback) |
| meriac | 0:7de85300ea3a | 52 | { |
| meriac | 0:7de85300ea3a | 53 | init(instance, (CCallback)callback, NULL); |
| meriac | 0:7de85300ea3a | 54 | } |
| meriac | 0:7de85300ea3a | 55 | |
| meriac | 0:7de85300ea3a | 56 | inline CThunk(T &instance, CCallback callback, void* context) |
| meriac | 0:7de85300ea3a | 57 | { |
| meriac | 0:7de85300ea3a | 58 | init(instance, callback, context); |
| meriac | 0:7de85300ea3a | 59 | } |
| meriac | 0:7de85300ea3a | 60 | |
| meriac | 0:7de85300ea3a | 61 | inline CThunk& operator=(T &instance) |
| meriac | 0:7de85300ea3a | 62 | { |
| meriac | 0:7de85300ea3a | 63 | m_thunk.instance = &instance; |
| meriac | 0:7de85300ea3a | 64 | return *this; |
| meriac | 0:7de85300ea3a | 65 | } |
| meriac | 0:7de85300ea3a | 66 | |
| meriac | 0:7de85300ea3a | 67 | inline CThunk& operator=(CCallback callback) |
| meriac | 0:7de85300ea3a | 68 | { |
| meriac | 0:7de85300ea3a | 69 | m_thunk.callback = callback; |
| meriac | 0:7de85300ea3a | 70 | return *this; |
| meriac | 0:7de85300ea3a | 71 | } |
| meriac | 0:7de85300ea3a | 72 | |
| meriac | 0:7de85300ea3a | 73 | inline CThunk& operator=(CCallbackSimple callback) |
| meriac | 0:7de85300ea3a | 74 | { |
| meriac | 0:7de85300ea3a | 75 | m_thunk.callback = (CCallback)callback; |
| meriac | 0:7de85300ea3a | 76 | return *this; |
| meriac | 0:7de85300ea3a | 77 | } |
| meriac | 0:7de85300ea3a | 78 | |
| meriac | 0:7de85300ea3a | 79 | inline CThunk& operator=(void* context) |
| meriac | 0:7de85300ea3a | 80 | { |
| meriac | 0:7de85300ea3a | 81 | m_thunk.context = context; |
| meriac | 0:7de85300ea3a | 82 | return *this; |
| meriac | 0:7de85300ea3a | 83 | } |
| meriac | 0:7de85300ea3a | 84 | |
| meriac | 0:7de85300ea3a | 85 | inline CThunk& operator=(uint32_t context) |
| meriac | 0:7de85300ea3a | 86 | { |
| meriac | 0:7de85300ea3a | 87 | m_thunk.context = (void*)context; |
| meriac | 0:7de85300ea3a | 88 | return *this; |
| meriac | 0:7de85300ea3a | 89 | } |
| meriac | 0:7de85300ea3a | 90 | |
| meriac | 0:7de85300ea3a | 91 | /* get thunk entry point for connecting rhunk to an IRQ table */ |
| meriac | 0:7de85300ea3a | 92 | inline operator CThunkEntry(void) |
| meriac | 0:7de85300ea3a | 93 | { |
| meriac | 1:53a00c956d82 | 94 | return (CThunkEntry)&m_thunk; |
| meriac | 0:7de85300ea3a | 95 | } |
| meriac | 0:7de85300ea3a | 96 | |
| meriac | 0:7de85300ea3a | 97 | /* get thunk entry point for connecting rhunk to an IRQ table */ |
| meriac | 0:7de85300ea3a | 98 | inline operator uint32_t(void) |
| meriac | 0:7de85300ea3a | 99 | { |
| meriac | 1:53a00c956d82 | 100 | return (uint32_t)&m_thunk; |
| meriac | 0:7de85300ea3a | 101 | } |
| meriac | 0:7de85300ea3a | 102 | |
| meriac | 0:7de85300ea3a | 103 | /* simple test function */ |
| meriac | 0:7de85300ea3a | 104 | inline void call(void) |
| meriac | 0:7de85300ea3a | 105 | { |
| meriac | 1:53a00c956d82 | 106 | ((CThunkEntry)&m_thunk)(); |
| meriac | 0:7de85300ea3a | 107 | } |
| meriac | 0:7de85300ea3a | 108 | |
| meriac | 0:7de85300ea3a | 109 | private: |
| meriac | 0:7de85300ea3a | 110 | typedef struct |
| meriac | 0:7de85300ea3a | 111 | { |
| meriac | 1:53a00c956d82 | 112 | uint32_t code; |
| meriac | 0:7de85300ea3a | 113 | T* instance; |
| meriac | 0:7de85300ea3a | 114 | void* context; |
| meriac | 0:7de85300ea3a | 115 | CCallback callback; |
| meriac | 0:7de85300ea3a | 116 | } __attribute__((packed)) CThunkTrampoline; |
| meriac | 0:7de85300ea3a | 117 | |
| meriac | 0:7de85300ea3a | 118 | CThunkTrampoline m_thunk; |
| meriac | 0:7de85300ea3a | 119 | |
| meriac | 0:7de85300ea3a | 120 | inline void init(T &instance, CCallback callback, void* context) |
| meriac | 0:7de85300ea3a | 121 | { |
| meriac | 2:3197c4a8ba85 | 122 | #ifdef __CORTEX_M3 |
| meriac | 1:53a00c956d82 | 123 | m_thunk.code = 0x8003E89F; |
| meriac | 1:53a00c956d82 | 124 | #else |
| meriac | 1:53a00c956d82 | 125 | #error "TODO: add support for non-cortex-m3 trampoline, too" |
| meriac | 1:53a00c956d82 | 126 | #endif |
| meriac | 0:7de85300ea3a | 127 | m_thunk.instance = &instance; |
| meriac | 0:7de85300ea3a | 128 | m_thunk.context = context; |
| meriac | 0:7de85300ea3a | 129 | m_thunk.callback = callback; |
| meriac | 0:7de85300ea3a | 130 | } |
| meriac | 0:7de85300ea3a | 131 | }; |
| meriac | 0:7de85300ea3a | 132 | |
| meriac | 1:53a00c956d82 | 133 | #endif/*__CTHUNK_H__*/ |