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:
c1728p9
Date:
Mon Nov 14 17:14:42 2016 -0600
Parent:
122:b744dfee1cf2
Child:
124:66949d9d57c1
Commit message:
Configure RTOS to behave as it did before 5.0

Changed in this revision

rtos/Mail.h Show annotated file Show diff for this revision Revisions of this file
rtos/MemoryPool.h Show annotated file Show diff for this revision Revisions of this file
rtos/Mutex.cpp Show annotated file Show diff for this revision Revisions of this file
rtos/Mutex.h Show annotated file Show diff for this revision Revisions of this file
rtos/Queue.h Show annotated file Show diff for this revision Revisions of this file
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.cpp 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
rtos/rtos.h Show annotated file Show diff for this revision Revisions of this file
rtos/rtos_idle.c Show annotated file Show diff for this revision Revisions of this file
rtos/rtos_idle.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_ARM7/RTX_CM_lib.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_ARM7/RTX_Conf_CM.c 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/RTX_Conf_CA.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/cmsis_os.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_CMSIS.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_TypeDef.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/HAL_CM.c 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/RTX_Config.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/HAL_CM4.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/HAL_CM4.S 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_CMSIS.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/rt_Event.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
rtx/TARGET_CORTEX_M/rt_List.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/rt_Mailbox.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/rt_MemBox.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/rt_Memory.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/rt_Mutex.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/rt_OsEventObserver.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/rt_Robin.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/rt_Semaphore.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/rt_System.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/rt_System.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/rt_Task.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/rt_Task.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/rt_Time.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/rt_Timer.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_M/rt_TypeDef.h Show annotated file Show diff for this revision Revisions of this file
--- a/rtos/Mail.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/Mail.h	Mon Nov 14 17:14:42 2016 -0600
@@ -28,6 +28,8 @@
 #include "cmsis_os.h"
 
 namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
 
 /** The Mail class allow to control, send, receive, or wait for mail.
  A mail is a memory block that is send to a thread or interrupt service routine.
@@ -107,3 +109,5 @@
 
 #endif
 
+
+/** @}*/
--- a/rtos/MemoryPool.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/MemoryPool.h	Mon Nov 14 17:14:42 2016 -0600
@@ -28,6 +28,8 @@
 #include "cmsis_os.h"
 
 namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
 
 /** Define and manage fixed-size memory pools of objects of a given type.
   @tparam  T         data type of a single object (element).
@@ -80,3 +82,5 @@
 
 }
 #endif
+
+/** @}*/
--- a/rtos/Mutex.cpp	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/Mutex.cpp	Mon Nov 14 17:14:42 2016 -0600
@@ -19,10 +19,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "Mutex.h"
+#include "rtos/Mutex.h"
 
 #include <string.h>
