Official mbed Real Time Operating System based on the RTX implementation of the CMSIS-RTOS API open standard.

Fork of mbed-rtos by mbed official

Files at this revision

API Documentation at this revision

Comitter:
Kojto
Date:
Wed Aug 10 16:09:20 2016 +0100
Parent:
119:6635230e06ba
Child:
121:4dc938e301cc
Commit message:
RTOS rev119

Compatible with the mbed library v123

Changes:
- new targets: NRF52 and NUC472
- mbed singleton mutex addition
- main thread with timers fix
- Thread - mutex addition for synchronization
- Semaphore - default count argument set to 0
- RTOSTimer - add new ctor with Callback

Changed in this revision

rtos/RtosTimer.cpp Show annotated file Show diff for this revision Revisions of this file
rtos/RtosTimer.h Show annotated file Show diff for this revision Revisions of this file
rtos/Semaphore.h Show annotated file Show diff for this revision Revisions of this file
rtos/Thread.cpp Show annotated file Show diff for this revision Revisions of this file
rtos/Thread.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/RTX_CM_lib.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_HAL_CA.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_HAL_CM.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/RTX_CM_lib.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/RTX_Conf_CM.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/cmsis_os.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/rt_HAL_CM.h Show annotated file Show diff for this revision Revisions of this file
--- a/rtos/RtosTimer.cpp	Mon Jul 25 14:12:24 2016 +0100
+++ b/rtos/RtosTimer.cpp	Wed Aug 10 16:09:20 2016 +0100
@@ -23,19 +23,21 @@
 
 #include <string.h>
 
