游戏王对战板,目前code还是空的

Committer:
WFKnight
Date:
Thu Jun 21 13:51:43 2018 +0000
Revision:
0:9b3d4731edbb
UART, RTOS, LED

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WFKnight 0:9b3d4731edbb 1
WFKnight 0:9b3d4731edbb 2 /** \addtogroup platform */
WFKnight 0:9b3d4731edbb 3 /** @{*/
WFKnight 0:9b3d4731edbb 4 /**
WFKnight 0:9b3d4731edbb 5 * \defgroup platform_CThunk CThunk class
WFKnight 0:9b3d4731edbb 6 * @{
WFKnight 0:9b3d4731edbb 7 */
WFKnight 0:9b3d4731edbb 8 /* General C++ Object Thunking class
WFKnight 0:9b3d4731edbb 9 *
WFKnight 0:9b3d4731edbb 10 * - allows direct callbacks to non-static C++ class functions
WFKnight 0:9b3d4731edbb 11 * - keeps track for the corresponding class instance
WFKnight 0:9b3d4731edbb 12 * - supports an optional context parameter for the called function
WFKnight 0:9b3d4731edbb 13 * - ideally suited for class object receiving interrupts (NVIC_SetVector)
WFKnight 0:9b3d4731edbb 14 *
WFKnight 0:9b3d4731edbb 15 * Copyright (c) 2014-2015 ARM Limited
WFKnight 0:9b3d4731edbb 16 *
WFKnight 0:9b3d4731edbb 17 * Licensed under the Apache License, Version 2.0 (the "License");
WFKnight 0:9b3d4731edbb 18 * you may not use this file except in compliance with the License.
WFKnight 0:9b3d4731edbb 19 * You may obtain a copy of the License at
WFKnight 0:9b3d4731edbb 20 *
WFKnight 0:9b3d4731edbb 21 * http://www.apache.org/licenses/LICENSE-2.0
WFKnight 0:9b3d4731edbb 22 *
WFKnight 0:9b3d4731edbb 23 * Unless required by applicable law or agreed to in writing, software
WFKnight 0:9b3d4731edbb 24 * distributed under the License is distributed on an "AS IS" BASIS,
WFKnight 0:9b3d4731edbb 25 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
WFKnight 0:9b3d4731edbb 26 * See the License for the specific language governing permissions and
WFKnight 0:9b3d4731edbb 27 * limitations under the License.
WFKnight 0:9b3d4731edbb 28 */
WFKnight 0:9b3d4731edbb 29
WFKnight 0:9b3d4731edbb 30 /* General C++ Object Thunking class
WFKnight 0:9b3d4731edbb 31 *
WFKnight 0:9b3d4731edbb 32 * - allows direct callbacks to non-static C++ class functions
WFKnight 0:9b3d4731edbb 33 * - keeps track for the corresponding class instance
WFKnight 0:9b3d4731edbb 34 * - supports an optional context parameter for the called function
WFKnight 0:9b3d4731edbb 35 * - ideally suited for class object receiving interrupts (NVIC_SetVector)
WFKnight 0:9b3d4731edbb 36 */
WFKnight 0:9b3d4731edbb 37
WFKnight 0:9b3d4731edbb 38 #ifndef __CTHUNK_H__
WFKnight 0:9b3d4731edbb 39 #define __CTHUNK_H__
WFKnight 0:9b3d4731edbb 40
WFKnight 0:9b3d4731edbb 41 #define CTHUNK_ADDRESS 1
WFKnight 0:9b3d4731edbb 42 #define CTHUNK_VARIABLES volatile uint32_t code[2]
WFKnight 0:9b3d4731edbb 43
WFKnight 0:9b3d4731edbb 44 #if (defined(__CORTEX_M3) || defined(__CORTEX_M4) || defined(__CORTEX_M7) || defined(__CORTEX_A9) \
WFKnight 0:9b3d4731edbb 45 || defined(__CORTEX_M33))
WFKnight 0:9b3d4731edbb 46 /**
WFKnight 0:9b3d4731edbb 47 * CTHUNK disassembly for Cortex-M3/M4/M7/A9 (thumb2):
WFKnight 0:9b3d4731edbb 48 * * adr r0, #4
WFKnight 0:9b3d4731edbb 49 * * ldm r0, {r0, r1, r2, pc}
WFKnight 0:9b3d4731edbb 50 *
WFKnight 0:9b3d4731edbb 51 * This instruction loads the arguments for the static thunking function to r0-r2, and
WFKnight 0:9b3d4731edbb 52 * branches to that function by loading its address into PC.
WFKnight 0:9b3d4731edbb 53 *
WFKnight 0:9b3d4731edbb 54 * This is safe for both regular calling and interrupt calling, since it only touches scratch registers
WFKnight 0:9b3d4731edbb 55 * which should be saved by the caller, and are automatically saved as part of the IRQ context switch.
WFKnight 0:9b3d4731edbb 56 */
WFKnight 0:9b3d4731edbb 57 #define CTHUNK_ASSIGMENT do { \
WFKnight 0:9b3d4731edbb 58 m_thunk.code[0] = 0xE890A001; \
WFKnight 0:9b3d4731edbb 59 m_thunk.code[1] = 0x00008007; \
WFKnight 0:9b3d4731edbb 60 } while (0)
WFKnight 0:9b3d4731edbb 61
WFKnight 0:9b3d4731edbb 62 #elif (defined(__CORTEX_M0PLUS) || defined(__CORTEX_M0) || defined(__CORTEX_M23))
WFKnight 0:9b3d4731edbb 63 /*
WFKnight 0:9b3d4731edbb 64 * CTHUNK disassembly for Cortex M0/M0+ (thumb):
WFKnight 0:9b3d4731edbb 65 * * adr r0, #4
WFKnight 0:9b3d4731edbb 66 * * ldm r0, {r0, r1, r2, r3}
WFKnight 0:9b3d4731edbb 67 * * bx r3
WFKnight 0:9b3d4731edbb 68 */
WFKnight 0:9b3d4731edbb 69 #define CTHUNK_ASSIGMENT do { \
WFKnight 0:9b3d4731edbb 70 m_thunk.code[0] = 0xC80FA001; \
WFKnight 0:9b3d4731edbb 71 m_thunk.code[1] = 0x00004718; \
WFKnight 0:9b3d4731edbb 72 } while (0)
WFKnight 0:9b3d4731edbb 73
WFKnight 0:9b3d4731edbb 74 #else
WFKnight 0:9b3d4731edbb 75 #error "Target is not currently suported."
WFKnight 0:9b3d4731edbb 76 #endif
WFKnight 0:9b3d4731edbb 77
WFKnight 0:9b3d4731edbb 78 /* IRQ/Exception compatible thunk entry function */
WFKnight 0:9b3d4731edbb 79 typedef void (*CThunkEntry)(void);
WFKnight 0:9b3d4731edbb 80
WFKnight 0:9b3d4731edbb 81 /**
WFKnight 0:9b3d4731edbb 82 * Class for created a pointer with data bound to it
WFKnight 0:9b3d4731edbb 83 *
WFKnight 0:9b3d4731edbb 84 * @note Synchronization level: Not protected
WFKnight 0:9b3d4731edbb 85 */
WFKnight 0:9b3d4731edbb 86 template<class T>
WFKnight 0:9b3d4731edbb 87 class CThunk
WFKnight 0:9b3d4731edbb 88 {
WFKnight 0:9b3d4731edbb 89 public:
WFKnight 0:9b3d4731edbb 90 typedef void (T::*CCallbackSimple)(void);
WFKnight 0:9b3d4731edbb 91 typedef void (T::*CCallback)(void* context);
WFKnight 0:9b3d4731edbb 92
WFKnight 0:9b3d4731edbb 93 inline CThunk(T *instance)
WFKnight 0:9b3d4731edbb 94 {
WFKnight 0:9b3d4731edbb 95 init(instance, NULL, NULL);
WFKnight 0:9b3d4731edbb 96 }
WFKnight 0:9b3d4731edbb 97
WFKnight 0:9b3d4731edbb 98 inline CThunk(T *instance, CCallback callback)
WFKnight 0:9b3d4731edbb 99 {
WFKnight 0:9b3d4731edbb 100 init(instance, callback, NULL);
WFKnight 0:9b3d4731edbb 101 }
WFKnight 0:9b3d4731edbb 102
WFKnight 0:9b3d4731edbb 103 ~CThunk() {
WFKnight 0:9b3d4731edbb 104
WFKnight 0:9b3d4731edbb 105 }
WFKnight 0:9b3d4731edbb 106
WFKnight 0:9b3d4731edbb 107 inline CThunk(T *instance, CCallbackSimple callback)
WFKnight 0:9b3d4731edbb 108 {
WFKnight 0:9b3d4731edbb 109 init(instance, (CCallback)callback, NULL);
WFKnight 0:9b3d4731edbb 110 }
WFKnight 0:9b3d4731edbb 111
WFKnight 0:9b3d4731edbb 112 inline CThunk(T &instance, CCallback callback)
WFKnight 0:9b3d4731edbb 113 {
WFKnight 0:9b3d4731edbb 114 init(instance, callback, NULL);
WFKnight 0:9b3d4731edbb 115 }
WFKnight 0:9b3d4731edbb 116
WFKnight 0:9b3d4731edbb 117 inline CThunk(T &instance, CCallbackSimple callback)
WFKnight 0:9b3d4731edbb 118 {
WFKnight 0:9b3d4731edbb 119 init(instance, (CCallback)callback, NULL);
WFKnight 0:9b3d4731edbb 120 }
WFKnight 0:9b3d4731edbb 121
WFKnight 0:9b3d4731edbb 122 inline CThunk(T &instance, CCallback callback, void* context)
WFKnight 0:9b3d4731edbb 123 {
WFKnight 0:9b3d4731edbb 124 init(instance, callback, context);
WFKnight 0:9b3d4731edbb 125 }
WFKnight 0:9b3d4731edbb 126
WFKnight 0:9b3d4731edbb 127 inline void callback(CCallback callback)
WFKnight 0:9b3d4731edbb 128 {
WFKnight 0:9b3d4731edbb 129 m_callback = callback;
WFKnight 0:9b3d4731edbb 130 }
WFKnight 0:9b3d4731edbb 131
WFKnight 0:9b3d4731edbb 132 inline void callback(CCallbackSimple callback)
WFKnight 0:9b3d4731edbb 133 {
WFKnight 0:9b3d4731edbb 134 m_callback = (CCallback)callback;
WFKnight 0:9b3d4731edbb 135 }
WFKnight 0:9b3d4731edbb 136
WFKnight 0:9b3d4731edbb 137 inline void context(void* context)
WFKnight 0:9b3d4731edbb 138 {
WFKnight 0:9b3d4731edbb 139 m_thunk.context = (uint32_t)context;
WFKnight 0:9b3d4731edbb 140 }
WFKnight 0:9b3d4731edbb 141
WFKnight 0:9b3d4731edbb 142 inline void context(uint32_t context)
WFKnight 0:9b3d4731edbb 143 {
WFKnight 0:9b3d4731edbb 144 m_thunk.context = context;
WFKnight 0:9b3d4731edbb 145 }
WFKnight 0:9b3d4731edbb 146
WFKnight 0:9b3d4731edbb 147 inline uint32_t entry(void)
WFKnight 0:9b3d4731edbb 148 {
WFKnight 0:9b3d4731edbb 149 return (((uint32_t)&m_thunk)|CTHUNK_ADDRESS);
WFKnight 0:9b3d4731edbb 150 }
WFKnight 0:9b3d4731edbb 151
WFKnight 0:9b3d4731edbb 152 /* get thunk entry point for connecting rhunk to an IRQ table */
WFKnight 0:9b3d4731edbb 153 inline operator CThunkEntry(void)
WFKnight 0:9b3d4731edbb 154 {
WFKnight 0:9b3d4731edbb 155 return (CThunkEntry)entry();
WFKnight 0:9b3d4731edbb 156 }
WFKnight 0:9b3d4731edbb 157
WFKnight 0:9b3d4731edbb 158 /* get thunk entry point for connecting rhunk to an IRQ table */
WFKnight 0:9b3d4731edbb 159 inline operator uint32_t(void)
WFKnight 0:9b3d4731edbb 160 {
WFKnight 0:9b3d4731edbb 161 return entry();
WFKnight 0:9b3d4731edbb 162 }
WFKnight 0:9b3d4731edbb 163
WFKnight 0:9b3d4731edbb 164 /* simple test function */
WFKnight 0:9b3d4731edbb 165 inline void call(void)
WFKnight 0:9b3d4731edbb 166 {
WFKnight 0:9b3d4731edbb 167 (((CThunkEntry)(entry()))());
WFKnight 0:9b3d4731edbb 168 }
WFKnight 0:9b3d4731edbb 169
WFKnight 0:9b3d4731edbb 170 private:
WFKnight 0:9b3d4731edbb 171 T* m_instance;
WFKnight 0:9b3d4731edbb 172 volatile CCallback m_callback;
WFKnight 0:9b3d4731edbb 173
WFKnight 0:9b3d4731edbb 174 // TODO: this needs proper fix, to refactor toolchain header file and all its use
WFKnight 0:9b3d4731edbb 175 // PACKED there is not defined properly for IAR
WFKnight 0:9b3d4731edbb 176 #if defined (__ICCARM__)
WFKnight 0:9b3d4731edbb 177 typedef __packed struct
WFKnight 0:9b3d4731edbb 178 {
WFKnight 0:9b3d4731edbb 179 CTHUNK_VARIABLES;
WFKnight 0:9b3d4731edbb 180 volatile uint32_t instance;
WFKnight 0:9b3d4731edbb 181 volatile uint32_t context;
WFKnight 0:9b3d4731edbb 182 volatile uint32_t callback;
WFKnight 0:9b3d4731edbb 183 volatile uint32_t trampoline;
WFKnight 0:9b3d4731edbb 184 } CThunkTrampoline;
WFKnight 0:9b3d4731edbb 185 #else
WFKnight 0:9b3d4731edbb 186 typedef struct
WFKnight 0:9b3d4731edbb 187 {
WFKnight 0:9b3d4731edbb 188 CTHUNK_VARIABLES;
WFKnight 0:9b3d4731edbb 189 volatile uint32_t instance;
WFKnight 0:9b3d4731edbb 190 volatile uint32_t context;
WFKnight 0:9b3d4731edbb 191 volatile uint32_t callback;
WFKnight 0:9b3d4731edbb 192 volatile uint32_t trampoline;
WFKnight 0:9b3d4731edbb 193 } __attribute__((__packed__)) CThunkTrampoline;
WFKnight 0:9b3d4731edbb 194 #endif
WFKnight 0:9b3d4731edbb 195
WFKnight 0:9b3d4731edbb 196 static void trampoline(T* instance, void* context, CCallback* callback)
WFKnight 0:9b3d4731edbb 197 {
WFKnight 0:9b3d4731edbb 198 if(instance && *callback) {
WFKnight 0:9b3d4731edbb 199 (static_cast<T*>(instance)->**callback)(context);
WFKnight 0:9b3d4731edbb 200 }
WFKnight 0:9b3d4731edbb 201 }
WFKnight 0:9b3d4731edbb 202
WFKnight 0:9b3d4731edbb 203 volatile CThunkTrampoline m_thunk;
WFKnight 0:9b3d4731edbb 204
WFKnight 0:9b3d4731edbb 205 inline void init(T *instance, CCallback callback, void* context)
WFKnight 0:9b3d4731edbb 206 {
WFKnight 0:9b3d4731edbb 207 /* remember callback - need to add this level of redirection
WFKnight 0:9b3d4731edbb 208 as pointer size for member functions differs between platforms */
WFKnight 0:9b3d4731edbb 209 m_callback = callback;
WFKnight 0:9b3d4731edbb 210
WFKnight 0:9b3d4731edbb 211 /* populate thunking trampoline */
WFKnight 0:9b3d4731edbb 212 CTHUNK_ASSIGMENT;
WFKnight 0:9b3d4731edbb 213 m_thunk.context = (uint32_t)context;
WFKnight 0:9b3d4731edbb 214 m_thunk.instance = (uint32_t)instance;
WFKnight 0:9b3d4731edbb 215 m_thunk.callback = (uint32_t)&m_callback;
WFKnight 0:9b3d4731edbb 216 m_thunk.trampoline = (uint32_t)&trampoline;
WFKnight 0:9b3d4731edbb 217
WFKnight 0:9b3d4731edbb 218 #if defined(__CORTEX_A9)
WFKnight 0:9b3d4731edbb 219 /* Data cache clean */
WFKnight 0:9b3d4731edbb 220 /* Cache control */
WFKnight 0:9b3d4731edbb 221 {
WFKnight 0:9b3d4731edbb 222 uint32_t start_addr = (uint32_t)&m_thunk & 0xFFFFFFE0;
WFKnight 0:9b3d4731edbb 223 uint32_t end_addr = (uint32_t)&m_thunk + sizeof(m_thunk);
WFKnight 0:9b3d4731edbb 224 uint32_t addr;
WFKnight 0:9b3d4731edbb 225
WFKnight 0:9b3d4731edbb 226 /* Data cache clean and invalid */
WFKnight 0:9b3d4731edbb 227 for (addr = start_addr; addr < end_addr; addr += 0x20) {
WFKnight 0:9b3d4731edbb 228 L1C_CleanInvalidateDCacheMVA((void *)addr);
WFKnight 0:9b3d4731edbb 229 }
WFKnight 0:9b3d4731edbb 230 /* Instruction cache invalid */
WFKnight 0:9b3d4731edbb 231 L1C_InvalidateICacheAll();
WFKnight 0:9b3d4731edbb 232 MMU_InvalidateTLB();
WFKnight 0:9b3d4731edbb 233 L1C_InvalidateBTAC();
WFKnight 0:9b3d4731edbb 234 }
WFKnight 0:9b3d4731edbb 235 #endif
WFKnight 0:9b3d4731edbb 236 #if defined(__CORTEX_M7)
WFKnight 0:9b3d4731edbb 237 /* Data cache clean and invalid */
WFKnight 0:9b3d4731edbb 238 SCB_CleanInvalidateDCache();
WFKnight 0:9b3d4731edbb 239
WFKnight 0:9b3d4731edbb 240 /* Instruction cache invalid */
WFKnight 0:9b3d4731edbb 241 SCB_InvalidateICache();
WFKnight 0:9b3d4731edbb 242 #endif
WFKnight 0:9b3d4731edbb 243 __ISB();
WFKnight 0:9b3d4731edbb 244 __DSB();
WFKnight 0:9b3d4731edbb 245 }
WFKnight 0:9b3d4731edbb 246 };
WFKnight 0:9b3d4731edbb 247
WFKnight 0:9b3d4731edbb 248 /**@}*/
WFKnight 0:9b3d4731edbb 249
WFKnight 0:9b3d4731edbb 250 /**@}*/
WFKnight 0:9b3d4731edbb 251
WFKnight 0:9b3d4731edbb 252 #endif/*__CTHUNK_H__*/
WFKnight 0:9b3d4731edbb 253