-#include "mbed_error.h"
+#include "platform/mbed_error.h"
 
 namespace rtos {
 
--- a/rtos/Mutex.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/Mutex.h	Mon Nov 14 17:14:42 2016 -0600
@@ -26,6 +26,8 @@
 #include "cmsis_os.h"
 
 namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
 
 /** The Mutex class is used to synchronise the execution of threads.
  This is for example used to protect access to a shared resource.
@@ -67,3 +69,5 @@
 
 }
 #endif
+
+/** @}*/
--- a/rtos/Queue.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/Queue.h	Mon Nov 14 17:14:42 2016 -0600
@@ -26,9 +26,11 @@
 #include <string.h>
 
 #include "cmsis_os.h"
-#include "mbed_error.h"
+#include "platform/mbed_error.h"
 
 namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
 
 /** The Queue class allow to control, send, receive, or wait for messages.
  A message can be a integer or pointer value  to a certain type T that is send
@@ -79,3 +81,5 @@
 
 }
 #endif
+
+/** @}*/
--- a/rtos/RtosTimer.cpp	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/RtosTimer.cpp	Mon Nov 14 17:14:42 2016 -0600
@@ -19,13 +19,13 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "RtosTimer.h"
+#include "rtos/RtosTimer.h"
 
 #include <string.h>
 
 #include "mbed.h"
 #include "cmsis_os.h"
-#include "mbed_error.h"
+#include "platform/mbed_error.h"
 
 namespace rtos {
 
--- a/rtos/RtosTimer.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/RtosTimer.h	Mon Nov 14 17:14:42 2016 -0600
@@ -24,10 +24,12 @@
 
 #include <stdint.h>
 #include "cmsis_os.h"
-#include "Callback.h"
-#include "toolchain.h"
+#include "platform/Callback.h"
+#include "platform/toolchain.h"
 
 namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
 
 /** The RtosTimer class allow creating and and controlling of timer functions in the system.
  A timer function is called when a time period expires whereby both on-shot and
@@ -47,7 +49,7 @@
     MBED_DEPRECATED_SINCE("mbed-os-5.1",
         "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);
+        constructor(mbed::callback((void (*)(void *))func, argument), type);
     }
     
     /** Create timer.
@@ -62,10 +64,16 @@
       @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)
+      @deprecated
+          The RtosTimer constructor does not support cv-qualifiers. Replaced by
+          RtosTimer(callback(obj, method), os_timer_type).
     */
     template <typename T, typename M>
+    MBED_DEPRECATED_SINCE("mbed-os-5.1",
+        "The RtosTimer constructor does not support cv-qualifiers. Replaced by "
+        "RtosTimer(callback(obj, method), os_timer_type).")
     RtosTimer(T *obj, M method, os_timer_type type=osTimerPeriodic) {
-        constructor(mbed::Callback<void()>(obj, method), type);
+        constructor(mbed::callback(obj, method), type);
     }
 
     /** Stop the timer.
@@ -99,3 +107,5 @@
 }
 
 #endif
+
+/** @}*/
--- a/rtos/Semaphore.cpp	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/Semaphore.cpp	Mon Nov 14 17:14:42 2016 -0600
@@ -19,7 +19,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "Semaphore.h"
+#include "rtos/Semaphore.h"
 
 #include <string.h>
 
--- a/rtos/Semaphore.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/Semaphore.h	Mon Nov 14 17:14:42 2016 -0600
@@ -26,6 +26,8 @@
 #include "cmsis_os.h"
 
 namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
 
 /** The Semaphore class is used to manage and protect access to a set of shared resources. */
 class Semaphore {
@@ -58,3 +60,5 @@
 
 }
 #endif
+
+/** @}*/
--- a/rtos/Thread.cpp	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/Thread.cpp	Mon Nov 14 17:14:42 2016 -0600
@@ -19,10 +19,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "Thread.h"
+#include "rtos/Thread.h"
 
 #include "mbed.h"
-#include "rtos_idle.h"
+#include "rtos/rtos_idle.h"
 
 // rt_tid2ptcb is an internal function which we exposed to get TCB for thread id
 #undef NULL  //Workaround for conflicting macros in rt_TypeDef.h and stdio.h
@@ -30,6 +30,15 @@
 
 extern "C" P_TCB rt_tid2ptcb(osThreadId thread_id);
 
+
+static void (*terminate_hook)(osThreadId id) = 0;
+extern "C" void thread_terminate_hook(osThreadId id)
+{
+    if (terminate_hook != (void (*)(osThreadId))NULL) {
+        terminate_hook(id);
+    }
+}
+
 namespace rtos {
 
 void Thread::constructor(osPriority priority,
@@ -74,10 +83,7 @@
     _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) {
-            _mutex.unlock();
-            return osErrorNoMemory;
-        }
+        MBED_ASSERT(_thread_def.stack_pointer != NULL);
     }
 
     //Fill the stack with a magic word for maximum usage checking
@@ -88,8 +94,12 @@
     _task = task;
     _tid = osThreadCreate(&_thread_def, this);
     if (_tid == NULL) {
-        if (_dynamic_stack) delete[] (_thread_def.stack_pointer);
+        if (_dynamic_stack) {
+            delete[] (_thread_def.stack_pointer);
+            _thread_def.stack_pointer = (uint32_t*)NULL;
+        }
         _mutex.unlock();
+        _join_sem.release();
         return osErrorResource;
     }
 
@@ -101,11 +111,14 @@
     osStatus ret;
     _mutex.lock();
 
-    ret = osThreadTerminate(_tid);
+    // Set the Thread's tid to NULL and
+    // release the semaphore before terminating
+    // since this thread could be terminating itself
+    osThreadId local_id = _tid;
+    _join_sem.release();
     _tid = (osThreadId)NULL;
 
-    // Wake threads joining the terminated thread
-    _join_sem.release();
+    ret = osThreadTerminate(local_id);
 
     _mutex.unlock();
     return ret;
@@ -116,6 +129,14 @@
     if (ret < 0) {
         return osErrorOS;
     }
+
+    // The semaphore has been released so this thread is being
+    // terminated or has been terminated. Once the mutex has
+    // been locked it is ensured that the thread is deleted.
+    _mutex.lock();
+    MBED_ASSERT(NULL == _tid);
+    _mutex.unlock();
+
     // Release sem so any other threads joining this thread wake up
     _join_sem.release();
     return osOK;
@@ -325,12 +346,17 @@
     rtos_attach_idle_hook(fptr);
 }
 
+void Thread::attach_terminate_hook(void (*fptr)(osThreadId id)) {
+    terminate_hook = fptr;
+}
+
 Thread::~Thread() {
     // terminate is thread safe
     terminate();
 #ifdef __MBED_CMSIS_RTOS_CM
     if (_dynamic_stack) {
         delete[] (_thread_def.stack_pointer);
+        _thread_def.stack_pointer = (uint32_t*)NULL;
     }
 #endif
 }
--- a/rtos/Thread.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/Thread.h	Mon Nov 14 17:14:42 2016 -0600
@@ -24,14 +24,43 @@
 
 #include <stdint.h>
 #include "cmsis_os.h"
-#include "Callback.h"
-#include "toolchain.h"
-#include "Semaphore.h"
-#include "Mutex.h"
+#include "platform/Callback.h"
+#include "platform/toolchain.h"
+#include "rtos/Semaphore.h"
+#include "rtos/Mutex.h"
 
 namespace rtos {
+/** \addtogroup rtos */
+/** @{*/
 
-/** The Thread class allow defining, creating, and controlling thread functions in the system. */
+/** The Thread class allow defining, creating, and controlling thread functions in the system.
+ *
+ *  Example:
+ *  @code
+ *  #include "mbed.h"
+ *  #include "rtos.h"
+ *
+ *  Thread thread;
+ *  DigitalOut led1(LED1);
+ *  volatile bool running = true;
+ *
+ *  // Blink function toggles the led in a long running loop
+ *  void blink(DigitalOut *led) {
+ *      while (running) {
+ *          *led = !*led;
+ *          Thread::wait(1000);
+ *      }
+ *  }
+ *
+ *  // Spawns a thread to run blink for 5 seconds
+ *  int main() {
+ *      thread.start(led1, blink);
+ *      Thread::wait(5000);
+ *      running = false;
+ *      thread.join();
+ *  }
+ *  @endcode
+ */
 class Thread {
 public:
     /** Allocate a new thread without starting execution
@@ -52,15 +81,20 @@
       @param   stack_size      stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
       @param   stack_pointer  pointer to the stack area to be used by this thread (default: NULL).
       @deprecated
-        Thread-spawning constructors hide errors and may lead to complex
-        program state when a thread is declared.
+        Thread-spawning constructors hide errors. Replaced by thread.start(task).
+
+        @code
+        Thread thread(priority, stack_size, stack_pointer);
 
-        The explicit Thread::start member function should be used to spawn
-        a thread.
+        osStatus status = thread.start(task);
+        if (status != osOK) {
+            error("oh no!");
+        }
+        @endcode
     */
     MBED_DEPRECATED_SINCE("mbed-os-5.1",
-        "Thread-spawning constructors hide errors and may lead to complex "
-        "program state when a thread is declared")
+        "Thread-spawning constructors hide errors. "
+        "Replaced by thread.start(task).")
     Thread(mbed::Callback<void()> task,
            osPriority priority=osPriorityNormal,
            uint32_t stack_size=DEFAULT_STACK_SIZE,
@@ -76,21 +110,26 @@
       @param   stack_size      stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
       @param   stack_pointer  pointer to the stack area to be used by this thread (default: NULL).
       @deprecated
-        Thread-spawning constructors hide errors and may lead to complex
-        program state when a thread is declared.
+        Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
+
+        @code
+        Thread thread(priority, stack_size, stack_pointer);
 
-        The explicit Thread::start member function should be used to spawn
-        a thread.
+        osStatus status = thread.start(callback(task, argument));
+        if (status != osOK) {
+            error("oh no!");
+        }
+        @endcode
     */
     template <typename T>
     MBED_DEPRECATED_SINCE("mbed-os-5.1",
-        "Thread-spawning constructors hide errors and may lead to complex "
-        "program state when a thread is declared")
-    Thread(T *obj, void (T::*method)(),
+        "Thread-spawning constructors hide errors. "
+        "Replaced by thread.start(callback(task, argument)).")
+    Thread(T *argument, void (T::*task)(),
            osPriority priority=osPriorityNormal,
            uint32_t stack_size=DEFAULT_STACK_SIZE,
            unsigned char *stack_pointer=NULL) {
-        constructor(mbed::Callback<void()>(obj, method),
+        constructor(mbed::callback(task, argument),
                     priority, stack_size, stack_pointer);
     }
 
@@ -102,21 +141,26 @@
       @param   stack_size      stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
       @param   stack_pointer  pointer to the stack area to be used by this thread (default: NULL).
       @deprecated
-        Thread-spawning constructors hide errors and may lead to complex
-        program state when a thread is declared.
+        Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
+
+        @code
+        Thread thread(priority, stack_size, stack_pointer);
 
-        The explicit Thread::start member function should be used to spawn
-        a thread.
+        osStatus status = thread.start(callback(task, argument));
+        if (status != osOK) {
+            error("oh no!");
+        }
+        @endcode
     */
     template <typename T>
     MBED_DEPRECATED_SINCE("mbed-os-5.1",
-        "Thread-spawning constructors hide errors and may lead to complex "
-        "program state when a thread is declared")
-    Thread(T *obj, void (*method)(T *),
+        "Thread-spawning constructors hide errors. "
+        "Replaced by thread.start(callback(task, argument)).")
+    Thread(T *argument, void (*task)(T *),
            osPriority priority=osPriorityNormal,
            uint32_t stack_size=DEFAULT_STACK_SIZE,
            unsigned char *stack_pointer=NULL) {
-        constructor(mbed::Callback<void()>(obj, method),
+        constructor(mbed::callback(task, argument),
                     priority, stack_size, stack_pointer);
     }
 
@@ -128,20 +172,25 @@
       @param   stack_size      stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
       @param   stack_pointer  pointer to the stack area to be used by this thread (default: NULL).
       @deprecated
-        Thread-spawning constructors hide errors and may lead to complex
-        program state when a thread is declared.
+        Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
+
+        @code
+        Thread thread(priority, stack_size, stack_pointer);
 
-        The explicit Thread::start member function should be used to spawn
-        a thread.
+        osStatus status = thread.start(callback(task, argument));
+        if (status != osOK) {
+            error("oh no!");
+        }
+        @endcode
     */
     MBED_DEPRECATED_SINCE("mbed-os-5.1",
-        "Thread-spawning constructors hide errors and may lead to complex "
-        "program state when a thread is declared")
+        "Thread-spawning constructors hide errors. "
+        "Replaced by thread.start(callback(task, argument)).")
     Thread(void (*task)(void const *argument), void *argument=NULL,
            osPriority priority=osPriorityNormal,
            uint32_t stack_size=DEFAULT_STACK_SIZE,
            unsigned char *stack_pointer=NULL) {
-        constructor(mbed::Callback<void()>(argument, (void (*)(void *))task),
+        constructor(mbed::callback((void (*)(void *))task, argument),
                     priority, stack_size, stack_pointer);
     }
 
@@ -155,10 +204,15 @@
       @param   obj            argument to task
       @param   method         function to be executed by this thread.
       @return  status code that indicates the execution status of the function.
+      @deprecated
+          The start function does not support cv-qualifiers. Replaced by start(callback(obj, method)).
     */
     template <typename T, typename M>
+    MBED_DEPRECATED_SINCE("mbed-os-5.1",
+        "The start function does not support cv-qualifiers. "
+        "Replaced by thread.start(callback(obj, method)).")
     osStatus start(T *obj, M method) {
-        return start(mbed::Callback<void()>(obj, method));
+        return start(mbed::callback(obj, method));
     }
 
     /** Wait for thread to terminate
@@ -268,6 +322,11 @@
     */
     static void attach_idle_hook(void (*fptr)(void));
 
+    /** Attach a function to be called when a task is killed
+      @param   fptr  pointer to the function to be called
+    */
+    static void attach_terminate_hook(void (*fptr)(osThreadId id));
+
     virtual ~Thread();
 
 private:
@@ -292,3 +351,5 @@
 
 }
 #endif
+
+/** @}*/
--- a/rtos/rtos.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/rtos.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /* mbed Microcontroller Library
  * Copyright (c) 2006-2012 ARM Limited
  *
@@ -22,13 +25,13 @@
 #ifndef RTOS_H
 #define RTOS_H
 
-#include "Thread.h"
-#include "Mutex.h"
-#include "RtosTimer.h"
-#include "Semaphore.h"
-#include "Mail.h"
-#include "MemoryPool.h"
-#include "Queue.h"
+#include "rtos/Thread.h"
+#include "rtos/Mutex.h"
+#include "rtos/RtosTimer.h"
+#include "rtos/Semaphore.h"
+#include "rtos/Mail.h"
+#include "rtos/MemoryPool.h"
+#include "rtos/Queue.h"
 
 using namespace rtos;
 
@@ -37,8 +40,10 @@
 */
 #include "mbed.h"
 
-#if (MBED_LIBRARY_VERSION < 124)
-#error "This version of RTOS requires mbed library version > 123"
+#if (MBED_LIBRARY_VERSION < 122)
+#error "This version of RTOS requires mbed library version > 121"
 #endif
 
 #endif
+
+/** @}*/
--- a/rtos/rtos_idle.c	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/rtos_idle.c	Mon Nov 14 17:14:42 2016 -0600
@@ -20,7 +20,7 @@
  * SOFTWARE.
  */
 
-#include "rtos_idle.h"
+#include "rtos/rtos_idle.h"
 
 static void default_idle_hook(void)
 {
--- a/rtos/rtos_idle.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtos/rtos_idle.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /* mbed Microcontroller Library
  * Copyright (c) 2006-2012 ARM Limited
  *
@@ -35,3 +38,5 @@
 #endif
 
 #endif
+
+/** @}*/
--- a/rtx/TARGET_ARM7/RTX_CM_lib.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_ARM7/RTX_CM_lib.h	Mon Nov 14 17:14:42 2016 -0600
@@ -198,15 +198,8 @@
 extern void pre_main (void);
 osThreadDef_t os_thread_def_main = {(os_pthread)pre_main, osPriorityNormal, 0, NULL};
 
-// This define should be probably moved to the CMSIS layer
-
-#if defined(TARGET_LPC2460)
-extern unsigned char     __usr_stack_top__[];
-#define INITIAL_SP            (__usr_stack_top__)
-
-#else
-#error "no target defined"
-
+#ifndef INITIAL_SP
+ #error "no target defined"
 #endif
 
 #ifdef __CC_ARM
--- a/rtx/TARGET_ARM7/RTX_Conf_CM.c	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_ARM7/RTX_Conf_CM.c	Mon Nov 14 17:14:42 2016 -0600
@@ -39,6 +39,9 @@
  *      RTX User configuration part BEGIN
  *---------------------------------------------------------------------------*/
 
+// Include per-target RTX config file
+#include "mbed_rtx.h"
+
 //-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
 //
 // <h>Thread Configuration
@@ -49,20 +52,12 @@
 //       counting "main", but not counting "osTimerThread"
 //   <i> Default: 6
 #ifndef OS_TASKCNT
-#  if  defined(TARGET_LPC2368) || defined(TARGET_LPC2460)
-#    define OS_TASKCNT         14
-#  else
-#    error "no target defined"
-#  endif
+ #error "no target defined"
 #endif
 
 //   <o>Scheduler (+ interrupts) stack size [bytes] <64-4096:8><#/4>
 #ifndef OS_SCHEDULERSTKSIZE
-#  if  defined(TARGET_LPC2368)  ||  defined(TARGET_LPC2460)
-#      define OS_SCHEDULERSTKSIZE    (136*2)
-#  else
-#    error "no target defined"
-#  endif
+ #error "no target defined"
 #endif
 
 //   <o>Idle stack size [bytes] <64-4096:8><#/4>
@@ -101,15 +96,7 @@
 //   <i> Defines the timer clock value.
 //   <i> Default: 6000000  (6MHz)
 #ifndef OS_CLOCK
-#  if defined(TARGET_LPC2368)
-#    define OS_CLOCK       96000000
-
-#  elif defined(TARGET_LPC2460)
-#    define OS_CLOCK       72000000
-
-#  else
-#    error "no target defined"
-#  endif
+ #error "no target defined"
 #endif
 
 //   <o>Timer tick value [us] <1-1000000>
--- a/rtx/TARGET_CORTEX_A/RTX_CM_lib.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_A/RTX_CM_lib.h	Mon Nov 14 17:14:42 2016 -0600
@@ -51,7 +51,7 @@
 #define _declare_box(pool,size,cnt)  uint32_t pool[(((size)+3)/4)*(cnt) + 3]
 #define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2]
 
-#define OS_TCB_SIZE     60
+#define OS_TCB_SIZE     64
 #define OS_TMR_SIZE     8
 
 #if defined (__CC_ARM) && !defined (__MICROLIB)
--- a/rtx/TARGET_CORTEX_A/RTX_Conf_CA.c	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_A/RTX_Conf_CA.c	Mon Nov 14 17:14:42 2016 -0600
@@ -38,10 +38,8 @@
  *      RTX User configuration part BEGIN
  *---------------------------------------------------------------------------*/
 
-#if defined(MBED_RTOS_SINGLE_THREAD)
-#define OS_TASKCNT  1
-#define OS_TIMERS   0
-#endif
+// Include per-target RTX config file
+#include "mbed_rtx.h"
 
 //-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
 //
@@ -122,11 +120,7 @@
 //   <i> Defines the timer clock value.
 //   <i> Default: 12000000  (12MHz)
 #ifndef OS_CLOCK
-#  if defined(TARGET_RZ_A1H) || defined(TARGET_VK_RZ_A1H)
- #define OS_CLOCK       12000000
-#  else
-#    error "no target defined"
-#  endif
+ #error "no target defined"
 #endif
 
 //   <o>Timer tick value [us] <1-1000000>
@@ -320,6 +314,14 @@
   for (;;);
 }
 
+/*----------------------------------------------------------------------------
+ *      RTX Hooks
+ *---------------------------------------------------------------------------*/
+extern void thread_terminate_hook(osThreadId id);
+
+void sysThreadTerminate(osThreadId id) {
+    thread_terminate_hook(id);
+}
 
 /*----------------------------------------------------------------------------
  *      RTX Configuration Functions
--- a/rtx/TARGET_CORTEX_A/cmsis_os.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_A/cmsis_os.h	Mon Nov 14 17:14:42 2016 -0600
@@ -160,6 +160,7 @@
 #define osFeature_Semaphore    65535   ///< maximum count for \ref osSemaphoreCreate function
 #define osFeature_Wait         0       ///< osWait function: 1=available, 0=not available
 #define osFeature_SysTick      1       ///< osKernelSysTick functions: 1=available, 0=not available
+#define osFeature_ThreadEnum   1       ///< Thread enumeration available
 
 #if defined (__CC_ARM)
 #define os_InRegs __value_in_regs      // Compiler specific: force struct in registers
@@ -223,6 +224,16 @@
   osTimerPeriodic         =     1        ///< repeating timer
 } os_timer_type;
 
+typedef enum {
+  osThreadInfoState,
+  osThreadInfoStackSize,
+  osThreadInfoStackMax,
+  osThreadInfoEntry,
+  osThreadInfoArg,
+
+  osThreadInfo_reserved   =  0x7FFFFFFF  ///< prevent from enum down-size compiler optimization.
+} osThreadInfo;
+
 /// Entry point of a thread.
 /// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS.
 typedef void (*os_pthread) (void const *argument);
@@ -261,6 +272,8 @@
 /// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS.
 typedef struct os_mailQ_cb *osMailQId;
 
+/// Thread enumeration ID identifies the enumeration (pointer to a thread enumeration control block).
+typedef uint32_t *osThreadEnumId;
 
 /// Thread Definition structure contains startup information of a thread.
 /// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS.
@@ -448,6 +461,13 @@
 uint8_t osThreadGetState (osThreadId thread_id);
 #endif
 
+/// Get into from an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     info          information to read.
+/// \return current state of the thread function.
+/// \return requested info that includes the status code.
+os_InRegs osEvent _osThreadGetInfo(osThreadId thread_id, osThreadInfo info);
+
 //  ==== Generic Wait Functions ====
 
 /// Wait for Timeout (Time Delay).
@@ -823,6 +843,26 @@
 #endif  // Mail Queues available
 
 
+//  ==== Thread Enumeration Functions ====
+
+#if (defined (osFeature_ThreadEnum)  &&  (osFeature_ThreadEnum != 0))     // Thread enumeration available
+
+/// Start a thread enumeration.
+/// \return an enumeration ID or NULL on error.
+osThreadEnumId _osThreadsEnumStart(void);
+
+/// Get the next task ID in the enumeration.
+/// \return a thread ID or NULL on if the end of the enumeration has been reached.
+osThreadId _osThreadEnumNext(osThreadEnumId enum_id);
+
+/// Free the enumeration structure.
+/// \param[in]     enum_id       pointer to the enumeration ID that was obtained with \ref _osThreadsEnumStart.
+/// \return status code that indicates the execution status of the function.
+osStatus _osThreadEnumFree(osThreadEnumId enum_id);
+
+#endif  // Thread Enumeration available
+
+
 //  ==== RTX Extensions ====
 
 /// os_suspend: http://www.keil.com/support/man/docs/rlarm/rlarm_os_suspend.htm
--- a/rtx/TARGET_CORTEX_A/rt_CMSIS.c	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_A/rt_CMSIS.c	Mon Nov 14 17:14:42 2016 -0600
@@ -479,6 +479,10 @@
 
 extern U32 IRQNestLevel; /* Indicates whether inside an ISR, and the depth of nesting.  0 = not in ISR. */
 
+// Thread creation and destruction
+osMutexDef(osThreadMutex);
+osMutexId osMutexId_osThreadMutex;
+void sysThreadTerminate(osThreadId id);
 
 // ==== Helper Functions ====
 
@@ -539,6 +543,11 @@
 }
 
 static __inline char __exceptional_mode(void) {
+    // Interrupts disabled
+    if (__get_CPSR() & 0x80) {
+        return 1;
+    }
+
     switch(__get_mode()) {
         case MODE_USR:
         case MODE_SYS:
@@ -596,6 +605,8 @@
     // Create OS Timers resources (Message Queue & Thread)
     osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL);
     osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL);
+    // Initialize thread mutex
+    osMutexId_osThreadMutex = osMutexCreate(osMutex(osThreadMutex));
   }
 
   sysThreadError(osOK);
@@ -708,6 +719,7 @@
 SVC_0_1(svcThreadYield,       osStatus,                                      RET_osStatus)
 SVC_2_1(svcThreadSetPriority, osStatus,         osThreadId,      osPriority, RET_osStatus)
 SVC_1_1(svcThreadGetPriority, osPriority,       osThreadId,                  RET_osPriority)
+SVC_2_3(svcThreadGetInfo,    os_InRegs osEvent, osThreadId,    osThreadInfo, RET_osEvent)
 
 // Thread Service Calls
 
@@ -846,6 +858,80 @@
   return (osPriority)(ptcb->prio - 1 + osPriorityIdle);
 }
 
+/// Get info from an active thread
+os_InRegs osEvent_type svcThreadGetInfo (osThreadId thread_id, osThreadInfo info) {
+  P_TCB ptcb;
+  osEvent ret;
+  ret.status = osOK;
+
+  ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
+  if (ptcb == NULL) {
+    ret.status = osErrorValue;
+#if defined (__GNUC__) && defined (__ARM_PCS_VFP)
+    osEvent_ret_status;
+    return;
+#else
+    return osEvent_ret_status;
+#endif
+  }
+
+  if (osThreadInfoStackSize == info) {
+    uint32_t size;
+    size = ptcb->priv_stack;
+    if (0 == size) {
+      // This is an OS task - always a fixed size
+      size = os_stackinfo & 0x3FFFF;
+    }
+    ret.value.v = size;
+#if defined (__GNUC__) && defined (__ARM_PCS_VFP)
+    osEvent_ret_value;
+    return;
+#else
+    return osEvent_ret_value;
+#endif
+  }
+
+  if (osThreadInfoStackMax == info) {
+    // Cortex-A RTX does not have stack init so
+    // the maximum stack usage cannot be obtained.
+    ret.status = osErrorResource;
+#if defined (__GNUC__) && defined (__ARM_PCS_VFP)
+    osEvent_ret_status;
+    return;
+#else
+    return osEvent_ret_status;
+#endif
+  }
+
+  if (osThreadInfoEntry == info) {
+    ret.value.p = (void*)ptcb->ptask;
+#if defined (__GNUC__) && defined (__ARM_PCS_VFP)
+    osEvent_ret_value;
+    return;
+#else
+    return osEvent_ret_value;
+#endif
+  }
+
+  if (osThreadInfoArg == info) {
+    ret.value.p = (void*)ptcb->argv;
+#if defined (__GNUC__) && defined (__ARM_PCS_VFP)
+    osEvent_ret_value;
+    return;
+#else
+    return osEvent_ret_value;
+#endif
+  }
+
+  // Unsupported option so return error
+  ret.status = osErrorParameter;
+#if defined (__GNUC__) && defined (__ARM_PCS_VFP)
+    osEvent_ret_status;
+    return;
+#else
+    return osEvent_ret_status;
+#endif
+}
 
 // Thread Public API
 
@@ -856,7 +942,12 @@
     // Privileged and not running
     return   svcThreadCreate(thread_def, argument);
   } else {
-    return __svcThreadCreate(thread_def, argument);
+    osThreadId id;
+    osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+    // Thread mutex must be held when a thread is created or terminated
+    id = __svcThreadCreate(thread_def, argument);
+    osMutexRelease(osMutexId_osThreadMutex);
+    return id;
   }
 }
 