+#include "mbed.h"
 #include "cmsis_os.h"
 #include "mbed_error.h"
 
 namespace rtos {
 
-RtosTimer::RtosTimer(void (*periodic_task)(void const *argument), os_timer_type type, void *argument) {
+void RtosTimer::constructor(mbed::Callback<void()> func, os_timer_type type) {
 #ifdef CMSIS_OS_RTX
-    _timer.ptimer = periodic_task;
+    _timer.ptimer = (void (*)(const void *))Callback<void()>::thunk;
 
     memset(_timer_data, 0, sizeof(_timer_data));
     _timer.timer = _timer_data;
 #endif
-    _timer_id = osTimerCreate(&_timer, type, argument);
+    _function = func;
+    _timer_id = osTimerCreate(&_timer, type, &_function);
 }
 
 osStatus RtosTimer::start(uint32_t millisec) {
--- a/rtos/RtosTimer.h	Mon Jul 25 14:12:24 2016 +0100
+++ b/rtos/RtosTimer.h	Wed Aug 10 16:09:20 2016 +0100
@@ -24,6 +24,8 @@
 
 #include <stdint.h>
 #include "cmsis_os.h"
+#include "Callback.h"
+#include "toolchain.h"
 
 namespace rtos {
 
@@ -36,21 +38,41 @@
 */
 class RtosTimer {
 public:
-    /** Create and Start timer.
-      @param   task      name of the timer call back function.
+    /** Create timer.
+      @param   func      function to be executed by this timer.
       @param   type      osTimerOnce for one-shot or osTimerPeriodic for periodic behaviour. (default: osTimerPeriodic)
       @param   argument  argument to the timer call back function. (default: NULL)
+      @deprecated Replaced with RtosTimer(Callback<void()>, os_timer_type)
+     */
+    MBED_DEPRECATED("Replaced with RtosTimer(Callback<void()>, os_timer_type)")
+    RtosTimer(void (*func)(void const *argument), os_timer_type type=osTimerPeriodic, void *argument=NULL) {
+        constructor(mbed::Callback<void()>(argument, (void (*)(void *))func), type);
+    }
+    
+    /** Create timer.
+      @param   func      function to be executed by this timer.
+      @param   type      osTimerOnce for one-shot or osTimerPeriodic for periodic behaviour. (default: osTimerPeriodic)
     */
-    RtosTimer(void (*task)(void const *argument),
-          os_timer_type type=osTimerPeriodic,
-          void *argument=NULL);
+    RtosTimer(mbed::Callback<void()> func, os_timer_type type=osTimerPeriodic) {
+        constructor(func, type);
+    }
+    
+    /** Create timer.
+      @param   obj       pointer to the object to call the member function on.
+      @param   method    member function to be executed by this timer.
+      @param   type      osTimerOnce for one-shot or osTimerPeriodic for periodic behaviour. (default: osTimerPeriodic)
+    */
+    template <typename T, typename M>
+    RtosTimer(T *obj, M method, os_timer_type type=osTimerPeriodic) {
+        constructor(mbed::Callback<void()>(obj, method), type);
+    }
 
     /** Stop the timer.
       @return  status code that indicates the execution status of the function.
     */
     osStatus stop(void);
 
-    /** start a timer.
+    /** Start the timer.
       @param   millisec  time delay value of the timer.
       @return  status code that indicates the execution status of the function.
     */
@@ -59,6 +81,11 @@
     ~RtosTimer();
 
 private:
+    // Required to share definitions without
+    // delegated constructors
+    void constructor(mbed::Callback<void()> func, os_timer_type type);
+    
+    mbed::Callback<void()> _function;
     osTimerId _timer_id;
     osTimerDef_t _timer;
 #if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
--- a/rtos/Semaphore.h	Mon Jul 25 14:12:24 2016 +0100
+++ b/rtos/Semaphore.h	Wed Aug 10 16:09:20 2016 +0100
@@ -31,9 +31,9 @@
 class Semaphore {
 public:
     /** Create and Initialize a Semaphore object used for managing resources.
-      @param number of available resources; maximum index value is (count-1).
+      @param number of available resources; maximum index value is (count-1). (default: 0).
     */
-    Semaphore(int32_t count);
+    Semaphore(int32_t count=0);
 
     /** Wait until a Semaphore resource becomes available.
       @param   millisec  timeout value or 0 in case of no time-out. (default: osWaitForever).
--- a/rtos/Thread.cpp	Mon Jul 25 14:12:24 2016 +0100
+++ b/rtos/Thread.cpp	Wed Aug 10 16:09:20 2016 +0100
@@ -63,16 +63,21 @@
 }
 
 osStatus Thread::start(Callback<void()> task) {
+    _mutex.lock();
+
     if (_tid != 0) {
+        _mutex.unlock();
         return osErrorParameter;
     }
 
 #if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
-    _thread_def.pthread = (void (*)(const void *))Callback<void()>::thunk;
+    _thread_def.pthread = Thread::_thunk;
     if (_thread_def.stack_pointer == NULL) {
         _thread_def.stack_pointer = new uint32_t[_thread_def.stacksize/sizeof(uint32_t)];
-        if (_thread_def.stack_pointer == NULL)
+        if (_thread_def.stack_pointer == NULL) {
+            _mutex.unlock();
             return osErrorNoMemory;
+        }
     }
 
     //Fill the stack with a magic word for maximum usage checking
@@ -81,67 +86,122 @@
     }
 #endif
     _task = task;
-    _tid = osThreadCreate(&_thread_def, &_task);
+    _tid = osThreadCreate(&_thread_def, this);
     if (_tid == NULL) {
         if (_dynamic_stack) delete[] (_thread_def.stack_pointer);
+        _mutex.unlock();
         return osErrorResource;
     }
+
+    _mutex.unlock();
     return osOK;
 }
 
 osStatus Thread::terminate() {
-    return osThreadTerminate(_tid);
+    osStatus ret;
+    _mutex.lock();
+
+    ret = osThreadTerminate(_tid);
+    _tid = (osThreadId)NULL;
+
+    // Wake threads joining the terminated thread
+    _join_sem.release();
+
+    _mutex.unlock();
+    return ret;
 }
 
 osStatus Thread::join() {
-    while (true) {
-        uint8_t state = get_state();
-        if (state == Thread::Inactive || state == osErrorParameter) {
-            return osOK;
-        }
-
-        osStatus status = yield();
-        if (status != osOK) {
-            return status;
-        }
+    int32_t ret = _join_sem.wait();
+    if (ret < 0) {
+        return osErrorOS;
     }
+    // Release sem so any other threads joining this thread wake up
+    _join_sem.release();
+    return osOK;
 }
 
 osStatus Thread::set_priority(osPriority priority) {
-    return osThreadSetPriority(_tid, priority);
+    osStatus ret;
+    _mutex.lock();
+
+    ret = osThreadSetPriority(_tid, priority);
+
+    _mutex.unlock();
+    return ret;
 }
 
 osPriority Thread::get_priority() {
-    return osThreadGetPriority(_tid);
+    osPriority ret;
+    _mutex.lock();
+
+    ret = osThreadGetPriority(_tid);
+
+    _mutex.unlock();
+    return ret;
 }
 
 int32_t Thread::signal_set(int32_t signals) {
+    // osSignalSet is thread safe as long as the underlying
+    // thread does not get terminated or return from main
     return osSignalSet(_tid, signals);
 }
 
 int32_t Thread::signal_clr(int32_t signals) {
+    // osSignalClear is thread safe as long as the underlying
+    // thread does not get terminated or return from main
     return osSignalClear(_tid, signals);
 }
 
 Thread::State Thread::get_state() {
 #if !defined(__MBED_CMSIS_RTOS_CA9) && !defined(__MBED_CMSIS_RTOS_CM)
 #ifdef CMSIS_OS_RTX
-    return ((State)_thread_def.tcb.state);
+    State status = Deleted;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        status = (State)_thread_def.tcb.state;
+    }
+
+    _mutex.unlock();
+    return status;
 #endif
 #else
-    uint8_t status;
-    status = osThreadGetState(_tid);
-    return ((State)status);
+    State status = Deleted;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        status = (State)osThreadGetState(_tid);
+    }
+
+    _mutex.unlock();
+    return status;
 #endif
 }
 
 uint32_t Thread::stack_size() {
 #ifndef __MBED_CMSIS_RTOS_CA9
 #if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
-    return _thread_def.tcb.priv_stack;
+    uint32_t size = 0;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        size = _thread_def.tcb.priv_stack;
+    }
+
+    _mutex.unlock();
+    return size;
 #else
-    P_TCB tcb = rt_tid2ptcb(_tid);
-    return tcb->priv_stack;
+    uint32_t size = 0;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        P_TCB tcb = rt_tid2ptcb(_tid);
+        size = tcb->priv_stack;
+    }
+
+    _mutex.unlock();
+    return size;
 #endif
 #else
     return 0;
@@ -151,12 +211,28 @@
 uint32_t Thread::free_stack() {
 #ifndef __MBED_CMSIS_RTOS_CA9
 #if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
-    uint32_t bottom = (uint32_t)_thread_def.tcb.stack;
-    return _thread_def.tcb.tsk_stack - bottom;
+    uint32_t size = 0;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        uint32_t bottom = (uint32_t)_thread_def.tcb.stack;
+        size = _thread_def.tcb.tsk_stack - bottom;
+    }
+
+    _mutex.unlock();
+    return size;
 #else
-    P_TCB tcb = rt_tid2ptcb(_tid);
-    uint32_t bottom = (uint32_t)tcb->stack;
-    return tcb->tsk_stack - bottom;
+    uint32_t size = 0;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        P_TCB tcb = rt_tid2ptcb(_tid);
+        uint32_t bottom = (uint32_t)tcb->stack;
+        size = tcb->tsk_stack - bottom;
+    }
+
+    _mutex.unlock();
+    return size;
 #endif
 #else
     return 0;
@@ -166,12 +242,28 @@
 uint32_t Thread::used_stack() {
 #ifndef __MBED_CMSIS_RTOS_CA9
 #if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
-    uint32_t top = (uint32_t)_thread_def.tcb.stack + _thread_def.tcb.priv_stack;
-    return top - _thread_def.tcb.tsk_stack;
+    uint32_t size = 0;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        uint32_t top = (uint32_t)_thread_def.tcb.stack + _thread_def.tcb.priv_stack;
+        size = top - _thread_def.tcb.tsk_stack;
+    }
+
+    _mutex.unlock();
+    return size;
 #else
-    P_TCB tcb = rt_tid2ptcb(_tid);
-    uint32_t top = (uint32_t)tcb->stack + tcb->priv_stack;
-    return top - tcb->tsk_stack;
+    uint32_t size = 0;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        P_TCB tcb = rt_tid2ptcb(_tid);
+        uint32_t top = (uint32_t)tcb->stack + tcb->priv_stack;
+        size =  top - tcb->tsk_stack;
+    }
+
+    _mutex.unlock();
+    return size;
 #endif
 #else
     return 0;
@@ -181,16 +273,32 @@
 uint32_t Thread::max_stack() {
 #ifndef __MBED_CMSIS_RTOS_CA9
 #if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
-    uint32_t high_mark = 0;
-    while (_thread_def.tcb.stack[high_mark] == 0xE25A2EA5)
-        high_mark++;
-    return _thread_def.tcb.priv_stack - (high_mark * 4);
+    uint32_t size = 0;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        uint32_t high_mark = 0;
+        while (_thread_def.tcb.stack[high_mark] == 0xE25A2EA5)
+            high_mark++;
+        size = _thread_def.tcb.priv_stack - (high_mark * 4);
+    }
+
+    _mutex.unlock();
+    return size;
 #else
-    P_TCB tcb = rt_tid2ptcb(_tid);
-    uint32_t high_mark = 0;
-    while (tcb->stack[high_mark] == 0xE25A2EA5)
-        high_mark++;
-    return tcb->priv_stack - (high_mark * 4);
+    uint32_t size = 0;
+    _mutex.lock();
+
+    if (_tid != NULL) {
+        P_TCB tcb = rt_tid2ptcb(_tid);
+        uint32_t high_mark = 0;
+        while (tcb->stack[high_mark] == 0xE25A2EA5)
+            high_mark++;
+        size = tcb->priv_stack - (high_mark * 4);
+    }
+
+    _mutex.unlock();
+    return size;
 #endif
 #else
     return 0;
@@ -218,6 +326,7 @@
 }
 
 Thread::~Thread() {
+    // terminate is thread safe
     terminate();
 #ifdef __MBED_CMSIS_RTOS_CM
     if (_dynamic_stack) {
@@ -226,4 +335,14 @@
 #endif
 }
 
+void Thread::_thunk(const void * thread_ptr)
+{
+    Thread *t = (Thread*)thread_ptr;
+    t->_task();
+    t->_mutex.lock();
+    t->_tid = (osThreadId)NULL;
+    t->_join_sem.release();
+    // rtos will release the mutex automatically
 }
+
+}
--- a/rtos/Thread.h	Mon Jul 25 14:12:24 2016 +0100
+++ b/rtos/Thread.h	Wed Aug 10 16:09:20 2016 +0100
@@ -26,6 +26,8 @@
 #include "cmsis_os.h"
 #include "Callback.h"
 #include "toolchain.h"
+#include "Semaphore.h"
+#include "Mutex.h"
 
 namespace rtos {
 
@@ -205,6 +207,9 @@
         WaitingSemaphore,   /**< Waiting for a semaphore event to occur */
         WaitingMailbox,     /**< Waiting for a mailbox event to occur */
         WaitingMutex,       /**< Waiting for a mutex event to occur */
+
+        /* Not in sync with RTX below here */
+        Deleted,            /**< The task has been deleted */
     };
 
     /** State of this Thread
@@ -275,11 +280,14 @@
                      osPriority priority=osPriorityNormal,
                      uint32_t stack_size=DEFAULT_STACK_SIZE,
                      unsigned char *stack_pointer=NULL);
+    static void _thunk(const void * thread_ptr);
 
     mbed::Callback<void()> _task;
     osThreadId _tid;
     osThreadDef_t _thread_def;
     bool _dynamic_stack;
+    Semaphore _join_sem;
+    Mutex _mutex;
 };
 
 }
--- a/rtx/TARGET_CORTEX_A/RTX_CM_lib.h	Mon Jul 25 14:12:24 2016 +0100
+++ b/rtx/TARGET_CORTEX_A/RTX_CM_lib.h	Wed Aug 10 16:09:20 2016 +0100
@@ -33,6 +33,7 @@
  *---------------------------------------------------------------------------*/
 
 #if   defined (__CC_ARM)
+#include <rt_misc.h>
 #pragma O3
 #define __USED __attribute__((used))
 #elif defined (__GNUC__)
@@ -224,6 +225,10 @@
 uint32_t const *m_tmr = NULL;
 uint16_t const mp_tmr_size = 0;
 
+/* singleton mutex */
+osMutexId singleton_mutex_id;
+osMutexDef(singleton_mutex);
+
 #if defined (__CC_ARM) && !defined (__MICROLIB)
  /* A memory space for arm standard library. */
  static uint32_t std_libspace[OS_TASK_CNT][96/4];
@@ -433,6 +438,7 @@
 
 void pre_main()  
 {  
+  singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
   $Super$$__cpp_initialize__aeabi_();  
   main();  
 }
@@ -442,25 +448,13 @@
 void * armcc_heap_base;
 void * armcc_heap_top;
 
-__asm void pre_main (void)
-{
-  IMPORT  __rt_lib_init
-  IMPORT  main
-  IMPORT  armcc_heap_base
-  IMPORT  armcc_heap_top
+int main(void);
 
-  LDR     R0,=armcc_heap_base
-  LDR     R1,=armcc_heap_top
-  LDR     R0,[R0]
-  LDR     R1,[R1]
-  /* Save link register (keep 8 byte alignment with dummy R4) */
-  PUSH    {R4, LR}
-  BL      __rt_lib_init
-  BL       main
-  /* Return to the thread destroy function.
-   */
-  POP     {R4, PC}
-  ALIGN
+void pre_main (void)
+{
+    singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
+    __rt_lib_init((unsigned)armcc_heap_base, (unsigned)armcc_heap_top);
+    main();
 }
 
 __asm void __rt_entry (void) {
@@ -496,6 +490,7 @@
 extern int main(int argc, char **argv);
 
 void pre_main(void) {
+    singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
     atexit(__libc_fini_array);
     __libc_init_array();
     main(0, NULL);
@@ -523,12 +518,16 @@
 extern __weak void __iar_init_vfp( void );
 extern void __iar_dynamic_initialization(void);
 extern void mbed_sdk_init(void);
+extern void mbed_main(void);
+extern int main(void);
 static uint8_t low_level_init_needed;
 
 void pre_main(void) {
+    singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
     if (low_level_init_needed) {
         __iar_dynamic_initialization();
     }
+    mbed_main();
     main();
 }
 
--- a/rtx/TARGET_CORTEX_A/rt_HAL_CA.h	Mon Jul 25 14:12:24 2016 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_HAL_CA.h	Wed Aug 10 16:09:20 2016 +0100
@@ -60,6 +60,11 @@
  #undef  __USE_EXCLUSIVE_ACCESS
 #endif
 
+/* Supress __ldrex and __strex deprecated warnings - "#3731-D: intrinsic is deprecated" */
+#ifdef __USE_EXCLUSIVE_ACCESS
+#pragma diag_suppress 3731
+#endif
+
 #elif defined (__GNUC__)        /* GNU Compiler */
 
 #undef  __USE_EXCLUSIVE_ACCESS
--- a/rtx/TARGET_CORTEX_A/rt_HAL_CM.h	Mon Jul 25 14:12:24 2016 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_HAL_CM.h	Wed Aug 10 16:09:20 2016 +0100
@@ -46,6 +46,11 @@
  #undef  __USE_EXCLUSIVE_ACCESS
 #endif
 
+/* Supress __ldrex and __strex deprecated warnings - "#3731-D: intrinsic is deprecated" */
+#ifdef __USE_EXCLUSIVE_ACCESS
+#pragma diag_suppress 3731
+#endif
+
 #elif defined (__GNUC__)        /* GNU Compiler */
 
 #undef  __USE_EXCLUSIVE_ACCESS
--- a/rtx/TARGET_CORTEX_M/RTX_CM_lib.h	Mon Jul 25 14:12:24 2016 +0100
+++ b/rtx/TARGET_CORTEX_M/RTX_CM_lib.h	Wed Aug 10 16:09:20 2016 +0100
@@ -34,6 +34,7 @@
 #include "mbed_error.h"
 
 #if   defined (__CC_ARM)
+#include <rt_misc.h>
 #pragma O3
 #define __USED __attribute__((used))
 #elif defined (__GNUC__)
@@ -186,6 +187,10 @@
 uint32_t const *m_tmr = NULL;
 uint16_t const mp_tmr_size = 0U;
 
+/* singleton mutex */
+osMutexId singleton_mutex_id;
+osMutexDef(singleton_mutex);
+
 #if defined (__CC_ARM) && !defined (__MICROLIB)
  /* A memory space for arm standard library. */
  static uint32_t std_libspace[OS_TASK_CNT][96/4];
@@ -428,6 +433,9 @@
 #elif defined(TARGET_STM32F411RE)
 #define INITIAL_SP            (0x20020000UL)
 
+#elif defined(TARGET_STM32F207ZG)
+#define INITIAL_SP            (0x20020000UL)
+
 #elif defined(TARGET_STM32F410RB)
 #define INITIAL_SP            (0x20008000UL)
 
@@ -518,17 +526,44 @@
 #elif defined(TARGET_MCU_NORDIC_16K)
 #define INITIAL_SP            (0x20004000UL)
 
+#elif defined(TARGET_MCU_NRF52832)
+#define INITIAL_SP            (0x20010000UL)
+
 #elif (defined(TARGET_STM32F767ZI))
 #define INITIAL_SP            (0x20080000UL)
 
+#elif defined(TARGET_NUMAKER_PFM_NUC472)
+#   if defined(__CC_ARM)
+extern uint32_t          	    Image$$ARM_LIB_STACK$$ZI$$Limit[];
+extern uint32_t          	    Image$$ARM_LIB_STACK$$ZI$$Base[];
+#define INITIAL_SP              ((uint32_t) Image$$ARM_LIB_STACK$$ZI$$Limit)
+#define FINAL_SP                ((uint32_t) Image$$ARM_LIB_STACK$$ZI$$Base)
+#   elif defined(__GNUC__)
+extern uint32_t	                __StackTop[];
+extern uint32_t	                __StackLimit[];
+#define INITIAL_SP              ((uint32_t) __StackTop)
+#define FINAL_SP                ((uint32_t) __StackLimit)
+#   elif defined(__ICCARM__)
+#pragma section="CSTACK"
+#define INITIAL_SP              ((uint32_t) __section_end("CSTACK"))
+#define FINAL_SP                ((uint32_t) __section_begin("CSTACK"))
+#   else
+#error "no toolchain defined"
+#   endif
+
 #else
 #error "no target defined"
 
 #endif
 
 #ifdef __CC_ARM
+#if defined(TARGET_NUMAKER_PFM_NUC472)
+extern uint32_t          Image$$ARM_LIB_HEAP$$Base[];
+#define HEAP_START      ((uint32_t) Image$$ARM_LIB_HEAP$$Base)
+#else
 extern uint32_t          Image$$RW_IRAM1$$ZI$$Limit[];
 #define HEAP_START      (Image$$RW_IRAM1$$ZI$$Limit)
+#endif
 #elif defined(__GNUC__)
 extern uint32_t          __end__[];
 #define HEAP_START      (__end__)
@@ -538,6 +573,12 @@
 #endif
 
 void set_main_stack(void) {
+#if defined(TARGET_NUMAKER_PFM_NUC472)
+    // Scheduler stack: OS_MAINSTKSIZE words
+    // Main thread stack: Reserved stack size - OS_MAINSTKSIZE words
+    os_thread_def_main.stack_pointer = (uint32_t *) FINAL_SP;
+    os_thread_def_main.stacksize = (uint32_t) INITIAL_SP - (uint32_t) FINAL_SP - OS_MAINSTKSIZE * 4;
+#else
     uint32_t interrupt_stack_size = ((uint32_t)OS_MAINSTKSIZE * 4);
 #if defined(__ICCARM__)
 	/* For IAR heap is defined  .icf file */
@@ -556,6 +597,7 @@
 
     // Leave OS_MAINSTKSIZE words for the scheduler and interrupts
     os_thread_def_main.stacksize = main_stack_size;
+#endif
 }
 
 #if defined (__CC_ARM)
@@ -584,6 +626,7 @@
 
 void pre_main()
 {
+  singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
   $Super$$__cpp_initialize__aeabi_();
   main();
 }
@@ -593,25 +636,13 @@
 void * armcc_heap_base;
 void * armcc_heap_top;
 
-__asm void pre_main (void)
-{
-  IMPORT  __rt_lib_init
-  IMPORT  main
-  IMPORT  armcc_heap_base
-  IMPORT  armcc_heap_top
+int main(void);
 
-  LDR     R0,=armcc_heap_base
-  LDR     R1,=armcc_heap_top
-  LDR     R0,[R0]
-  LDR     R1,[R1]
-  /* Save link register (keep 8 byte alignment with dummy R4) */
-  PUSH    {R4, LR}
-  BL      __rt_lib_init
-  BL       main
-  /* Return to the thread destroy function.
-   */
-  POP     {R4, PC}
-  ALIGN
+void pre_main (void)
+{
+    singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
+    __rt_lib_init((unsigned)armcc_heap_base, (unsigned)armcc_heap_top);
+    main();
 }
 
 /* The single memory model is checking for stack collision at run time, verifing
@@ -676,6 +707,7 @@
 extern int main(int argc, char **argv);
 
 void pre_main(void) {
+    singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
     malloc_mutex_id = osMutexCreate(osMutex(malloc_mutex));
     env_mutex_id = osMutexCreate(osMutex(env_mutex));
     atexit(__libc_fini_array);
@@ -737,6 +769,7 @@
 static uint8_t low_level_init_needed;
 
 void pre_main(void) {
+    singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
     if (low_level_init_needed) {
         __iar_dynamic_initialization();
     }
--- a/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c	Mon Jul 25 14:12:24 2016 +0100
+++ b/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c	Wed Aug 10 16:09:20 2016 +0100
@@ -50,16 +50,17 @@
 #ifndef OS_TASKCNT
 #  if   defined(TARGET_LPC1768) || defined(TARGET_LPC2368)   || defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM) || defined(TARGET_LPC4330) || defined(TARGET_LPC4337) || defined(TARGET_LPC1347) || defined(TARGET_K64F) || defined(TARGET_STM32F401RE)\
    || defined(TARGET_STM32F410RB) || defined(TARGET_KL46Z) || defined(TARGET_KL43Z)  || defined(TARGET_STM32F407) || defined(TARGET_F407VG)  || defined(TARGET_STM32F303VC) || defined(TARGET_LPC1549) || defined(TARGET_LPC11U68) \
-   || defined(TARGET_STM32F411RE) || defined(TARGET_STM32F405RG) || defined(TARGET_K22F) || defined(TARGET_STM32F429ZI) || defined(TARGET_STM32F401VC) || defined(TARGET_MAX32610) || defined(TARGET_MAX32600) || defined(TARGET_TEENSY3_1) \
+   || defined(TARGET_STM32F411RE) || defined(TARGET_STM32F207ZG) || defined(TARGET_STM32F405RG) || defined(TARGET_K22F) || defined(TARGET_STM32F429ZI) || defined(TARGET_STM32F401VC) || defined(TARGET_MAX32610) || defined(TARGET_MAX32600) || defined(TARGET_TEENSY3_1) \
    || defined(TARGET_STM32L152RE) || defined(TARGET_STM32F446RE) || defined(TARGET_STM32F446VE) || defined(TARGET_STM32F446ZE) || defined(TARGET_STM32L432KC) || defined(TARGET_STM32L476VG) || defined(TARGET_STM32L476RG) || defined(TARGET_STM32F469NI) || defined(TARGET_STM32F746NG) || defined(TARGET_STM32F746ZG) || defined(TARGET_STM32L152RC) \
-   || defined(TARGET_EFM32GG_STK3700) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32PG_STK3401) || defined(TARGET_STM32F767ZI)
+   || defined(TARGET_EFM32GG_STK3700) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32PG_STK3401) || defined(TARGET_STM32F767ZI) \
+   || defined(TARGET_NUMAKER_PFM_NUC472)
 #    define OS_TASKCNT         14
 #  elif defined(TARGET_LPC11U24) || defined(TARGET_STM32F303RE) || defined(TARGET_STM32F303K8) || defined(TARGET_LPC11U35_401)  || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO) || defined(TARGET_LPC1114) \
    || defined(TARGET_LPC812)   || defined(TARGET_KL25Z)         || defined(TARGET_KL26Z)       || defined(TARGET_KL27Z)         || defined(TARGET_KL05Z)        || defined(TARGET_STM32F100RB)  || defined(TARGET_STM32F051R8) \
    || defined(TARGET_STM32F103RB) || defined(TARGET_LPC824) || defined(TARGET_STM32F302R8) || defined(TARGET_STM32F334R8) || defined(TARGET_STM32F334C8) \
    || defined(TARGET_STM32L031K6) || defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8) || defined(TARGET_STM32L073RZ) || defined(TARGET_STM32F072RB) || defined(TARGET_STM32F091RC) || defined(TARGET_NZ32_SC151) \
    || defined(TARGET_SSCI824)  || defined(TARGET_STM32F030R8) || defined(TARGET_STM32F070RB) \
-   || defined(TARGET_EFM32HG_STK3400) || defined(TARGET_MCU_NRF51822) || defined(TARGET_BEETLE)
+   || defined(TARGET_EFM32HG_STK3400) || defined(TARGET_MCU_NRF51822) || defined(TARGET_BEETLE) || defined(TARGET_MCU_NRF52832)
 #    define OS_TASKCNT         6
 #  else
 #    error "no target defined"
@@ -87,7 +88,8 @@
    || defined(TARGET_STM32F410RB) || defined(TARGET_KL46Z) || defined(TARGET_KL43Z) || defined(TARGET_STM32F407) || defined(TARGET_F407VG)  || defined(TARGET_STM32F303VC) || defined(TARGET_LPC1549) || defined(TARGET_LPC11U68) \
    || defined(TARGET_STM32F411RE) || defined(TARGET_STM32F405RG) || defined(TARGET_K22F) || defined(TARGET_STM32F429ZI) || defined(TARGET_STM32F401VC) || defined(TARGET_MAX32610) || defined(TARGET_MAX32600) || defined(TARGET_TEENSY3_1) \
    || defined(TARGET_STM32L152RE) || defined(TARGET_STM32F446RE) || defined(TARGET_STM32F446VE) || defined(TARGET_STM32F446ZE) || defined(TARGET_STM32L432KC) || defined(TARGET_STM32L476VG) || defined(TARGET_STM32L476RG) || defined(TARGET_STM32F469NI) || defined(TARGET_STM32F746NG) || defined(TARGET_STM32F746ZG) || defined(TARGET_STM32L152RC) \
-   ||defined(TARGET_EFM32GG_STK3700) || defined(TARGET_STM32F767ZI)
+   ||defined(TARGET_EFM32GG_STK3700) || defined(TARGET_STM32F767ZI) || defined(TARGET_STM32F207ZG) \
+   || defined(TARGET_NUMAKER_PFM_NUC472)
 #      define OS_MAINSTKSIZE    256
 #  elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11U35_401)  || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO)  || defined(TARGET_LPC1114) \
    || defined(TARGET_LPC812)   || defined(TARGET_KL25Z)         || defined(TARGET_KL26Z)        || defined(TARGET_KL27Z)        || defined(TARGET_KL05Z)        || defined(TARGET_STM32F100RB)  || defined(TARGET_STM32F051R8) \
@@ -99,7 +101,7 @@
    || defined(TARGET_STM32L031K6) || defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8) || defined(TARGET_STM32L073RZ) \
    || defined(TARGET_EFM32HG_STK3400) || defined(TARGET_BEETLE)
 #      define OS_MAINSTKSIZE    112
-#  elif defined(TARGET_MCU_NRF51822)
+#  elif defined(TARGET_MCU_NRF51822) ||  defined(TARGET_MCU_NRF52832)
 #      define OS_MAINSTKSIZE    512
 #  else
 #    error "no target defined"
@@ -186,7 +188,7 @@
 #  elif  defined(TARGET_STM32F100RB) || defined(TARGET_BEETLE)
 #    define OS_CLOCK       24000000
 
-#  elif defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM) || defined(TARGET_K64F) || defined(TARGET_K22F)
+#  elif defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM) || defined(TARGET_K64F)
 #    define OS_CLOCK       120000000
 
 #  elif defined(TARGET_LPC4330)
@@ -204,6 +206,9 @@
 #  elif defined(TARGET_STM32F411RE)
 #     define OS_CLOCK      100000000
 
+#  elif defined(TARGET_STM32F207ZG)
+#     define OS_CLOCK      120000000
+
 #  elif defined(TARGET_STM32F410RB)
 #     define OS_CLOCK      100000000
 
@@ -243,7 +248,7 @@
 #elif defined(TARGET_STM32F070RB)
 #    define OS_CLOCK       48000000
 
-#elif defined(TARGET_STM32L432KC) || defined(TARGET_STM32L476VG) || defined(TARGET_STM32L476RG)
+#elif defined(TARGET_STM32L432KC) || defined(TARGET_STM32L476VG) || defined(TARGET_STM32L476RG) || defined(TARGET_K22F)
 #    define OS_CLOCK       80000000
 
 #elif defined(TARGET_STM32F469NI)
@@ -259,6 +264,12 @@
 #elif defined(TARGET_MCU_NRF51822)
 #    define OS_CLOCK        32768
 
+#elif defined(TARGET_MCU_NRF52832)
+#    define OS_CLOCK        64000000
+
+#elif defined(TARGET_NUMAKER_PFM_NUC472)
+#    define OS_CLOCK       84000000
+
 #  else
 #    error "no target defined"
 #  endif
--- a/rtx/TARGET_CORTEX_M/cmsis_os.h	Mon Jul 25 14:12:24 2016 +0100
+++ b/rtx/TARGET_CORTEX_M/cmsis_os.h	Wed Aug 10 16:09:20 2016 +0100
@@ -83,10 +83,10 @@
 /* If os timers macro is set to 0, there's no timer thread created, therefore
  * main thread has tid 0x01  
  */
-#if (OS_TIMERS != 0)
+#if defined(OS_TIMERS) && (OS_TIMERS == 0)
+#define MAIN_THREAD_ID 0x01
+#else
 #define MAIN_THREAD_ID 0x02
-#else
-#define MAIN_THREAD_ID 0x01
 #endif
 #endif
 
--- a/rtx/TARGET_CORTEX_M/rt_HAL_CM.h	Mon Jul 25 14:12:24 2016 +0100
+++ b/rtx/TARGET_CORTEX_M/rt_HAL_CM.h	Wed Aug 10 16:09:20 2016 +0100
@@ -47,6 +47,11 @@
  #undef  __USE_EXCLUSIVE_ACCESS
 #endif
 
+/* Supress __ldrex and __strex deprecated warnings - "#3731-D: intrinsic is deprecated" */
+#ifdef __USE_EXCLUSIVE_ACCESS
+#pragma diag_suppress 3731
+#endif
+
 #ifndef __CMSIS_GENERIC
 #define __DMB() do {\
                    __schedule_barrier();\