The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Dependents:   hello SerialTestv11 SerialTestv12 Sierpinski ... more

mbed 2

This is the mbed 2 library. If you'd like to learn about Mbed OS please see the mbed-os docs.

Revision:
172:65be27845400
Parent:
170:e95d10626187
--- a/platform/CThunk.h	Thu Nov 08 11:45:42 2018 +0000
+++ b/platform/CThunk.h	Wed Feb 20 20:53:29 2019 +0000
@@ -13,6 +13,7 @@
  * - ideally suited for class object receiving interrupts (NVIC_SetVector)
  *
  * Copyright (c) 2014-2015 ARM Limited
+ * SPDX-License-Identifier: Apache-2.0
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -38,45 +39,7 @@
 #ifndef __CTHUNK_H__
 #define __CTHUNK_H__
 
-#define CTHUNK_ADDRESS 1
-#define CTHUNK_VARIABLES volatile uint32_t code[2]
-
-#if (defined(__CORTEX_M3) || defined(__CORTEX_M4) || defined(__CORTEX_M7) || defined(__CORTEX_A9) \
-    || defined(__CORTEX_M33))
-/**
-* CTHUNK disassembly for Cortex-M3/M4/M7/A9 (thumb2):
-* * adr  r0, #4
-* * ldm  r0, {r0, r1, r2, pc}
-*
-* This instruction loads the arguments for the static thunking function to r0-r2, and
-* branches to that function by loading its address into PC.
-*
-* This is safe for both regular calling and interrupt calling, since it only touches scratch registers
-* which should be saved by the caller, and are automatically saved as part of the IRQ context switch.
-*/
-#define CTHUNK_ASSIGMENT do {                              \
-                             m_thunk.code[0] = 0xE890A001; \
-                             m_thunk.code[1] = 0x00008007; \
-                         } while (0)
-
-#elif (defined(__CORTEX_M0PLUS) || defined(__CORTEX_M0) || defined(__CORTEX_M23))
-/*
-* CTHUNK disassembly for Cortex M0/M0+ (thumb):
-* * adr  r0, #4
-* * ldm  r0, {r0, r1, r2, r3}
-* * bx   r3
-*/
-#define CTHUNK_ASSIGMENT do {                              \
-                             m_thunk.code[0] = 0xC80FA001; \
-                             m_thunk.code[1] = 0x00004718; \
-                         } while (0)
-
-#else
-#error "Target is not currently suported."
-#endif
-
-/* IRQ/Exception compatible thunk entry function */
-typedef void (*CThunkEntry)(void);
+#include "CThunkBase.h"
 
 /**
  * Class for created a pointer with data bound to it
@@ -84,7 +47,7 @@
  * @note Synchronization level: Not protected
  */
 template<class T>
-class CThunk {
+class CThunk: public CThunkBase {
 public:
     typedef void (T::*CCallbackSimple)(void);
     typedef void (T::*CCallback)(void *context);
@@ -101,7 +64,8 @@
 
     ~CThunk()
     {
-
+        cthunk_free(_entry);
+        _entry = NULL;
     }
 
     inline CThunk(T *instance, CCallbackSimple callback)
@@ -126,27 +90,30 @@
 
     inline void callback(CCallback callback)
     {
-        m_callback = callback;
+        _callback = callback;
     }
 
     inline void callback(CCallbackSimple callback)
     {
-        m_callback = (CCallback)callback;
+        _callback_simple = callback;
     }
 
     inline void context(void *context)
     {
-        m_thunk.context = (uint32_t)context;
+        _context = context;
     }
 
     inline void context(uint32_t context)
     {
-        m_thunk.context = context;
+        _context = (void *)context;
     }
 
     inline uint32_t entry(void)
     {
-        return (((uint32_t)&m_thunk) | CTHUNK_ADDRESS);
+        if (_entry == NULL) {
+            _entry = cthunk_alloc(this);
+        }
+        return (uint32_t)_entry;
     }
 
     /* get thunk entry point for connecting rhunk to an IRQ table */
@@ -168,78 +135,34 @@
     }
 
 private:
-    T *m_instance;
-    volatile CCallback m_callback;
+    T *_instance;
+    void *_context;
+    union {
+        CCallbackSimple _callback_simple;
+        CCallback _callback;
+    };
+
+    CThunkEntry _entry;
 
-// TODO: this needs proper fix, to refactor toolchain header file and all its use
-// PACKED there is not defined properly for IAR
-#if defined (__ICCARM__)
-    typedef __packed struct {
-        CTHUNK_VARIABLES;
-        volatile uint32_t instance;
-        volatile uint32_t context;
-        volatile uint32_t callback;
-        volatile uint32_t trampoline;
-    }  CThunkTrampoline;
-#else
-    typedef struct {
-        CTHUNK_VARIABLES;
-        volatile uint32_t instance;
-        volatile uint32_t context;
-        volatile uint32_t callback;
-        volatile uint32_t trampoline;
-    } __attribute__((__packed__)) CThunkTrampoline;
-#endif
+    static void trampoline(CThunkBase *base)
+    {
+        CThunk<T> *self = static_cast<CThunk<T>*>(base);
+        T *instance = self->_instance;
+        void *context = self->_context;
+        CCallback callback = self->_callback;
 
-    static void trampoline(T *instance, void *context, CCallback *callback)
-    {
-        if (instance && *callback) {
-            (static_cast<T *>(instance)->**callback)(context);
+        if (instance && callback) {
+            (instance->*callback)(context);
         }
     }
 
-    volatile CThunkTrampoline m_thunk;
-
     inline void init(T *instance, CCallback callback, void *context)
     {
-        /* remember callback - need to add this level of redirection
-           as pointer size for member functions differs between platforms */
-        m_callback = callback;
-
-        /* populate thunking trampoline */
-        CTHUNK_ASSIGMENT;
-        m_thunk.context = (uint32_t)context;
-        m_thunk.instance = (uint32_t)instance;
-        m_thunk.callback = (uint32_t)&m_callback;
-        m_thunk.trampoline = (uint32_t)&trampoline;
-
-#if defined(__CORTEX_A9)
-        /* Data cache clean */
-        /* Cache control */
-        {
-            uint32_t start_addr = (uint32_t)&m_thunk & 0xFFFFFFE0;
-            uint32_t end_addr   = (uint32_t)&m_thunk + sizeof(m_thunk);
-            uint32_t addr;
-
-            /* Data cache clean and invalid */
-            for (addr = start_addr; addr < end_addr; addr += 0x20) {
-                L1C_CleanInvalidateDCacheMVA((void *)addr);
-            }
-            /* Instruction cache invalid */
-            L1C_InvalidateICacheAll();
-            MMU_InvalidateTLB();
-            L1C_InvalidateBTAC();
-        }
-#endif
-#if defined(__CORTEX_M7)
-        /* Data cache clean and invalid */
-        SCB_CleanInvalidateDCache();
-
-        /* Instruction cache invalid */
-        SCB_InvalidateICache();
-#endif
-        __ISB();
-        __DSB();
+        _instance = instance;
+        _context = context;
+        _callback = callback;
+        _trampoline = &trampoline;
+        _entry = 0;
     }
 };