@@ -868,8 +959,14 @@
 
 /// Terminate execution of a thread and remove it from ActiveThreads
 osStatus osThreadTerminate (osThreadId thread_id) {
+  osStatus status;
   if (__exceptional_mode()) return osErrorISR;     // Not allowed in ISR
-  return __svcThreadTerminate(thread_id);
+  osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+  sysThreadTerminate(thread_id);
+  // Thread mutex must be held when a thread is created or terminated
+  status = __svcThreadTerminate(thread_id);
+  osMutexRelease(osMutexId_osThreadMutex);
+  return status;
 }
 
 /// Pass control to next thread that is in state READY
@@ -893,7 +990,14 @@
 /// INTERNAL - Not Public
 /// Auto Terminate Thread on exit (used implicitly when thread exists)
 __NO_RETURN void osThreadExit (void) {
-  __svcThreadTerminate(__svcThreadGetId());
+  osThreadId id;
+  // Thread mutex must be held when a thread is created or terminated
+  // Note - the mutex will be released automatically by the os when
+  //        the thread is terminated
+  osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+  id = __svcThreadGetId();
+  sysThreadTerminate(id);
+  __svcThreadTerminate(id);
   for (;;);                                     // Should never come here
 }
 
@@ -911,6 +1015,48 @@
 }
 #endif
 
+/// Get the requested info from the specified active thread
+os_InRegs osEvent _osThreadGetInfo(osThreadId thread_id, osThreadInfo info) {
+  osEvent ret;
+  if (__exceptional_mode()) {
+    ret.status = osErrorISR;
+    return ret;                                 // Not allowed in ISR
+  }
+  return __svcThreadGetInfo(thread_id, info);
+}
+
+osThreadEnumId _osThreadsEnumStart() {
+  static uint32_t thread_enum_index;
+  osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+  thread_enum_index = 0;
+  return &thread_enum_index;
+}
+
+osThreadId _osThreadEnumNext(osThreadEnumId enum_id) {
+  uint32_t i;
+  osThreadId id = NULL;
+  uint32_t *index = (uint32_t*)enum_id;
+  for (i = *index; i < os_maxtaskrun; i++) {
+    if (os_active_TCB[i] != NULL) {
+      id = (osThreadId)os_active_TCB[i];
+      break;
+    }
+  }
+  if (i == os_maxtaskrun) {
+    // Include the idle task at the end of the enumeration
+    id = &os_idle_TCB;
+  }
+  *index = i + 1;
+  return id;
+}
+
+osStatus _osThreadEnumFree(osThreadEnumId enum_id) {
+  uint32_t *index = (uint32_t*)enum_id;
+  *index = 0;
+  osMutexRelease(osMutexId_osThreadMutex);
+  return osOK;
+}
+
 // ==== Generic Wait Functions ====
 
 // Generic Wait Service Calls declarations
--- a/rtx/TARGET_CORTEX_A/rt_TypeDef.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_A/rt_TypeDef.h	Mon Nov 14 17:14:42 2016 -0600
@@ -85,6 +85,7 @@
 
   /* Task entry point used for uVision debugger                              */
   FUNCP  ptask;                   /* Task entry address                      */
+  void   *argv;                   /* Task argument                           */
 } *P_TCB;
 #define TCB_TID          3        /* 'task id' offset                        */
 #define TCB_STACKF      37        /* 'stack_frame' offset                    */
--- a/rtx/TARGET_CORTEX_M/HAL_CM.c	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/HAL_CM.c	Mon Nov 14 17:14:42 2016 -0600
@@ -90,6 +90,32 @@
   /* Task entry point. */
   p_TCB->ptask = task_body;
 
