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

Dependents:   denki-yohou_b TestY201 Network-RTOS NTPClient_HelloWorld ... more

Deprecated

This is the mbed 2 rtos library. mbed OS 5 integrates the mbed library with mbed-rtos. With this, we have provided thread safety for all mbed APIs. If you'd like to learn about using mbed OS 5, please see the docs.

Files at this revision

API Documentation at this revision

Comitter:
Kojto
Date:
Wed Aug 10 16:09:20 2016 +0100
Parent:
118:6635230e06ba
Child:
120: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();\