+
+#ifdef __MBED_CMSIS_RTOS_CM
+  /* Set a magic word for checking of stack overflow.
+   For the main thread (ID: MAIN_THREAD_ID) the stack is in a memory area shared with the
+   heap, therefore the last word of the stack is a moving target.
+   We want to do stack/heap collision detection instead.
+   Similar applies to stack filling for the magic pattern.
+  */
+  if (p_TCB->task_id != MAIN_THREAD_ID) {
+    p_TCB->stack[0] = MAGIC_WORD;
+
+    /* Initialize stack with magic pattern. */
+    if (os_stackinfo & 0x10000000U) {
+      if (size > (16U+1U)) {
+        for (i = ((size - 16U)/2U) - 1U; i; i--) {
+          stk -= 2U;
+          stk[1] = MAGIC_PATTERN;
+          stk[0] = MAGIC_PATTERN;
+        }
+        if (--stk > p_TCB->stack) {
+          *stk = MAGIC_PATTERN;
+        }
+      }
+    }
+  }
+#else
   /* Initialize stack with magic pattern. */
   if (os_stackinfo & 0x10000000U) {
     if (size > (16U+1U)) {
@@ -106,6 +132,7 @@
 
   /* Set a magic word for checking of stack overflow. */
   p_TCB->stack[0] = MAGIC_WORD;
+#endif
 }
 
 
--- a/rtx/TARGET_CORTEX_M/RTX_CM_lib.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/RTX_CM_lib.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -52,7 +55,7 @@
 #define _declare_box(pool,size,cnt)  uint32_t pool[(((size)+3)/4)*(cnt) + 3]
 #define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2]
 
-#define OS_TCB_SIZE     60
+#define OS_TCB_SIZE     64
 #define OS_TMR_SIZE     8
 
 typedef void    *OS_ID;
@@ -350,347 +353,43 @@
 
 /* Main Thread definition */
 extern void pre_main (void);
-
-#if defined(TARGET_MCU_NRF51822) || defined(TARGET_MCU_NRF52832) || defined (TARGET_STM32F334R8) ||\
-    defined(TARGET_STM32F302R8) || defined(TARGET_STM32F303K8) || defined (TARGET_STM32F334C8)
-static uint32_t thread_stack_main[DEFAULT_STACK_SIZE / sizeof(uint32_t)];
-#else
-static uint32_t thread_stack_main[DEFAULT_STACK_SIZE * 2 / sizeof(uint32_t)];
-#endif
-osThreadDef_t os_thread_def_main = {(os_pthread)pre_main, osPriorityNormal, 1U, sizeof(thread_stack_main), thread_stack_main};
+osThreadDef_t os_thread_def_main = {(os_pthread)pre_main, osPriorityNormal, 1U, 0U, NULL};
 
-/*
- * IAR Default Memory layout notes:
- * -Heap defined by "HEAP" region in .icf file
- * -Interrupt stack defined by "CSTACK" region in .icf file
- * -Value INITIAL_SP is ignored
- *
- * IAR Custom Memory layout notes:
- * -There is no custom layout available for IAR - everything must be defined in
- *      the .icf file and use the default layout
- *
- *
- * GCC Default Memory layout notes:
- * -Block of memory from symbol __end__ to define INITIAL_SP used to setup interrupt
- *      stack and heap in the function set_stack_heap()
- * -ISR_STACK_SIZE can be overridden to be larger or smaller
- *
- * GCC Custom Memory layout notes:
- * -Heap can be explicitly placed by defining both HEAP_START and HEAP_SIZE
- * -Interrupt stack can be explicitly placed by defining both ISR_STACK_START and ISR_STACK_SIZE
- *
- *
- * ARM Memory layout
- * -Block of memory from end of region "RW_IRAM1" to define INITIAL_SP used to setup interrupt
- *      stack and heap in the function set_stack_heap()
- * -ISR_STACK_SIZE can be overridden to be larger or smaller
- *
- * ARM Custom Memory layout notes:
- * -Heap can be explicitly placed by defining both HEAP_START and HEAP_SIZE
- * -Interrupt stack can be explicitly placed by defining both ISR_STACK_START and ISR_STACK_SIZE
- *
- */
-
-
-// This define should be probably moved to the CMSIS layer
-#if   defined(TARGET_LPC1768)
-#define INITIAL_SP            (0x10008000UL)
-
-#elif defined(TARGET_LPC11U24)
-#define INITIAL_SP            (0x10002000UL)
-
-#elif defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO)
-#define INITIAL_SP            (0x10002000UL)
-
-#elif defined(TARGET_LPC1114)
-#define INITIAL_SP            (0x10001000UL)
-
-#elif defined(TARGET_LPC812)
-#define INITIAL_SP            (0x10001000UL)
-
-#elif defined(TARGET_LPC824) || defined(TARGET_SSCI824)
-#define INITIAL_SP            (0x10002000UL)
-
-#elif defined(TARGET_KL25Z)
-#define INITIAL_SP            (0x20003000UL)
-
-#elif defined(TARGET_KL26Z)
-#define INITIAL_SP            (0x20003000UL)
-
-#elif defined(TARGET_KL27Z)
-#define INITIAL_SP            (0x20003000UL)
-
-#elif defined(TARGET_K64F)
-#define INITIAL_SP            (0x20030000UL)
-
-#if defined(__CC_ARM) || defined(__GNUC__)
-#define ISR_STACK_SIZE        (0x1000)
+#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__)
+#elif defined(__ICCARM__)
+#pragma section="HEAP"
+#define HEAP_END  (void *)__section_end("HEAP")
 #endif
 
-#elif defined(TARGET_K66F)
-#define INITIAL_SP            (0x20030000UL)
-
-#elif defined(TARGET_K22F)
-#define INITIAL_SP            (0x20010000UL)
-
-#elif defined(TARGET_KL46Z)
-#define INITIAL_SP            (0x20006000UL)
-
-#elif defined(TARGET_KL43Z)
-#define INITIAL_SP            (0x20006000UL)
-
-#elif defined(TARGET_KL05Z)
-#define INITIAL_SP            (0x20000C00UL)
-
-#elif defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM)
-#define INITIAL_SP            (0x10010000UL)
-
-#elif defined(TARGET_LPC4330)
-#define INITIAL_SP            (0x10008000UL)
-
-#elif defined(TARGET_LPC4337)
-#define INITIAL_SP            (0x10008000UL)
-
-#elif defined(TARGET_LPC1347)
-#define INITIAL_SP            (0x10002000UL)
-
-#elif defined(TARGET_STM32F100RB) || defined(TARGET_STM32F051R8)
-#define INITIAL_SP            (0x20002000UL)
-
-#elif defined(TARGET_DISCO_F303VC)
-#define INITIAL_SP            (0x2000A000UL)
-
-#elif defined(TARGET_STM32F407) || defined(TARGET_F407VG)
-#define INITIAL_SP            (0x20020000UL)
-
-#elif defined(TARGET_STM32F401RE)
-#define INITIAL_SP            (0x20018000UL)
-
-#elif defined(TARGET_LPC1549)
-#define INITIAL_SP            (0x02009000UL)
-
-#elif defined(TARGET_LPC11U68)
-#define INITIAL_SP            (0x10008000UL)
-
-#elif defined(TARGET_STM32F411RE)
-#define INITIAL_SP            (0x20020000UL)
-
-#elif defined(TARGET_STM32F207ZG)
-#define INITIAL_SP            (0x20020000UL)
-
-#elif defined(TARGET_STM32F410RB)
-#define INITIAL_SP            (0x20008000UL)
-
-#elif defined(TARGET_STM32F103RB) || defined(TARGET_STM32L073RZ)
-#define INITIAL_SP            (0x20005000UL)
-
-#elif defined(TARGET_STM32F302R8)
-#define INITIAL_SP            (0x20004000UL)
-
-#elif  defined(TARGET_STM32F334R8)
-#define INITIAL_SP            (0x20003000UL)
-
-#elif  defined(TARGET_STM32F334C8)
-#define INITIAL_SP            (0x20003000UL)
-
-#elif  defined(TARGET_STM32F405RG)
-#define INITIAL_SP            (0x20020000UL)
-
-#elif defined(TARGET_STM32F429ZI)
-#define INITIAL_SP            (0x20030000UL)
-
-#elif defined(TARGET_STM32L031K6) || defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)
-#define INITIAL_SP            (0x20002000UL)
-
-#elif defined(TARGET_STM32F072RB)
-#define INITIAL_SP            (0x20004000UL)
-
-#elif defined(TARGET_STM32F091RC)
-#define INITIAL_SP            (0x20008000UL)
-
-#elif defined(TARGET_STM32F401VC)
-#define INITIAL_SP            (0x20010000UL)
-
-#elif defined(TARGET_STM32F303RE)
-#define INITIAL_SP            (0x20010000UL)
-
-#elif defined(TARGET_STM32F303K8)
-#define INITIAL_SP            (0x20003000UL)
-
-#elif (defined(TARGET_STM32F746NG) || defined(TARGET_STM32F746ZG))
-#define INITIAL_SP            (0x20050000UL)
-
-#elif defined(TARGET_MAX32610) || defined(TARGET_MAX32600) || defined(TARGET_MAX32620)
-#define INITIAL_SP            (0x20008000UL)
-
-#elif defined(TARGET_TEENSY3_1)
-#define INITIAL_SP            (0x20008000UL)
-
-#elif defined(TARGET_STM32L152RE)
-#define INITIAL_SP            (0x20014000UL)
-
-#elif defined(TARGET_NZ32_SC151)
-#define INITIAL_SP            (0x20008000UL)
-
-#elif defined(TARGET_STM32F446RE) || defined(TARGET_STM32F446VE) || defined(TARGET_STM32F446ZE)
-#define INITIAL_SP            (0x20020000UL)
-
-#elif defined(TARGET_STM32F070RB) || defined(TARGET_STM32F030R8)
-#define INITIAL_SP            (0x20002000UL)
-
-#elif defined(TARGET_STM32L432KC)
-#define INITIAL_SP            (0x2000C000UL)
-
-#elif defined(TARGET_STM32L476VG)
-#define INITIAL_SP            (0x20018000UL)
-
-#elif defined(TARGET_STM32L476RG)
-#define INITIAL_SP            (0x20018000UL)
-
-#elif defined(TARGET_STM32F469NI)
-#define INITIAL_SP            (0x20050000UL)
-
-#elif defined(TARGET_STM32L152RC)
-#define INITIAL_SP            (0x20008000UL)
-
-#elif defined(TARGET_EFM32GG_STK3700) || defined(TARGET_BEETLE)
-#define INITIAL_SP            (0x20020000UL)
-
-#elif defined(TARGET_EFM32HG_STK3400)
-#define INITIAL_SP            (0x20002000UL)
+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
+#if defined(__ICCARM__)
+    /* For IAR heap is defined  .icf file */
+    uint32_t main_stack_size = ((uint32_t)INITIAL_SP - (uint32_t)HEAP_END) - interrupt_stack_size;
+#else
+    /* For ARM , uARM, or GCC_ARM , heap can grow and reach main stack */
+#endif
+    // That is the bottom of the main stack block: no collision detection
+    os_thread_def_main.stack_pointer = HEAP_START;
 
-#elif defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32PG_STK3401)
-#define INITIAL_SP            (0x20008000UL)
-
-#elif defined(TARGET_MCU_NORDIC_32K)
-#define INITIAL_SP            (0x20008000UL)
-
-#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_HEAP$$Base[];
-extern uint32_t                 Image$$ARM_LIB_HEAP$$Length[];
-extern uint32_t                 Image$$ARM_LIB_STACK$$ZI$$Base[];
-extern uint32_t                 Image$$ARM_LIB_STACK$$ZI$$Length[];
-#define HEAP_START              ((unsigned char*) Image$$ARM_LIB_HEAP$$Base)
-#define HEAP_SIZE               ((uint32_t) Image$$ARM_LIB_HEAP$$Length)
-#define ISR_STACK_START         ((unsigned char*)Image$$ARM_LIB_STACK$$ZI$$Base)
-#define ISR_STACK_SIZE          ((uint32_t)Image$$ARM_LIB_STACK$$ZI$$Length)
-#   elif defined(__GNUC__)
-extern uint32_t	                __StackTop[];
-extern uint32_t	                __StackLimit[];
-extern uint32_t                 __end__[];
-extern uint32_t                 __HeapLimit[];
-#define HEAP_START              ((unsigned char*)__end__)
-#define HEAP_SIZE               ((uint32_t)((uint32_t)__HeapLimit - (uint32_t)HEAP_START))
-#define ISR_STACK_START         ((unsigned char*)__StackLimit)
-#define ISR_STACK_SIZE          ((uint32_t)((uint32_t)__StackTop - (uint32_t)__StackLimit))
-#   elif defined(__ICCARM__)
-/* No region declarations needed */
-#   else
-#error "no toolchain defined"
-#   endif
-
-#elif defined(TARGET_NCS36510)
-#define INITIAL_SP            (0x40000000UL)
-
-#else
-#error "no target defined"
-
-#endif
-
-extern unsigned char *mbed_heap_start;
-extern uint32_t mbed_heap_size;
-
-unsigned char *mbed_stack_isr_start = 0;
-uint32_t mbed_stack_isr_size = 0;
-
-/*
- * Sanity check values
- */
-#if defined(__ICCARM__) &&                                  \
-    (defined(HEAP_START) || defined(HEAP_SIZE) ||           \
-     defined(ISR_STACK_START) && defined(ISR_STACK_SIZE))
-    #error "No custom layout allowed for IAR. Use .icf file instead"
-#endif
-#if defined(HEAP_START) && !defined(HEAP_SIZE)
-    #error "HEAP_SIZE must be defined if HEAP_START is defined"
+    // Leave OS_MAINSTKSIZE words for the scheduler and interrupts
+    os_thread_def_main.stacksize = (INITIAL_SP - (unsigned int)HEAP_START) - (OS_MAINSTKSIZE * 4);
 #endif
-#if defined(ISR_STACK_START) && !defined(ISR_STACK_SIZE)
-    #error "ISR_STACK_SIZE must be defined if ISR_STACK_START is defined"
-#endif
-#if defined(HEAP_SIZE) && !defined(HEAP_START)
-    #error "HEAP_START must be defined if HEAP_SIZE is defined"
-#endif
-
-/* Interrupt stack and heap always defined for IAR
- * Main thread defined here
- */
-#if defined(__ICCARM__)
-    #pragma section="CSTACK"
-    #pragma section="HEAP"
-    #define HEAP_START          ((unsigned char*)__section_begin("HEAP"))
-    #define HEAP_SIZE           ((uint32_t)__section_size("HEAP"))
-    #define ISR_STACK_START     ((unsigned char*)__section_begin("CSTACK"))
-    #define ISR_STACK_SIZE      ((uint32_t)__section_size("CSTACK"))
-#endif
-
-/* Define heap region if it has not been defined already */
-#if !defined(HEAP_START)
-    #if defined(__ICCARM__)
-        #error "Heap should already be defined for IAR"
-    #elif defined(__CC_ARM)
-        extern uint32_t          Image$$RW_IRAM1$$ZI$$Limit[];
-        #define HEAP_START      ((unsigned char*)Image$$RW_IRAM1$$ZI$$Limit)
-        #define HEAP_SIZE       ((uint32_t)((uint32_t)INITIAL_SP - (uint32_t)HEAP_START))
-    #elif defined(__GNUC__)
-        extern uint32_t         __end__[];
-        #define HEAP_START      ((unsigned char*)__end__)
-        #define HEAP_SIZE       ((uint32_t)((uint32_t)INITIAL_SP - (uint32_t)HEAP_START))
-    #endif
-#endif
-
-/* Define stack sizes if they haven't been set already */
-#if !defined(ISR_STACK_SIZE)
-    #define ISR_STACK_SIZE ((uint32_t)OS_MAINSTKSIZE * 4)
-#endif
-
-/*
- * set_stack_heap purpose is to set the following variables:
- * -mbed_heap_start
- * -mbed_heap_size
- * -mbed_stack_isr_start
- * -mbed_stack_isr_size
- *
- * Along with setting up os_thread_def_main
- */
-void set_stack_heap(void) {
-
-    unsigned char *free_start = HEAP_START;
-    uint32_t free_size = HEAP_SIZE;
-
-#ifdef ISR_STACK_START
-    /* Interrupt stack explicitly specified */
-    mbed_stack_isr_size = ISR_STACK_SIZE;
-    mbed_stack_isr_start = ISR_STACK_START;
-#else
-    /* Interrupt stack -  reserve space at the end of the free block */
-    mbed_stack_isr_size = ISR_STACK_SIZE;
-    mbed_stack_isr_start = free_start + free_size - mbed_stack_isr_size;
-    free_size -= mbed_stack_isr_size;
-#endif
-
-    /* Heap - everything else */
-    mbed_heap_size = free_size;
-    mbed_heap_start = free_start;
 }
 
 #if defined (__CC_ARM)
@@ -704,7 +403,7 @@
 void _main_init (void) {
   osKernelInitialize();
 #ifdef __MBED_CMSIS_RTOS_CM
-  set_stack_heap();
+  set_main_stack();
 #endif
   osThreadCreate(&os_thread_def_main, NULL);
   osKernelStart();
@@ -726,12 +425,15 @@
 
 #else
 
+void * armcc_heap_base;
+void * armcc_heap_top;
+
 int main(void);
 
 void pre_main (void)
 {
     singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
-    __rt_lib_init((unsigned)mbed_heap_start, (unsigned)(mbed_heap_start + mbed_heap_size));
+    __rt_lib_init((unsigned)armcc_heap_base, (unsigned)armcc_heap_top);
     main();
 }
 
@@ -746,10 +448,13 @@
 __asm void __rt_entry (void) {
 
   IMPORT  __user_setup_stackheap
+  IMPORT  armcc_heap_base
+  IMPORT  armcc_heap_top
+  IMPORT  _platform_post_stackheap_init
   IMPORT  os_thread_def_main
   IMPORT  osKernelInitialize
 #ifdef __MBED_CMSIS_RTOS_CM
-  IMPORT  set_stack_heap
+  IMPORT  set_main_stack
 #endif
   IMPORT  osKernelStart
   IMPORT  osThreadCreate
@@ -763,12 +468,14 @@
    * ARM Compiler ARM C and C++ Libraries and Floating-Point Support User Guide
    */
   BL      __user_setup_stackheap
-  /* Ignore return value of __user_setup_stackheap since
-   * this will be setup by set_stack_heap
-   */
+  LDR     R3,=armcc_heap_base
+  LDR     R4,=armcc_heap_top
+  STR     R0,[R3]
+  STR     R2,[R4]
+  BL      _platform_post_stackheap_init
   BL      osKernelInitialize
 #ifdef __MBED_CMSIS_RTOS_CM
-  BL      set_stack_heap
+  BL      set_main_stack
 #endif
   LDR     R0,=os_thread_def_main
   MOVS    R1,#0
@@ -798,7 +505,6 @@
     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);
     __libc_init_array();
     main(0, NULL);
 }
@@ -807,7 +513,7 @@
   __asm (
     "bl   osKernelInitialize\n"
 #ifdef __MBED_CMSIS_RTOS_CM
-    "bl   set_stack_heap\n"
+    "bl   set_main_stack\n"
 #endif
     "ldr  r0,=os_thread_def_main\n"
     "movs r1,#0\n"
@@ -884,7 +590,7 @@
 #endif
   osKernelInitialize();
 #ifdef __MBED_CMSIS_RTOS_CM
-  set_stack_heap();
+  set_main_stack();
 #endif
   osThreadCreate(&os_thread_def_main, NULL);
   osKernelStart();
@@ -898,3 +604,5 @@
 /*----------------------------------------------------------------------------
  * end of file
  *---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c	Mon Nov 14 17:14:42 2016 -0600
@@ -39,6 +39,9 @@
  *      RTX User configuration part BEGIN
  *---------------------------------------------------------------------------*/
 
+// Include per-target RTX config file
+#include "mbed_rtx.h"
+
 //-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
 //
 // <h>Thread Configuration
@@ -48,23 +51,7 @@
 //   <i> Defines max. number of user threads that will run at the same time.
 //   <i> Default: 6
 #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_K66F)|| 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_STM32F207ZG) || defined(TARGET_STM32F405RG) || defined(TARGET_K22F) || defined(TARGET_STM32F429ZI) || defined(TARGET_STM32F401VC) || defined(TARGET_MAX32610) || defined(TARGET_MAX32600) || defined(TARGET_MAX32620) || 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_NUMAKER_PFM_NUC472) || defined(TARGET_NCS36510)
-#    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_MCU_NRF52832)
-#    define OS_TASKCNT         6
-#  else
-#    error "no target defined"
-#  endif
+ #error "no target defined"
 #endif
 
 #ifdef __MBED_CMSIS_RTOS_CM
@@ -84,28 +71,7 @@
 
 //   <o>Main Thread stack size [bytes] <64-32768:8><#/4>
 #ifndef OS_MAINSTKSIZE
-#  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_K66F) ||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_MAX32620) || 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_STM32F207ZG) \
-   || defined(TARGET_NUMAKER_PFM_NUC472) || defined(TARGET_NCS36510)
-#      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) \
-   || defined(TARGET_STM32F103RB) || defined(TARGET_LPC824) || defined(TARGET_STM32F302R8) || defined(TARGET_STM32F072RB) || defined(TARGET_STM32F091RC) || defined(TARGET_NZ32_SC151) \
-   || defined(TARGET_SSCI824) || defined(TARGET_STM32F030R8) || defined(TARGET_STM32F070RB) \
-   || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32PG_STK3401)
-#      define OS_MAINSTKSIZE    128
-#  elif defined(TARGET_STM32F334R8) || defined(TARGET_STM32F303RE) ||  defined(TARGET_STM32F303K8) ||  defined(TARGET_STM32F334C8) \
-   || 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) ||  defined(TARGET_MCU_NRF52832)
-#      define OS_MAINSTKSIZE    512
-#  else
-#    error "no target defined"
-#  endif
+ #error "no target defined"
 #endif
 
 #ifndef __MBED_CMSIS_RTOS_CM
@@ -135,7 +101,11 @@
 //   <i> Initialize thread stack with watermark pattern for analyzing stack usage (current/maximum) in System and Thread Viewer.
 //   <i> Enabling this option increases significantly the execution time of osThreadCreate.
 #ifndef OS_STKINIT
-#define OS_STKINIT      0
+  #if (defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED)
+   #define OS_STKINIT   1
+  #else
+   #define OS_STKINIT   0
+  #endif
 #endif
 
 //   <o>Processor mode for thread execution
@@ -154,11 +124,7 @@
 //   <i> Cortex-M processors provide in most cases a SysTick timer that can be used as
 //   <i> as time-base for RTX.
 #ifndef OS_SYSTICK
-#   if defined(TARGET_MCU_NRF51822)
-#       define OS_SYSTICK                0
-#   else
-#       define OS_SYSTICK                1
-#   endif
+ #define OS_SYSTICK                1
 #endif
 //
 //   <o>RTOS Kernel Timer input clock frequency [Hz] <1-1000000000>
@@ -166,119 +132,7 @@
 //   <i> When the Cortex-M SysTick timer is used, the input clock
 //   <i> is on most systems identical with the core clock.
 #ifndef OS_CLOCK
-#  if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_TEENSY3_1)
-#    define OS_CLOCK       96000000
-
-#  elif defined(TARGET_LPC1347) || defined(TARGET_STM32F303VC) || defined(TARGET_LPC1549) || defined(TARGET_STM32F334R8) || defined(TARGET_STM32F334C8) || defined(TARGET_STM32F303RE)
-#    define OS_CLOCK       72000000
-
-#  elif defined(TARGET_STM32F303K8)
-#    define OS_CLOCK       64000000
-
-#  elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11U35_401)  || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO)  || defined(TARGET_LPC1114) || defined(TARGET_KL25Z) \
-     || defined(TARGET_KL26Z) || defined(TARGET_KL27Z) || defined(TARGET_KL05Z) || defined(TARGET_KL46Z) || defined(TARGET_KL43Z) || defined(TARGET_STM32F051R8) || defined(TARGET_LPC11U68) || defined(TARGET_STM32F072RB) || defined(TARGET_STM32F091RC)
-#    define OS_CLOCK       48000000
-
-#  elif defined(TARGET_LPC812)
-#    define OS_CLOCK       36000000
-
-#  elif defined(TARGET_LPC824) || defined(TARGET_SSCI824)
-#    define OS_CLOCK       30000000
-
-#  elif  defined(TARGET_STM32F100RB) || defined(TARGET_BEETLE)
-#    define OS_CLOCK       24000000
-
-#  elif defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM) || defined(TARGET_K64F) || defined(TARGET_K66F)
-#    define OS_CLOCK       120000000
-
-#  elif defined(TARGET_LPC4330)
-#    define OS_CLOCK       204000000
-
-#  elif defined(TARGET_LPC4337)
-#    define OS_CLOCK       204000000
-
-#  elif defined(TARGET_STM32F407) || defined(TARGET_F407VG)
-#    define OS_CLOCK       168000000
-
-#  elif defined(TARGET_STM32F401RE)
-#    define OS_CLOCK       84000000
-
-#  elif defined(TARGET_STM32F411RE)
-#     define OS_CLOCK      100000000
-
-#  elif defined(TARGET_STM32F207ZG)
-#     define OS_CLOCK      120000000
-
-#  elif defined(TARGET_STM32F410RB)
-#     define OS_CLOCK      100000000
-
-#elif defined(TARGET_STM32F103RB)
-#    define OS_CLOCK       72000000
-
-#elif defined(TARGET_STM32F429ZI)
-#    define OS_CLOCK       168000000
-
-#elif defined(TARGET_STM32F302R8)
-#    define OS_CLOCK       72000000
-
-#elif defined(TARGET_STM32L031K6) || defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8) || defined(TARGET_STM32L073RZ) 
-#    define OS_CLOCK       32000000
-
-#elif defined(TARGET_STM32F401VC)
-#    define OS_CLOCK       84000000
-
-#  elif defined(TARGET_STM32F746NG) || defined(TARGET_STM32F746ZG) || defined(TARGET_STM32F767ZI)
-#     define OS_CLOCK      216000000
-
-#elif defined(TARGET_MAX32610) || defined(TARGET_MAX32600)
-#    define OS_CLOCK       24000000
-
-#elif defined(TARGET_MAX32620)
-#    define OS_CLOCK       96000000
-
-#elif defined(TARGET_NZ32_SC151)
-#    define OS_CLOCK       32000000
-
-#elif defined(TARGET_STM32L152RE)
-#    define OS_CLOCK       24000000
-
-#elif defined(TARGET_STM32F446RE) || defined(TARGET_STM32F446ZE) || defined(TARGET_STM32F446VE)
-#    define OS_CLOCK       180000000
-
-#elif defined(TARGET_STM32F030R8)
-#    define OS_CLOCK       48000000
-
-#elif defined(TARGET_STM32F070RB)
-#    define OS_CLOCK       48000000
-
-#elif defined(TARGET_STM32L432KC) || defined(TARGET_STM32L476VG) || defined(TARGET_STM32L476RG) || defined(TARGET_K22F)
-#    define OS_CLOCK       80000000
-
-#elif defined(TARGET_STM32F469NI)
-#    define OS_CLOCK       168000000
-
-#elif defined(TARGET_STM32L152RC)
-#    define OS_CLOCK       24000000
-
-#elif defined(TARGET_EFM32)
-#    include "clocking.h"
-#    define OS_CLOCK       REFERENCE_FREQUENCY
-
-#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
-
-#elif defined(TARGET_NCS36510)
-#    define OS_CLOCK       32000000
-
-#  else
-#    error "no target defined"
-#  endif
+ #error "no target defined"
 #endif
 
 //   <o>RTX Timer tick interval value [us] <1-1000000>
@@ -408,6 +262,15 @@
 }
 
 /*----------------------------------------------------------------------------
+ *      RTX Hooks
+ *---------------------------------------------------------------------------*/
+extern void thread_terminate_hook(osThreadId id);
+
+void sysThreadTerminate(osThreadId id) {
+    thread_terminate_hook(id);
+}
+
+/*----------------------------------------------------------------------------
  *      RTX Configuration Functions
  *---------------------------------------------------------------------------*/
 
--- a/rtx/TARGET_CORTEX_M/RTX_Config.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/RTX_Config.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -77,3 +80,5 @@
 /*----------------------------------------------------------------------------
  * end of file
  *---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/HAL_CM4.c	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/HAL_CM4.c	Mon Nov 14 17:14:42 2016 -0600
@@ -164,7 +164,9 @@
 
 SVC_ContextSave
         TST     LR,#0x10                ; is it extended frame?
+#if (__FPU_PRESENT == 1)
         VSTMDBEQ R12!,{S16-S31}         ; yes, stack also VFP hi-regs
+#endif
         MOVEQ   R0,#0x01                ; os_tsk->stack_frame val
         MOVNE   R0,#0x00
         STRB    R0,[R1,#TCB_STACKF]     ; os_tsk.run->stack_frame = val
@@ -184,7 +186,9 @@
         CMP     R0,#0                   ; Basic/Extended Stack Frame
         MVNEQ   LR,#:NOT:0xFFFFFFFD     ; set EXC_RETURN value
         MVNNE   LR,#:NOT:0xFFFFFFED
+#if (__FPU_PRESENT == 1)
         VLDMIANE R12!,{S16-S31}         ; restore VFP hi-registers
+#endif
         MSR     PSP,R12                 ; Write PSP
 
 SVC_Exit
@@ -247,7 +251,9 @@
 
         MRS     R12,PSP                 ; Read PSP
         TST     LR,#0x10                ; is it extended frame?
+#if (__FPU_PRESENT == 1)
         VSTMDBEQ R12!,{S16-S31}         ; yes, stack also VFP hi-regs
+#endif
         MOVEQ   R0,#0x01                ; os_tsk->stack_frame val
         MOVNE   R0,#0x00
         STRB    R0,[R1,#TCB_STACKF]     ; os_tsk.run->stack_frame = val
@@ -266,7 +272,9 @@
         CMP     R0,#0                   ; Basic/Extended Stack Frame
         MVNEQ   LR,#:NOT:0xFFFFFFFD     ; set EXC_RETURN value
         MVNNE   LR,#:NOT:0xFFFFFFED
+#if (__FPU_PRESENT == 1)
         VLDMIANE R12!,{S16-S31}         ; restore VFP hi-regs
+#endif
         MSR     PSP,R12                 ; Write PSP
 
 Sys_Exit
--- a/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/HAL_CM4.S	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/HAL_CM4.S	Mon Nov 14 17:14:42 2016 -0600
@@ -188,8 +188,12 @@
 
 SVC_ContextSave:
         TST     LR,#0x10                /* is it extended frame? */
+#if (__FPU_PRESENT == 1)
         ITTE    EQ
         VSTMDBEQ R12!,{S16-S31}         /* yes, stack also VFP hi-regs */
+#else
+        ITE     EQ
+#endif
         MOVEQ   R0,#0x01                /* os_tsk->stack_frame val */
         MOVNE   R0,#0x00
         STRB    R0,[R1,#TCB_STACKF]     /* os_tsk.run->stack_frame = val */
@@ -207,10 +211,16 @@
         LDMIA   R12!,{R4-R11}           /* Restore New Context */
         LDRB    R0,[R2,#TCB_STACKF]     /* Stack Frame */
         CMP     R0,#0                   /* Basic/Extended Stack Frame */
+#if (__FPU_PRESENT == 1)
         ITEE    EQ
+#else
+        ITE     EQ
+#endif
         MVNEQ   LR,#~0xFFFFFFFD         /* set EXC_RETURN value */
         MVNNE   LR,#~0xFFFFFFED
+#if (__FPU_PRESENT == 1)
         VLDMIANE R12!,{S16-S31}         /* restore VFP hi-registers */
+#endif
         MSR     PSP,R12                 /* Write PSP */
 
 SVC_Exit:
@@ -274,8 +284,12 @@
 
         MRS     R12,PSP                 /* Read PSP */
         TST     LR,#0x10                /* is it extended frame? */
+#if (__FPU_PRESENT == 1)
         ITTE    EQ
         VSTMDBEQ R12!,{S16-S31}         /* yes, stack also VFP hi-regs */
+#else
+        ITE     EQ
+#endif
         MOVEQ   R0,#0x01                /* os_tsk->stack_frame val */
         MOVNE   R0,#0x00
         STRB    R0,[R1,#TCB_STACKF]     /* os_tsk.run->stack_frame = val */
@@ -292,10 +306,16 @@
         LDMIA   R12!,{R4-R11}           /* Restore New Context */
         LDRB    R0,[R2,#TCB_STACKF]     /* Stack Frame */
         CMP     R0,#0                   /* Basic/Extended Stack Frame */
+#if (__FPU_PRESENT == 1)
         ITEE    EQ
+#else
+        ITE     EQ
+#endif
         MVNEQ   LR,#~0xFFFFFFFD         /* set EXC_RETURN value */
         MVNNE   LR,#~0xFFFFFFED
+#if (__FPU_PRESENT == 1)
         VLDMIANE R12!,{S16-S31}         /* restore VFP hi-registers */
+#endif
         MSR     PSP,R12                 /* Write PSP */
 
 Sys_Exit:
--- a/rtx/TARGET_CORTEX_M/cmsis_os.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/cmsis_os.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /* ----------------------------------------------------------------------
  * $Date:        5. February 2013
  * $Revision:    V1.02
@@ -74,16 +77,22 @@
 
 #ifdef __MBED_CMSIS_RTOS_CM
 
-/* Single thread - disable timers and set task count to one */
-#if defined(MBED_RTOS_SINGLE_THREAD)
-#define OS_TASKCNT  1
-#define OS_TIMERS   0
+/* If os timers macro is set to 0, there's no timer thread created, therefore
+ * main thread has tid 0x01  
+ */
+#if defined(OS_TIMERS) && (OS_TIMERS == 0)
+#define MAIN_THREAD_ID 0x01
+#else
+#define MAIN_THREAD_ID 0x02
+#endif
 #endif
 
+#if defined(TARGET_XDOT_L151CC)
+#define DEFAULT_STACK_SIZE         (WORDS_STACK_SIZE/2)
+#else
+#define DEFAULT_STACK_SIZE         (WORDS_STACK_SIZE*4)
 #endif
 
-#define DEFAULT_STACK_SIZE         (WORDS_STACK_SIZE*4)
-
 #define osCMSIS           0x10002U     ///< CMSIS-RTOS API version (main [31:16] .sub [15:0])
 
 #define osCMSIS_RTX     ((4<<16)|80)   ///< RTOS identification and version (main [31:16] .sub [15:0])
@@ -99,6 +108,7 @@
 #define osFeature_Semaphore    65535   ///< Maximum count for \ref osSemaphoreCreate function
 #define osFeature_Wait         0       ///< osWait not available
 #define osFeature_SysTick      1       ///< osKernelSysTick functions available
+#define osFeature_ThreadEnum   1       ///< Thread enumeration available
 
 #if defined (__CC_ARM)
 #define os_InRegs __value_in_regs      // Compiler specific: force struct in registers
@@ -159,6 +169,16 @@
   osTimerPeriodic         =     1        ///< repeating timer
 } os_timer_type;
 
+typedef enum {
+  osThreadInfoState,
+  osThreadInfoStackSize,
+  osThreadInfoStackMax,
+  osThreadInfoEntry,
+  osThreadInfoArg,
+
+  osThreadInfo_reserved   =  0x7FFFFFFF  ///< prevent from enum down-size compiler optimization.
+} osThreadInfo;
+
 /// Entry point of a thread.
 typedef void (*os_pthread) (void const *argument);
 
@@ -188,6 +208,8 @@
 /// Mail ID identifies the mail queue (pointer to a mail queue control block).
 typedef struct os_mailQ_cb *osMailQId;
 
+/// Thread enumeration ID identifies the enumeration (pointer to a thread enumeration control block).
+typedef uint32_t *osThreadEnumId;
 
 /// Thread Definition structure contains startup information of a thread.
 typedef struct os_thread_def  {
@@ -358,6 +380,13 @@
 uint8_t osThreadGetState (osThreadId thread_id);
 #endif
 
+/// Get into from an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     info          information to read.
+/// \return current state of the thread function.
+/// \return requested info that includes the status code.
+os_InRegs osEvent _osThreadGetInfo(osThreadId thread_id, osThreadInfo info);
+
 //  ==== Generic Wait Functions ====
 
 /// Wait for Timeout (Time Delay).
@@ -680,6 +709,26 @@
 #endif  // Mail Queues available
 
 
+//  ==== Thread Enumeration Functions ====
+
+#if (defined (osFeature_ThreadEnum)  &&  (osFeature_ThreadEnum != 0))     // Thread enumeration available
+
+/// Start a thread enumeration.
+/// \return an enumeration ID or NULL on error.
+osThreadEnumId _osThreadsEnumStart(void);
+
+/// Get the next task ID in the enumeration.
+/// \return a thread ID or NULL on if the end of the enumeration has been reached.
+osThreadId _osThreadEnumNext(osThreadEnumId enum_id);
+
+/// Free the enumeration structure.
+/// \param[in]     enum_id       pointer to the enumeration ID that was obtained with \ref _osThreadsEnumStart.
+/// \return status code that indicates the execution status of the function.
+osStatus _osThreadEnumFree(osThreadEnumId enum_id);
+
+#endif  // Thread Enumeration available
+
+
 //  ==== RTX Extensions ====
 
 /// Suspend the RTX task scheduler.
@@ -696,3 +745,5 @@
 #endif
 
 #endif  // _CMSIS_OS_H
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_CMSIS.c	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_CMSIS.c	Mon Nov 14 17:14:42 2016 -0600
@@ -392,6 +392,10 @@
 extern const osMessageQDef_t os_messageQ_def_osTimerMessageQ;
 extern       osMessageQId    osMessageQId_osTimerMessageQ;
 
+// Thread creation and destruction
+osMutexDef(osThreadMutex);
+osMutexId osMutexId_osThreadMutex;
+void sysThreadTerminate(osThreadId id);
 
 // ==== Helper Functions ====
 
@@ -490,6 +494,8 @@
     // Create OS Timers resources (Message Queue & Thread)
     osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL);
     osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL, NULL);
+    // Initialize thread mutex
+    osMutexId_osThreadMutex = osMutexCreate(osMutex(osThreadMutex));
   }
 
   sysThreadError(osOK);
@@ -546,7 +552,7 @@
 
 /// Initialize the RTOS Kernel for creating objects
 osStatus osKernelInitialize (void) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return osErrorISR;                          // Not allowed in ISR
   }
   if ((__get_CONTROL() & 1U) == 0U) {           // Privileged mode
@@ -560,7 +566,7 @@
 osStatus osKernelStart (void) {
   uint32_t stack[8];
 
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return osErrorISR;                          // Not allowed in ISR
   }
 
@@ -601,7 +607,7 @@
 
 /// Check if the RTOS kernel is already started
 int32_t osKernelRunning (void) {
-  if ((__get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) {
+  if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) {
     // in ISR or Privileged
     return (int32_t)os_running;
   } else {
@@ -611,7 +617,7 @@
 
 /// Get the RTOS kernel system timer counter
 uint32_t osKernelSysTick (void) {
-  if (__get_IPSR() != 0U) { return 0U; }        // Not allowed in ISR
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { return 0U; }        // Not allowed in ISR
   return __svcKernelSysTick();
 }
 
@@ -632,6 +638,7 @@
 SVC_0_1(svcThreadYield,       osStatus,                                      RET_osStatus)
 SVC_2_1(svcThreadSetPriority, osStatus,         osThreadId,      osPriority, RET_osStatus)
 SVC_1_1(svcThreadGetPriority, osPriority,       osThreadId,                  RET_osPriority)
+SVC_2_3(svcThreadGetInfo,    os_InRegs osEvent, osThreadId,    osThreadInfo, RET_osEvent)
 
 // Thread Service Calls
 
@@ -791,6 +798,67 @@
   return (osPriority)(ptcb->prio - 1 + osPriorityIdle); 
 }
 
+/// Get info from an active thread
+os_InRegs osEvent_type svcThreadGetInfo (osThreadId thread_id, osThreadInfo info) {
+  P_TCB ptcb;
+  osEvent ret;
+  ret.status = osOK;
+
+  ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
+  if (ptcb == NULL) {
+    ret.status = osErrorValue;
+    return osEvent_ret_status;
+  }
+
+  if (osThreadInfoStackSize == info) {
+    uint32_t size;
+    size = ptcb->priv_stack;
+    if (0 == size) {
+      // This is an OS task - always a fixed size
+      size = os_stackinfo & 0x3FFFF;
+    }
+    ret.value.v = size;
+    return osEvent_ret_value;
+  }
+
+  if (osThreadInfoStackMax == info) {
+    uint32_t i;
+    uint32_t *stack_ptr;
+    uint32_t stack_size;
+    if (!(os_stackinfo & (1 << 28))) {
+      // Stack init must be turned on for max stack usage
+      ret.status = osErrorResource;
+      return osEvent_ret_status;
+    }
+    stack_ptr = (uint32_t*)ptcb->stack;
+    stack_size = ptcb->priv_stack;
+    if (0 == stack_size) {
+      // This is an OS task - always a fixed size
+      stack_size = os_stackinfo & 0x3FFFF;
+    }
+    for (i = 1; i <stack_size / 4; i++) {
+      if (stack_ptr[i] != MAGIC_PATTERN) {
+        break;
+      }
+    }
+    ret.value.v = stack_size - i * 4;
+    return osEvent_ret_value;
+  }
+
+  if (osThreadInfoEntry == info) {
+    ret.value.p = (void*)ptcb->ptask;
+    return osEvent_ret_value;
+  }
+
+  if (osThreadInfoArg == info) {
+    ret.value.p = (void*)ptcb->argv;
+    return osEvent_ret_value;
+  }
+
+  // Unsupported option so return error
+  ret.status = osErrorParameter;
+  return osEvent_ret_status;
+}
 
 // Thread Public API
 
@@ -799,20 +867,25 @@
   return osThreadContextCreate(thread_def, argument, NULL);
 }
 osThreadId osThreadContextCreate (const osThreadDef_t *thread_def, void *argument, void *context) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return NULL;                                // Not allowed in ISR
   }
   if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
     // Privileged and not running
     return   svcThreadCreate(thread_def, argument, context);
   } else {
-    return __svcThreadCreate(thread_def, argument, context);
+    osThreadId id;
+    osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+    // Thread mutex must be held when a thread is created or terminated
+    id = __svcThreadCreate(thread_def, argument, context);
+    osMutexRelease(osMutexId_osThreadMutex);
+    return id;
   }
 }
 
 /// Return the thread ID of the current running thread
 osThreadId osThreadGetId (void) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return NULL;                                // Not allowed in ISR
   }
   return __svcThreadGetId();
@@ -820,15 +893,21 @@
 
 /// Terminate execution of a thread and remove it from ActiveThreads
 osStatus osThreadTerminate (osThreadId thread_id) {
-  if (__get_IPSR() != 0U) { 
+  osStatus status;
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return osErrorISR;                          // Not allowed in ISR
   }
-  return __svcThreadTerminate(thread_id);
+  osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+  sysThreadTerminate(thread_id);
+  // Thread mutex must be held when a thread is created or terminated
+  status = __svcThreadTerminate(thread_id);
+  osMutexRelease(osMutexId_osThreadMutex);
+  return status;
 }
 
 /// Pass control to next thread that is in state READY
 osStatus osThreadYield (void) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return osErrorISR;                          // Not allowed in ISR
   }
   return __svcThreadYield();
@@ -836,7 +915,7 @@
 
 /// Change priority of an active thread
 osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return osErrorISR;                          // Not allowed in ISR
   }
   return __svcThreadSetPriority(thread_id, priority);
@@ -844,7 +923,7 @@
 
 /// Get current priority of an active thread
 osPriority osThreadGetPriority (osThreadId thread_id) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return osPriorityError;                     // Not allowed in ISR
   }
   return __svcThreadGetPriority(thread_id);
@@ -852,8 +931,15 @@
 
 /// INTERNAL - Not Public
 /// Auto Terminate Thread on exit (used implicitly when thread exists)
-__NO_RETURN void osThreadExit (void) { 
-  __svcThreadTerminate(__svcThreadGetId()); 
+__NO_RETURN void osThreadExit (void) {
+  osThreadId id;
+  // Thread mutex must be held when a thread is created or terminated
+  // Note - the mutex will be released automatically by the os when
+  //        the thread is terminated
+  osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+  id = __svcThreadGetId();
+  sysThreadTerminate(id);
+  __svcThreadTerminate(id);
   for (;;);                                     // Should never come here
 }
 
@@ -862,7 +948,7 @@
 uint8_t osThreadGetState (osThreadId thread_id) {
   P_TCB ptcb;
 
-  if (__get_IPSR() != 0U) return osErrorISR;     // Not allowed in ISR
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) return osErrorISR;     // Not allowed in ISR
 
   ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
   if (ptcb == NULL) return INACTIVE;
@@ -871,6 +957,49 @@
 }
 #endif
 
+/// Get the requested info from the specified active thread
+os_InRegs osEvent _osThreadGetInfo(osThreadId thread_id, osThreadInfo info) {
+  osEvent ret;
+
+  if (__get_IPSR() != 0U) {                     // Not allowed in ISR
+    ret.status = osErrorISR;
+    return ret;
+  }
+  return __svcThreadGetInfo(thread_id, info);
+}
+
+osThreadEnumId _osThreadsEnumStart() {
+  static uint32_t thread_enum_index;
+  osMutexWait(osMutexId_osThreadMutex, osWaitForever);
+  thread_enum_index = 0;
+  return &thread_enum_index;
+}
+
+osThreadId _osThreadEnumNext(osThreadEnumId enum_id) {
+  uint32_t i;
+  osThreadId id = NULL;
+  uint32_t *index = (uint32_t*)enum_id;
+  for (i = *index; i < os_maxtaskrun; i++) {
+    if (os_active_TCB[i] != NULL) {
+      id = (osThreadId)os_active_TCB[i];
+      break;
+    }
+  }
+  if (i == os_maxtaskrun) {
+    // Include the idle task at the end of the enumeration
+    id = &os_idle_TCB;
+  }
+  *index = i + 1;
+  return id;
+}
+
+osStatus _osThreadEnumFree(osThreadEnumId enum_id) {
+  uint32_t *index = (uint32_t*)enum_id;
+  *index = 0;
+  osMutexRelease(osMutexId_osThreadMutex);
+  return osOK;
+}
+
 // ==== Generic Wait Functions ====
 
 // Generic Wait Service Calls declarations
@@ -911,7 +1040,7 @@
 
 /// Wait for Timeout (Time Delay)
 osStatus osDelay (uint32_t millisec) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return osErrorISR;                          // Not allowed in ISR
   }
   return __svcDelay(millisec);
@@ -925,7 +1054,7 @@
   ret.status = osErrorOS;
   return ret;
 #else
-  if (__get_IPSR() != 0U) {                     // Not allowed in ISR
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {                     // Not allowed in ISR
     ret.status = osErrorISR;
     return ret;
   }
@@ -1208,7 +1337,7 @@
 
 /// Create timer
 osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return NULL;                                // Not allowed in ISR
   }
   if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -1221,7 +1350,7 @@
 
 /// Start or restart timer
 osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return osErrorISR;                          // Not allowed in ISR
   }
   return __svcTimerStart(timer_id, millisec);
@@ -1229,7 +1358,7 @@
 
 /// Stop timer
 osStatus osTimerStop (osTimerId timer_id) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return osErrorISR;                          // Not allowed in ISR
   }
   return __svcTimerStop(timer_id);
@@ -1237,7 +1366,7 @@
 
 /// Delete timer
 osStatus osTimerDelete (osTimerId timer_id) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return osErrorISR;                          // Not allowed in ISR
   }
   return __svcTimerDelete(timer_id);
@@ -1374,7 +1503,7 @@
 
 /// Set the specified Signal Flags of an active thread
 int32_t osSignalSet (osThreadId thread_id, int32_t signals) {
-  if (__get_IPSR() != 0U) {                     // in ISR
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {                     // in ISR
     return   isrSignalSet(thread_id, signals); 
   } else {                                      // in Thread
     return __svcSignalSet(thread_id, signals);
@@ -1383,7 +1512,7 @@
 
 /// Clear the specified Signal Flags of an active thread
 int32_t osSignalClear (osThreadId thread_id, int32_t signals) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return (int32_t)0x80000000U;                // Not allowed in ISR
   }
   return __svcSignalClear(thread_id, signals);
@@ -1393,7 +1522,7 @@
 os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) {
   osEvent ret;
 
-  if (__get_IPSR() != 0U) {                     // Not allowed in ISR
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {                     // Not allowed in ISR
     ret.status = osErrorISR;
     return ret;
   }
@@ -1505,7 +1634,7 @@
 
 /// Create and Initialize a Mutex object
 osMutexId osMutexCreate (const osMutexDef_t *mutex_def) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return NULL;                                // Not allowed in ISR
   }
   if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -1518,7 +1647,7 @@
 
 /// Wait until a Mutex becomes available
 osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return osErrorISR;                          // Not allowed in ISR
   }
   return __svcMutexWait(mutex_id, millisec);
@@ -1526,7 +1655,7 @@
 
 /// Release a Mutex that was obtained with osMutexWait
 osStatus osMutexRelease (osMutexId mutex_id) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return osErrorISR;                          // Not allowed in ISR
   }
   return __svcMutexRelease(mutex_id);
@@ -1534,7 +1663,7 @@
 
 /// Delete a Mutex that was created by osMutexCreate
 osStatus osMutexDelete (osMutexId mutex_id) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return osErrorISR;                          // Not allowed in ISR
   }
   return __svcMutexDelete(mutex_id);
@@ -1672,7 +1801,7 @@
 
 /// Create and Initialize a Semaphore object
 osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return NULL;                                // Not allowed in ISR
   }
   if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -1685,7 +1814,7 @@
 
 /// Wait until a Semaphore becomes available
 int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return -1;                                  // Not allowed in ISR
   }
   return __svcSemaphoreWait(semaphore_id, millisec);
@@ -1693,16 +1822,16 @@
 
 /// Release a Semaphore
 osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) {
-  if (__get_IPSR() != 0U) {                     // in ISR
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {    // in ISR
     return   isrSemaphoreRelease(semaphore_id);
-  } else {                                      // in Thread
+  } else {                                              // in Thread
     return __svcSemaphoreRelease(semaphore_id);
   }
 }
 
 /// Delete a Semaphore that was created by osSemaphoreCreate
 osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return osErrorISR;                          // Not allowed in ISR
   }
   return __svcSemaphoreDelete(semaphore_id);
@@ -1785,7 +1914,7 @@
 
 /// Create and Initialize memory pool
 osPoolId osPoolCreate (const osPoolDef_t *pool_def) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return NULL;                                // Not allowed in ISR
   }
   if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -1798,7 +1927,7 @@
 
 /// Allocate a memory block from a memory pool
 void *osPoolAlloc (osPoolId pool_id) {
-  if ((__get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) {     // in ISR or Privileged
+  if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) {     // in ISR or Privileged
     return   sysPoolAlloc(pool_id);
   } else {                                      // in Thread
     return __sysPoolAlloc(pool_id);
@@ -1809,7 +1938,7 @@
 void *osPoolCAlloc (osPoolId pool_id) {
   void *mem;
 
-  if ((__get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) {     // in ISR or Privileged
+  if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) {     // in ISR or Privileged
     mem =   sysPoolAlloc(pool_id);
   } else {                                      // in Thread
     mem = __sysPoolAlloc(pool_id);
@@ -1822,7 +1951,7 @@
 
 /// Return an allocated memory block back to a specific memory pool
 osStatus osPoolFree (osPoolId pool_id, void *block) {
-  if ((__get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) {     // in ISR or Privileged
+  if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) {     // in ISR or Privileged
     return   sysPoolFree(pool_id, block);
   } else {                                      // in Thread
     return __sysPoolFree(pool_id, block);
@@ -1962,7 +2091,7 @@
 
 /// Create and Initialize Message Queue
 osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return NULL;                                // Not allowed in ISR
   }
   if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -1975,7 +2104,7 @@
 
 /// Put a Message to a Queue
 osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
-  if (__get_IPSR() != 0U) {                     // in ISR
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {                     // in ISR
     return   isrMessagePut(queue_id, info, millisec);
   } else {                                      // in Thread
     return __svcMessagePut(queue_id, info, millisec);
@@ -1984,7 +2113,7 @@
 
 /// Get a Message or Wait for a Message from a Queue
 os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) {
-  if (__get_IPSR() != 0U) {                     // in ISR
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {                     // in ISR
     return   isrMessageGet(queue_id, millisec);
   } else {                                      // in Thread
     return __svcMessageGet(queue_id, millisec);
@@ -2121,7 +2250,7 @@
 
 /// Create and Initialize mail queue
 osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) {
-  if (__get_IPSR() != 0U) {
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
     return NULL;                                // Not allowed in ISR
   }
   if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -2134,7 +2263,7 @@
 
 /// Allocate a memory block from a mail
 void *osMailAlloc (osMailQId queue_id, uint32_t millisec) {
-  if (__get_IPSR() != 0U) {                     // in ISR
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {                     // in ISR
     return   sysMailAlloc(queue_id, millisec, 1U);
   } else {                                      // in Thread
     return __sysMailAlloc(queue_id, millisec, 0U);
@@ -2146,7 +2275,7 @@
   void *pool;
   void *mem;
 
-  if (__get_IPSR() != 0U) {                     // in ISR
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {                     // in ISR
     mem =   sysMailAlloc(queue_id, millisec, 1U);
   } else {                                      // in Thread
     mem = __sysMailAlloc(queue_id, millisec, 0U);
@@ -2161,7 +2290,7 @@
 
 /// Free a memory block from a mail
 osStatus osMailFree (osMailQId queue_id, void *mail) {
-  if (__get_IPSR() != 0U) {                     // in ISR
+  if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {                     // in ISR
     return   sysMailFree(queue_id, mail, 1U);
   } else {                                      // in Thread
     return __sysMailFree(queue_id, mail, 0U);
--- a/rtx/TARGET_CORTEX_M/rt_Event.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Event.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -44,3 +47,5 @@
  * end of file
  *---------------------------------------------------------------------------*/
 
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_HAL_CM.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_HAL_CM.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -53,11 +56,19 @@
 #endif
 
 #ifndef __CMSIS_GENERIC
+
+__attribute__((always_inline)) static inline U32 __get_PRIMASK(void)
+{
+    register U32 primask __asm("primask");
+    return primask;
+}
+
 #define __DMB() do {\
                    __schedule_barrier();\
                    __dmb(0xF);\
                    __schedule_barrier();\
                 } while (0)
+
 #endif
 
 #elif defined (__GNUC__)        /* GNU Compiler */
@@ -77,6 +88,14 @@
 
 #ifndef __CMSIS_GENERIC
 
+__attribute__((always_inline)) static inline U32 __get_PRIMASK(void)
+{
+  U32 result;
+
+  __asm volatile ("mrs %0, primask" : "=r" (result));
+  return result;
+}
+
 __attribute__((always_inline)) static inline void __enable_irq(void)
 {
   __asm volatile ("cpsie i");
@@ -101,7 +120,7 @@
 __attribute__(( always_inline)) static inline U8 __clz(U32 value)
 {
   U8 result;
-  
+
   __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value));
   return(result);
 }
@@ -122,6 +141,14 @@
 
 #ifndef __CMSIS_GENERIC
 
+static inline U32 __get_PRIMASK(void)
+{
+  U32 result;
+  
+  __asm volatile ("mrs %0, primask" : "=r" (result));
+  return result;
+}
+
 static inline void __enable_irq(void)
 {
   __asm volatile ("cpsie i");
@@ -203,8 +230,22 @@
  #define rt_inc(p)     while(__strex((__ldrex(p)+1U),p))
  #define rt_dec(p)     while(__strex((__ldrex(p)-1U),p))
 #else
- #define rt_inc(p)     __disable_irq();(*p)++;__enable_irq();
- #define rt_dec(p)     __disable_irq();(*p)--;__enable_irq();
+ #define rt_inc(p) do {\
+                     U32 primask = __get_PRIMASK();\
+                     __disable_irq();\
+                     (*p)++;\
+                     if (!primask) {\
+                       __enable_irq();\
+                     }\
+                   } while (0)
+ #define rt_dec(p) do {\
+                     U32 primask = __get_PRIMASK();\
+                     __disable_irq();\
+                     (*p)--;\
+                     if (!primask) {\
+                       __enable_irq();\
+                     }\
+                   } while (0)
 #endif
 
 __inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) {
@@ -220,6 +261,7 @@
     if (c2 == size) { c2 = 0U; }
   } while (__strex(c2, first));
 #else
+  U32 primask = __get_PRIMASK();
   __disable_irq();
   if ((cnt = *count) < size) {
     *count = (U8)(cnt+1U);
@@ -227,7 +269,9 @@
     if (c2 == size) { c2 = 0U; }
     *first = (U8)c2; 
   }
-  __enable_irq ();
+  if (!primask) {
+    __enable_irq ();
+  }
 #endif
   return (cnt);
 }
@@ -296,3 +340,5 @@
 /*----------------------------------------------------------------------------
  * end of file
  *---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_List.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_List.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -65,3 +68,5 @@
  * end of file
  *---------------------------------------------------------------------------*/
 
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_Mailbox.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Mailbox.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -46,3 +49,5 @@
  * end of file
  *---------------------------------------------------------------------------*/
 
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_MemBox.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_MemBox.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -43,3 +46,5 @@
 /*----------------------------------------------------------------------------
  * end of file
  *---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_Memory.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Memory.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -42,3 +45,5 @@
 extern U32   rt_init_mem  (void *pool, U32  size);
 extern void *rt_alloc_mem (void *pool, U32  size);
 extern U32   rt_free_mem  (void *pool, void *mem);
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_Mutex.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Mutex.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -42,3 +45,5 @@
  * end of file
  *---------------------------------------------------------------------------*/
 
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_OsEventObserver.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_OsEventObserver.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -56,3 +59,5 @@
 #endif
 
 #endif
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_Robin.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Robin.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -43,3 +46,5 @@
  * end of file
  *---------------------------------------------------------------------------*/
 
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_Semaphore.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Semaphore.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -44,3 +47,5 @@
  * end of file
  *---------------------------------------------------------------------------*/
 
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_System.c	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_System.c	Mon Nov 14 17:14:42 2016 -0600
@@ -313,10 +313,22 @@
 /*--------------------------- rt_stk_check ----------------------------------*/
 
 __weak void rt_stk_check (void) {
+#ifdef __MBED_CMSIS_RTOS_CM
+    /* Check for stack overflow. */
+    if (os_tsk.run->task_id == MAIN_THREAD_ID) {
+        // TODO: For the main thread the check should be done against the main heap pointer
+    } else {
+        if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) ||
+            (os_tsk.run->stack[0] != MAGIC_WORD)) {
+            os_error (OS_ERR_STK_OVF);
+        }
+    }
+#else
     if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) ||
         (os_tsk.run->stack[0] != MAGIC_WORD)) {
         os_error (OS_ERR_STK_OVF);
     }
+#endif
 }
 
 /*----------------------------------------------------------------------------
--- a/rtx/TARGET_CORTEX_M/rt_System.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_System.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -50,3 +53,5 @@
  * end of file
  *---------------------------------------------------------------------------*/
 
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_Task.c	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Task.c	Mon Nov 14 17:14:42 2016 -0600
@@ -247,6 +247,7 @@
   task_context->task_id = (U8)i;
   /* Pass parameter 'argv' to 'rt_init_context' */
   task_context->msg = argv;
+  task_context->argv = argv;
   /* For 'size == 0' system allocates the user stack from the memory pool. */
   rt_init_context (task_context, (U8)(prio_stksz & 0xFFU), task);
 
--- a/rtx/TARGET_CORTEX_M/rt_Task.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Task.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -81,3 +84,5 @@
 /*----------------------------------------------------------------------------
  * end of file
  *---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_Time.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Time.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -45,3 +48,5 @@
  * end of file
  *---------------------------------------------------------------------------*/
 
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_Timer.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_Timer.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -43,3 +46,5 @@
 /*----------------------------------------------------------------------------
  * end of file
  *---------------------------------------------------------------------------*/
+
+/** @}*/
--- a/rtx/TARGET_CORTEX_M/rt_TypeDef.h	Wed Nov 09 12:22:14 2016 -0600
+++ b/rtx/TARGET_CORTEX_M/rt_TypeDef.h	Mon Nov 14 17:14:42 2016 -0600
@@ -1,3 +1,6 @@
+
+/** \addtogroup rtos */
+/** @{*/
 /*----------------------------------------------------------------------------
  *      CMSIS-RTOS  -  RTX
  *----------------------------------------------------------------------------
@@ -79,6 +82,7 @@
 
   /* Task entry point used for uVision debugger                              */
   FUNCP  ptask;                   /* Task entry address                      */
+  void   *argv;                   /* Task argument                           */
   void   *context;                /* Pointer to thread context               */
 } *P_TCB;
 #define TCB_STACKF      37        /* 'stack_frame' offset                    */
@@ -167,3 +171,5 @@
 #define NULL            ((void *) 0)
 
 #endif
+
+/** @}*/