Added RTX 5.0.0-Alpha (CMSIS RTOS API 2)
diff --git a/ARM.CMSIS.pdsc b/ARM.CMSIS.pdsc
index 7eb78b0..c30eff0 100644
--- a/ARM.CMSIS.pdsc
+++ b/ARM.CMSIS.pdsc
@@ -8,6 +8,11 @@
   <url>http://www.keil.com/pack/</url>
 
   <releases>
+    <release version="5.0.0-Beta8">
+      CMSIS-RTOS:
+        - API 2.0
+        - RTX 5.0.0-Alpha
+    </release>
     <release version="5.0.0-Beta7">
       CMSIS_Core:
        - Added macro __ALIGNED.
@@ -382,6 +387,12 @@
         <file category="doc" name="CMSIS/Documentation/RTOS/html/index.html"/>
       </files>
     </api>
+    <api Cclass="CMSIS" Cgroup="RTOS" Capiversion="2.0" exclusive="1">
+      <description>CMSIS-RTOS API for Cortex-M, SC000, and SC300</description>
+      <files>
+        <file category="doc" name="CMSIS/Documentation/RTOS2/html/index.html"/>
+      </files>
+    </api>
     <api Cclass="CMSIS Driver" Cgroup="USART" Capiversion="2.02" exclusive="0">
       <description>USART Driver API for Cortex-M</description>
       <files>
@@ -525,12 +536,6 @@
       <require Cclass="CMSIS" Cgroup="CORE"/>
     </condition>
 
-    <condition id="Cortex-M Device Startup">
-      <description>Only show for Cortex-M based devices. Depends on Device Startup component.</description>
-      <require condition="Cortex-M Device"/>
-      <require Cclass="Device" Cgroup="Startup"/>
-    </condition>
-
     <condition id="CMSIS Core">
       <description>CMSIS CORE processor and device specific Startup files</description>
         <require Cclass="CMSIS" Cgroup="CORE"/>
@@ -1028,6 +1033,22 @@
       <accept Dcore="Cortex-M7" Dfpu="DP_FPU" Dendian="Big-endian"/>
       <require Tcompiler="IAR"/>
     </condition>
+
+    <condition id="RTX Dependency">
+      <description>Components required for RTX</description>
+      <require condition="Cortex-M Device"/>
+      <require Cclass="Device" Cgroup="Startup"/>
+      <deny    Cclass="CMSIS" Cgroup="RTOS" Csub="Keil RTX5"/>
+    </condition>
+
+    <condition id="RTX5 Dependency">
+      <description>Components required for RTX5</description>
+      <require condition="Cortex-M Device"/>
+      <require Cclass="CMSIS" Cgroup="CORE"/>
+      <require Cclass="Device" Cgroup="Startup"/>
+      <deny    Cclass="CMSIS" Cgroup="RTOS" Csub="Keil RTX"/>
+    </condition>
+
   </conditions>
 
   <components>
@@ -1315,7 +1336,7 @@
     </component>
 
     <!-- CMSIS-RTOS Keil RTX component -->
-    <component Cclass="CMSIS" Cgroup="RTOS" Csub="Keil RTX" Cversion="4.81.0" Capiversion="1.0" condition="Cortex-M Device Startup">
+    <component Cclass="CMSIS" Cgroup="RTOS" Csub="Keil RTX" Cversion="4.81.0" Capiversion="1.0" condition="RTX Dependency">
       <description>CMSIS-RTOS RTX implementation for Cortex-M, SC000, and SC300</description>
       <RTE_Components_h>
         <!-- the following content goes into file 'RTE_Components.h' -->
@@ -1389,6 +1410,51 @@
         <file category="library" condition="CM7F_BE_IAR"       name="CMSIS/RTOS/RTX/LIB/IAR/RTX_CM4_B.a"      src="CMSIS/RTOS/RTX/SRC/IAR"/>
       </files>
     </component>
+
+    <!-- CMSIS-RTOS Keil RTX5 component -->
+    <component Cclass="CMSIS" Cgroup="RTOS" Csub="Keil RTX5" Cversion="5.0.0-Alpha" Capiversion="2.0" condition="RTX5 Dependency">
+      <description>CMSIS-RTOS RTX implementation for Cortex-M, SC000, and SC300</description>
+      <RTE_Components_h>
+        <!-- the following content goes into file 'RTE_Components.h' -->
+        #define RTE_CMSIS_RTOS                  /* CMSIS-RTOS */
+        #define RTE_CMSIS_RTOS_RTX              /* CMSIS-RTOS Keil RTX */
+      </RTE_Components_h>
+      <files>
+        <!-- RTX documentation -->
+   <!-- <file category="doc"    name="CMSIS/Documentation/RTOS2/html/_r_t_x_implementation.html"/> -->
+
+        <!-- RTX header files -->
+        <file category="header" name="CMSIS/RTOS2/RTX/Include/cmsis_os.h"/>
+        <file category="header" name="CMSIS/RTOS2/RTX/Include/cmsis_os2.h"/>
+        <file category="header" name="CMSIS/RTOS2/RTX/Include/rtx_os.h"/>
+
+        <!-- RTX configuration -->
+        <file category="source" attr="config"   name="CMSIS/RTOS2/RTX/Config/RTX_Config.c" version="5.0.0"/>
+
+        <!-- RTX templates -->
+        <file category="source" attr="template" name="CMSIS/RTOS2/RTX/Template/main.c"   select="CMSIS-RTOS 'main' function"/>
+        <file category="source" attr="template" name="CMSIS/RTOS2/RTX/Source/user_svc.c" select="CMSIS-RTOS User SVC"/>
+
+        <!-- RTX compatibility module for API V1 -->
+        <file category="source" name="CMSIS/RTOS2/RTX/Library/cmsis_os1.c"/>
+
+        <!-- RTX libraries (CPU and Compiler dependent) -->
+        <!-- ARMCC -->
+        <file category="library" condition="CM0_LE_ARMCC"      name="CMSIS/RTOS2/RTX/Library/ARM/RTX_CM0.lib"      src="CMSIS/RTOS2/RTX/Source"/>
+        <file category="library" condition="CM3_LE_ARMCC"      name="CMSIS/RTOS2/RTX/Library/ARM/RTX_CM3.lib"      src="CMSIS/RTOS2/RTX/Source"/>
+        <file category="library" condition="CM4_LE_ARMCC_STD"  name="CMSIS/RTOS2/RTX/Library/ARM/RTX_CM3.lib"      src="CMSIS/RTOS2/RTX/Source"/>
+        <file category="library" condition="CM4F_LE_ARMCC_STD" name="CMSIS/RTOS2/RTX/Library/ARM/RTX_CM4F.lib"     src="CMSIS/RTOS2/RTX/Source"/>
+        <file category="library" condition="CM7_LE_ARMCC"      name="CMSIS/RTOS2/RTX/Library/ARM/RTX_CM3.lib"      src="CMSIS/RTOS2/RTX/Source"/>
+        <file category="library" condition="CM7F_LE_ARMCC"     name="CMSIS/RTOS2/RTX/Library/ARM/RTX_CM4F.lib"     src="CMSIS/RTOS2/RTX/Source"/>
+        <!-- GCC -->
+        <file category="library" condition="CM0_LE_GCC"        name="CMSIS/RTOS2/RTX/Library/GCC/libRTX_CM0.a"     src="CMSIS/RTOS2/RTX/Source"/>
+        <file category="library" condition="CM3_LE_GCC"        name="CMSIS/RTOS2/RTX/Library/GCC/libRTX_CM3.a"     src="CMSIS/RTOS2/RTX/Source"/>
+        <file category="library" condition="CM4_LE_GCC_STD"    name="CMSIS/RTOS2/RTX/Library/GCC/libRTX_CM3.a"     src="CMSIS/RTOS2/RTX/Source"/>
+        <file category="library" condition="CM4F_LE_GCC_STD"   name="CMSIS/RTOS2/RTX/Library/GCC/libRTX_CM4F.a"    src="CMSIS/RTOS2/RTX/Source"/>
+        <file category="library" condition="CM7_LE_GCC"        name="CMSIS/RTOS2/RTX/Library/GCC/libRTX_CM3.a"     src="CMSIS/RTOS2/RTX/Source"/>
+        <file category="library" condition="CM7F_LE_GCC"       name="CMSIS/RTOS2/RTX/Library/GCC/libRTX_CM4F.a"    src="CMSIS/RTOS2/RTX/Source"/>
+      </files>
+    </component>
   </components>
 
   <boards>
diff --git a/CMSIS/RTOS2/RTX/Config/RTX_Config.c b/CMSIS/RTOS2/RTX/Config/RTX_Config.c
new file mode 100644
index 0000000..b487b53
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Config/RTX_Config.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * $Revision:   V5.0.0
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       RTX Configuration
+ *
+ * -----------------------------------------------------------------------------
+ */
+ 
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+ 
+// <h>Thread Configuration
+// =======================
+ 
+//   <e>Static Resources
+//   <i> Enables static resources allocation.
+#define OS_THREAD_STATIC            0
+ 
+//     <o>Number of user Threads (total) <1-1000>
+//     <i> Defines maximum number of user threads that can be active at the same time.
+#define OS_THREAD_NUM               1
+ 
+//     <o>Number of user Threads with user-provided Stack size <0-1000>
+//     <i> Defines maximum number of user threads with user-provided stack size.
+//     <i> Default: 0
+#define OS_THREAD_USER_STACK_NUM    0
+  
+//   </e>
+ 
+//   <o>Default Thread Stack size [bytes] <96-1073741824:8>
+//   <i> Defines stack size for threads with zero stack size specified.
+//   <i> Default: 200
+#define OS_STACK_SIZE               200
+ 
+//   <o>Idle Thread Stack size [bytes] <72-1073741824:8>
+//   <i> Defines stack size for Idle thread.
+//   <i> Default: 200
+#define OS_IDLE_THREAD_STACK_SIZE   200
+ 
+//   <q>Stack overrun checking
+//   <i> Enable stack overrun checks at thread switch.
+//   <i> Enabling this option increases slightly the execution time of a thread switch.
+#define OS_STACK_CHECK              1
+ 
+//   <q>Stack usage watermark
+//   <i> Initialize thread stack with watermark pattern for analyzing stack usage.
+//   <i> Enabling this option increases significantly the execution time of thread creation.
+#define OS_STACK_WATERMARK          0
+ 
+//   <o>Processor mode for Thread execution 
+//     <0=> Unprivileged mode 
+//     <1=> Privileged mode
+//   <i> Default: Privileged mode
+#define OS_PRIVILEGE_MODE           1
+ 
+// </h>
+ 
+// <h>Timer Configuration
+// ======================
+ 
+//   <e>Static Resources
+//   <i> Enables static resources allocation.
+#define OS_TIMER_STATIC             0
+ 
+//     <o>Number of user Timers <1-1000>
+//     <i> Defines maximum number of user timers that can be active at the same time.
+#define OS_TIMER_NUM                1
+ 
+//   </e>
+ 
+//   <o>Timer Thread Priority
+//      <8=> Low
+//     <16=> Below Normal  <24=> Normal  <32=> Above Normal
+//     <40=> High
+//     <48=> Realtime
+//   <i> Defines priority for timer thread
+//   <i> Default: High
+#define OS_TIMER_THREAD_PRIO        40
+ 
+//   <o>Timer Thread Stack size [bytes] <0-1073741824:8>
+//   <i> Defines stack size for Timer thread.
+//   <i> May be set to 0 when timers are not used.
+//   <i> Default: 200
+#define OS_TIMER_THREAD_STACK_SIZE  200
+ 
+//   <o>Timer Callback Queue entries <0-256>
+//   <i> Number of concurrent active timer callback functions.
+//   <i> May be set to 0 when timers are not used.
+//   <i> Default: 4
+#define OS_TIMER_CB_QUEUE           4
+ 
+// </h>
+ 
+// <h>Event Flags Configuration
+// ============================
+ 
+//   <e>Static Resources
+//   <i> Enables static resources allocation.
+#define OS_EVFLAGS_STATIC           0
+ 
+//     <o>Number of Event Flags objects <1-1000>
+//     <i> Defines maximum number of objects that can be active at the same time.
+#define OS_EVFLAGS_NUM              1
+ 
+//   </e>
+ 
+// </h>
+ 
+// <h>Mutex Configuration
+// ======================
+ 
+//   <e>Static Resources
+//   <i> Enables static resources allocation.
+#define OS_MUTEX_STATIC             0
+ 
+//     <o>Number of Mutex objects <1-1000>
+//     <i> Defines maximum number of objects that can be active at the same time.
+#define OS_MUTEX_NUM                1
+ 
+//   </e>
+ 
+// </h>
+ 
+// <h>Semaphore Configuration
+// ==========================
+ 
+//   <e>Static Resources
+//   <i> Enables static resources allocation.
+#define OS_SEMAPHORE_STATIC         0
+ 
+//     <o>Number of Semaphore objects <1-1000>
+//     <i> Defines maximum number of objects that can be active at the same time.
+#define OS_SEMAPHORE_NUM            1
+ 
+//   </e>
+ 
+// </h>
+ 
+// <h>Memory Pool Configuration
+// ============================
+ 
+//   <e>Static Resources
+//   <i> Enables static resources allocation.
+#define OS_MEMPOOL_STATIC           0
+ 
+//     <o>Number of Memory Pool objects <1-1000>
+//     <i> Defines maximum number of objects that can be active at the same time.
+#define OS_MEMPOOL_NUM              1
+ 
+//   </e>
+ 
+// </h>
+ 
+// <h>Message Queue Configuration
+// ==============================
+ 
+//   <e>Static Resources
+//   <i> Enables static resources allocation.
+#define OS_MSGQUEUE_STATIC          0
+ 
+//     <o>Number of Message Queue objects <1-1000>
+//     <i> Defines maximum number of objects that can be active at the same time.
+#define OS_MSGQUEUE_NUM             1
+ 
+//   </e>
+ 
+// </h>
+ 
+// <h>System Configuration
+// =======================
+ 
+//   <e>Dynamic Resources
+//   <i> Enables dynamic resources allocation
+#define OS_DYNAMIC                  0
+ 
+//     <o>Memory size [bytes] for Control Blocks <0-1073741824:4>
+//     <i> Defines the combined memory size for control blocks.
+//     <i> Excluding objects with static resources.
+//     <i> Default: 0
+#define OS_DYNAMIC_MEM_CB_SIZE      0
+ 
+//     <o>Memory size [bytes] for Data Storage <0-1073741824:4>
+//     <i> Defines the combined memory size for data storage (Memory Pool and Message Queue).
+//     <i> Default: 0
+#define OS_DYNAMIC_MEM_DATA_SIZE    0
+ 
+//     <o>Memory size [bytes] for Stack <0-1073741824:8>
+//     <i> Defines the combined memory size for stack (Thread).
+//     <i> Excluding threads with static resources and default stack size.
+//     <i> Default: 0
+#define OS_DYNAMIC_MEM_STACK_SIZE   0
+ 
+//   </e>
+ 
+//     <o>Dynamic Memory size [bytes] <0-1073741824:8>
+//     <i> Defines the combined dynamic memory size (excluding static and dynamic resources).
+//     <i> Default: 4096
+#define OS_DYNAMIC_MEM_SIZE         4096
+ 
+//   <e>Round-Robin Thread switching
+//   <i> Enables Round-Robin Thread switching.
+#define OS_ROBIN_ENABLE             1
+ 
+//     <o>Round-Robin Timeout [ms] <1-1000>
+//     <i> Defines how long a thread will execute before a thread switch.
+//     <i> Default: 5
+#define OS_ROBIN_TIMEOUT            5
+ 
+//   </e>
+ 
+//   <o>ISR FIFO Queue 
+//      <4=>  4 entries    <8=>   8 entries   <12=>  12 entries   <16=>  16 entries
+//     <24=> 24 entries   <32=>  32 entries   <48=>  48 entries   <64=>  64 entries
+//     <96=> 96 entries  <128=> 128 entries  <196=> 196 entries  <256=> 256 entries
+//   <i> RTOS Functions called from ISR store requests to this buffer.
+//   <i> Default: 16 entries
+#define OS_ISR_FIFO_QUEUE           16
+ 
+// </h>
+ 
+// Number of Threads which use standard C/C++ library libspace
+// (when static thread resource allocation is not used).
+#if (OS_THREAD_STATIC == 0)
+#define OS_THREAD_LIBSPACE_NUM      4
+#else
+#define OS_THREAD_LIBSPACE_NUM      OS_THREAD_NUM
+#endif
+ 
+//------------- <<< end of configuration section >>> ---------------------------
+ 
+#include "rtx_os.h"
+ 
+// OS Idle Thread
+void *os_IdleThread (void *argument) {
+  (void)argument;
+
+  for (;;) {}
+}
+ 
+// OS Error Callback function
+uint32_t os_Error (uint32_t code, void *object_id) {
+  (void)object_id;
+
+  switch (code) {
+    case os_ErrorStackUnderflow:
+      // Stack underflow detected for thread (thread_id=object_id)
+      break;
+    case os_ErrorISRQueueOverflow:
+      // ISR Queue overflow detected when inserting object (object_id)
+      break;
+    case os_ErrorTimerQueueOverflow:
+      // User Timer Callback Queue overflow detected for timer (timer_id=object_id)
+      break;
+    case os_ErrorClibSpace:
+      // Standard C/C++ library libspace not available: increase OS_THREAD_LIBSPACE_NUM
+      break;
+    case os_ErrorClibMutex:
+      // Standard C/C++ library mutex initialization failed
+      break;
+    default:
+      break;
+  }
+  for (;;) {}
+//return 0U;
+}
+ 
+#include "rtx_config.h"
diff --git a/CMSIS/RTOS2/RTX/Include/cmsis_os.h b/CMSIS/RTOS2/RTX/Include/cmsis_os.h
new file mode 100644
index 0000000..84b8a78
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Include/cmsis_os.h
@@ -0,0 +1,875 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ----------------------------------------------------------------------
+ *
+ * $Date:        30. June 2016
+ * $Revision:    V2.0
+ *
+ * Project:      CMSIS-RTOS API
+ * Title:        cmsis_os.h RTX header file
+ *
+ * Version 0.02
+ *    Initial Proposal Phase
+ * Version 0.03
+ *    osKernelStart added, optional feature: main started as thread
+ *    osSemaphores have standard behavior
+ *    osTimerCreate does not start the timer, added osTimerStart
+ *    osThreadPass is renamed to osThreadYield
+ * Version 1.01
+ *    Support for C++ interface
+ *     - const attribute removed from the osXxxxDef_t typedefs
+ *     - const attribute added to the osXxxxDef macros
+ *    Added: osTimerDelete, osMutexDelete, osSemaphoreDelete
+ *    Added: osKernelInitialize
+ * Version 1.02
+ *    Control functions for short timeouts in microsecond resolution:
+ *    Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec
+ *    Removed: osSignalGet 
+ * Version 2.0
+ *    OS objects creation without macros (dynamic creation and resource allocation):
+ *     - added: osXxxxNew functions which replace osXxxxCreate
+ *     - added: osXxxxAttr_t structures
+ *     - deprecated: osXxxxCreate functions, osXxxxDef_t structures
+ *     - deprecated: osXxxxDef and osXxxx macros
+ *    osStatus codes simplified and renamed to osStatus_t
+ *    osEvent return structure deprecated
+ *    Kernel:
+ *     - added: osKernelInfo_t and osKernelGetInfo
+ *     - added: osKernelState_t and osKernelGetState (replaces osKernelRunning)
+ *     - added: osKernelLock, osKernelUnlock
+ *     - added: osKernelSuspend, osKernelResume
+ *     - added: osKernelGetTime
+ *     - renamed osKernelSysTick to osKernelGetSysTick
+ *    Thread:
+ *     - extended number of thread priorities
+ *     - renamed osPrioriry to osPrioriry_t
+ *     - changed thread return value
+ *     - replaced osThreadCreate with osThreadNew
+ *     - added: osThreadState_t and osThreadGetState
+ *     - added: osThreadAbortWait, osThreadSuspend, osThreadResume
+ *     - added: osThreadJoin, osThreadDetach, osThreadExit
+ *     - added: Thread Flags (moved from Signals) 
+ *    Signals:
+ *     - renamed osSignals to osThreadFlags (moved to Thread Flags)
+ *     - changed return value of Set/Clear/Wait functions
+ *     - extended Wait function (options)
+ *     - added: osThreadFlagsGet
+ *    Event Flags:
+ *     - added new independent object for handling Event Flags
+ *    Delay and Wait functions:
+ *     - added: osDelayUntil
+ *     - deprecated: osWait
+ *    Timer:
+ *     - replaced osTimerCreate with osTimerNew
+ *     - added: osTimerIsRunning
+ *    Mutex:
+ *     - extended: attributes (Recursive, Priority Inherit, Robust)
+ *     - replaced osMutexCreate with osMutexNew
+ *     - renamed osMutexWait to osMutexAcquire
+ *     - added: osMutexGetOwner
+ *    Semaphore:
+ *     - extended: maximum and initial token count
+ *     - replaced osSemaphoreCreate with osSemaphoreNew
+ *     - renamed osSemaphoreWait to osSemaphoreAcquire (changed return value)
+ *     - added: osSemaphoreGetCount
+ *    Memory Pool:
+ *     - using osMemoryPool prefix instead of osPool
+ *     - replaced osPoolCreate with osMemoryPoolNew
+ *     - extended osMemoryPoolAlloc (timeout)
+ *     - added: osMemoryPoolGetCapacity, osMemoryPoolGetBlockSize
+ *     - added: osMemoryPoolGetCount, osMemoryPoolGetSpace
+ *     - added: osMemoryPoolDelete
+ *     - deprecated: osPoolCAlloc
+ *    Message Queue:
+ *     - extended: fixed size message instead of a single 32-bit value
+ *     - using osMessageQueue prefix instead of osMessage
+ *     - replaced osMessageCreate with osMessageQueueNew
+ *     - updated: osMessageQueuePut, osMessageQueueGet
+ *     - added: osMessageQueueGetCapacity, osMessageQueueGetMsgSize
+ *     - added: osMessageQueueGetCount, osMessageQueueGetSpace
+ *     - added: osMessageQueueReset, osMessageQueueDelete
+ *    Mail Queue: 
+ *     - deprecated (superseded by extended Message Queue functionality)
+ *---------------------------------------------------------------------------*/
+ 
+#ifndef __CMSIS_OS_H
+#define __CMSIS_OS_H
+ 
+#define osCMSIS             0x20000U    ///< API version (main[31:16].sub[15:0])
+ 
+#define osCMSIS_RTX         0x50000U    ///< RTOS identification and version (main[31:16].sub[15:0])
+ 
+#define osKernelSystemId   "RTX V5.0"   ///< RTOS identification string
+ 
+#define osFeature_MainThread  0         ///< main thread      1=main can be thread, 0=not available
+#define osFeature_Signals     31U       ///< maximum number of Signal Flags available per thread
+#define osFeature_Semaphore   65535U    ///< 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_Pool        1         ///< Memory Pools:    1=available, 0=not available
+#define osFeature_MessageQ    1         ///< Message Queues:  1=available, 0=not available
+#define osFeature_MailQ       1         ///< Mail Queues:     1=available, 0=not available
+ 
+#if (osCMSIS >= 0x20000U)
+#include "cmsis_os2.h"
+#else
+#include <stdint.h>
+#include <stddef.h>
+#endif
+#include "rtx_os.h"
+ 
+#ifdef  __cplusplus
+extern "C"
+{
+#endif
+ 
+ 
+// ==== Enumerations, structures, defines ====
+ 
+/// Priority values.
+#if (osCMSIS < 0x20000U)
+typedef enum {
+  osPriorityIdle          = -3,         ///< Priority: idle (lowest)
+  osPriorityLow           = -2,         ///< Priority: low
+  osPriorityBelowNormal   = -1,         ///< Priority: below normal
+  osPriorityNormal        =  0,         ///< Priority: normal (default)
+  osPriorityAboveNormal   = +1,         ///< Priority: above normal
+  osPriorityHigh          = +2,         ///< Priority: high
+  osPriorityRealtime      = +3,         ///< Priority: realtime (highest)
+  osPriorityError         = 0x84,       ///< System cannot determine priority or illegal priority.
+  osPriorityReserved      = 0x7FFFFFFF  ///< Prevents enum down-size compiler optimization.
+} osPriority;
+#else
+#define osPriority osPriority_t
+#endif
+
+/// Entry point of a thread.
+typedef void (*os_pthread) (void const *argument);
+ 
+/// Entry point of a timer call back function.
+typedef void (*os_ptimer) (void const *argument);
+ 
+/// Timer type.
+#if (osCMSIS < 0x20000U)
+typedef enum {
+  osTimerOnce             = 0,          ///< One-shot timer.
+  osTimerPeriodic         = 1           ///< Repeating timer.
+} os_timer_type;
+#else
+#define os_timer_type osTimerType_t
+#endif
+ 
+/// Timeout value.
+#define osWaitForever       0xFFFFFFFFU ///< Wait forever timeout value.
+ 
+/// Status code values returned by CMSIS-RTOS functions.
+#if (osCMSIS < 0x20000U)
+typedef enum {
+  osOK                    =    0,       ///< Function completed; no error or event occurred.
+  osEventSignal           = 0x08,       ///< Function completed; signal event occurred.
+  osEventMessage          = 0x10,       ///< Function completed; message event occurred.
+  osEventMail             = 0x20,       ///< Function completed; mail event occurred.
+  osEventTimeout          = 0x40,       ///< Function completed; timeout occurred.
+  osErrorParameter        = 0x80,       ///< Parameter error: a mandatory parameter was missing or specified an incorrect object.
+  osErrorResource         = 0x81,       ///< Resource not available: a specified resource was not available.
+  osErrorTimeoutResource  = 0xC1,       ///< Resource not available within given time: a specified resource was not available within the timeout period.
+  osErrorISR              = 0x82,       ///< Not allowed in ISR context: the function cannot be called from interrupt service routines.
+  osErrorISRRecursive     = 0x83,       ///< Function called multiple times from ISR with same object.
+  osErrorPriority         = 0x84,       ///< System cannot determine priority or thread has illegal priority.
+  osErrorNoMemory         = 0x85,       ///< System is out of memory: it was impossible to allocate or reserve memory for the operation.
+  osErrorValue            = 0x86,       ///< Value of a parameter is out of range.
+  osErrorOS               = 0xFF,       ///< Unspecified RTOS error: run-time error but no other error message fits.
+  osStatusReserved        = 0x7FFFFFFF  ///< Prevents enum down-size compiler optimization.
+} osStatus;
+#else
+typedef int32_t                  osStatus;
+#define osEventSignal           (0x08)
+#define osEventMessage          (0x10)
+#define osEventMail             (0x20)
+#define osEventTimeout          (0x40)
+#define osErrorOS               osError
+#define osErrorTimeoutResource  osErrorTimeout
+#define osErrorISRRecursive     (-126)
+#define osErrorValue            (-127)
+#define osErrorPriority         (-128)
+#endif
+ 
+ 
+// >>> the following data type definitions may be adapted towards a specific RTOS
+ 
+/// Thread ID identifies the thread.
+#if (osCMSIS < 0x20000U)
+typedef uint32_t osThreadId;
+#else
+#define osThreadId osThreadId_t
+#endif
+ 
+/// Timer ID identifies the timer.
+#if (osCMSIS < 0x20000U)
+typedef uint32_t osTimerId;
+#else
+#define osTimerId osTimerId_t
+#endif
+ 
+/// Mutex ID identifies the mutex.
+#if (osCMSIS < 0x20000U)
+typedef uint32_t osMutexId;
+#else
+#define osMutexId osMutexId_t
+#endif
+ 
+/// Semaphore ID identifies the semaphore.
+#if (osCMSIS < 0x20000U)
+typedef uint32_t osSemaphoreId;
+#else
+#define osSemaphoreId osSemaphoreId_t
+#endif
+ 
+/// Pool ID identifies the memory pool.
+typedef uint32_t osPoolId;
+ 
+/// Message ID identifies the message queue.
+typedef uint32_t osMessageQId;
+ 
+/// Mail ID identifies the mail queue.
+typedef uint32_t osMailQId;
+ 
+ 
+/// Thread Definition structure contains startup information of a thread.
+#if (osCMSIS < 0x20000U)
+typedef struct os_thread_def {
+  os_pthread                 pthread;   ///< start address of thread function
+  osPriority               tpriority;   ///< initial thread priority
+  uint32_t                 instances;   ///< maximum number of instances of that thread function
+  uint32_t                 stacksize;   ///< stack size requirements in bytes; 0 is default stack size
+} osThreadDef_t;
+#else
+typedef struct os_thread_def {
+  os_pthread                 pthread;   ///< start address of thread function
+  osThreadAttr_t                attr;   ///< thread attributes
+} osThreadDef_t;
+#endif
+ 
+/// Timer Definition structure contains timer parameters.
+#if (osCMSIS < 0x20000U)
+typedef struct os_timer_def {
+  os_ptimer                   ptimer;   ///< start address of a timer function
+} osTimerDef_t;
+#else
+typedef struct os_timer_def {
+  os_ptimer                   ptimer;   ///< start address of a timer function
+  osTimerAttr_t                 attr;   ///< timer attributes
+} osTimerDef_t;
+#endif
+ 
+/// Mutex Definition structure contains setup information for a mutex.
+#if (osCMSIS < 0x20000U)
+typedef struct os_mutex_def {
+  uint32_t                     dummy;   ///< dummy value
+} osMutexDef_t;
+#else
+#define osMutexDef_t osMutexAttr_t
+#endif
+ 
+/// Semaphore Definition structure contains setup information for a semaphore.
+#if (osCMSIS < 0x20000U)
+typedef struct os_semaphore_def {
+  uint32_t                     dummy;   ///< dummy value
+} osSemaphoreDef_t;
+#else
+#define osSemaphoreDef_t osSemaphoreAttr_t
+#endif
+ 
+/// Definition structure for memory block allocation.
+#if (osCMSIS < 0x20000U)
+typedef struct os_pool_def {
+  uint32_t                   pool_sz;   ///< number of items (elements) in the pool
+  uint32_t                   item_sz;   ///< size of an item
+  void                         *pool;   ///< pointer to memory for pool
+} osPoolDef_t;
+#else
+typedef struct os_pool_def {
+  uint32_t                   pool_sz;   ///< number of items (elements) in the pool
+  uint32_t                   item_sz;   ///< size of an item
+  osMemoryPoolAttr_t            attr;   ///< memory pool attributes
+} osPoolDef_t;
+#endif
+ 
+/// Definition structure for message queue.
+#if (osCMSIS < 0x20000U)
+typedef struct os_messageQ_def {
+  uint32_t                  queue_sz;   ///< number of elements in the queue
+  void                         *pool;   ///< memory array for messages
+} osMessageQDef_t;
+#else
+typedef struct os_messageQ_def {
+  uint32_t                  queue_sz;   ///< number of elements in the queue
+  osMessageQueueAttr_t          attr;   ///< message queue attributes
+} osMessageQDef_t;
+#endif
+ 
+/// Definition structure for mail queue.
+#if (osCMSIS < 0x20000U)
+typedef struct os_mailQ_def {
+  uint32_t                  queue_sz;   ///< number of elements in the queue
+  uint32_t                   item_sz;   ///< size of an item
+  void                         *pool;   ///< memory array for mail
+} osMailQDef_t;
+#else
+typedef struct os_mailQ_def {
+  uint32_t                  queue_sz;   ///< number of elements in the queue
+  uint32_t                   item_sz;   ///< size of an item
+  void                         *mail;   ///< pointer to mail
+  osMemoryPoolAttr_t         mp_attr;   ///< memory pool attributes
+  osMessageQueueAttr_t       mq_attr;   ///< message queue attributes
+} osMailQDef_t;
+#endif
+ 
+ 
+/// Event structure contains detailed information about an event.
+typedef struct {
+  osStatus                    status;   ///< status code: event or error information
+  union {
+    uint32_t                       v;   ///< message as 32-bit value
+    void                          *p;   ///< message or mail as void pointer
+    int32_t                  signals;   ///< signal flags
+  } value;                              ///< event value
+  union {
+    osMailQId                mail_id;   ///< mail id obtained by \ref osMailCreate
+    osMessageQId          message_id;   ///< message id obtained by \ref osMessageCreate
+  } def;                                ///< event definition
+} osEvent;
+ 
+ 
+//  ==== Kernel Management Functions ====
+ 
+/// Initialize the RTOS Kernel for creating objects.
+/// \return status code that indicates the execution status of the function.
+#if (osCMSIS < 0x20000U)
+osStatus osKernelInitialize (void);
+#endif
+ 
+/// Start the RTOS Kernel scheduler.
+/// \return status code that indicates the execution status of the function.
+#if (osCMSIS < 0x20000U)
+osStatus osKernelStart (void);
+#endif
+ 
+/// Check if the RTOS kernel is already started.
+/// \return 0 RTOS is not started, 1 RTOS is started.
+#if (osCMSIS < 0x20000U)
+int32_t osKernelRunning(void);
+#endif
+ 
+#if (defined(osFeature_SysTick) && (osFeature_SysTick != 0))  // System Timer available
+ 
+/// Get the RTOS kernel system timer counter.
+/// \return RTOS kernel system timer as 32-bit value 
+#if (osCMSIS < 0x20000U)
+uint32_t osKernelSysTick (void);
+#else
+#define  osKernelSysTick osKernelGetTick
+#endif
+ 
+/// The RTOS kernel system timer frequency in Hz.
+/// \note Reflects the system timer setting and is typically defined in a configuration file.
+#define osKernelSysTickFrequency 100000000
+ 
+/// Convert a microseconds value to a RTOS kernel system timer value.
+/// \param         microsec     time value in microseconds.
+/// \return time value normalized to the \ref osKernelSysTickFrequency
+#if (osCMSIS < 0x20000U)
+#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000)
+#else
+#define osKernelSysTickMicroSec osKernelTickMicroSec
+#endif
+ 
+#endif  // System Timer available
+ 
+ 
+//  ==== Thread Management Functions ====
+ 
+/// Create a Thread Definition with function, priority, and stack requirements.
+/// \param         name          name of the thread function.
+/// \param         priority      initial priority of the thread function.
+/// \param         instances     number of possible thread instances.
+/// \param         stacksz       stack size (in bytes) requirements for the thread function.
+#if defined (osObjectsExternal)  // object is external
+#define osThreadDef(name, priority, instances, stacksz) \
+extern const osThreadDef_t os_thread_def_##name
+#else                            // define the object
+#if (osCMSIS < 0x20000U)
+#define osThreadDef(name, priority, instances, stacksz) \
+const osThreadDef_t os_thread_def_##name = \
+{ (name), (priority), (instances), (stacksz) }
+#else
+#define osThreadDef(name, priority, instances, stacksz) \
+static uint64_t os_thread_stack##name[(stacksz)?(((stacksz+7)/8)):1] __attribute__((section(".os.object.stack"))); \
+static os_thread_t os_thread_cb_##name __attribute__((section(".os.object.cb"))); \
+const osThreadDef_t os_thread_def_##name = \
+{ (name), \
+  { NULL, osThreadDetached, \
+    (instances == 1) ? (&os_thread_cb_##name) : NULL,\
+    (instances == 1) ? os_ThreadCbSize : 0U, \
+    ((stacksz) && (instances == 1)) ? (&os_thread_stack##name) : NULL, \
+    8*((stacksz+7)/8), \
+    (priority), { 0U, 0U } } }
+#endif
+#endif
+ 
+/// Access a Thread definition.
+/// \param         name          name of the thread definition object.
+#define osThread(name) \
+&os_thread_def_##name
+ 
+/// Create a thread and add it to Active Threads and set it to state READY.
+/// \param[in]     thread_def    thread definition referenced with \ref osThread.
+/// \param[in]     argument      pointer that is passed to the thread function as start argument.
+/// \return thread ID for reference by other functions or NULL in case of error.
+osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument);
+ 
+/// Return the thread ID of the current running thread.
+/// \return thread ID for reference by other functions or NULL in case of error.
+#if (osCMSIS < 0x20000U)
+osThreadId osThreadGetId (void);
+#endif
+ 
+/// Change priority of a thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     priority      new priority value for the thread function.
+/// \return status code that indicates the execution status of the function.
+#if (osCMSIS < 0x20000U)
+osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority);
+#endif
+ 
+/// Get current priority of a thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \return current priority value of the specified thread.
+#if (osCMSIS < 0x20000U)
+osPriority osThreadGetPriority (osThreadId thread_id);
+#endif
+ 
+/// Pass control to next thread that is in state \b READY.
+/// \return status code that indicates the execution status of the function.
+#if (osCMSIS < 0x20000U)
+osStatus osThreadYield (void);
+#endif
+ 
+/// Terminate execution of a thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \return status code that indicates the execution status of the function.
+#if (osCMSIS < 0x20000U)
+osStatus osThreadTerminate (osThreadId thread_id);
+#endif
+ 
+ 
+//  ==== Signal Management ====
+ 
+/// Set the specified Signal Flags of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     signals       specifies the signal flags of the thread that should be set.
+/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
+int32_t osSignalSet (osThreadId thread_id, int32_t signals);
+ 
+/// Clear the specified Signal Flags of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     signals       specifies the signal flags of the thread that shall be cleared.
+/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters or call from ISR.
+int32_t osSignalClear (osThreadId thread_id, int32_t signals);
+ 
+/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
+/// \param[in]     signals       wait until all specified signal flags set or 0 for any single signal flag.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return event flag information or error code.
+osEvent osSignalWait (int32_t signals, uint32_t millisec);
+ 
+ 
+//  ==== Generic Wait Functions ====
+ 
+/// Wait for Timeout (Time Delay).
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue "time delay" value
+/// \return status code that indicates the execution status of the function.
+#if (osCMSIS < 0x20000U)
+osStatus osDelay (uint32_t millisec);
+#endif
+ 
+#if (defined (osFeature_Wait) && (osFeature_Wait != 0))  // Generic Wait available
+ 
+/// Wait for Signal, Message, Mail, or Timeout.
+/// \param[in] millisec          \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
+/// \return event that contains signal, message, or mail information or error code.
+osEvent osWait (uint32_t millisec);
+ 
+#endif  // Generic Wait available
+ 
+ 
+//  ==== Timer Management Functions ====
+ 
+/// Define a Timer object.
+/// \param         name          name of the timer object.
+/// \param         function      name of the timer call back function.
+#if defined (osObjectsExternal)  // object is external
+#define osTimerDef(name, function) \
+extern const osTimerDef_t os_timer_def_##name
+#else                            // define the object
+#if (osCMSIS < 0x20000U)
+#define osTimerDef(name, function) \
+const osTimerDef_t os_timer_def_##name = { (function) }
+#else
+#define osTimerDef(name, function) \
+static os_timer_t os_timer_cb_##name __attribute__((section(".os.object.cb"))); \
+const osTimerDef_t os_timer_def_##name = \
+{ (function), { NULL, 0U, (&os_timer_cb_##name), os_TimerCbSize } }
+#endif
+#endif
+ 
+/// Access a Timer definition.
+/// \param         name          name of the timer object.
+#define osTimer(name) \
+&os_timer_def_##name
+ 
+/// Create and Initialize a timer.
+/// \param[in]     timer_def     timer object referenced with \ref osTimer.
+/// \param[in]     type          osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
+/// \param[in]     argument      argument to the timer call back function.
+/// \return timer ID for reference by other functions or NULL in case of error.
+osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument);
+ 
+/// Start or restart a timer.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue "time delay" value of the timer.
+/// \return status code that indicates the execution status of the function.
+#if (osCMSIS < 0x20000U)
+osStatus osTimerStart (osTimerId timer_id, uint32_t millisec);
+#endif
+ 
+/// Stop a timer.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
+/// \return status code that indicates the execution status of the function.
+#if (osCMSIS < 0x20000U)
+osStatus osTimerStop (osTimerId timer_id);
+#endif
+ 
+/// Delete a timer.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
+/// \return status code that indicates the execution status of the function.
+#if (osCMSIS < 0x20000U)
+osStatus osTimerDelete (osTimerId timer_id);
+#endif
+ 
+ 
+//  ==== Mutex Management Functions ====
+ 
+/// Define a Mutex.
+/// \param         name          name of the mutex object.
+#if defined (osObjectsExternal)  // object is external
+#define osMutexDef(name) \
+extern const osMutexDef_t os_mutex_def_##name
+#else                            // define the object
+#if (osCMSIS < 0x20000U)
+#define osMutexDef(name) \
+const osMutexDef_t os_mutex_def_##name = { 0 }
+#else
+#define osMutexDef(name) \
+static os_mutex_t os_mutex_cb_##name __attribute__((section(".os.object.cb"))); \
+const osMutexDef_t os_mutex_def_##name = \
+{ NULL, osMutexRecursive | osMutexPrioInherit | osMutexRobust, (&os_mutex_cb_##name), os_MutexCbSize }
+#endif
+#endif
+ 
+/// Access a Mutex definition.
+/// \param         name          name of the mutex object.
+#define osMutex(name) \
+&os_mutex_def_##name
+ 
+/// Create and Initialize a Mutex object.
+/// \param[in]     mutex_def     mutex definition referenced with \ref osMutex.
+/// \return mutex ID for reference by other functions or NULL in case of error.
+osMutexId osMutexCreate (const osMutexDef_t *mutex_def);
+ 
+/// Wait until a Mutex becomes available.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return status code that indicates the execution status of the function.
+#if (osCMSIS < 0x20000U)
+osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec);
+#else
+#define  osMutexWait osMutexAcquire
+#endif
+ 
+/// Release a Mutex that was obtained by \ref osMutexWait.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
+/// \return status code that indicates the execution status of the function.
+#if (osCMSIS < 0x20000U)
+osStatus osMutexRelease (osMutexId mutex_id);
+#endif
+ 
+/// Delete a Mutex object.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
+/// \return status code that indicates the execution status of the function.
+#if (osCMSIS < 0x20000U)
+osStatus osMutexDelete (osMutexId mutex_id);
+#endif
+ 
+ 
+//  ==== Semaphore Management Functions ====
+ 
+#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0U))  // Semaphore available
+ 
+/// Define a Semaphore object.
+/// \param         name          name of the semaphore object.
+#if defined (osObjectsExternal)  // object is external
+#define osSemaphoreDef(name) \
+extern const osSemaphoreDef_t os_semaphore_def_##name
+#else                            // define the object
+#if (osCMSIS < 0x20000U)
+#define osSemaphoreDef(name) \
+const osSemaphoreDef_t os_semaphore_def_##name = { 0 }
+#else
+#define osSemaphoreDef(name) \
+static os_semaphore_t os_semaphore_cb_##name __attribute__((section(".os.object.cb"))); \
+const osSemaphoreDef_t os_semaphore_def_##name = \
+{ NULL, 0U, (&os_semaphore_cb_##name), os_SemaphoreCbSize }
+#endif
+#endif
+ 
+/// Access a Semaphore definition.
+/// \param         name          name of the semaphore object.
+#define osSemaphore(name) \
+&os_semaphore_def_##name
+ 
+/// Create and Initialize a Semaphore object.
+/// \param[in]     semaphore_def semaphore definition referenced with \ref osSemaphore.
+/// \param[in]     count         maximum and initial number of available tokens.
+/// \return semaphore ID for reference by other functions or NULL in case of error.
+osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count);
+ 
+/// Wait until a Semaphore token becomes available.
+/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return number of available tokens, or -1 in case of incorrect parameters.
+int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec);
+ 
+/// Release a Semaphore token.
+/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
+/// \return status code that indicates the execution status of the function.
+#if (osCMSIS < 0x20000U)
+osStatus osSemaphoreRelease (osSemaphoreId semaphore_id);
+#endif
+ 
+/// Delete a Semaphore object.
+/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
+/// \return status code that indicates the execution status of the function.
+#if (osCMSIS < 0x20000U)
+osStatus osSemaphoreDelete (osSemaphoreId semaphore_id);
+#endif
+ 
+#endif  // Semaphore available
+ 
+ 
+//  ==== Memory Pool Management Functions ====
+ 
+#if (defined(osFeature_Pool) && (osFeature_Pool != 0))  // Memory Pool available
+ 
+/// \brief Define a Memory Pool.
+/// \param         name          name of the memory pool.
+/// \param         no            maximum number of blocks (objects) in the memory pool.
+/// \param         type          data type of a single block (object).
+#if defined (osObjectsExternal)  // object is external
+#define osPoolDef(name, no, type) \
+extern const osPoolDef_t os_pool_def_##name
+#else                            // define the object
+#if (osCMSIS < 0x20000U)
+#define osPoolDef(name, no, type) \
+const osPoolDef_t os_pool_def_##name = \
+{ (no), sizeof(type), NULL }
+#else
+#define osPoolDef(name, no, type) \
+static os_memory_pool_t os_mp_cb_##name __attribute__((section(".os.object.cb"))); \
+static uint32_t os_mp_data_##name[os_MemoryPoolMemSize((no),sizeof(type))/4] __attribute__((section(".os.object.data"))); \
+const osPoolDef_t os_pool_def_##name = \
+{ (no), sizeof(type), \
+  { NULL, 0U, (&os_mp_cb_##name), os_MemoryPoolCbSize, \
+              (&os_mp_data_##name), sizeof(os_mp_data_##name) } }
+#endif
+#endif
+ 
+/// \brief Access a Memory Pool definition.
+/// \param         name          name of the memory pool
+#define osPool(name) \
+&os_pool_def_##name
+ 
+/// Create and Initialize a Memory Pool object.
+/// \param[in]     pool_def      memory pool definition referenced with \ref osPool.
+/// \return memory pool ID for reference by other functions or NULL in case of error.
+osPoolId osPoolCreate (const osPoolDef_t *pool_def);
+ 
+/// Allocate a memory block from a Memory Pool.
+/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+/// \return address of the allocated memory block or NULL in case of no memory available.
+void *osPoolAlloc (osPoolId pool_id);
+ 
+/// Allocate a memory block from a Memory Pool and set memory block to zero.
+/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+/// \return address of the allocated memory block or NULL in case of no memory available.
+void *osPoolCAlloc (osPoolId pool_id);
+ 
+/// Return an allocated memory block back to a Memory Pool.
+/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+/// \param[in]     block         address of the allocated memory block to be returned to the memory pool.
+/// \return status code that indicates the execution status of the function.
+osStatus osPoolFree (osPoolId pool_id, void *block);
+ 
+#endif  // Memory Pool available
+ 
+ 
+//  ==== Message Queue Management Functions ====
+ 
+#if (defined(osFeature_MessageQ) && (osFeature_MessageQ != 0))  // Message Queue available
+  
+/// \brief Create a Message Queue Definition.
+/// \param         name          name of the queue.
+/// \param         queue_sz      maximum number of messages in the queue.
+/// \param         type          data type of a single message element (for debugger).
+#if defined (osObjectsExternal)  // object is external
+#define osMessageQDef(name, queue_sz, type) \
+extern const osMessageQDef_t os_messageQ_def_##name
+#else                            // define the object
+#if (osCMSIS < 0x20000U)
+#define osMessageQDef(name, queue_sz, type) \
+const osMessageQDef_t os_messageQ_def_##name = \
+{ (queue_sz), NULL }
+#else
+#define osMessageQDef(name, queue_sz, type) \
+static os_message_queue_t os_mq_cb_##name __attribute__((section(".os.object.cb"))); \
+static uint32_t os_mq_data_##name[os_MessageQueueMemSize((queue_sz),sizeof(uint32_t))/4] __attribute__((section(".os.object.data"))); \
+const osMessageQDef_t os_messageQ_def_##name = \
+{ (queue_sz), \
+  { NULL, 0U, (&os_mq_cb_##name), os_MessageQueueCbSize, \
+              (&os_mq_data_##name), sizeof(os_mq_data_##name) } }
+#endif
+#endif
+ 
+/// \brief Access a Message Queue Definition.
+/// \param         name          name of the queue
+#define osMessageQ(name) \
+&os_messageQ_def_##name
+ 
+/// Create and Initialize a Message Queue object.
+/// \param[in]     queue_def     message queue definition referenced with \ref osMessageQ.
+/// \param[in]     thread_id     thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
+/// \return message queue ID for reference by other functions or NULL in case of error.
+osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id);
+ 
+/// Put a Message to a Queue.
+/// \param[in]     queue_id      message queue ID obtained with \ref osMessageCreate.
+/// \param[in]     info          message information.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return status code that indicates the execution status of the function.
+osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec);
+ 
+/// Get a Message from a Queue or timeout if Queue is empty.
+/// \param[in]     queue_id      message queue ID obtained with \ref osMessageCreate.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return event information that includes status code.
+osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec);
+ 
+#endif  // Message Queue available
+ 
+ 
+//  ==== Mail Queue Management Functions ====
+ 
+#if (defined(osFeature_MailQ) && (osFeature_MailQ != 0))  // Mail Queue available
+ 
+/// \brief Create a Mail Queue Definition.
+/// \param         name          name of the queue.
+/// \param         queue_sz      maximum number of mails in the queue.
+/// \param         type          data type of a single mail element.
+#if defined (osObjectsExternal)  // object is external
+#define osMailQDef(name, queue_sz, type) \
+extern const osMailQDef_t os_mailQ_def_##name
+#else                            // define the object
+#if (osCMSIS < 0x20000U)
+#define osMailQDef(name, queue_sz, type) \
+const osMailQDef_t os_mailQ_def_##name = \
+{ (queue_sz), sizeof(type), NULL }
+#else
+#define osMailQDef(name, queue_sz, type) \
+static void              *os_mail_p_##name[2]  __attribute__((section(".os.object.cb"))); \
+static os_memory_pool_t   os_mail_mp_cb_##name __attribute__((section(".os.object.cb"))); \
+static os_message_queue_t os_mail_mq_cb_##name __attribute__((section(".os.object.cb"))); \
+static uint32_t os_mail_mp_data_##name[os_MemoryPoolMemSize  ((queue_sz),sizeof(type))/4] __attribute__((section(".os.object.data"))); \
+static uint32_t os_mail_mq_data_##name[os_MessageQueueMemSize((queue_sz),sizeof(type))/4] __attribute__((section(".os.object.data"))); \
+const osMailQDef_t os_mailQ_def_##name = \
+{ (queue_sz), sizeof(type), (&os_mail_p_##name), \
+  { NULL, 0U, (&os_mail_mp_cb_##name), os_MemoryPoolCbSize, \
+              (&os_mail_mp_data_##name), sizeof(os_mail_mp_data_##name) }, \
+  { NULL, 0U, (&os_mail_mq_cb_##name), os_MessageQueueCbSize, \
+              (&os_mail_mq_data_##name), sizeof(os_mail_mq_data_##name) } }
+#endif
+#endif
+ 
+/// \brief Access a Mail Queue Definition.
+/// \param         name          name of the queue
+#define osMailQ(name) \
+&os_mailQ_def_##name
+ 
+/// Create and Initialize a Mail Queue object.
+/// \param[in]     queue_def     mail queue definition referenced with \ref osMailQ.
+/// \param[in]     thread_id     thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
+/// \return mail queue ID for reference by other functions or NULL in case of error.
+osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id);
+ 
+/// Allocate a memory block for mail from a mail memory pool.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
+/// \return pointer to memory block that can be filled with mail or NULL in case of error.
+void *osMailAlloc (osMailQId queue_id, uint32_t millisec);
+ 
+/// Allocate a memory block for mail from a mail memory pool and set memory block to zero.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
+/// \return pointer to memory block that can be filled with mail or NULL in case of error.
+void *osMailCAlloc (osMailQId queue_id, uint32_t millisec);
+ 
+/// Put a Mail into a Queue.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     mail          pointer to memory with mail to put into a queue.
+/// \return status code that indicates the execution status of the function.
+osStatus osMailPut (osMailQId queue_id, const void *mail);
+ 
+/// Get a Mail from a Queue or timeout if Queue is empty.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return event information that includes status code.
+osEvent osMailGet (osMailQId queue_id, uint32_t millisec);
+ 
+/// Free a memory block by returning it to a mail memory pool.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     mail          pointer to memory block that was obtained with \ref osMailGet.
+/// \return status code that indicates the execution status of the function.
+osStatus osMailFree (osMailQId queue_id, void *mail);
+ 
+#endif  // Mail Queue available
+ 
+ 
+#ifdef  __cplusplus
+}
+#endif
+ 
+#endif  // __CMSIS_OS_H
diff --git a/CMSIS/RTOS2/RTX/Include/cmsis_os2.h b/CMSIS/RTOS2/RTX/Include/cmsis_os2.h
new file mode 100644
index 0000000..67b4791
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Include/cmsis_os2.h
@@ -0,0 +1,667 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ----------------------------------------------------------------------
+ *
+ * $Date:        30. June 2016
+ * $Revision:    V2.0
+ *
+ * Project:      CMSIS-RTOS2 API
+ * Title:        cmsis_os2.h header file
+ *
+ * Version 2.0
+ *    Initial Release
+ *---------------------------------------------------------------------------*/
+ 
+#ifndef __CMSIS_OS2_H
+#define __CMSIS_OS2_H
+ 
+#if   defined(__CC_ARM)
+#define __NO_RETURN __declspec(noreturn)
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+#define __NO_RETURN __attribute__((noreturn))
+#elif defined(__GNUC__)
+#define __NO_RETURN __attribute__((noreturn))
+#elif defined(__ICCARM__)
+#define __NO_RETURN __noreturn
+#else
+#define __NO_RETURN
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+ 
+#ifdef  __cplusplus
+extern "C"
+{
+#endif
+ 
+ 
+//  ==== Enumerations, structures, defines ====
+
+/// Version information.
+typedef struct osVersion_s {
+  uint32_t                       api;   ///< API version (major.minor.rev: mmnnnrrrr dec).
+  uint32_t                    kernel;   ///< Kernel version (major.minor.rev: mmnnnrrrr dec).
+} osVersion_t;
+ 
+/// Kernel state.
+typedef enum {
+  osKernelInactive        =  0,         ///< Inactive.
+  osKernelReady           =  1,         ///< Ready.
+  osKernelRunning         =  2,         ///< Running.
+  osKernelLocked          =  3,         ///< Locked.
+  osKernelSuspended       =  4,         ///< Suspended.
+  osKernelError           = -1,         ///< Error.
+  osKernelReserved        = 0x7FFFFFFFU ///< Prevents enum down-size compiler optimization.
+} osKernelState_t;
+ 
+/// Thread state.
+typedef enum {
+  osThreadInactive        =  0,         ///< Inactive.
+  osThreadReady           =  1,         ///< Ready.
+  osThreadRunning         =  2,         ///< Running.
+  osThreadWaiting         =  3,         ///< Waiting.
+  osThreadSuspended       =  4,         ///< Suspended.
+  osThreadTerminated      =  5,         ///< Terminated.
+  osThreadError           = -1,         ///< Error.
+  osThreadReserved        = 0x7FFFFFFF  ///< Prevents enum down-size compiler optimization.
+} osThreadState_t;
+ 
+/// Priority values.
+typedef enum {
+  osPriorityNone          =  0,         ///< No priority (not initialized).
+  osPriorityIdle          =  1,         ///< Reserved for Idle thread.
+  osPriorityLow           =  8,         ///< Priority: low
+  osPriorityLow1          =  8+1,       ///< Priority: low + 1
+  osPriorityLow2          =  8+2,       ///< Priority: low + 2
+  osPriorityLow3          =  8+3,       ///< Priority: low + 3
+  osPriorityLow4          =  8+4,       ///< Priority: low + 4
+  osPriorityLow5          =  8+5,       ///< Priority: low + 5
+  osPriorityLow6          =  8+6,       ///< Priority: low + 6
+  osPriorityLow7          =  8+7,       ///< Priority: low + 7
+  osPriorityBelowNormal   = 16,         ///< Priority: below normal
+  osPriorityBelowNormal1  = 16+1,       ///< Priority: below normal + 1
+  osPriorityBelowNormal2  = 16+2,       ///< Priority: below normal + 2
+  osPriorityBelowNormal3  = 16+3,       ///< Priority: below normal + 3
+  osPriorityBelowNormal4  = 16+4,       ///< Priority: below normal + 4
+  osPriorityBelowNormal5  = 16+5,       ///< Priority: below normal + 5
+  osPriorityBelowNormal6  = 16+6,       ///< Priority: below normal + 6
+  osPriorityBelowNormal7  = 16+7,       ///< Priority: below normal + 7
+  osPriorityNormal        = 24,         ///< Priority: normal
+  osPriorityNormal1       = 24+1,       ///< Priority: normal + 1
+  osPriorityNormal2       = 24+2,       ///< Priority: normal + 2
+  osPriorityNormal3       = 24+3,       ///< Priority: normal + 3
+  osPriorityNormal4       = 24+4,       ///< Priority: normal + 4
+  osPriorityNormal5       = 24+5,       ///< Priority: normal + 5
+  osPriorityNormal6       = 24+6,       ///< Priority: normal + 6
+  osPriorityNormal7       = 24+7,       ///< Priority: normal + 7
+  osPriorityAboveNormal   = 32,         ///< Priority: above normal
+  osPriorityAboveNormal1  = 32+1,       ///< Priority: above normal + 1
+  osPriorityAboveNormal2  = 32+2,       ///< Priority: above normal + 2
+  osPriorityAboveNormal3  = 32+3,       ///< Priority: above normal + 3
+  osPriorityAboveNormal4  = 32+4,       ///< Priority: above normal + 4
+  osPriorityAboveNormal5  = 32+5,       ///< Priority: above normal + 5
+  osPriorityAboveNormal6  = 32+6,       ///< Priority: above normal + 6
+  osPriorityAboveNormal7  = 32+7,       ///< Priority: above normal + 7
+  osPriorityHigh          = 40,         ///< Priority: high
+  osPriorityHigh1         = 40+1,       ///< Priority: high + 1
+  osPriorityHigh2         = 40+2,       ///< Priority: high + 2
+  osPriorityHigh3         = 40+3,       ///< Priority: high + 3
+  osPriorityHigh4         = 40+4,       ///< Priority: high + 4
+  osPriorityHigh5         = 40+5,       ///< Priority: high + 5
+  osPriorityHigh6         = 40+6,       ///< Priority: high + 6
+  osPriorityHigh7         = 40+7,       ///< Priority: high + 7
+  osPriorityRealtime      = 48,         ///< Priority: realtime
+  osPriorityRealtime1     = 48+1,       ///< Priority: realtime + 1
+  osPriorityRealtime2     = 48+2,       ///< Priority: realtime + 2
+  osPriorityRealtime3     = 48+3,       ///< Priority: realtime + 3
+  osPriorityRealtime4     = 48+4,       ///< Priority: realtime + 4
+  osPriorityRealtime5     = 48+5,       ///< Priority: realtime + 5
+  osPriorityRealtime6     = 48+6,       ///< Priority: realtime + 6
+  osPriorityRealtime7     = 48+7,       ///< Priority: realtime + 7
+  osPriorityISR           = 56,         ///< Reserved for ISR deferred thread.
+  osPriorityError         = -1,         ///< System cannot determine priority or illegal priority.
+  osPriorityReserved      = 0x7FFFFFFF  ///< Prevents enum down-size compiler optimization.
+} osPriority_t;
+
+/// Entry point of a thread.
+typedef void *(*os_thread_func_t) (void *argument);
+ 
+/// Entry point of a timer call back function.
+typedef void (*os_timer_func_t) (void *argument);
+ 
+/// Timer type.
+typedef enum {
+  osTimerOnce             = 0,          ///< One-shot timer.
+  osTimerPeriodic         = 1           ///< Repeating timer.
+} osTimerType_t;
+ 
+/// Timeout value.
+#define osWaitForever       0xFFFFFFFFU ///< Wait forever timeout value.
+ 
+/// Flags options (\ref osThreadFlagsWait and \ref osEventFlagsWait).
+#define osFlagsWaitAny      0x00000000U ///< Wait for any flag (default).
+#define osFlagsWaitAll      0x00000001U ///< Wait for all flags.
+#define osFlagsAutoClear    0x00000002U ///< Clear flags which have been specified to wait for.
+ 
+/// Thread attributes (attr_bits in \ref osThreadAttr_t).
+#define osThreadJoinable    0x00000000U ///< Thread created in joinable state (default)
+#define osThreadDetached    0x00000001U ///< Thread created in detached state
+ 
+/// Mutex attributes (attr_bits in \ref osMutexAttr_t).
+#define osMutexRecursive    0x00000001U ///< Recursive mutex.
+#define osMutexPrioInherit  0x00000002U ///< Priority inherit protocol.
+#define osMutexRobust       0x00000008U ///< Robust mutex.
+ 
+/// Status code values returned by CMSIS-RTOS functions.
+typedef enum {
+  osOK                    =  0,         ///< Operation completed successfully.
+  osError                 = -1,         ///< Unspecified RTOS error: run-time error but no other error message fits.
+  osErrorTimeout          = -2,         ///< Operation not completed within the timeout period.
+  osErrorResource         = -3,         ///< Resource not available.
+  osErrorParameter        = -4,         ///< Parameter error.
+  osErrorNoMemory         = -5,         ///< System is out of memory: it was impossible to allocate or reserve memory for the operation.
+  osErrorISR              = -6,         ///< Not allowed in ISR context: the function cannot be called from interrupt service routines.
+  osStatusReserved        = 0x7FFFFFFF  ///< Prevents enum down-size compiler optimization.
+} osStatus_t;
+ 
+ 
+/// \details Thread ID identifies the thread.
+typedef uint32_t osThreadId_t;
+ 
+/// \details Timer ID identifies the timer.
+typedef uint32_t osTimerId_t;
+ 
+/// \details Event Flags ID identifies the event flags.
+typedef uint32_t osEventFlagsId_t;
+ 
+/// \details Mutex ID identifies the mutex.
+typedef uint32_t osMutexId_t;
+ 
+/// \details Semaphore ID identifies the semaphore.
+typedef uint32_t osSemaphoreId_t;
+ 
+/// \details Memory Pool ID identifies the memory pool.
+typedef uint32_t osMemoryPoolId_t;
+ 
+/// \details Message Queue ID identifies the message queue.
+typedef uint32_t osMessageQueueId_t;
+ 
+ 
+/// Attributes structure for thread.
+typedef struct osThreadAttr_s {
+  const char                   *name;   ///< name of the thread
+  uint32_t                 attr_bits;   ///< attribute bits
+  void                      *cb_mem;    ///< memory for control block
+  uint32_t                   cb_size;   ///< size of provided memory for control block
+  void                   *stack_mem;    ///< memory for stack
+  uint32_t                stack_size;   ///< size of stack
+  osPriority_t              priority;   ///< initial thread priority (default: osPriorityNormal)
+  uint32_t               reserved[2];   ///< reserved (must be 0)
+} osThreadAttr_t;
+ 
+/// Attributes structure for timer.
+typedef struct osTimerAttr_s {
+  const char                   *name;   ///< name of the timer
+  uint32_t                 attr_bits;   ///< attribute bits
+  void                      *cb_mem;    ///< memory for control block
+  uint32_t                   cb_size;   ///< size of provided memory for control block
+} osTimerAttr_t;
+ 
+/// Attributes structure for event flags.
+typedef struct osEventFlagsAttr_s {
+  const char                   *name;   ///< name of the event flags
+  uint32_t                 attr_bits;   ///< attribute bits
+  void                      *cb_mem;    ///< memory for control block
+  uint32_t                   cb_size;   ///< size of provided memory for control block
+} osEventFlagsAttr_t;
+ 
+/// Attributes structure for mutex.
+typedef struct osMutexAttr_s {
+  const char                   *name;   ///< name of the mutex
+  uint32_t                 attr_bits;   ///< attribute bits
+  void                      *cb_mem;    ///< memory for control block
+  uint32_t                   cb_size;   ///< size of provided memory for control block
+} osMutexAttr_t;
+ 
+/// Attributes structure for semaphore.
+typedef struct osSemaphoreAttr_s {
+  const char                   *name;   ///< name of the semaphore
+  uint32_t                 attr_bits;   ///< attribute bits
+  void                      *cb_mem;    ///< memory for control block
+  uint32_t                   cb_size;   ///< size of provided memory for control block
+} osSemaphoreAttr_t;
+ 
+/// Attributes structure for memory pool.
+typedef struct osMemoryPoolAttr_s {
+  const char                   *name;   ///< name of the memory pool
+  uint32_t                 attr_bits;   ///< attribute bits
+  void                      *cb_mem;    ///< memory for control block
+  uint32_t                   cb_size;   ///< size of provided memory for control block
+  void                      *mp_mem;    ///< memory for data storage
+  uint32_t                   mp_size;   ///< size of provided memory for data storage 
+} osMemoryPoolAttr_t;
+ 
+/// Attributes structure for message queue.
+typedef struct osMessageQueueAttr_s {
+  const char                   *name;   ///< name of the message queue
+  uint32_t                 attr_bits;   ///< attribute bits
+  void                      *cb_mem;    ///< memory for control block
+  uint32_t                   cb_size;   ///< size of provided memory for control block
+  void                      *mq_mem;    ///< memory for data storage
+  uint32_t                   mq_size;   ///< size of provided memory for data storage 
+} osMessageQueueAttr_t;
+ 
+ 
+//  ==== Kernel Management Functions ====
+ 
+/// Initialize the RTOS Kernel.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osKernelInitialize (void);
+ 
+///  Get RTOS Kernel Information.
+/// \param[out]    version       pointer to buffer for retrieving version information.
+/// \param[out]    id_buf        pointer to buffer for retrieving kernel identification string.
+/// \param[in]     id_size       maximum size of buffer for kernel identification string.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size);
+ 
+/// Get the current RTOS Kernel state.
+/// \return current RTOS Kernel state.
+osKernelState_t osKernelGetState (void);
+ 
+/// Start the RTOS Kernel scheduler.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osKernelStart (void);
+ 
+/// Lock the RTOS Kernel scheduler.
+/// \return 0 already locked, 1 locked.
+uint32_t osKernelLock (void);
+ 
+/// Unlock the RTOS Kernel scheduler.
+void osKernelUnlock (void);
+ 
+/// Suspend the RTOS Kernel scheduler.
+/// \return time in millisec, for how long the system can sleep or power-down.
+uint32_t osKernelSuspend (void);
+ 
+/// Resume the RTOS Kernel scheduler.
+/// \param[in]     sleep_time    time in millisec for how long the system was in sleep or power-down mode.
+void osKernelResume (uint32_t sleep_time);
+ 
+/// Get the RTOS kernel time.
+/// \return RTOS kernel current time in millisec.
+uint64_t osKernelGetTime (void);
+ 
+/// Get the RTOS kernel system timer counter.
+/// \return RTOS kernel system timer as 32-bit value.
+uint32_t osKernelGetTick (void);
+ 
+/// Convert a microseconds value to a RTOS kernel system timer value.
+/// \param         microsec     time value in microseconds.
+/// \return time value normalized to the system timer ticks.
+uint32_t osKernelTickMicroSec (uint32_t microsec);
+ 
+ 
+//  ==== Thread Management Functions ====
+ 
+/// Create a thread and add it to Active Threads.
+/// \param[in]     func          thread function.
+/// \param[in]     argument      pointer that is passed to the thread function as start argument.
+/// \param[in]     attr          thread attributes; NULL: default values.
+/// \return thread ID for reference by other functions or NULL in case of error.
+osThreadId_t osThreadNew (os_thread_func_t func, void *argument, const osThreadAttr_t *attr);
+ 
+/// Return the thread ID of the current running thread.
+/// \return thread ID for reference by other functions or NULL in case of error.
+osThreadId_t osThreadGetId (void);
+ 
+/// Get current thread state of a thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
+/// \return current thread state of the specified thread.
+osThreadState_t osThreadGetState (osThreadId_t thread_id);
+ 
+/// Change priority of a thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
+/// \param[in]     priority      new priority value for the thread function.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority);
+ 
+/// Get current priority of a thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
+/// \return current priority value of the specified thread.
+osPriority_t osThreadGetPriority (osThreadId_t thread_id);
+ 
+/// Pass control to next thread that is in state \b READY.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osThreadYield (void);
+ 
+/// Abort waiting operation of a thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osThreadAbortWait (osThreadId_t thread_id);
+ 
+/// Suspend execution of a thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osThreadSuspend (osThreadId_t thread_id);
+ 
+/// Resume execution of a thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osThreadResume (osThreadId_t thread_id);
+ 
+/// Detach a thread (thread storage can be reclaimed when thread terminates).
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osThreadDetach (osThreadId_t thread_id);
+ 
+/// Wait for specified thread to terminate.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
+/// \param[out]    exit_ptr      pointer to thread exit pointer value.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osThreadJoin (osThreadId_t thread_id, void **exit_ptr);
+ 
+/// Terminate execution of current running thread.
+/// \param[in]     exit_ptr      thread exit pointer value.
+__NO_RETURN void osThreadExit (void *exit_ptr);
+ 
+/// Terminate execution of a thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osThreadTerminate (osThreadId_t thread_id);
+ 
+ 
+//  ==== Thread Flags Functions ====
+ 
+/// Set the specified Thread Flags of a thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
+/// \param[in]     flags         specifies the flags of the thread that shall be set.
+/// \return thread flags after setting or error code if negative.
+int32_t osThreadFlagsSet (osThreadId_t thread_id, int32_t flags);
+ 
+/// Clear the specified Thread Flags of a thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
+/// \param[in]     flags         specifies the flags of the thread that shall be cleared.
+/// \return thread flags before clearing or error code if negative.
+int32_t osThreadFlagsClear (osThreadId_t thread_id, int32_t flags);
+ 
+/// Get the current Thread Flags of a thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
+/// \return current thread flags.
+int32_t osThreadFlagsGet (osThreadId_t thread_id);
+ 
+/// Wait for one or more Thread Flags of the current running thread to become signaled.
+/// \param[in]     flags         specifies the flags to wait for.
+/// \param[in]     options       specifies flags options (osFlagsXxxx).
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return thread flags before clearing or error code if negative.
+int32_t osThreadFlagsWait (int32_t flags, uint32_t options, uint32_t millisec);
+ 
+ 
+//  ==== Generic Wait Functions ====
+ 
+/// Wait for Timeout (Time Delay).
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue "time delay" value
+/// \return status code that indicates the execution status of the function.
+osStatus_t osDelay (uint32_t millisec);
+ 
+/// Wait until specified time.
+/// \param[in]     millisec      absolute time in millisec
+/// \return status code that indicates the execution status of the function.
+osStatus_t osDelayUntil (uint64_t millisec);
+ 
+ 
+//  ==== Timer Management Functions ====
+ 
+/// Create and Initialize a timer.
+/// \param[in]     func          start address of a timer call back function.
+/// \param[in]     type          osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
+/// \param[in]     argument      argument to the timer call back function.
+/// \param[in]     attr          timer attributes; NULL: default values.
+/// \return timer ID for reference by other functions or NULL in case of error.
+osTimerId_t osTimerNew (os_timer_func_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr);
+ 
+/// Start or restart a timer.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerNew.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue "time delay" value of the timer.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t millisec);
+ 
+/// Stop a timer.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerNew.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osTimerStop (osTimerId_t timer_id);
+ 
+/// Check if a timer is running.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerNew.
+/// \return 0 not running, 1 running.
+uint32_t osTimerIsRunning (osTimerId_t timer_id);
+ 
+/// Delete a timer.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerNew.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osTimerDelete (osTimerId_t timer_id);
+ 
+ 
+//  ==== Event Flags Management Functions ====
+ 
+/// Create and Initialize an Event Flags object.
+/// \param[in]     attr          event flags attributes; NULL: default values.
+/// \return event flags ID for reference by other functions or NULL in case of error.
+osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr);
+ 
+/// Set the specified Event Flags.
+/// \param[in]     ef_id         event flags ID obtained by \ref osEventFlagsNew.
+/// \param[in]     flags         specifies the flags that shall be set.
+/// \return event flags after setting or error code if negative.
+int32_t osEventFlagsSet (osEventFlagsId_t ef_id, int32_t flags);
+ 
+/// Clear the specified Event Flags.
+/// \param[in]     ef_id         event flags ID obtained by \ref osEventFlagsNew.
+/// \param[in]     flags         specifies the flags that shall be cleared.
+/// \return event flags before clearing or error code if negative.
+int32_t osEventFlagsClear (osEventFlagsId_t ef_id, int32_t flags);
+ 
+/// Get the current Event Flags.
+/// \param[in]     ef_id         event flags ID obtained by \ref osEventFlagsNew.
+/// \return current event flags.
+int32_t osEventFlagsGet (osEventFlagsId_t ef_id);
+ 
+/// Wait for one or more Event Flags to become signaled.
+/// \param[in]     ef_id         event flags ID obtained by \ref osEventFlagsNew.
+/// \param[in]     flags         specifies the flags to wait for.
+/// \param[in]     options       specifies flags options (osFlagsXxxx).
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return event flags before clearing or error code if negative.
+int32_t osEventFlagsWait (osEventFlagsId_t ef_id, int32_t flags, uint32_t options, uint32_t millisec);
+ 
+/// Delete an Event Flags object.
+/// \param[in]     ef_id         event flags ID obtained by \ref osEventFlagsNew.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id);
+ 
+ 
+//  ==== Mutex Management Functions ====
+ 
+/// Create and Initialize a Mutex object.
+/// \param[in]     attr          mutex attributes; NULL: default values.
+/// \return mutex ID for reference by other functions or NULL in case of error.
+osMutexId_t osMutexNew (const osMutexAttr_t *attr);
+ 
+/// Acquire a Mutex or timeout if it is locked.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexNew.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t millisec);
+ 
+/// Release a Mutex that was acquired by \ref osMutexAcquire.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexNew.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osMutexRelease (osMutexId_t mutex_id);
+ 
+/// Get Thread which owns a Mutex object.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexNew.
+/// \return thread ID of owner thread or NULL when mutex was not acquired.
+osThreadId_t osMutexGetOwner (osMutexId_t mutex_id);
+ 
+/// Delete a Mutex object.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexNew.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osMutexDelete (osMutexId_t mutex_id);
+ 
+ 
+//  ==== Semaphore Management Functions ====
+ 
+/// Create and Initialize a Semaphore object.
+/// \param[in]     max_count     maximum number of available tokens.
+/// \param[in]     initial_count initial number of available tokens.
+/// \param[in]     attr          semaphore attributes; NULL: default values.
+/// \return semaphore ID for reference by other functions or NULL in case of error.
+osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr);
+ 
+/// Acquire a Semaphore token or timeout if no tokens are available.
+/// \param[in]     semaphore_id  semaphore ID obtained by \ref osSemaphoreNew.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t millisec);
+ 
+/// Release a Semaphore token that was acquired by \ref osSemaphoreAcquire.
+/// \param[in]     semaphore_id  semaphore ID obtained by \ref osSemaphoreNew.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id);
+ 
+/// Get current Semaphore token count.
+/// \param[in]     semaphore_id  semaphore ID obtained by \ref osSemaphoreNew.
+/// \return number of tokens available.
+uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id);
+ 
+/// Delete a Semaphore object.
+/// \param[in]     semaphore_id  semaphore ID obtained by \ref osSemaphoreNew.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id);
+ 
+ 
+//  ==== Memory Pool Management Functions ====
+ 
+/// Create and Initialize a Memory Pool object.
+/// \param[in]     block_count   maximum number of memory blocks in memory pool.
+/// \param[in]     block_size    memory block size in bytes.
+/// \param[in]     attr          memory pool attributes; NULL: default values.
+/// \return memory pool ID for reference by other functions or NULL in case of error.
+osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr);
+ 
+/// Allocate a memory block from a Memory Pool.
+/// \param[in]     mp_id         memory pool ID obtained by \ref osMemoryPoolNew.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return address of the allocated memory block or NULL in case of no memory is available.
+void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t millisec);
+ 
+/// Return an allocated memory block back to a Memory Pool.
+/// \param[in]     mp_id         memory pool ID obtained by \ref osMemoryPoolNew.
+/// \param[in]     block         address of the allocated memory block to be returned to the memory pool.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block);
+ 
+/// Get maximum number of memory blocks in a Memory Pool.
+/// \param[in]     mp_id         memory pool ID obtained by \ref osMemoryPoolNew.
+/// \return maximum number of memory blocks.
+uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id);
+ 
+/// Get memory block size in a Memory Pool.
+/// \param[in]     mp_id         memory pool ID obtained by \ref osMemoryPoolNew.
+/// \return memory block size in bytes.
+uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id);
+ 
+/// Get number of memory blocks used in a Memory Pool.
+/// \param[in]     mp_id         memory pool ID obtained by \ref osMemoryPoolNew.
+/// \return number of memory blocks used.
+uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id);
+ 
+/// Get number of memory blocks available in a Memory Pool.
+/// \param[in]     mp_id         memory pool ID obtained by \ref osMemoryPoolNew.
+/// \return number of memory blocks available.
+uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id);
+ 
+/// Delete a Memory Pool object.
+/// \param[in]     mp_id         memory pool ID obtained by \ref osMemoryPoolNew.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id);
+ 
+ 
+//  ==== Message Queue Management Functions ====
+ 
+/// Create and Initialize a Message Queue object.
+/// \param[in]     msg_count     maximum number of messages in queue.
+/// \param[in]     msg_size      maximum message size in bytes.
+/// \param[in]     attr          message queue attributes; NULL: default values.
+/// \return message queue ID for reference by other functions or NULL in case of error.
+osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr);
+ 
+/// Put a Message into a Queue or timeout if Queue is full.
+/// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew.
+/// \param[in]     msg_ptr       pointer to buffer with message to put into a queue.
+/// \param[in]     msg_prio      message priority.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t millisec);
+ 
+/// Get a Message from a Queue or timeout if Queue is empty.
+/// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew.
+/// \param[out]    msg_ptr       pointer to buffer for message to get from a queue.
+/// \param[out]    msg_prio      pointer to buffer for message priority or NULL.
+/// \param[in]     millisec      \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t millisec);
+ 
+/// Get maximum number of messages in a Message Queue.
+/// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew.
+/// \return maximum number of messages.
+uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id);
+ 
+/// Get maximum message size in a Memory Pool.
+/// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew.
+/// \return maximum message size in bytes.
+uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id);
+ 
+/// Get number of queued messages in a Message Queue.
+/// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew.
+/// \return number of queued messages.
+uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id);
+ 
+/// Get number of available slots for messages in a Message Queue.
+/// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew.
+/// \return number of available slots for messages.
+uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id);
+ 
+/// Reset a Message Queue to initial empty state.
+/// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id);
+ 
+/// Delete a Message Queue object.
+/// \param[in]     mq_id         message queue ID obtained by \ref osMessageQueueNew.
+/// \return status code that indicates the execution status of the function.
+osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id);
+ 
+ 
+#ifdef  __cplusplus
+}
+#endif
+ 
+#endif  // __CMSIS_OS2_H
diff --git a/CMSIS/RTOS2/RTX/Include/rtx_config.h b/CMSIS/RTOS2/RTX/Include/rtx_config.h
new file mode 100644
index 0000000..d132645
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Include/rtx_config.h
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       RTX Library Configuration
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#include "cmsis_os2.h"
+#include "rtx_os.h"
+
+
+// Thread Configuration
+// ====================
+
+#if (((OS_STACK_SIZE & 7) != 0) || (OS_STACK_SIZE < 72))
+#error "Invalid default Thread Stack size!"
+#endif
+
+#if (((OS_IDLE_THREAD_STACK_SIZE & 7) != 0) || (OS_IDLE_THREAD_STACK_SIZE < 72))
+#error "Invalid Idle Thread Stack size!"
+#endif
+
+
+#if (OS_THREAD_STATIC != 0)
+
+#define OS_THREAD_DEF_STACK_NUM (OS_THREAD_NUM - OS_THREAD_USER_STACK_NUM)
+
+#if ((OS_THREAD_NUM == 0) || (OS_THREAD_DEF_STACK_NUM < 0))
+#error "Invalid number of user Threads!"
+#endif
+
+// Thread Control Blocks
+static os_thread_t os_thread_cb[OS_THREAD_NUM] \
+__attribute__((section(".os.object.cb")));
+
+// Thread Default Stack
+#if (OS_THREAD_DEF_STACK_NUM != 0)
+static uint64_t os_thread_stack[OS_THREAD_DEF_STACK_NUM*(OS_STACK_SIZE/8)] \
+__attribute__((section(".os.object.stack")));
+#endif
+
+// Memory Pool for Thread Control Blocks
+static os_mp_info_t os_mpi_thread \
+__attribute__((section(".os.object.cb"))) =
+{ (uint32_t)OS_THREAD_NUM, 0U, (uint32_t)os_ThreadCbSize, &os_thread_cb, NULL, NULL };
+
+// Memory Pool for Thread Default Stack
+#if (OS_THREAD_DEF_STACK_NUM != 0)
+static os_mp_info_t os_mpi_stack \
+__attribute__((section(".os.object.cb"))) =
+{ (uint32_t)OS_THREAD_DEF_STACK_NUM, 0U, (uint32_t)OS_STACK_SIZE, &os_thread_stack, NULL, NULL };
+#endif
+
+#endif  // (OS_THREAD_STATIC != 0)
+
+
+// Stack overrun checking
+#if (OS_STACK_CHECK == 0)
+// Override library function
+void os_ThreadStackCheck (void);
+void os_ThreadStackCheck (void) {}
+#endif
+
+
+// Idle Thread Control Block
+static os_thread_t os_idle_thread_cb \
+__attribute__((section(".os.object.cb")));
+
+// Idle Thread Stack
+static uint64_t os_idle_thread_stack[OS_IDLE_THREAD_STACK_SIZE/8] \
+__attribute__((section(".os.object.stack")));
+
+// Idle Thread Attributes
+static const osThreadAttr_t os_idle_thread_attr = {
+  NULL,
+  osThreadDetached,
+  &os_idle_thread_cb,
+  (uint32_t)sizeof(os_idle_thread_cb),
+  &os_idle_thread_stack,
+  (uint32_t)sizeof(os_idle_thread_stack),
+  osPriorityIdle,
+  { 0U, 0U }
+};
+
+
+// Timer Configuration
+// ===================
+
+#if (OS_TIMER_STATIC != 0)
+
+#if (OS_TIMER_NUM == 0)
+#error "Invalid number of user Timers!"
+#endif
+
+// Timer Control Blocks
+static os_timer_t os_timer_cb[OS_TIMER_NUM] \
+__attribute__((section(".os.object.cb")));
+
+// Memory Pool for Timer Control Blocks
+static os_mp_info_t os_mpi_timer \
+__attribute__((section(".os.object.cb"))) =
+{ (uint32_t)OS_TIMER_NUM, 0U, (uint32_t)os_TimerCbSize, &os_timer_cb, NULL, NULL };
+
+#endif  // (OS_TIMER_STATIC != 0)
+
+
+#if ((OS_TIMER_THREAD_STACK_SIZE > 0) && (OS_TIMER_CB_QUEUE > 0))
+
+#if (((OS_TIMER_THREAD_STACK_SIZE & 7) != 0) || (OS_TIMER_THREAD_STACK_SIZE < 96))
+#error "Invalid Timer Thread Stack size!"
+#endif
+
+// Timer Thread Control Block
+static os_thread_t os_timer_thread_cb \
+__attribute__((section(".os.object.cb")));
+
+// Timer Thread Stack
+static uint64_t os_timer_thread_stack[OS_TIMER_THREAD_STACK_SIZE/8] \
+__attribute__((section(".os.object.stack")));
+
+// Timer Thread Attributes
+static const osThreadAttr_t os_timer_thread_attr = {
+  NULL,
+  osThreadDetached,
+  &os_timer_thread_cb,
+  (uint32_t)sizeof(os_timer_thread_cb),
+  &os_timer_thread_stack,
+  (uint32_t)sizeof(os_timer_thread_stack),
+  (osPriority_t)OS_TIMER_THREAD_PRIO,
+  { 0U, 0U }
+};
+
+// Timer Message Queue Control Block
+static os_message_queue_t os_timer_mq_cb \
+__attribute__((section(".os.object.cb")));
+
+// Timer Message Queue Data
+static uint32_t os_timer_mq_data[os_MessageQueueMemSize(OS_TIMER_CB_QUEUE,8)/4] \
+__attribute__((section(".os.object.data")));
+
+// Timer Message Queue Attributes
+static const osMessageQueueAttr_t os_timer_mq_attr = {
+  NULL,
+  0U,
+  &os_timer_mq_cb,
+  (uint32_t)sizeof(os_timer_mq_cb),
+  &os_timer_mq_data,
+  (uint32_t)sizeof(os_timer_mq_data)
+};
+
+#endif  // ((OS_TIMER_THREAD_STACK_SIZE > 0) && (OS_TIMER_CB_QUEUE > 0))
+
+
+// Event Flags Configuration
+// =========================
+
+#if (OS_EVFLAGS_STATIC != 0)
+
+#if (OS_EVFLAGS_NUM == 0)
+#error "Invalid number of Event Flags objects!"
+#endif
+
+// Event Flags Control Blocks
+static os_event_flags_t os_ef_cb[OS_EVFLAGS_NUM] \
+__attribute__((section(".os.object.cb")));
+
+// Memory Pool for Event Flags Control Blocks
+static os_mp_info_t os_mpi_ef \
+__attribute__((section(".os.object.cb"))) =
+{ (uint32_t)OS_EVFLAGS_NUM, 0U, (uint32_t)os_EventFlagsCbSize, &os_ef_cb, NULL, NULL };
+
+#endif  // (OS_EVFLAGS_STATIC != 0)
+
+
+// Mutex Configuration
+// ===================
+
+#if (OS_MUTEX_STATIC != 0)
+
+#if (OS_MUTEX_NUM == 0)
+#error "Invalid number of Mutex objects!"
+#endif
+
+// Mutex Control Blocks
+static os_mutex_t os_mutex_cb[OS_MUTEX_NUM] \
+__attribute__((section(".os.object.cb")));
+
+// Memory Pool for Mutex Control Blocks
+static os_mp_info_t os_mpi_mutex \
+__attribute__((section(".os.object.cb"))) =
+{ (uint32_t)OS_MUTEX_NUM, 0U, (uint32_t)os_MutexCbSize, &os_mutex_cb, NULL, NULL };
+
+#endif  // (OS_MUTEX_STATIC != 0)
+
+
+// Semaphore Configuration
+// =======================
+
+#if (OS_SEMAPHORE_STATIC != 0)
+
+#if (OS_SEMAPHORE_NUM == 0)
+#error "Invalid number of Semaphore objects!"
+#endif
+
+// Semaphore Control Blocks
+static os_semaphore_t os_semaphore_cb[OS_SEMAPHORE_NUM] \
+__attribute__((section(".os.object.cb")));
+
+// Memory Pool for Semaphore Control Blocks
+static os_mp_info_t os_mpi_semaphore \
+__attribute__((section(".os.object.cb"))) =
+{ (uint32_t)OS_SEMAPHORE_NUM, 0U, (uint32_t)os_SemaphoreCbSize, &os_semaphore_cb, NULL, NULL };
+
+#endif  // (OS_SEMAPHORE_STATIC != 0)
+
+
+// Memory Pool Configuration
+// =========================
+
+#if (OS_MEMPOOL_STATIC != 0)
+
+#if (OS_MUTEX_NUM == 0)
+#error "Invalid number of Memory Pool objects!"
+#endif
+
+// Memory Pool Control Blocks
+static os_memory_pool_t os_mp_cb[OS_MEMPOOL_NUM] \
+__attribute__((section(".os.object.cb")));
+
+// Memory Pool for Memory Pool Control Blocks
+static os_mp_info_t os_mpi_mp \
+__attribute__((section(".os.object.cb"))) =
+{ (uint32_t)OS_MEMPOOL_NUM, 0U, (uint32_t)os_MemoryPoolCbSize, &os_mp_cb, NULL, NULL };
+
+#endif  // (OS_MEMPOOL_STATIC != 0)
+
+
+// Message Queue Configuration
+// ===========================
+
+#if (OS_MSGQUEUE_STATIC != 0)
+
+#if (OS_MUTEX_NUM == 0)
+#error "Invalid number of Message Queue objects!"
+#endif
+
+// Message Queue Control Blocks
+static os_message_queue_t os_mq_cb[OS_MSGQUEUE_NUM] \
+__attribute__((section(".os.object.cb")));
+
+// Memory Pool for Message Queue Control Blocks
+static os_mp_info_t os_mpi_mq \
+__attribute__((section(".os.object.cb"))) =
+{ (uint32_t)OS_MSGQUEUE_NUM, 0U, (uint32_t)os_MessageQueueCbSize, &os_mq_cb, NULL, NULL };
+
+#endif  // (OS_MSGQUEUE_STATIC != 0)
+
+
+// System Configuration
+// ====================
+
+#if (OS_DYNAMIC != 0)
+
+// Memory for Control Blocks
+#if (OS_DYNAMIC_MEM_CB_SIZE != 0)
+#if ((OS_DYNAMIC_MEM_CB_SIZE & 4) != 0)
+#error "Invalid memory size for Control Blocks!"
+#endif
+static uint32_t os_mem_cb[OS_DYNAMIC_MEM_CB_SIZE/4] \
+__attribute__((section(".os.object.cb")));
+#endif
+
+// Memory for Data Storage
+#if (OS_DYNAMIC_MEM_DATA_SIZE != 0)
+#if ((OS_DYNAMIC_MEM_DATA_SIZE & 4) != 0)
+#error "Invalid memory size for Data Storage!"
+#endif
+static uint32_t os_mem_data[OS_DYNAMIC_MEM_DATA_SIZE/4] \
+__attribute__((section(".os.object.data")));
+#endif
+
+// Memory for Stack
+#if (OS_DYNAMIC_MEM_STACK_SIZE != 0)
+#if ((OS_DYNAMIC_MEM_STACK_SIZE & 7) != 0)
+#error "Invalid memory size for Stack!"
+#endif
+static uint64_t os_mem_stack[OS_DYNAMIC_MEM_STACK_SIZE/8] \
+__attribute__((section(".os.object.stack")));
+#endif
+
+#endif  // (OS_DYNAMIC != 0)
+
+// Dynamic Memory
+#if (OS_DYNAMIC_MEM_SIZE != 0)
+#if ((OS_DYNAMIC_MEM_SIZE & 8) != 0)
+#error "Invalid Dynamic Memory size!"
+#endif
+static uint64_t os_mem[OS_DYNAMIC_MEM_SIZE/8] \
+__attribute__((section(".os.object")));
+#endif
+
+// ISR FIFO Queue
+static void *os_isr_queue[OS_ISR_FIFO_QUEUE] \
+__attribute__((section(".os.data")));
+
+
+// OS Configuration
+// ================
+
+const os_config_t os_Config = {
+  0U   // Flags
+#if (OS_PRIVILEGE_MODE != 0)
+  | os_ConfigPrivilegedMode
+#endif
+#if (OS_STACK_WATERMARK != 0)
+  | os_ConfigStackWatermark
+#endif
+  ,
+#if (OS_ROBIN_ENABLE != 0)
+  (uint32_t)OS_ROBIN_TIMEOUT,
+#else
+  0U,
+#endif
+  { &os_isr_queue[0], sizeof(os_isr_queue)/sizeof(void *), 0U },
+  { 
+    // Memory Pools (Variable Block Size)
+#if (OS_DYNAMIC_MEM_CB_SIZE != 0)
+    &os_mem_cb, (uint32_t)OS_DYNAMIC_MEM_CB_SIZE,
+#else
+    NULL, 0U,
+#endif
+#if (OS_DYNAMIC_MEM_DATA_SIZE != 0)
+    &os_mem_data, (uint32_t)OS_DYNAMIC_MEM_DATA_SIZE,
+#else
+    NULL, 0U,
+#endif
+#if (OS_DYNAMIC_MEM_STACK_SIZE != 0)
+    &os_mem_stack, (uint32_t)OS_DYNAMIC_MEM_STACK_SIZE,
+#else
+    NULL, 0U,
+#endif
+#if (OS_DYNAMIC_MEM_SIZE != 0)
+    &os_mem, (uint32_t)OS_DYNAMIC_MEM_SIZE,
+#else
+    NULL, 0U
+#endif
+  },
+  {
+    // Memory Pools (Fixed Block Size)
+#if (OS_THREAD_STATIC != 0)
+#if (OS_THREAD_DEF_STACK_NUM != 0)
+    &os_mpi_stack,
+#else
+    NULL,
+#endif
+    &os_mpi_thread,
+#else
+    NULL, 
+    NULL,
+#endif
+#if (OS_TIMER_STATIC != 0)
+    &os_mpi_timer,
+#else
+    NULL,
+#endif
+#if (OS_EVFLAGS_STATIC != 0)
+    &os_mpi_ef,
+#else
+    NULL,
+#endif
+#if (OS_MUTEX_STATIC != 0)
+    &os_mpi_mutex,
+#else
+    NULL,
+#endif
+#if (OS_SEMAPHORE_STATIC != 0)
+    &os_mpi_semaphore,
+#else
+    NULL,
+#endif
+#if (OS_MEMPOOL_STATIC != 0)
+    &os_mpi_mp,
+#else
+    NULL,
+#endif
+#if (OS_MSGQUEUE_STATIC != 0)
+    &os_mpi_mq,
+#else
+    NULL,
+#endif
+  },
+  (uint32_t)OS_STACK_SIZE,
+  &os_idle_thread_attr,
+#if ((OS_TIMER_THREAD_STACK_SIZE > 0) && (OS_TIMER_CB_QUEUE > 0))
+  &os_timer_thread_attr,
+  &os_timer_mq_attr,
+  (uint32_t)OS_TIMER_CB_QUEUE
+#else
+  NULL,
+  NULL,
+  0U
+#endif
+};
+
+
+// Non weak reference to library irq_cm module
+extern       uint8_t  os_irq_cm;
+extern const uint8_t *os_irq_cm_ref;
+       const uint8_t* os_irq_cm_ref = &os_irq_cm;
+
+
+// OS Initialization
+// =================
+
+#if  defined(__CC_ARM) || \
+    (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
+
+#ifndef __MICROLIB
+void _platform_post_stackheap_init (void);
+void _platform_post_stackheap_init (void) {
+  osKernelInitialize();
+}
+#endif
+
+#elif defined (__GNUC__)
+
+void software_init_hook (void);
+void software_init_hook (void) {
+  osKernelInitialize();
+}
+
+#endif
+
+
+// C/C++ Standard Library Multithreading Interface
+// ===============================================
+
+#if (( defined(__CC_ARM) || \
+      (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))) && \
+      !defined(__MICROLIB))
+
+#define LIBSPACE_SIZE 96
+
+// Memory for libspace
+static uint32_t os_libspace[OS_THREAD_LIBSPACE_NUM+1][LIBSPACE_SIZE/sizeof(uint32_t)] \
+__attribute__((section(".os.object.data")));
+
+// Thread IDs for libspace
+static uint32_t os_libspace_id[OS_THREAD_LIBSPACE_NUM] \
+__attribute__((section(".os.object.cb")));
+
+// Check if Kernel has been started
+static uint32_t os_kernel_is_active (void) {
+  static uint8_t os_kernel_active = 0U;
+
+  if (os_kernel_active == 0U) {
+    if (osKernelGetState() > osKernelReady) {
+      os_kernel_active = 1U;
+      return 1U;
+    }
+    return 0U;
+  } else {
+    return 1U;
+  }
+}
+
+// Provide libspace for current thread
+void *__user_perthread_libspace (void);
+void *__user_perthread_libspace (void) {
+  uint32_t id;
+  uint32_t n;
+
+  if (!os_kernel_is_active()) {
+    return (void *)&os_libspace[OS_THREAD_LIBSPACE_NUM][0];
+  }
+
+  id = osThreadGetId();
+  for (n = 0U; n < OS_THREAD_LIBSPACE_NUM; n++) {
+    if (os_libspace_id[n] == 0U) {
+      os_libspace_id[n] = id;
+      return (void *)&os_libspace[n][0];
+    }
+    if (os_libspace_id[n] == id) {
+      return (void *)&os_libspace[n][0];
+    }
+  }
+
+  if (n == OS_THREAD_LIBSPACE_NUM) {
+    os_Error(os_ErrorClibSpace, (void *)id);
+  }
+
+  return (void *)&os_libspace[n][0];
+}
+
+// Mutex identifier
+typedef uint32_t mutex;
+
+// Initialize mutex
+int _mutex_initialize(mutex *m);
+int _mutex_initialize(mutex *m) {
+  *m = osMutexNew(NULL);
+  if (*m == (mutex)NULL) {
+    os_Error(os_ErrorClibMutex, m);
+    return 0;
+  }
+  return 1;
+}
+
+// Acquire mutex
+void _mutex_acquire(mutex *m);
+void _mutex_acquire(mutex *m) {
+  if (os_kernel_is_active()) {
+    osMutexAcquire(*m, osWaitForever);
+  }
+}
+
+// Release mutex
+void _mutex_release(mutex *m);
+void _mutex_release(mutex *m) {
+  if (os_kernel_is_active()) {
+    osMutexRelease(*m);
+  }
+}
+
+// Free mutex
+void _mutex_free(mutex *m);
+void _mutex_free(mutex *m) {
+  osMutexDelete(*m);
+}
+
+#endif
diff --git a/CMSIS/RTOS2/RTX/Include/rtx_os.h b/CMSIS/RTOS2/RTX/Include/rtx_os.h
new file mode 100644
index 0000000..46485b8
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Include/rtx_os.h
@@ -0,0 +1,478 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       RTX OS definitions
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#ifndef __RTX_OS_H
+#define __RTX_OS_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef  __cplusplus
+extern "C"
+{
+#endif
+
+
+/// Kernel Information
+#define os_CMSIS_API         20000000   ///< API version (2.0.0)
+#define os_CMSIS_RTX         50000000   ///< Kernel version (5.0.0)
+#define os_KernelId       "RTX V5.0.0"  ///< Kernel identification string
+
+
+//  ==== Common definitions ====
+
+/// Object Identifier definitions
+#define os_IdInvalid            0x00U
+#define os_IdThread             0x01U
+#define os_IdTimer              0x02U
+#define os_IdEventFlags         0x03U
+#define os_IdMutex              0x04U
+#define os_IdSemaphore          0x05U
+#define os_IdMemoryPool         0x06U
+#define os_IdMessage            0x07U
+#define os_IdMessageQueue       0x08U
+
+/// Object State definitions (except for Threads and Timers)
+#define os_ObjectInactive       0x00U
+#define os_ObjectActive         0x01U
+
+/// Object Flags definitions
+#define os_FlagSystemObject     0x01U
+#define os_FlagSystemMemory     0x02U
+
+
+//  ==== Kernel definitions ====
+
+/// Kernel State definitions
+#define os_KernelInactive           ((uint8_t)osKernelInactive)
+#define os_KernelReady              ((uint8_t)osKernelReady)
+#define os_KernelRunning            ((uint8_t)osKernelRunning)
+#define os_KernelLocked             ((uint8_t)osKernelLocked)
+#define os_KernelSuspended          ((uint8_t)osKernelSuspended)
+
+
+//  ==== Thread definitions ====
+
+/// Thread State definitions (extending osThreadState)
+#define os_ThreadStateMask          0x0FU
+
+#define os_ThreadInactive           ((uint8_t)osThreadInactive)
+#define os_ThreadReady              ((uint8_t)osThreadReady)
+#define os_ThreadRunning            ((uint8_t)osThreadRunning)
+#define os_ThreadWaiting            ((uint8_t)osThreadWaiting)
+#define os_ThreadSuspended          ((uint8_t)osThreadSuspended)
+#define os_ThreadTerminated         ((uint8_t)osThreadTerminated)
+
+#define os_ThreadWaitingDelay       (os_ThreadWaiting | 0x10U)
+#define os_ThreadWaitingJoin        (os_ThreadWaiting | 0x20U)
+#define os_ThreadWaitingThreadFlags (os_ThreadWaiting | 0x30U) 
+#define os_ThreadWaitingEventFlags  (os_ThreadWaiting | 0x40U) 
+#define os_ThreadWaitingMutex       (os_ThreadWaiting | 0x50U)
+#define os_ThreadWaitingSemaphore   (os_ThreadWaiting | 0x60U)
+#define os_ThreadWaitingMemoryPool  (os_ThreadWaiting | 0x70U)
+#define os_ThreadWaitingMessageGet  (os_ThreadWaiting | 0x80U)
+#define os_ThreadWaitingMessagePut  (os_ThreadWaiting | 0x90U)
+
+/// Thread Flags definitions
+#define os_ThreadFlagDefStack   0x10U   ///< Default Stack flag
+#define os_ThreadFlagExitPtr    0x20U   ///< Exit Pointer flag
+
+/// Stack Frame definitions
+#define os_StackFrameBasic      0x00U   ///< Stack Frame: Basic (CPU)
+#define os_StackFrameExtended   0x01U   ///< Stack Frame: Extended (CPU and FPU)
+
+/// Stack Marker definitions
+#define os_StackMagicWord       0xE25A2EA5U ///< Stack Magic Word (Stack Base)
+#define os_StackFillPattern     0xCCCCCCCCU ///< Stack Fill Pattern 
+
+/// Thread Control Block
+typedef struct os_thread_s {
+  uint8_t                          id;  ///< Object Identifier
+  uint8_t                       state;  ///< Object State
+  uint8_t                       flags;  ///< Object Flags
+  uint8_t                        attr;  ///< Object Attributes
+  const char                    *name;  ///< Object Name
+  struct os_thread_s     *thread_next;  ///< Link pointer to next Thread in Object list
+  struct os_thread_s     *thread_prev;  ///< Link pointer to previous Thread in Object list
+  struct os_thread_s      *delay_next;  ///< Link pointer to next Thread in Delay list
+  struct os_thread_s      *delay_prev;  ///< Link pointer to previous Thread in Delay list
+  struct os_thread_s     *thread_join;  ///< Thread waiting to Join
+  uint32_t                      delay;  ///< Delay Time
+  int8_t                     priority;  ///< Thread Priority
+  int8_t                priority_base;  ///< Base Priority
+  uint8_t                 stack_frame;  ///< Stack Frame
+  uint8_t               flags_options;  ///< Thread/Event Flags Options
+  int32_t                  wait_flags;  ///< Waiting Thread/Event Flags
+  int32_t                thread_flags;  ///< Thread Flags
+  struct os_mutex_s       *mutex_list;  ///< Link pointer to list of owned Mutexes
+  void                     *stack_mem;  ///< Stack Memory
+  uint32_t                 stack_size;  ///< Stack Size
+  uint32_t                         sp;  ///< Current Stack Pointer
+} os_thread_t;
+
+
+//  ==== Timer definitions ====
+
+/// Timer State definitions
+#define os_TimerInactive        0x00U   ///< Timer Inactive
+#define os_TimerStopped         0x01U   ///< Timer Stopped
+#define os_TimerRunning         0x02U   ///< Timer Running
+
+/// Timer Type definitions
+#define os_TimerPeriodic        ((uint8_t)osTimerPeriodic)
+
+/// Timer Function Information
+typedef struct os_timer_finfo_s {
+  void                            *fp;  ///< Function Pointer
+  void                           *arg;  ///< Function Argument
+} os_timer_finfo_t;
+
+/// Timer Control Block
+typedef struct os_timer_s {
+  uint8_t                          id;  ///< Object Identifier
+  uint8_t                       state;  ///< Object State
+  uint8_t                       flags;  ///< Object Flags
+  uint8_t                        type;  ///< Timer Type (Periodic/One-shot)
+  const char                    *name;  ///< Object Name
+  struct os_timer_s             *prev;  ///< Pointer to previous active Timer
+  struct os_timer_s             *next;  ///< Pointer to next active Timer
+  uint32_t                       tick;  ///< Timer current Tick
+  uint32_t                       load;  ///< Timer Load value
+  os_timer_finfo_t              finfo;  ///< Timer Function Info
+} os_timer_t;
+
+
+//  ==== Event Flags definitions ====
+
+/// Event Flags Control Block
+typedef struct os_event_flags_s {
+  uint8_t                          id;  ///< Object Identifier
+  uint8_t                       state;  ///< Object State
+  uint8_t                       flags;  ///< Object Flags
+  uint8_t                    reserved;
+  const char                    *name;  ///< Object Name
+  os_thread_t            *thread_list;  ///< Waiting Threads List
+  int32_t                 event_flags;  ///< Event Flags
+} os_event_flags_t;
+
+
+//  ==== Mutex definitions ====
+
+/// Mutex Control Block
+typedef struct os_mutex_s {
+  uint8_t                          id;  ///< Object Identifier
+  uint8_t                       state;  ///< Object State
+  uint8_t                       flags;  ///< Object Flags
+  uint8_t                        attr;  ///< Object Attributes
+  const char                    *name;  ///< Object Name
+  os_thread_t            *thread_list;  ///< Waiting Threads List
+  os_thread_t           *owner_thread;  ///< Owner Thread
+  struct os_mutex_s       *owner_prev;  ///< Pointer to previous owned Mutex
+  struct os_mutex_s       *owner_next;  ///< Pointer to next owned Mutex
+  uint8_t                        lock;  ///< Lock counter
+  uint8_t                  padding[3];
+} os_mutex_t;
+
+
+//  ==== Semaphore definitions ====
+
+/// Semaphore Control Block
+typedef struct os_semaphore_s {
+  uint8_t                          id;  ///< Object Identifier
+  uint8_t                       state;  ///< Object State
+  uint8_t                       flags;  ///< Object Flags
+  uint8_t                    reserved;
+  const char                    *name;  ///< Object Name
+  os_thread_t            *thread_list;  ///< Waiting Threads List
+  uint16_t                     tokens;  ///< Current number of tokens
+  uint16_t                 max_tokens;  ///< Maximum number of tokens
+} os_semaphore_t;
+
+
+//  ==== Memory Pool definitions ====
+
+/// Memory Pool Information
+typedef struct os_mp_info_s {
+  uint32_t                 max_blocks;  ///< Maximum number of Blocks
+  uint32_t                used_blocks;  ///< Number of used Blocks
+  uint32_t                 block_size;  ///< Block Size
+  void                    *block_base;  ///< Block Memory Base Address
+  void                     *block_lim;  ///< Block Memory Limit Address
+  void                    *block_free;  ///< First free Block Address
+} os_mp_info_t;
+
+/// Memory Pool Control Block
+typedef struct os_memory_pool_s {
+  uint8_t                          id;  ///< Object Identifier
+  uint8_t                       state;  ///< Object State
+  uint8_t                       flags;  ///< Object Flags
+  uint8_t                    reserved;
+  const char                    *name;  ///< Object Name
+  os_thread_t            *thread_list;  ///< Waiting Threads List
+  os_mp_info_t                mp_info;  ///< Memory Pool Info
+} os_memory_pool_t;
+
+
+//  ==== Message Queue definitions ====
+
+/// Message Control Block
+typedef struct os_message_s {
+  uint8_t                          id;  ///< Object Identifier
+  uint8_t                       state;  ///< Object State
+  uint8_t                       flags;  ///< Object Flags
+  uint8_t                    priority;  ///< Message Priority
+  struct os_message_s           *prev;  ///< Pointer to previous Message
+  struct os_message_s           *next;  ///< Pointer to next Message
+} os_message_t;
+
+/// Message Queue Control Block
+typedef struct os_message_queue_s {
+  uint8_t                          id;  ///< Object Identifier
+  uint8_t                       state;  ///< Object State
+  uint8_t                       flags;  ///< Object Flags
+  uint8_t                    reserved;
+  const char                    *name;  ///< Object Name
+  os_thread_t            *thread_list;  ///< Waiting Threads List
+  os_mp_info_t                mp_info;  ///< Memory Pool Info
+  uint32_t                   msg_size;  ///< Message Size
+  uint32_t                  msg_count;  ///< Number of queued Messages
+  os_message_t             *msg_first;  ///< Pointer to first Message
+  os_message_t              *msg_last;  ///< Pointer to last Message
+} os_message_queue_t;
+
+
+//  ==== Generic Object definitions ====
+
+/// Generic Object Control Block
+typedef struct os_object_s {
+  uint8_t                          id;  ///< Object Identifier
+  uint8_t                       state;  ///< Object State
+  uint8_t                       flags;  ///< Object Flags
+  uint8_t                    reserved;
+  const char                    *name;  ///< Object Name
+  os_thread_t            *thread_list;  ///< Threads List
+} os_object_t;
+
+
+//  ==== OS Runtime Information definitions ====
+
+/// OS Runtime Information structure
+typedef struct {
+  const char                   *os_id;  ///< OS Identification
+  uint32_t                    version;  ///< OS Version
+  struct {                              ///< Kernel Info
+    uint8_t                     state;  ///< State
+    volatile uint8_t          blocked;  ///< Blocked
+    uint8_t                   pendISR;  ///< Pending ISR (SV and SysTick)
+    uint8_t                    pendSV;  ///< Pending SV
+    uint32_t               usec_ticks;  ///< 1 microsec ticks * 2^16
+    uint64_t                     time;  ///< Time in millisec
+  } kernel;
+  int32_t                   tick_irqn;  ///< Tick Timer IRQ Number
+  struct {                              ///< Thread Info
+    struct {                            ///< Thread Run Info
+      os_thread_t               *curr;  ///< Current running Thread
+      os_thread_t               *next;  ///< Next Thread to Run
+    } run;
+    volatile os_object_t        ready;  ///< Ready List Object
+    os_thread_t                 *idle;  ///< Idle Thread
+    os_thread_t           *delay_list;  ///< Delay List
+    os_thread_t       *suspended_list;  ///< Suspended Thread List
+    os_thread_t      *terminated_list;  ///< Terminated Thread List
+    struct {                            ///< Thread Round Robin Info
+      os_thread_t             *thread;  ///< Round Robin Thread
+      uint32_t                   tick;  ///< Round Robin Time Tick
+      uint32_t                timeout;  ///< Round Robin Timeout
+    } robin;
+  } thread;
+  struct {                              ///< Timer Info
+    os_timer_t                  *list;  ///< Active Timer List
+    os_thread_t               *thread;  ///< Timer Thread
+    os_message_queue_t            *mq;  ///< Timer Message Queue
+  } timer;
+  struct {                              ///< ISR Post Processing Queue
+    uint16_t                      max;  ///< Maximum Items
+    uint16_t                      cnt;  ///< Item Count
+    uint16_t                       in;  ///< Incoming Item Index
+    uint16_t                      out;  ///< Outgoing Item Index
+    void                       **data;  ///< Queue Data
+  } isr_queue;
+  struct {                                  ///< ISR Post Processing functions
+    void           (*thread)(os_thread_t*); ///< Thread Post Processing function
+    void (*event_flags)(os_event_flags_t*); ///< Event Flags Post Processing function
+    void     (*semaphore)(os_semaphore_t*); ///< Semaphore Post Processing function
+    void (*memory_pool)(os_memory_pool_t*); ///< Memory Pool Post Processing function
+    void   (*message_queue)(os_message_t*); ///< MEssage Queue Post Processing function
+  } post_process;
+  struct {                              ///< Memory Pools (Variable Block Size)
+    void                          *cb;  ///< Control Blocks Memory
+    void                        *data;  ///< Data Memory
+    void                       *stack;  ///< Stack Memory
+    void                      *common;  ///< Common Memory Address
+  } mem;
+  struct {                              ///< Memory Pools (Fixed Block Size)
+    os_mp_info_t               *stack;  ///< Stack for Threads
+    os_mp_info_t              *thread;  ///< Thread Control Blocks
+    os_mp_info_t               *timer;  ///< Timer Control Blocks
+    os_mp_info_t         *event_flags;  ///< Event Flags Control Blocks
+    os_mp_info_t               *mutex;  ///< Mutex Control Blocks
+    os_mp_info_t           *semaphore;  ///< Semaphore Control Blocks
+    os_mp_info_t         *memory_pool;  ///< Memory Pool Control Blocks
+    os_mp_info_t       *message_queue;  ///< Message Queue Control Blocks
+  } mpi;
+} os_info_t;
+
+extern os_info_t os_Info;               ///< OS Runtime Information
+
+
+//  ==== OS API definitions ====
+
+/// Object Limits definitions
+#define os_ThreadFlagsLimit     31U     ///< number of Thread Flags available per thread
+#define os_EventFlagsLimit      31U     ///< number of Event Flags available per object
+#define os_MutexLockLimit       255U    ///< maximum number of recursive mutex locks
+#define os_SemaphoreTokenLimit  65535U  ///< maximum number of tokens per semaphore
+
+/// Control Block sizes
+#define os_ThreadCbSize         sizeof(os_thread_t)
+#define os_TimerCbSize          sizeof(os_timer_t)
+#define os_EventFlagsCbSize     sizeof(os_event_flags_t)
+#define os_MutexCbSize          sizeof(os_mutex_t)
+#define os_SemaphoreCbSize      sizeof(os_semaphore_t)
+#define os_MemoryPoolCbSize     sizeof(os_memory_pool_t)
+#define os_MessageQueueCbSize   sizeof(os_message_queue_t)
+
+/// Memory size in bytes for Memory Pool storage.
+/// \param         block_count   maximum number of memory blocks in memory pool.
+/// \param         block_size    memory block size in bytes.
+#define os_MemoryPoolMemSize(block_count, block_size) \
+  (4*(block_count)*(((block_size)+3)/4))
+ 
+/// Memory size in bytes for Message Queue storage.
+/// \param         msg_count     maximum number of messages in queue.
+/// \param         msg_size      maximum message size in bytes.
+#define os_MessageQueueMemSize(msg_count, msg_size) \
+  (4*(msg_count)*(3+(((msg_size)+3)/4)))
+
+
+//  ==== OS External Functions ====
+
+/// OS Error Codes
+#define os_ErrorStackUnderflow      1U
+#define os_ErrorISRQueueOverflow    2U
+#define os_ErrorTimerQueueOverflow  3U
+#define os_ErrorClibSpace           4U
+#define os_ErrorClibMutex           5U
+
+/// OS Error Callback function
+extern uint32_t os_Error (uint32_t code, void *object_id);
+
+/// OS Idle Thread
+extern void *os_IdleThread (void *argument);
+
+/// OS Exception handlers
+extern void SVC_Handler     (void);
+extern void PendSV_Handler  (void);
+extern void SysTick_Handler (void);
+
+
+/// OS Tick functions (default implementation uses SysTick)
+
+/// Setup Tick Timer.
+/// \return tick timer IRQ number.
+extern int32_t os_TickSetup (void);
+
+/// Enable Tick Timer.
+extern void os_TickEnable (void);
+
+/// Disable Tick Timer.
+extern void os_TickDisable (void);
+
+/// Acknowledge Tick Timer IRQ.
+extern void os_TickAckIRQ (void);
+
+/// Get Tick Timer Value.
+/// \return tick timer value.
+extern uint32_t os_TickGetVal (void);
+
+/// Convert microseconds value to Tick Timer value.
+/// \param         microsec     time value in microseconds.
+/// \return time value normalized to timer ticks.
+extern uint32_t os_TickMicroSec (uint32_t microsec);
+
+
+//  ==== OS External Configuration ====
+
+/// OS Configuration flags
+#define os_ConfigPrivilegedMode     (1UL<<0)    ///< Threads in Privileged mode
+#define os_ConfigStackWatermark     (1UL<<1)    ///< Stack usage Watermark
+
+/// OS Configuration structure
+typedef struct {
+  uint32_t                             flags;   ///< OS Configuration Flags
+  uint32_t                     robin_timeout;   ///< Round Robin Timeout Tick
+  struct {                                      ///< ISR Post Processing Queue
+    void                              **data;   ///< Queue Data
+    uint16_t                             max;   ///< Maximum Items
+    uint16_t                         padding;
+  } isr_queue;
+  struct {                                      ///< Memory Pools (Variable Block Size)
+    void                            *cb_addr;   ///< Control Blocks Memory Address
+    uint32_t                         cb_size;   ///< Control Blocks Memory Size
+    void                          *data_addr;   ///< Data Memory Address
+    uint32_t                       data_size;   ///< Data Memory Size
+    void                         *stack_addr;   ///< Stack Memory Address
+    uint32_t                      stack_size;   ///< Stack Memory Size
+    void                        *common_addr;   ///< Common Memory Address
+    uint32_t                     common_size;   ///< Common Memory Size
+  } mem;
+  struct {                                      ///< Memory Pools (Fixed Block Size)
+    os_mp_info_t                      *stack;   ///< Stack for Threads
+    os_mp_info_t                     *thread;   ///< Thread Control Blocks
+    os_mp_info_t                      *timer;   ///< Timer Control Blocks
+    os_mp_info_t                *event_flags;   ///< Event Flags Control Blocks
+    os_mp_info_t                      *mutex;   ///< Mutex Control Blocks
+    os_mp_info_t                  *semaphore;   ///< Semaphore Control Blocks
+    os_mp_info_t                *memory_pool;   ///< Memory Pool Control Blocks
+    os_mp_info_t              *message_queue;   ///< Message Queue Control Blocks
+  } mpi;
+  uint32_t                 thread_stack_size;   ///< Default Thread Stack Size
+  const 
+  struct osThreadAttr_s    *idle_thread_attr;   ///< Idle Thread Attributes
+  const
+  struct osThreadAttr_s   *timer_thread_attr;   ///< Timer Thread Attributes
+  const
+  struct osMessageQueueAttr_s *timer_mq_attr;   ///< Timer Message Queue Attributes
+  uint32_t                     timer_mq_mcnt;   ///< Timer Message Queue maximum Messages
+} os_config_t;
+
+extern const os_config_t os_Config;             ///< OS Configuration
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif  // __RTX_OS_H
diff --git a/CMSIS/RTOS2/RTX/Library/ARM/MDK/RTE/RTE_Components.h b/CMSIS/RTOS2/RTX/Library/ARM/MDK/RTE/RTE_Components.h
new file mode 100644
index 0000000..002e1bf
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Library/ARM/MDK/RTE/RTE_Components.h
@@ -0,0 +1,20 @@
+
+/*
+ * Auto generated Run-Time-Environment Component Configuration File
+ *      *** Do not modify ! ***
+ *
+ * Project: 'RTX_CM' 
+ * Target:  'CM0_LE' 
+ */
+
+#ifndef RTE_COMPONENTS_H
+#define RTE_COMPONENTS_H
+
+
+/*
+ * Define the Device Header File: 
+ */
+#define CMSIS_device_header "ARMCM0.h"
+
+
+#endif /* RTE_COMPONENTS_H */
diff --git a/CMSIS/RTOS2/RTX/Library/ARM/MDK/RTX_CM.uvoptx b/CMSIS/RTOS2/RTX/Library/ARM/MDK/RTX_CM.uvoptx
new file mode 100644
index 0000000..607a7af
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Library/ARM/MDK/RTX_CM.uvoptx
@@ -0,0 +1,642 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<ProjectOpt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_optx.xsd">
+
+  <SchemaVersion>1.0</SchemaVersion>
+
+  <Header>### uVision Project, (C) Keil Software</Header>
+
+  <Extensions>
+    <cExt>*.c</cExt>
+    <aExt>*.s*; *.src; *.a*</aExt>
+    <oExt>*.obj</oExt>
+    <lExt>*.lib</lExt>
+    <tExt>*.txt; *.h; *.inc</tExt>
+    <pExt>*.plm</pExt>
+    <CppX>*.cpp</CppX>
+    <nMigrate>0</nMigrate>
+  </Extensions>
+
+  <DaveTm>
+    <dwLowDateTime>0</dwLowDateTime>
+    <dwHighDateTime>0</dwHighDateTime>
+  </DaveTm>
+
+  <Target>
+    <TargetName>CM0_LE</TargetName>
+    <ToolsetNumber>0x4</ToolsetNumber>
+    <ToolsetName>ARM-ADS</ToolsetName>
+    <TargetOption>
+      <CLKADS>12000000</CLKADS>
+      <OPTTT>
+        <gFlags>1</gFlags>
+        <BeepAtEnd>1</BeepAtEnd>
+        <RunSim>0</RunSim>
+        <RunTarget>1</RunTarget>
+        <RunAbUc>0</RunAbUc>
+      </OPTTT>
+      <OPTHX>
+        <HexSelection>1</HexSelection>
+        <FlashByte>65535</FlashByte>
+        <HexRangeLowAddress>0</HexRangeLowAddress>
+        <HexRangeHighAddress>0</HexRangeHighAddress>
+        <HexOffset>0</HexOffset>
+      </OPTHX>
+      <OPTLEX>
+        <PageWidth>79</PageWidth>
+        <PageLength>66</PageLength>
+        <TabStop>8</TabStop>
+        <ListingPath>.\CM0_LE\</ListingPath>
+      </OPTLEX>
+      <ListingPage>
+        <CreateCListing>1</CreateCListing>
+        <CreateAListing>1</CreateAListing>
+        <CreateLListing>1</CreateLListing>
+        <CreateIListing>0</CreateIListing>
+        <AsmCond>1</AsmCond>
+        <AsmSymb>1</AsmSymb>
+        <AsmXref>0</AsmXref>
+        <CCond>1</CCond>
+        <CCode>0</CCode>
+        <CListInc>0</CListInc>
+        <CSymb>0</CSymb>
+        <LinkerCodeListing>0</LinkerCodeListing>
+      </ListingPage>
+      <OPTXL>
+        <LMap>1</LMap>
+        <LComments>1</LComments>
+        <LGenerateSymbols>1</LGenerateSymbols>
+        <LLibSym>1</LLibSym>
+        <LLines>1</LLines>
+        <LLocSym>1</LLocSym>
+        <LPubSym>1</LPubSym>
+        <LXref>0</LXref>
+        <LExpSel>0</LExpSel>
+      </OPTXL>
+      <OPTFL>
+        <tvExp>1</tvExp>
+        <tvExpOptDlg>0</tvExpOptDlg>
+        <IsCurrentTarget>1</IsCurrentTarget>
+      </OPTFL>
+      <CpuCode>7</CpuCode>
+      <DebugOpt>
+        <uSim>1</uSim>
+        <uTrg>0</uTrg>
+        <sLdApp>1</sLdApp>
+        <sGomain>1</sGomain>
+        <sRbreak>1</sRbreak>
+        <sRwatch>1</sRwatch>
+        <sRmem>1</sRmem>
+        <sRfunc>1</sRfunc>
+        <sRbox>1</sRbox>
+        <tLdApp>1</tLdApp>
+        <tGomain>1</tGomain>
+        <tRbreak>1</tRbreak>
+        <tRwatch>1</tRwatch>
+        <tRmem>1</tRmem>
+        <tRfunc>0</tRfunc>
+        <tRbox>1</tRbox>
+        <tRtrace>1</tRtrace>
+        <sRSysVw>1</sRSysVw>
+        <tRSysVw>1</tRSysVw>
+        <sRunDeb>0</sRunDeb>
+        <sLrtime>0</sLrtime>
+        <nTsel>0</nTsel>
+        <sDll></sDll>
+        <sDllPa></sDllPa>
+        <sDlgDll></sDlgDll>
+        <sDlgPa></sDlgPa>
+        <sIfile></sIfile>
+        <tDll></tDll>
+        <tDllPa></tDllPa>
+        <tDlgDll></tDlgDll>
+        <tDlgPa></tDlgPa>
+        <tIfile></tIfile>
+        <pMon>BIN\UL2CM3.DLL</pMon>
+      </DebugOpt>
+      <TargetDriverDllRegistry>
+        <SetRegEntry>
+          <Number>0</Number>
+          <Key>UL2CM3</Key>
+          <Name>UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0NEW_DEVICE -FL040000 -FS00 -FP0($$Device:ARMCM0$Device\ARM\Flash\NEW_DEVICE.FLM)</Name>
+        </SetRegEntry>
+      </TargetDriverDllRegistry>
+      <Breakpoint/>
+      <Tracepoint>
+        <THDelay>0</THDelay>
+      </Tracepoint>
+      <DebugFlag>
+        <trace>0</trace>
+        <periodic>1</periodic>
+        <aLwin>0</aLwin>
+        <aCover>0</aCover>
+        <aSer1>0</aSer1>
+        <aSer2>0</aSer2>
+        <aPa>0</aPa>
+        <viewmode>0</viewmode>
+        <vrSel>0</vrSel>
+        <aSym>0</aSym>
+        <aTbox>0</aTbox>
+        <AscS1>0</AscS1>
+        <AscS2>0</AscS2>
+        <AscS3>0</AscS3>
+        <aSer3>0</aSer3>
+        <eProf>0</eProf>
+        <aLa>0</aLa>
+        <aPa1>0</aPa1>
+        <AscS4>0</AscS4>
+        <aSer4>0</aSer4>
+        <StkLoc>0</StkLoc>
+        <TrcWin>0</TrcWin>
+        <newCpu>0</newCpu>
+        <uProt>0</uProt>
+      </DebugFlag>
+      <LintExecutable></LintExecutable>
+      <LintConfigFile></LintConfigFile>
+      <bLintAuto>0</bLintAuto>
+      <Lin2Executable></Lin2Executable>
+      <Lin2ConfigFile></Lin2ConfigFile>
+      <bLin2Auto>0</bLin2Auto>
+    </TargetOption>
+  </Target>
+
+  <Target>
+    <TargetName>CM3_LE</TargetName>
+    <ToolsetNumber>0x4</ToolsetNumber>
+    <ToolsetName>ARM-ADS</ToolsetName>
+    <TargetOption>
+      <CLKADS>12000000</CLKADS>
+      <OPTTT>
+        <gFlags>1</gFlags>
+        <BeepAtEnd>1</BeepAtEnd>
+        <RunSim>0</RunSim>
+        <RunTarget>1</RunTarget>
+        <RunAbUc>0</RunAbUc>
+      </OPTTT>
+      <OPTHX>
+        <HexSelection>1</HexSelection>
+        <FlashByte>65535</FlashByte>
+        <HexRangeLowAddress>0</HexRangeLowAddress>
+        <HexRangeHighAddress>0</HexRangeHighAddress>
+        <HexOffset>0</HexOffset>
+      </OPTHX>
+      <OPTLEX>
+        <PageWidth>79</PageWidth>
+        <PageLength>66</PageLength>
+        <TabStop>8</TabStop>
+        <ListingPath>.\CM3_LE\</ListingPath>
+      </OPTLEX>
+      <ListingPage>
+        <CreateCListing>1</CreateCListing>
+        <CreateAListing>1</CreateAListing>
+        <CreateLListing>1</CreateLListing>
+        <CreateIListing>0</CreateIListing>
+        <AsmCond>1</AsmCond>
+        <AsmSymb>1</AsmSymb>
+        <AsmXref>0</AsmXref>
+        <CCond>1</CCond>
+        <CCode>0</CCode>
+        <CListInc>0</CListInc>
+        <CSymb>0</CSymb>
+        <LinkerCodeListing>0</LinkerCodeListing>
+      </ListingPage>
+      <OPTXL>
+        <LMap>1</LMap>
+        <LComments>1</LComments>
+        <LGenerateSymbols>1</LGenerateSymbols>
+        <LLibSym>1</LLibSym>
+        <LLines>1</LLines>
+        <LLocSym>1</LLocSym>
+        <LPubSym>1</LPubSym>
+        <LXref>0</LXref>
+        <LExpSel>0</LExpSel>
+      </OPTXL>
+      <OPTFL>
+        <tvExp>1</tvExp>
+        <tvExpOptDlg>0</tvExpOptDlg>
+        <IsCurrentTarget>0</IsCurrentTarget>
+      </OPTFL>
+      <CpuCode>7</CpuCode>
+      <DebugOpt>
+        <uSim>1</uSim>
+        <uTrg>0</uTrg>
+        <sLdApp>1</sLdApp>
+        <sGomain>1</sGomain>
+        <sRbreak>1</sRbreak>
+        <sRwatch>1</sRwatch>
+        <sRmem>1</sRmem>
+        <sRfunc>1</sRfunc>
+        <sRbox>1</sRbox>
+        <tLdApp>1</tLdApp>
+        <tGomain>1</tGomain>
+        <tRbreak>1</tRbreak>
+        <tRwatch>1</tRwatch>
+        <tRmem>1</tRmem>
+        <tRfunc>0</tRfunc>
+        <tRbox>1</tRbox>
+        <tRtrace>1</tRtrace>
+        <sRSysVw>1</sRSysVw>
+        <tRSysVw>1</tRSysVw>
+        <sRunDeb>0</sRunDeb>
+        <sLrtime>0</sLrtime>
+        <nTsel>0</nTsel>
+        <sDll></sDll>
+        <sDllPa></sDllPa>
+        <sDlgDll></sDlgDll>
+        <sDlgPa></sDlgPa>
+        <sIfile></sIfile>
+        <tDll></tDll>
+        <tDllPa></tDllPa>
+        <tDlgDll></tDlgDll>
+        <tDlgPa></tDlgPa>
+        <tIfile></tIfile>
+        <pMon>BIN\UL2CM3.DLL</pMon>
+      </DebugOpt>
+      <TargetDriverDllRegistry>
+        <SetRegEntry>
+          <Number>0</Number>
+          <Key>UL2CM3</Key>
+          <Name>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0NEW_DEVICE -FS00 -FL040000 -FP0($$Device:ARMCM3$Device\ARM\Flash\NEW_DEVICE.FLM))</Name>
+        </SetRegEntry>
+      </TargetDriverDllRegistry>
+      <Breakpoint/>
+      <Tracepoint>
+        <THDelay>0</THDelay>
+      </Tracepoint>
+      <DebugFlag>
+        <trace>0</trace>
+        <periodic>1</periodic>
+        <aLwin>0</aLwin>
+        <aCover>0</aCover>
+        <aSer1>0</aSer1>
+        <aSer2>0</aSer2>
+        <aPa>0</aPa>
+        <viewmode>0</viewmode>
+        <vrSel>0</vrSel>
+        <aSym>0</aSym>
+        <aTbox>0</aTbox>
+        <AscS1>0</AscS1>
+        <AscS2>0</AscS2>
+        <AscS3>0</AscS3>
+        <aSer3>0</aSer3>
+        <eProf>0</eProf>
+        <aLa>0</aLa>
+        <aPa1>0</aPa1>
+        <AscS4>0</AscS4>
+        <aSer4>0</aSer4>
+        <StkLoc>0</StkLoc>
+        <TrcWin>0</TrcWin>
+        <newCpu>0</newCpu>
+        <uProt>0</uProt>
+      </DebugFlag>
+      <LintExecutable></LintExecutable>
+      <LintConfigFile></LintConfigFile>
+      <bLintAuto>0</bLintAuto>
+      <Lin2Executable></Lin2Executable>
+      <Lin2ConfigFile></Lin2ConfigFile>
+      <bLin2Auto>0</bLin2Auto>
+    </TargetOption>
+  </Target>
+
+  <Target>
+    <TargetName>CM4F_LE</TargetName>
+    <ToolsetNumber>0x4</ToolsetNumber>
+    <ToolsetName>ARM-ADS</ToolsetName>
+    <TargetOption>
+      <CLKADS>12000000</CLKADS>
+      <OPTTT>
+        <gFlags>1</gFlags>
+        <BeepAtEnd>1</BeepAtEnd>
+        <RunSim>0</RunSim>
+        <RunTarget>1</RunTarget>
+        <RunAbUc>0</RunAbUc>
+      </OPTTT>
+      <OPTHX>
+        <HexSelection>1</HexSelection>
+        <FlashByte>65535</FlashByte>
+        <HexRangeLowAddress>0</HexRangeLowAddress>
+        <HexRangeHighAddress>0</HexRangeHighAddress>
+        <HexOffset>0</HexOffset>
+      </OPTHX>
+      <OPTLEX>
+        <PageWidth>79</PageWidth>
+        <PageLength>66</PageLength>
+        <TabStop>8</TabStop>
+        <ListingPath>.\CM4F_LE\</ListingPath>
+      </OPTLEX>
+      <ListingPage>
+        <CreateCListing>1</CreateCListing>
+        <CreateAListing>1</CreateAListing>
+        <CreateLListing>1</CreateLListing>
+        <CreateIListing>0</CreateIListing>
+        <AsmCond>1</AsmCond>
+        <AsmSymb>1</AsmSymb>
+        <AsmXref>0</AsmXref>
+        <CCond>1</CCond>
+        <CCode>0</CCode>
+        <CListInc>0</CListInc>
+        <CSymb>0</CSymb>
+        <LinkerCodeListing>0</LinkerCodeListing>
+      </ListingPage>
+      <OPTXL>
+        <LMap>1</LMap>
+        <LComments>1</LComments>
+        <LGenerateSymbols>1</LGenerateSymbols>
+        <LLibSym>1</LLibSym>
+        <LLines>1</LLines>
+        <LLocSym>1</LLocSym>
+        <LPubSym>1</LPubSym>
+        <LXref>0</LXref>
+        <LExpSel>0</LExpSel>
+      </OPTXL>
+      <OPTFL>
+        <tvExp>1</tvExp>
+        <tvExpOptDlg>0</tvExpOptDlg>
+        <IsCurrentTarget>0</IsCurrentTarget>
+      </OPTFL>
+      <CpuCode>7</CpuCode>
+      <DebugOpt>
+        <uSim>1</uSim>
+        <uTrg>0</uTrg>
+        <sLdApp>1</sLdApp>
+        <sGomain>1</sGomain>
+        <sRbreak>1</sRbreak>
+        <sRwatch>1</sRwatch>
+        <sRmem>1</sRmem>
+        <sRfunc>1</sRfunc>
+        <sRbox>1</sRbox>
+        <tLdApp>1</tLdApp>
+        <tGomain>1</tGomain>
+        <tRbreak>1</tRbreak>
+        <tRwatch>1</tRwatch>
+        <tRmem>1</tRmem>
+        <tRfunc>0</tRfunc>
+        <tRbox>1</tRbox>
+        <tRtrace>1</tRtrace>
+        <sRSysVw>1</sRSysVw>
+        <tRSysVw>1</tRSysVw>
+        <sRunDeb>0</sRunDeb>
+        <sLrtime>0</sLrtime>
+        <nTsel>0</nTsel>
+        <sDll></sDll>
+        <sDllPa></sDllPa>
+        <sDlgDll></sDlgDll>
+        <sDlgPa></sDlgPa>
+        <sIfile></sIfile>
+        <tDll></tDll>
+        <tDllPa></tDllPa>
+        <tDlgDll></tDlgDll>
+        <tDlgPa></tDlgPa>
+        <tIfile></tIfile>
+        <pMon>BIN\UL2CM3.DLL</pMon>
+      </DebugOpt>
+      <TargetDriverDllRegistry>
+        <SetRegEntry>
+          <Number>0</Number>
+          <Key>UL2CM3</Key>
+          <Name>UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0NEW_DEVICE -FL040000 -FS00 -FP0($$Device:ARMCM4_FP$Device\ARM\Flash\NEW_DEVICE.FLM)</Name>
+        </SetRegEntry>
+      </TargetDriverDllRegistry>
+      <Breakpoint/>
+      <Tracepoint>
+        <THDelay>0</THDelay>
+      </Tracepoint>
+      <DebugFlag>
+        <trace>0</trace>
+        <periodic>1</periodic>
+        <aLwin>0</aLwin>
+        <aCover>0</aCover>
+        <aSer1>0</aSer1>
+        <aSer2>0</aSer2>
+        <aPa>0</aPa>
+        <viewmode>0</viewmode>
+        <vrSel>0</vrSel>
+        <aSym>0</aSym>
+        <aTbox>0</aTbox>
+        <AscS1>0</AscS1>
+        <AscS2>0</AscS2>
+        <AscS3>0</AscS3>
+        <aSer3>0</aSer3>
+        <eProf>0</eProf>
+        <aLa>0</aLa>
+        <aPa1>0</aPa1>
+        <AscS4>0</AscS4>
+        <aSer4>0</aSer4>
+        <StkLoc>0</StkLoc>
+        <TrcWin>0</TrcWin>
+        <newCpu>0</newCpu>
+        <uProt>0</uProt>
+      </DebugFlag>
+      <LintExecutable></LintExecutable>
+      <LintConfigFile></LintConfigFile>
+      <bLintAuto>0</bLintAuto>
+      <Lin2Executable></Lin2Executable>
+      <Lin2ConfigFile></Lin2ConfigFile>
+      <bLin2Auto>0</bLin2Auto>
+    </TargetOption>
+  </Target>
+
+  <Group>
+    <GroupName>Core</GroupName>
+    <tvExp>1</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>1</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_kernel.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_kernel.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>2</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_thread.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_thread.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>3</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_delay.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_delay.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>4</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_timer.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_timer.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>5</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_evflags.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_evflags.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>6</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_mutex.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_mutex.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>7</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_semaphore.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_semaphore.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>8</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_memory.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_memory.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>9</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_mempool.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_mempool.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>10</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_msgqueue.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_msgqueue.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>11</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_system.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_system.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>12</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\user_svc.c</PathWithFileName>
+      <FilenameWithoutPath>user_svc.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>Handlers</GroupName>
+    <tvExp>1</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>13</FileNumber>
+      <FileType>2</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\ARM\irq_cm0.s</PathWithFileName>
+      <FilenameWithoutPath>irq_cm0.s</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>14</FileNumber>
+      <FileType>2</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\ARM\irq_cm3.s</PathWithFileName>
+      <FilenameWithoutPath>irq_cm3.s</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>15</FileNumber>
+      <FileType>2</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\ARM\irq_cm4f.s</PathWithFileName>
+      <FilenameWithoutPath>irq_cm4f.s</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>::CMSIS</GroupName>
+    <tvExp>0</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>1</RteFlg>
+  </Group>
+
+</ProjectOpt>
diff --git a/CMSIS/RTOS2/RTX/Library/ARM/MDK/RTX_CM.uvprojx b/CMSIS/RTOS2/RTX/Library/ARM/MDK/RTX_CM.uvprojx
new file mode 100644
index 0000000..31033af
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Library/ARM/MDK/RTX_CM.uvprojx
@@ -0,0 +1,1625 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
+
+  <SchemaVersion>2.1</SchemaVersion>
+
+  <Header>### uVision Project, (C) Keil Software</Header>
+
+  <Targets>
+    <Target>
+      <TargetName>CM0_LE</TargetName>
+      <ToolsetNumber>0x4</ToolsetNumber>
+      <ToolsetName>ARM-ADS</ToolsetName>
+      <pArmCC>6050000::V6.5::.\ARMCLANG_6.5</pArmCC>
+      <pCCUsed>6050000::V6.5::.\ARMCLANG_6.5</pCCUsed>
+      <TargetOption>
+        <TargetCommonOption>
+          <Device>ARMCM0</Device>
+          <Vendor>ARM</Vendor>
+          <PackID>ARM.CMSIS.5.0.0</PackID>
+          <PackURL>http://www.keil.com/pack/</PackURL>
+          <Cpu>IRAM(0x20000000,0x00020000) IROM(0x00000000,0x00040000) CPUTYPE("Cortex-M0") CLOCK(12000000) ESEL ELITTLE</Cpu>
+          <FlashUtilSpec></FlashUtilSpec>
+          <StartupFile></StartupFile>
+          <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0NEW_DEVICE -FS00 -FL040000 -FP0($$Device:ARMCM0$Device\ARM\Flash\NEW_DEVICE.FLM))</FlashDriverDll>
+          <DeviceId>0</DeviceId>
+          <RegisterFile>$$Device:ARMCM0$Device\ARM\ARMCM0\Include\ARMCM0.h</RegisterFile>
+          <MemoryEnv></MemoryEnv>
+          <Cmp></Cmp>
+          <Asm></Asm>
+          <Linker></Linker>
+          <OHString></OHString>
+          <InfinionOptionDll></InfinionOptionDll>
+          <SLE66CMisc></SLE66CMisc>
+          <SLE66AMisc></SLE66AMisc>
+          <SLE66LinkerMisc></SLE66LinkerMisc>
+          <SFDFile>$$Device:ARMCM0$Device\ARM\SVD\ARMCM0.svd</SFDFile>
+          <bCustSvd>0</bCustSvd>
+          <UseEnv>0</UseEnv>
+          <BinPath></BinPath>
+          <IncludePath></IncludePath>
+          <LibPath></LibPath>
+          <RegisterFilePath></RegisterFilePath>
+          <DBRegisterFilePath></DBRegisterFilePath>
+          <TargetStatus>
+            <Error>0</Error>
+            <ExitCodeStop>0</ExitCodeStop>
+            <ButtonStop>0</ButtonStop>
+            <NotGenerated>0</NotGenerated>
+            <InvalidFlash>1</InvalidFlash>
+          </TargetStatus>
+          <OutputDirectory>.\CM0_LE\</OutputDirectory>
+          <OutputName>RTX_CM0</OutputName>
+          <CreateExecutable>0</CreateExecutable>
+          <CreateLib>1</CreateLib>
+          <CreateHexFile>0</CreateHexFile>
+          <DebugInformation>1</DebugInformation>
+          <BrowseInformation>1</BrowseInformation>
+          <ListingPath>.\CM0_LE\</ListingPath>
+          <HexFormatSelection>1</HexFormatSelection>
+          <Merge32K>0</Merge32K>
+          <CreateBatchFile>1</CreateBatchFile>
+          <BeforeCompile>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopU1X>0</nStopU1X>
+            <nStopU2X>0</nStopU2X>
+          </BeforeCompile>
+          <BeforeMake>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopB1X>0</nStopB1X>
+            <nStopB2X>0</nStopB2X>
+          </BeforeMake>
+          <AfterMake>
+            <RunUserProg1>1</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name>cmd.exe /C copy CM0_LE\RTX_CM0.lib ..\.</UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopA1X>0</nStopA1X>
+            <nStopA2X>0</nStopA2X>
+          </AfterMake>
+          <SelectedForBatchBuild>0</SelectedForBatchBuild>
+          <SVCSIdString></SVCSIdString>
+        </TargetCommonOption>
+        <CommonProperty>
+          <UseCPPCompiler>0</UseCPPCompiler>
+          <RVCTCodeConst>0</RVCTCodeConst>
+          <RVCTZI>0</RVCTZI>
+          <RVCTOtherData>0</RVCTOtherData>
+          <ModuleSelection>0</ModuleSelection>
+          <IncludeInBuild>1</IncludeInBuild>
+          <AlwaysBuild>0</AlwaysBuild>
+          <GenerateAssemblyFile>0</GenerateAssemblyFile>
+          <AssembleAssemblyFile>0</AssembleAssemblyFile>
+          <PublicsOnly>0</PublicsOnly>
+          <StopOnExitCode>3</StopOnExitCode>
+          <CustomArgument></CustomArgument>
+          <IncludeLibraryModules></IncludeLibraryModules>
+          <ComprImg>1</ComprImg>
+        </CommonProperty>
+        <DllOption>
+          <SimDllName>SARMCM3.DLL</SimDllName>
+          <SimDllArguments>  </SimDllArguments>
+          <SimDlgDll>DARMCM1.DLL</SimDlgDll>
+          <SimDlgDllArguments>-pCM0</SimDlgDllArguments>
+          <TargetDllName>SARMCM3.DLL</TargetDllName>
+          <TargetDllArguments> </TargetDllArguments>
+          <TargetDlgDll>TARMCM1.DLL</TargetDlgDll>
+          <TargetDlgDllArguments>-pCM0</TargetDlgDllArguments>
+        </DllOption>
+        <DebugOption>
+          <OPTHX>
+            <HexSelection>1</HexSelection>
+            <HexRangeLowAddress>0</HexRangeLowAddress>
+            <HexRangeHighAddress>0</HexRangeHighAddress>
+            <HexOffset>0</HexOffset>
+            <Oh166RecLen>16</Oh166RecLen>
+          </OPTHX>
+        </DebugOption>
+        <Utilities>
+          <Flash1>
+            <UseTargetDll>1</UseTargetDll>
+            <UseExternalTool>0</UseExternalTool>
+            <RunIndependent>0</RunIndependent>
+            <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
+            <Capability>1</Capability>
+            <DriverSelection>4096</DriverSelection>
+          </Flash1>
+          <bUseTDR>1</bUseTDR>
+          <Flash2>BIN\UL2CM3.DLL</Flash2>
+          <Flash3></Flash3>
+          <Flash4></Flash4>
+          <pFcarmOut></pFcarmOut>
+          <pFcarmGrp></pFcarmGrp>
+          <pFcArmRoot></pFcArmRoot>
+          <FcArmLst>0</FcArmLst>
+        </Utilities>
+        <TargetArmAds>
+          <ArmAdsMisc>
+            <GenerateListings>0</GenerateListings>
+            <asHll>1</asHll>
+            <asAsm>1</asAsm>
+            <asMacX>1</asMacX>
+            <asSyms>1</asSyms>
+            <asFals>1</asFals>
+            <asDbgD>1</asDbgD>
+            <asForm>1</asForm>
+            <ldLst>0</ldLst>
+            <ldmm>1</ldmm>
+            <ldXref>1</ldXref>
+            <BigEnd>0</BigEnd>
+            <AdsALst>0</AdsALst>
+            <AdsACrf>1</AdsACrf>
+            <AdsANop>0</AdsANop>
+            <AdsANot>0</AdsANot>
+            <AdsLLst>0</AdsLLst>
+            <AdsLmap>1</AdsLmap>
+            <AdsLcgr>1</AdsLcgr>
+            <AdsLsym>1</AdsLsym>
+            <AdsLszi>1</AdsLszi>
+            <AdsLtoi>1</AdsLtoi>
+            <AdsLsun>1</AdsLsun>
+            <AdsLven>1</AdsLven>
+            <AdsLsxf>1</AdsLsxf>
+            <RvctClst>0</RvctClst>
+            <GenPPlst>0</GenPPlst>
+            <AdsCpuType>"Cortex-M0"</AdsCpuType>
+            <RvctDeviceName></RvctDeviceName>
+            <mOS>0</mOS>
+            <uocRom>0</uocRom>
+            <uocRam>0</uocRam>
+            <hadIROM>1</hadIROM>
+            <hadIRAM>1</hadIRAM>
+            <hadXRAM>0</hadXRAM>
+            <uocXRam>0</uocXRam>
+            <RvdsVP>0</RvdsVP>
+            <hadIRAM2>0</hadIRAM2>
+            <hadIROM2>0</hadIROM2>
+            <StupSel>8</StupSel>
+            <useUlib>0</useUlib>
+            <EndSel>1</EndSel>
+            <uLtcg>0</uLtcg>
+            <nSecure>0</nSecure>
+            <RoSelD>3</RoSelD>
+            <RwSelD>3</RwSelD>
+            <CodeSel>0</CodeSel>
+            <OptFeed>0</OptFeed>
+            <NoZi1>0</NoZi1>
+            <NoZi2>0</NoZi2>
+            <NoZi3>0</NoZi3>
+            <NoZi4>0</NoZi4>
+            <NoZi5>0</NoZi5>
+            <Ro1Chk>0</Ro1Chk>
+            <Ro2Chk>0</Ro2Chk>
+            <Ro3Chk>0</Ro3Chk>
+            <Ir1Chk>1</Ir1Chk>
+            <Ir2Chk>0</Ir2Chk>
+            <Ra1Chk>0</Ra1Chk>
+            <Ra2Chk>0</Ra2Chk>
+            <Ra3Chk>0</Ra3Chk>
+            <Im1Chk>1</Im1Chk>
+            <Im2Chk>0</Im2Chk>
+            <OnChipMemories>
+              <Ocm1>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm1>
+              <Ocm2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm2>
+              <Ocm3>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm3>
+              <Ocm4>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm4>
+              <Ocm5>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm5>
+              <Ocm6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm6>
+              <IRAM>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x20000</Size>
+              </IRAM>
+              <IROM>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x40000</Size>
+              </IROM>
+              <XRAM>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </XRAM>
+              <OCR_RVCT1>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT1>
+              <OCR_RVCT2>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT2>
+              <OCR_RVCT3>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT3>
+              <OCR_RVCT4>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x40000</Size>
+              </OCR_RVCT4>
+              <OCR_RVCT5>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT5>
+              <OCR_RVCT6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT6>
+              <OCR_RVCT7>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT7>
+              <OCR_RVCT8>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT8>
+              <OCR_RVCT9>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x20000</Size>
+              </OCR_RVCT9>
+              <OCR_RVCT10>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT10>
+            </OnChipMemories>
+            <RvctStartVector></RvctStartVector>
+          </ArmAdsMisc>
+          <Cads>
+            <interw>1</interw>
+            <Optim>4</Optim>
+            <oTime>0</oTime>
+            <SplitLS>0</SplitLS>
+            <OneElfS>1</OneElfS>
+            <Strict>0</Strict>
+            <EnumInt>0</EnumInt>
+            <PlainCh>0</PlainCh>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <wLevel>2</wLevel>
+            <uThumb>0</uThumb>
+            <uSurpInc>0</uSurpInc>
+            <uC99>0</uC99>
+            <useXO>0</useXO>
+            <v6Lang>3</v6Lang>
+            <v6LangP>0</v6LangP>
+            <vShortEn>1</vShortEn>
+            <vShortWch>1</vShortWch>
+            <v6Lto>0</v6Lto>
+            <v6WtE>0</v6WtE>
+            <VariousControls>
+              <MiscControls></MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath>..\..\..\Include</IncludePath>
+            </VariousControls>
+          </Cads>
+          <Aads>
+            <interw>1</interw>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <thumb>1</thumb>
+            <SplitLS>0</SplitLS>
+            <SwStkChk>0</SwStkChk>
+            <NoWarn>0</NoWarn>
+            <uSurpInc>0</uSurpInc>
+            <useXO>0</useXO>
+            <VariousControls>
+              <MiscControls>--no_hide_all</MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath></IncludePath>
+            </VariousControls>
+          </Aads>
+          <LDads>
+            <umfTarg>0</umfTarg>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <noStLib>0</noStLib>
+            <RepFail>1</RepFail>
+            <useFile>0</useFile>
+            <TextAddressRange></TextAddressRange>
+            <DataAddressRange></DataAddressRange>
+            <pXoBase></pXoBase>
+            <ScatterFile></ScatterFile>
+            <IncludeLibs></IncludeLibs>
+            <IncludeLibsPath></IncludeLibsPath>
+            <Misc></Misc>
+            <LinkerInputFile></LinkerInputFile>
+            <DisabledWarnings></DisabledWarnings>
+          </LDads>
+        </TargetArmAds>
+      </TargetOption>
+      <Groups>
+        <Group>
+          <GroupName>Core</GroupName>
+          <Files>
+            <File>
+              <FileName>rtx_kernel.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_kernel.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_thread.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_thread.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_delay.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_delay.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_timer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_timer.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_evflags.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_evflags.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_mutex.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_mutex.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_semaphore.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_semaphore.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_memory.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_memory.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_mempool.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_mempool.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_msgqueue.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_msgqueue.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_system.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_system.c</FilePath>
+            </File>
+            <File>
+              <FileName>user_svc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\user_svc.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Handlers</GroupName>
+          <Files>
+            <File>
+              <FileName>irq_cm0.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\ARM\irq_cm0.s</FilePath>
+            </File>
+            <File>
+              <FileName>irq_cm3.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\ARM\irq_cm3.s</FilePath>
+              <FileOption>
+                <CommonProperty>
+                  <UseCPPCompiler>2</UseCPPCompiler>
+                  <RVCTCodeConst>0</RVCTCodeConst>
+                  <RVCTZI>0</RVCTZI>
+                  <RVCTOtherData>0</RVCTOtherData>
+                  <ModuleSelection>0</ModuleSelection>
+                  <IncludeInBuild>0</IncludeInBuild>
+                  <AlwaysBuild>2</AlwaysBuild>
+                  <GenerateAssemblyFile>2</GenerateAssemblyFile>
+                  <AssembleAssemblyFile>2</AssembleAssemblyFile>
+                  <PublicsOnly>2</PublicsOnly>
+                  <StopOnExitCode>11</StopOnExitCode>
+                  <CustomArgument></CustomArgument>
+                  <IncludeLibraryModules></IncludeLibraryModules>
+                  <ComprImg>1</ComprImg>
+                </CommonProperty>
+                <FileArmAds>
+                  <Aads>
+                    <interw>2</interw>
+                    <Ropi>2</Ropi>
+                    <Rwpi>2</Rwpi>
+                    <thumb>2</thumb>
+                    <SplitLS>2</SplitLS>
+                    <SwStkChk>2</SwStkChk>
+                    <NoWarn>2</NoWarn>
+                    <uSurpInc>2</uSurpInc>
+                    <useXO>2</useXO>
+                    <VariousControls>
+                      <MiscControls></MiscControls>
+                      <Define></Define>
+                      <Undefine></Undefine>
+                      <IncludePath></IncludePath>
+                    </VariousControls>
+                  </Aads>
+                </FileArmAds>
+              </FileOption>
+            </File>
+            <File>
+              <FileName>irq_cm4f.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\ARM\irq_cm4f.s</FilePath>
+              <FileOption>
+                <CommonProperty>
+                  <UseCPPCompiler>2</UseCPPCompiler>
+                  <RVCTCodeConst>0</RVCTCodeConst>
+                  <RVCTZI>0</RVCTZI>
+                  <RVCTOtherData>0</RVCTOtherData>
+                  <ModuleSelection>0</ModuleSelection>
+                  <IncludeInBuild>0</IncludeInBuild>
+                  <AlwaysBuild>2</AlwaysBuild>
+                  <GenerateAssemblyFile>2</GenerateAssemblyFile>
+                  <AssembleAssemblyFile>2</AssembleAssemblyFile>
+                  <PublicsOnly>2</PublicsOnly>
+                  <StopOnExitCode>11</StopOnExitCode>
+                  <CustomArgument></CustomArgument>
+                  <IncludeLibraryModules></IncludeLibraryModules>
+                  <ComprImg>1</ComprImg>
+                </CommonProperty>
+                <FileArmAds>
+                  <Aads>
+                    <interw>2</interw>
+                    <Ropi>2</Ropi>
+                    <Rwpi>2</Rwpi>
+                    <thumb>2</thumb>
+                    <SplitLS>2</SplitLS>
+                    <SwStkChk>2</SwStkChk>
+                    <NoWarn>2</NoWarn>
+                    <uSurpInc>2</uSurpInc>
+                    <useXO>2</useXO>
+                    <VariousControls>
+                      <MiscControls></MiscControls>
+                      <Define></Define>
+                      <Undefine></Undefine>
+                      <IncludePath></IncludePath>
+                    </VariousControls>
+                  </Aads>
+                </FileArmAds>
+              </FileOption>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>::CMSIS</GroupName>
+        </Group>
+      </Groups>
+    </Target>
+    <Target>
+      <TargetName>CM3_LE</TargetName>
+      <ToolsetNumber>0x4</ToolsetNumber>
+      <ToolsetName>ARM-ADS</ToolsetName>
+      <pArmCC>6050000::V6.5::.\ARMCLANG_6.5</pArmCC>
+      <pCCUsed>6050000::V6.5::.\ARMCLANG_6.5</pCCUsed>
+      <TargetOption>
+        <TargetCommonOption>
+          <Device>ARMCM3</Device>
+          <Vendor>ARM</Vendor>
+          <PackID>ARM.CMSIS.5.0.0</PackID>
+          <PackURL>http://www.keil.com/pack/</PackURL>
+          <Cpu>IRAM(0x20000000,0x00020000) IROM(0x00000000,0x00040000) CPUTYPE("Cortex-M3") CLOCK(12000000) ESEL ELITTLE</Cpu>
+          <FlashUtilSpec></FlashUtilSpec>
+          <StartupFile></StartupFile>
+          <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0NEW_DEVICE -FS00 -FL040000 -FP0($$Device:ARMCM3$Device\ARM\Flash\NEW_DEVICE.FLM))</FlashDriverDll>
+          <DeviceId>0</DeviceId>
+          <RegisterFile>$$Device:ARMCM3$Device\ARM\ARMCM3\Include\ARMCM3.h</RegisterFile>
+          <MemoryEnv></MemoryEnv>
+          <Cmp></Cmp>
+          <Asm></Asm>
+          <Linker></Linker>
+          <OHString></OHString>
+          <InfinionOptionDll></InfinionOptionDll>
+          <SLE66CMisc></SLE66CMisc>
+          <SLE66AMisc></SLE66AMisc>
+          <SLE66LinkerMisc></SLE66LinkerMisc>
+          <SFDFile>$$Device:ARMCM3$Device\ARM\SVD\ARMCM3.svd</SFDFile>
+          <bCustSvd>0</bCustSvd>
+          <UseEnv>0</UseEnv>
+          <BinPath></BinPath>
+          <IncludePath></IncludePath>
+          <LibPath></LibPath>
+          <RegisterFilePath></RegisterFilePath>
+          <DBRegisterFilePath></DBRegisterFilePath>
+          <TargetStatus>
+            <Error>0</Error>
+            <ExitCodeStop>0</ExitCodeStop>
+            <ButtonStop>0</ButtonStop>
+            <NotGenerated>0</NotGenerated>
+            <InvalidFlash>1</InvalidFlash>
+          </TargetStatus>
+          <OutputDirectory>.\CM3_LE\</OutputDirectory>
+          <OutputName>RTX_CM3</OutputName>
+          <CreateExecutable>0</CreateExecutable>
+          <CreateLib>1</CreateLib>
+          <CreateHexFile>0</CreateHexFile>
+          <DebugInformation>1</DebugInformation>
+          <BrowseInformation>1</BrowseInformation>
+          <ListingPath>.\CM3_LE\</ListingPath>
+          <HexFormatSelection>1</HexFormatSelection>
+          <Merge32K>0</Merge32K>
+          <CreateBatchFile>1</CreateBatchFile>
+          <BeforeCompile>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopU1X>0</nStopU1X>
+            <nStopU2X>0</nStopU2X>
+          </BeforeCompile>
+          <BeforeMake>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopB1X>0</nStopB1X>
+            <nStopB2X>0</nStopB2X>
+          </BeforeMake>
+          <AfterMake>
+            <RunUserProg1>1</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name>cmd.exe /C copy CM3_LE\RTX_CM3.lib ..\.</UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopA1X>0</nStopA1X>
+            <nStopA2X>0</nStopA2X>
+          </AfterMake>
+          <SelectedForBatchBuild>0</SelectedForBatchBuild>
+          <SVCSIdString></SVCSIdString>
+        </TargetCommonOption>
+        <CommonProperty>
+          <UseCPPCompiler>0</UseCPPCompiler>
+          <RVCTCodeConst>0</RVCTCodeConst>
+          <RVCTZI>0</RVCTZI>
+          <RVCTOtherData>0</RVCTOtherData>
+          <ModuleSelection>0</ModuleSelection>
+          <IncludeInBuild>1</IncludeInBuild>
+          <AlwaysBuild>0</AlwaysBuild>
+          <GenerateAssemblyFile>0</GenerateAssemblyFile>
+          <AssembleAssemblyFile>0</AssembleAssemblyFile>
+          <PublicsOnly>0</PublicsOnly>
+          <StopOnExitCode>3</StopOnExitCode>
+          <CustomArgument></CustomArgument>
+          <IncludeLibraryModules></IncludeLibraryModules>
+          <ComprImg>1</ComprImg>
+        </CommonProperty>
+        <DllOption>
+          <SimDllName>SARMCM3.DLL</SimDllName>
+          <SimDllArguments>  -MPU</SimDllArguments>
+          <SimDlgDll>DCM.DLL</SimDlgDll>
+          <SimDlgDllArguments>-pCM3</SimDlgDllArguments>
+          <TargetDllName>SARMCM3.DLL</TargetDllName>
+          <TargetDllArguments> -MPU</TargetDllArguments>
+          <TargetDlgDll>TCM.DLL</TargetDlgDll>
+          <TargetDlgDllArguments>-pCM3</TargetDlgDllArguments>
+        </DllOption>
+        <DebugOption>
+          <OPTHX>
+            <HexSelection>1</HexSelection>
+            <HexRangeLowAddress>0</HexRangeLowAddress>
+            <HexRangeHighAddress>0</HexRangeHighAddress>
+            <HexOffset>0</HexOffset>
+            <Oh166RecLen>16</Oh166RecLen>
+          </OPTHX>
+        </DebugOption>
+        <Utilities>
+          <Flash1>
+            <UseTargetDll>1</UseTargetDll>
+            <UseExternalTool>0</UseExternalTool>
+            <RunIndependent>0</RunIndependent>
+            <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
+            <Capability>1</Capability>
+            <DriverSelection>4096</DriverSelection>
+          </Flash1>
+          <bUseTDR>1</bUseTDR>
+          <Flash2>BIN\UL2CM3.DLL</Flash2>
+          <Flash3>"" ()</Flash3>
+          <Flash4></Flash4>
+          <pFcarmOut></pFcarmOut>
+          <pFcarmGrp></pFcarmGrp>
+          <pFcArmRoot></pFcArmRoot>
+          <FcArmLst>0</FcArmLst>
+        </Utilities>
+        <TargetArmAds>
+          <ArmAdsMisc>
+            <GenerateListings>0</GenerateListings>
+            <asHll>1</asHll>
+            <asAsm>1</asAsm>
+            <asMacX>1</asMacX>
+            <asSyms>1</asSyms>
+            <asFals>1</asFals>
+            <asDbgD>1</asDbgD>
+            <asForm>1</asForm>
+            <ldLst>0</ldLst>
+            <ldmm>1</ldmm>
+            <ldXref>1</ldXref>
+            <BigEnd>0</BigEnd>
+            <AdsALst>0</AdsALst>
+            <AdsACrf>1</AdsACrf>
+            <AdsANop>0</AdsANop>
+            <AdsANot>0</AdsANot>
+            <AdsLLst>0</AdsLLst>
+            <AdsLmap>1</AdsLmap>
+            <AdsLcgr>1</AdsLcgr>
+            <AdsLsym>1</AdsLsym>
+            <AdsLszi>1</AdsLszi>
+            <AdsLtoi>1</AdsLtoi>
+            <AdsLsun>1</AdsLsun>
+            <AdsLven>1</AdsLven>
+            <AdsLsxf>1</AdsLsxf>
+            <RvctClst>0</RvctClst>
+            <GenPPlst>0</GenPPlst>
+            <AdsCpuType>"Cortex-M3"</AdsCpuType>
+            <RvctDeviceName></RvctDeviceName>
+            <mOS>0</mOS>
+            <uocRom>0</uocRom>
+            <uocRam>0</uocRam>
+            <hadIROM>1</hadIROM>
+            <hadIRAM>1</hadIRAM>
+            <hadXRAM>0</hadXRAM>
+            <uocXRam>0</uocXRam>
+            <RvdsVP>0</RvdsVP>
+            <hadIRAM2>0</hadIRAM2>
+            <hadIROM2>0</hadIROM2>
+            <StupSel>8</StupSel>
+            <useUlib>0</useUlib>
+            <EndSel>1</EndSel>
+            <uLtcg>0</uLtcg>
+            <nSecure>0</nSecure>
+            <RoSelD>3</RoSelD>
+            <RwSelD>3</RwSelD>
+            <CodeSel>0</CodeSel>
+            <OptFeed>0</OptFeed>
+            <NoZi1>0</NoZi1>
+            <NoZi2>0</NoZi2>
+            <NoZi3>0</NoZi3>
+            <NoZi4>0</NoZi4>
+            <NoZi5>0</NoZi5>
+            <Ro1Chk>0</Ro1Chk>
+            <Ro2Chk>0</Ro2Chk>
+            <Ro3Chk>0</Ro3Chk>
+            <Ir1Chk>1</Ir1Chk>
+            <Ir2Chk>0</Ir2Chk>
+            <Ra1Chk>0</Ra1Chk>
+            <Ra2Chk>0</Ra2Chk>
+            <Ra3Chk>0</Ra3Chk>
+            <Im1Chk>1</Im1Chk>
+            <Im2Chk>0</Im2Chk>
+            <OnChipMemories>
+              <Ocm1>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm1>
+              <Ocm2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm2>
+              <Ocm3>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm3>
+              <Ocm4>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm4>
+              <Ocm5>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm5>
+              <Ocm6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm6>
+              <IRAM>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x20000</Size>
+              </IRAM>
+              <IROM>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x40000</Size>
+              </IROM>
+              <XRAM>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </XRAM>
+              <OCR_RVCT1>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT1>
+              <OCR_RVCT2>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT2>
+              <OCR_RVCT3>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT3>
+              <OCR_RVCT4>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x40000</Size>
+              </OCR_RVCT4>
+              <OCR_RVCT5>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT5>
+              <OCR_RVCT6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT6>
+              <OCR_RVCT7>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT7>
+              <OCR_RVCT8>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT8>
+              <OCR_RVCT9>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x20000</Size>
+              </OCR_RVCT9>
+              <OCR_RVCT10>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT10>
+            </OnChipMemories>
+            <RvctStartVector></RvctStartVector>
+          </ArmAdsMisc>
+          <Cads>
+            <interw>1</interw>
+            <Optim>4</Optim>
+            <oTime>0</oTime>
+            <SplitLS>0</SplitLS>
+            <OneElfS>1</OneElfS>
+            <Strict>0</Strict>
+            <EnumInt>0</EnumInt>
+            <PlainCh>0</PlainCh>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <wLevel>2</wLevel>
+            <uThumb>0</uThumb>
+            <uSurpInc>0</uSurpInc>
+            <uC99>0</uC99>
+            <useXO>0</useXO>
+            <v6Lang>3</v6Lang>
+            <v6LangP>0</v6LangP>
+            <vShortEn>1</vShortEn>
+            <vShortWch>1</vShortWch>
+            <v6Lto>0</v6Lto>
+            <v6WtE>0</v6WtE>
+            <VariousControls>
+              <MiscControls></MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath>..\..\..\Include</IncludePath>
+            </VariousControls>
+          </Cads>
+          <Aads>
+            <interw>1</interw>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <thumb>1</thumb>
+            <SplitLS>0</SplitLS>
+            <SwStkChk>0</SwStkChk>
+            <NoWarn>0</NoWarn>
+            <uSurpInc>0</uSurpInc>
+            <useXO>0</useXO>
+            <VariousControls>
+              <MiscControls>--no_hide_all</MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath></IncludePath>
+            </VariousControls>
+          </Aads>
+          <LDads>
+            <umfTarg>0</umfTarg>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <noStLib>0</noStLib>
+            <RepFail>1</RepFail>
+            <useFile>0</useFile>
+            <TextAddressRange></TextAddressRange>
+            <DataAddressRange></DataAddressRange>
+            <pXoBase></pXoBase>
+            <ScatterFile></ScatterFile>
+            <IncludeLibs></IncludeLibs>
+            <IncludeLibsPath></IncludeLibsPath>
+            <Misc></Misc>
+            <LinkerInputFile></LinkerInputFile>
+            <DisabledWarnings></DisabledWarnings>
+          </LDads>
+        </TargetArmAds>
+      </TargetOption>
+      <Groups>
+        <Group>
+          <GroupName>Core</GroupName>
+          <Files>
+            <File>
+              <FileName>rtx_kernel.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_kernel.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_thread.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_thread.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_delay.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_delay.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_timer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_timer.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_evflags.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_evflags.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_mutex.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_mutex.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_semaphore.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_semaphore.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_memory.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_memory.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_mempool.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_mempool.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_msgqueue.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_msgqueue.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_system.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_system.c</FilePath>
+            </File>
+            <File>
+              <FileName>user_svc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\user_svc.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Handlers</GroupName>
+          <Files>
+            <File>
+              <FileName>irq_cm0.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\ARM\irq_cm0.s</FilePath>
+              <FileOption>
+                <CommonProperty>
+                  <UseCPPCompiler>2</UseCPPCompiler>
+                  <RVCTCodeConst>0</RVCTCodeConst>
+                  <RVCTZI>0</RVCTZI>
+                  <RVCTOtherData>0</RVCTOtherData>
+                  <ModuleSelection>0</ModuleSelection>
+                  <IncludeInBuild>0</IncludeInBuild>
+                  <AlwaysBuild>2</AlwaysBuild>
+                  <GenerateAssemblyFile>2</GenerateAssemblyFile>
+                  <AssembleAssemblyFile>2</AssembleAssemblyFile>
+                  <PublicsOnly>2</PublicsOnly>
+                  <StopOnExitCode>11</StopOnExitCode>
+                  <CustomArgument></CustomArgument>
+                  <IncludeLibraryModules></IncludeLibraryModules>
+                  <ComprImg>1</ComprImg>
+                </CommonProperty>
+                <FileArmAds>
+                  <Aads>
+                    <interw>2</interw>
+                    <Ropi>2</Ropi>
+                    <Rwpi>2</Rwpi>
+                    <thumb>2</thumb>
+                    <SplitLS>2</SplitLS>
+                    <SwStkChk>2</SwStkChk>
+                    <NoWarn>2</NoWarn>
+                    <uSurpInc>2</uSurpInc>
+                    <useXO>2</useXO>
+                    <VariousControls>
+                      <MiscControls></MiscControls>
+                      <Define></Define>
+                      <Undefine></Undefine>
+                      <IncludePath></IncludePath>
+                    </VariousControls>
+                  </Aads>
+                </FileArmAds>
+              </FileOption>
+            </File>
+            <File>
+              <FileName>irq_cm3.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\ARM\irq_cm3.s</FilePath>
+            </File>
+            <File>
+              <FileName>irq_cm4f.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\ARM\irq_cm4f.s</FilePath>
+              <FileOption>
+                <CommonProperty>
+                  <UseCPPCompiler>2</UseCPPCompiler>
+                  <RVCTCodeConst>0</RVCTCodeConst>
+                  <RVCTZI>0</RVCTZI>
+                  <RVCTOtherData>0</RVCTOtherData>
+                  <ModuleSelection>0</ModuleSelection>
+                  <IncludeInBuild>0</IncludeInBuild>
+                  <AlwaysBuild>2</AlwaysBuild>
+                  <GenerateAssemblyFile>2</GenerateAssemblyFile>
+                  <AssembleAssemblyFile>2</AssembleAssemblyFile>
+                  <PublicsOnly>2</PublicsOnly>
+                  <StopOnExitCode>11</StopOnExitCode>
+                  <CustomArgument></CustomArgument>
+                  <IncludeLibraryModules></IncludeLibraryModules>
+                  <ComprImg>1</ComprImg>
+                </CommonProperty>
+                <FileArmAds>
+                  <Aads>
+                    <interw>2</interw>
+                    <Ropi>2</Ropi>
+                    <Rwpi>2</Rwpi>
+                    <thumb>2</thumb>
+                    <SplitLS>2</SplitLS>
+                    <SwStkChk>2</SwStkChk>
+                    <NoWarn>2</NoWarn>
+                    <uSurpInc>2</uSurpInc>
+                    <useXO>2</useXO>
+                    <VariousControls>
+                      <MiscControls></MiscControls>
+                      <Define></Define>
+                      <Undefine></Undefine>
+                      <IncludePath></IncludePath>
+                    </VariousControls>
+                  </Aads>
+                </FileArmAds>
+              </FileOption>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>::CMSIS</GroupName>
+        </Group>
+      </Groups>
+    </Target>
+    <Target>
+      <TargetName>CM4F_LE</TargetName>
+      <ToolsetNumber>0x4</ToolsetNumber>
+      <ToolsetName>ARM-ADS</ToolsetName>
+      <pArmCC>6050000::V6.5::.\ARMCLANG_6.5</pArmCC>
+      <pCCUsed>6050000::V6.5::.\ARMCLANG_6.5</pCCUsed>
+      <TargetOption>
+        <TargetCommonOption>
+          <Device>ARMCM4_FP</Device>
+          <Vendor>ARM</Vendor>
+          <PackID>ARM.CMSIS.5.0.0</PackID>
+          <PackURL>http://www.keil.com/pack/</PackURL>
+          <Cpu>IRAM(0x20000000,0x00020000) IROM(0x00000000,0x00040000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ESEL ELITTLE</Cpu>
+          <FlashUtilSpec></FlashUtilSpec>
+          <StartupFile></StartupFile>
+          <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0NEW_DEVICE -FS00 -FL040000 -FP0($$Device:ARMCM4_FP$Device\ARM\Flash\NEW_DEVICE.FLM))</FlashDriverDll>
+          <DeviceId>0</DeviceId>
+          <RegisterFile>$$Device:ARMCM4_FP$Device\ARM\ARMCM4\Include\ARMCM4_FP.h</RegisterFile>
+          <MemoryEnv></MemoryEnv>
+          <Cmp></Cmp>
+          <Asm></Asm>
+          <Linker></Linker>
+          <OHString></OHString>
+          <InfinionOptionDll></InfinionOptionDll>
+          <SLE66CMisc></SLE66CMisc>
+          <SLE66AMisc></SLE66AMisc>
+          <SLE66LinkerMisc></SLE66LinkerMisc>
+          <SFDFile>$$Device:ARMCM4_FP$Device\ARM\SVD\ARMCM4.svd</SFDFile>
+          <bCustSvd>0</bCustSvd>
+          <UseEnv>0</UseEnv>
+          <BinPath></BinPath>
+          <IncludePath></IncludePath>
+          <LibPath></LibPath>
+          <RegisterFilePath></RegisterFilePath>
+          <DBRegisterFilePath></DBRegisterFilePath>
+          <TargetStatus>
+            <Error>0</Error>
+            <ExitCodeStop>0</ExitCodeStop>
+            <ButtonStop>0</ButtonStop>
+            <NotGenerated>0</NotGenerated>
+            <InvalidFlash>1</InvalidFlash>
+          </TargetStatus>
+          <OutputDirectory>.\CM4F_LE\</OutputDirectory>
+          <OutputName>RTX_CM4F</OutputName>
+          <CreateExecutable>0</CreateExecutable>
+          <CreateLib>1</CreateLib>
+          <CreateHexFile>0</CreateHexFile>
+          <DebugInformation>1</DebugInformation>
+          <BrowseInformation>1</BrowseInformation>
+          <ListingPath>.\CM4F_LE\</ListingPath>
+          <HexFormatSelection>1</HexFormatSelection>
+          <Merge32K>0</Merge32K>
+          <CreateBatchFile>1</CreateBatchFile>
+          <BeforeCompile>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopU1X>0</nStopU1X>
+            <nStopU2X>0</nStopU2X>
+          </BeforeCompile>
+          <BeforeMake>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopB1X>0</nStopB1X>
+            <nStopB2X>0</nStopB2X>
+          </BeforeMake>
+          <AfterMake>
+            <RunUserProg1>1</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name>cmd.exe /C copy CM4F_LE\RTX_CM4F.lib ..\.</UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopA1X>0</nStopA1X>
+            <nStopA2X>0</nStopA2X>
+          </AfterMake>
+          <SelectedForBatchBuild>0</SelectedForBatchBuild>
+          <SVCSIdString></SVCSIdString>
+        </TargetCommonOption>
+        <CommonProperty>
+          <UseCPPCompiler>0</UseCPPCompiler>
+          <RVCTCodeConst>0</RVCTCodeConst>
+          <RVCTZI>0</RVCTZI>
+          <RVCTOtherData>0</RVCTOtherData>
+          <ModuleSelection>0</ModuleSelection>
+          <IncludeInBuild>1</IncludeInBuild>
+          <AlwaysBuild>0</AlwaysBuild>
+          <GenerateAssemblyFile>0</GenerateAssemblyFile>
+          <AssembleAssemblyFile>0</AssembleAssemblyFile>
+          <PublicsOnly>0</PublicsOnly>
+          <StopOnExitCode>3</StopOnExitCode>
+          <CustomArgument></CustomArgument>
+          <IncludeLibraryModules></IncludeLibraryModules>
+          <ComprImg>1</ComprImg>
+        </CommonProperty>
+        <DllOption>
+          <SimDllName>SARMCM3.DLL</SimDllName>
+          <SimDllArguments>  -MPU</SimDllArguments>
+          <SimDlgDll>DCM.DLL</SimDlgDll>
+          <SimDlgDllArguments>-pCM4</SimDlgDllArguments>
+          <TargetDllName>SARMCM3.DLL</TargetDllName>
+          <TargetDllArguments> -MPU</TargetDllArguments>
+          <TargetDlgDll>TCM.DLL</TargetDlgDll>
+          <TargetDlgDllArguments>-pCM4</TargetDlgDllArguments>
+        </DllOption>
+        <DebugOption>
+          <OPTHX>
+            <HexSelection>1</HexSelection>
+            <HexRangeLowAddress>0</HexRangeLowAddress>
+            <HexRangeHighAddress>0</HexRangeHighAddress>
+            <HexOffset>0</HexOffset>
+            <Oh166RecLen>16</Oh166RecLen>
+          </OPTHX>
+        </DebugOption>
+        <Utilities>
+          <Flash1>
+            <UseTargetDll>1</UseTargetDll>
+            <UseExternalTool>0</UseExternalTool>
+            <RunIndependent>0</RunIndependent>
+            <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
+            <Capability>1</Capability>
+            <DriverSelection>4096</DriverSelection>
+          </Flash1>
+          <bUseTDR>1</bUseTDR>
+          <Flash2>BIN\UL2CM3.DLL</Flash2>
+          <Flash3></Flash3>
+          <Flash4></Flash4>
+          <pFcarmOut></pFcarmOut>
+          <pFcarmGrp></pFcarmGrp>
+          <pFcArmRoot></pFcArmRoot>
+          <FcArmLst>0</FcArmLst>
+        </Utilities>
+        <TargetArmAds>
+          <ArmAdsMisc>
+            <GenerateListings>0</GenerateListings>
+            <asHll>1</asHll>
+            <asAsm>1</asAsm>
+            <asMacX>1</asMacX>
+            <asSyms>1</asSyms>
+            <asFals>1</asFals>
+            <asDbgD>1</asDbgD>
+            <asForm>1</asForm>
+            <ldLst>0</ldLst>
+            <ldmm>1</ldmm>
+            <ldXref>1</ldXref>
+            <BigEnd>0</BigEnd>
+            <AdsALst>0</AdsALst>
+            <AdsACrf>1</AdsACrf>
+            <AdsANop>0</AdsANop>
+            <AdsANot>0</AdsANot>
+            <AdsLLst>0</AdsLLst>
+            <AdsLmap>1</AdsLmap>
+            <AdsLcgr>1</AdsLcgr>
+            <AdsLsym>1</AdsLsym>
+            <AdsLszi>1</AdsLszi>
+            <AdsLtoi>1</AdsLtoi>
+            <AdsLsun>1</AdsLsun>
+            <AdsLven>1</AdsLven>
+            <AdsLsxf>1</AdsLsxf>
+            <RvctClst>0</RvctClst>
+            <GenPPlst>0</GenPPlst>
+            <AdsCpuType>"Cortex-M4"</AdsCpuType>
+            <RvctDeviceName></RvctDeviceName>
+            <mOS>0</mOS>
+            <uocRom>0</uocRom>
+            <uocRam>0</uocRam>
+            <hadIROM>1</hadIROM>
+            <hadIRAM>1</hadIRAM>
+            <hadXRAM>0</hadXRAM>
+            <uocXRam>0</uocXRam>
+            <RvdsVP>2</RvdsVP>
+            <hadIRAM2>0</hadIRAM2>
+            <hadIROM2>0</hadIROM2>
+            <StupSel>8</StupSel>
+            <useUlib>0</useUlib>
+            <EndSel>1</EndSel>
+            <uLtcg>0</uLtcg>
+            <nSecure>0</nSecure>
+            <RoSelD>3</RoSelD>
+            <RwSelD>3</RwSelD>
+            <CodeSel>0</CodeSel>
+            <OptFeed>0</OptFeed>
+            <NoZi1>0</NoZi1>
+            <NoZi2>0</NoZi2>
+            <NoZi3>0</NoZi3>
+            <NoZi4>0</NoZi4>
+            <NoZi5>0</NoZi5>
+            <Ro1Chk>0</Ro1Chk>
+            <Ro2Chk>0</Ro2Chk>
+            <Ro3Chk>0</Ro3Chk>
+            <Ir1Chk>1</Ir1Chk>
+            <Ir2Chk>0</Ir2Chk>
+            <Ra1Chk>0</Ra1Chk>
+            <Ra2Chk>0</Ra2Chk>
+            <Ra3Chk>0</Ra3Chk>
+            <Im1Chk>1</Im1Chk>
+            <Im2Chk>0</Im2Chk>
+            <OnChipMemories>
+              <Ocm1>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm1>
+              <Ocm2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm2>
+              <Ocm3>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm3>
+              <Ocm4>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm4>
+              <Ocm5>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm5>
+              <Ocm6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm6>
+              <IRAM>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x20000</Size>
+              </IRAM>
+              <IROM>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x40000</Size>
+              </IROM>
+              <XRAM>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </XRAM>
+              <OCR_RVCT1>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT1>
+              <OCR_RVCT2>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT2>
+              <OCR_RVCT3>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT3>
+              <OCR_RVCT4>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x40000</Size>
+              </OCR_RVCT4>
+              <OCR_RVCT5>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT5>
+              <OCR_RVCT6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT6>
+              <OCR_RVCT7>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT7>
+              <OCR_RVCT8>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT8>
+              <OCR_RVCT9>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x20000</Size>
+              </OCR_RVCT9>
+              <OCR_RVCT10>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT10>
+            </OnChipMemories>
+            <RvctStartVector></RvctStartVector>
+          </ArmAdsMisc>
+          <Cads>
+            <interw>1</interw>
+            <Optim>4</Optim>
+            <oTime>0</oTime>
+            <SplitLS>0</SplitLS>
+            <OneElfS>1</OneElfS>
+            <Strict>0</Strict>
+            <EnumInt>0</EnumInt>
+            <PlainCh>0</PlainCh>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <wLevel>2</wLevel>
+            <uThumb>0</uThumb>
+            <uSurpInc>0</uSurpInc>
+            <uC99>0</uC99>
+            <useXO>0</useXO>
+            <v6Lang>3</v6Lang>
+            <v6LangP>0</v6LangP>
+            <vShortEn>1</vShortEn>
+            <vShortWch>1</vShortWch>
+            <v6Lto>0</v6Lto>
+            <v6WtE>0</v6WtE>
+            <VariousControls>
+              <MiscControls></MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath>..\..\..\Include</IncludePath>
+            </VariousControls>
+          </Cads>
+          <Aads>
+            <interw>1</interw>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <thumb>1</thumb>
+            <SplitLS>0</SplitLS>
+            <SwStkChk>0</SwStkChk>
+            <NoWarn>0</NoWarn>
+            <uSurpInc>0</uSurpInc>
+            <useXO>0</useXO>
+            <VariousControls>
+              <MiscControls>--no_hide_all</MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath></IncludePath>
+            </VariousControls>
+          </Aads>
+          <LDads>
+            <umfTarg>0</umfTarg>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <noStLib>0</noStLib>
+            <RepFail>1</RepFail>
+            <useFile>0</useFile>
+            <TextAddressRange></TextAddressRange>
+            <DataAddressRange></DataAddressRange>
+            <pXoBase></pXoBase>
+            <ScatterFile></ScatterFile>
+            <IncludeLibs></IncludeLibs>
+            <IncludeLibsPath></IncludeLibsPath>
+            <Misc></Misc>
+            <LinkerInputFile></LinkerInputFile>
+            <DisabledWarnings></DisabledWarnings>
+          </LDads>
+        </TargetArmAds>
+      </TargetOption>
+      <Groups>
+        <Group>
+          <GroupName>Core</GroupName>
+          <Files>
+            <File>
+              <FileName>rtx_kernel.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_kernel.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_thread.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_thread.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_delay.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_delay.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_timer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_timer.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_evflags.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_evflags.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_mutex.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_mutex.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_semaphore.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_semaphore.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_memory.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_memory.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_mempool.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_mempool.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_msgqueue.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_msgqueue.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_system.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_system.c</FilePath>
+            </File>
+            <File>
+              <FileName>user_svc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\user_svc.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Handlers</GroupName>
+          <Files>
+            <File>
+              <FileName>irq_cm0.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\ARM\irq_cm0.s</FilePath>
+              <FileOption>
+                <CommonProperty>
+                  <UseCPPCompiler>2</UseCPPCompiler>
+                  <RVCTCodeConst>0</RVCTCodeConst>
+                  <RVCTZI>0</RVCTZI>
+                  <RVCTOtherData>0</RVCTOtherData>
+                  <ModuleSelection>0</ModuleSelection>
+                  <IncludeInBuild>0</IncludeInBuild>
+                  <AlwaysBuild>2</AlwaysBuild>
+                  <GenerateAssemblyFile>2</GenerateAssemblyFile>
+                  <AssembleAssemblyFile>2</AssembleAssemblyFile>
+                  <PublicsOnly>2</PublicsOnly>
+                  <StopOnExitCode>11</StopOnExitCode>
+                  <CustomArgument></CustomArgument>
+                  <IncludeLibraryModules></IncludeLibraryModules>
+                  <ComprImg>1</ComprImg>
+                </CommonProperty>
+                <FileArmAds>
+                  <Aads>
+                    <interw>2</interw>
+                    <Ropi>2</Ropi>
+                    <Rwpi>2</Rwpi>
+                    <thumb>2</thumb>
+                    <SplitLS>2</SplitLS>
+                    <SwStkChk>2</SwStkChk>
+                    <NoWarn>2</NoWarn>
+                    <uSurpInc>2</uSurpInc>
+                    <useXO>2</useXO>
+                    <VariousControls>
+                      <MiscControls></MiscControls>
+                      <Define></Define>
+                      <Undefine></Undefine>
+                      <IncludePath></IncludePath>
+                    </VariousControls>
+                  </Aads>
+                </FileArmAds>
+              </FileOption>
+            </File>
+            <File>
+              <FileName>irq_cm3.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\ARM\irq_cm3.s</FilePath>
+              <FileOption>
+                <CommonProperty>
+                  <UseCPPCompiler>2</UseCPPCompiler>
+                  <RVCTCodeConst>0</RVCTCodeConst>
+                  <RVCTZI>0</RVCTZI>
+                  <RVCTOtherData>0</RVCTOtherData>
+                  <ModuleSelection>0</ModuleSelection>
+                  <IncludeInBuild>0</IncludeInBuild>
+                  <AlwaysBuild>2</AlwaysBuild>
+                  <GenerateAssemblyFile>2</GenerateAssemblyFile>
+                  <AssembleAssemblyFile>2</AssembleAssemblyFile>
+                  <PublicsOnly>2</PublicsOnly>
+                  <StopOnExitCode>11</StopOnExitCode>
+                  <CustomArgument></CustomArgument>
+                  <IncludeLibraryModules></IncludeLibraryModules>
+                  <ComprImg>1</ComprImg>
+                </CommonProperty>
+                <FileArmAds>
+                  <Aads>
+                    <interw>2</interw>
+                    <Ropi>2</Ropi>
+                    <Rwpi>2</Rwpi>
+                    <thumb>2</thumb>
+                    <SplitLS>2</SplitLS>
+                    <SwStkChk>2</SwStkChk>
+                    <NoWarn>2</NoWarn>
+                    <uSurpInc>2</uSurpInc>
+                    <useXO>2</useXO>
+                    <VariousControls>
+                      <MiscControls></MiscControls>
+                      <Define></Define>
+                      <Undefine></Undefine>
+                      <IncludePath></IncludePath>
+                    </VariousControls>
+                  </Aads>
+                </FileArmAds>
+              </FileOption>
+            </File>
+            <File>
+              <FileName>irq_cm4f.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\ARM\irq_cm4f.s</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>::CMSIS</GroupName>
+        </Group>
+      </Groups>
+    </Target>
+  </Targets>
+
+  <RTE>
+    <apis/>
+    <components>
+      <component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="5.0.0" condition="Cortex-M ARMv8-M Device">
+        <package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="5.0.0-Beta4"/>
+        <targetInfos>
+          <targetInfo name="CM0_LE"/>
+          <targetInfo name="CM3_LE"/>
+          <targetInfo name="CM4F_LE"/>
+        </targetInfos>
+      </component>
+    </components>
+    <files/>
+  </RTE>
+
+</Project>
diff --git a/CMSIS/RTOS2/RTX/Library/ARM/RTX_CM0.lib b/CMSIS/RTOS2/RTX/Library/ARM/RTX_CM0.lib
new file mode 100644
index 0000000..c62952f
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Library/ARM/RTX_CM0.lib
Binary files differ
diff --git a/CMSIS/RTOS2/RTX/Library/ARM/RTX_CM3.lib b/CMSIS/RTOS2/RTX/Library/ARM/RTX_CM3.lib
new file mode 100644
index 0000000..4ba1c6d
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Library/ARM/RTX_CM3.lib
Binary files differ
diff --git a/CMSIS/RTOS2/RTX/Library/ARM/RTX_CM4F.lib b/CMSIS/RTOS2/RTX/Library/ARM/RTX_CM4F.lib
new file mode 100644
index 0000000..12ec33b
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Library/ARM/RTX_CM4F.lib
Binary files differ
diff --git a/CMSIS/RTOS2/RTX/Library/GCC/MDK/RTE/RTE_Components.h b/CMSIS/RTOS2/RTX/Library/GCC/MDK/RTE/RTE_Components.h
new file mode 100644
index 0000000..002e1bf
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Library/GCC/MDK/RTE/RTE_Components.h
@@ -0,0 +1,20 @@
+
+/*
+ * Auto generated Run-Time-Environment Component Configuration File
+ *      *** Do not modify ! ***
+ *
+ * Project: 'RTX_CM' 
+ * Target:  'CM0_LE' 
+ */
+
+#ifndef RTE_COMPONENTS_H
+#define RTE_COMPONENTS_H
+
+
+/*
+ * Define the Device Header File: 
+ */
+#define CMSIS_device_header "ARMCM0.h"
+
+
+#endif /* RTE_COMPONENTS_H */
diff --git a/CMSIS/RTOS2/RTX/Library/GCC/MDK/RTX_CM.uvoptx b/CMSIS/RTOS2/RTX/Library/GCC/MDK/RTX_CM.uvoptx
new file mode 100644
index 0000000..90c8c6d
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Library/GCC/MDK/RTX_CM.uvoptx
@@ -0,0 +1,642 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<ProjectOpt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_optx.xsd">
+
+  <SchemaVersion>1.0</SchemaVersion>
+
+  <Header>### uVision Project, (C) Keil Software</Header>
+
+  <Extensions>
+    <cExt>*.c</cExt>
+    <aExt>*.s*; *.src; *.a*</aExt>
+    <oExt>*.obj</oExt>
+    <lExt>*.lib</lExt>
+    <tExt>*.txt; *.h; *.inc</tExt>
+    <pExt>*.plm</pExt>
+    <CppX>*.cpp</CppX>
+    <nMigrate>0</nMigrate>
+  </Extensions>
+
+  <DaveTm>
+    <dwLowDateTime>0</dwLowDateTime>
+    <dwHighDateTime>0</dwHighDateTime>
+  </DaveTm>
+
+  <Target>
+    <TargetName>CM0_LE</TargetName>
+    <ToolsetNumber>0x3</ToolsetNumber>
+    <ToolsetName>ARM-GNU</ToolsetName>
+    <TargetOption>
+      <CLKARM>12000000</CLKARM>
+      <OPTTT>
+        <gFlags>1</gFlags>
+        <BeepAtEnd>1</BeepAtEnd>
+        <RunSim>0</RunSim>
+        <RunTarget>1</RunTarget>
+        <RunAbUc>0</RunAbUc>
+      </OPTTT>
+      <OPTHX>
+        <HexSelection>1</HexSelection>
+        <FlashByte>65535</FlashByte>
+        <HexRangeLowAddress>0</HexRangeLowAddress>
+        <HexRangeHighAddress>0</HexRangeHighAddress>
+        <HexOffset>0</HexOffset>
+      </OPTHX>
+      <OPTLEX>
+        <PageWidth>120</PageWidth>
+        <PageLength>65</PageLength>
+        <TabStop>8</TabStop>
+        <ListingPath>.\CM0_LE\</ListingPath>
+      </OPTLEX>
+      <ListingPage>
+        <CreateCListing>1</CreateCListing>
+        <CreateAListing>1</CreateAListing>
+        <CreateLListing>1</CreateLListing>
+        <CreateIListing>0</CreateIListing>
+        <AsmCond>1</AsmCond>
+        <AsmSymb>1</AsmSymb>
+        <AsmXref>0</AsmXref>
+        <CCond>1</CCond>
+        <CCode>0</CCode>
+        <CListInc>0</CListInc>
+        <CSymb>0</CSymb>
+        <LinkerCodeListing>0</LinkerCodeListing>
+      </ListingPage>
+      <OPTXL>
+        <LMap>1</LMap>
+        <LComments>1</LComments>
+        <LGenerateSymbols>1</LGenerateSymbols>
+        <LLibSym>1</LLibSym>
+        <LLines>1</LLines>
+        <LLocSym>1</LLocSym>
+        <LPubSym>1</LPubSym>
+        <LXref>0</LXref>
+        <LExpSel>0</LExpSel>
+      </OPTXL>
+      <OPTFL>
+        <tvExp>1</tvExp>
+        <tvExpOptDlg>0</tvExpOptDlg>
+        <IsCurrentTarget>1</IsCurrentTarget>
+      </OPTFL>
+      <CpuCode>7</CpuCode>
+      <DebugOpt>
+        <uSim>0</uSim>
+        <uTrg>1</uTrg>
+        <sLdApp>1</sLdApp>
+        <sGomain>1</sGomain>
+        <sRbreak>1</sRbreak>
+        <sRwatch>1</sRwatch>
+        <sRmem>1</sRmem>
+        <sRfunc>1</sRfunc>
+        <sRbox>1</sRbox>
+        <tLdApp>1</tLdApp>
+        <tGomain>1</tGomain>
+        <tRbreak>1</tRbreak>
+        <tRwatch>1</tRwatch>
+        <tRmem>1</tRmem>
+        <tRfunc>0</tRfunc>
+        <tRbox>1</tRbox>
+        <tRtrace>1</tRtrace>
+        <sRSysVw>1</sRSysVw>
+        <tRSysVw>1</tRSysVw>
+        <sRunDeb>0</sRunDeb>
+        <sLrtime>0</sLrtime>
+        <nTsel>0</nTsel>
+        <sDll></sDll>
+        <sDllPa></sDllPa>
+        <sDlgDll></sDlgDll>
+        <sDlgPa></sDlgPa>
+        <sIfile></sIfile>
+        <tDll></tDll>
+        <tDllPa></tDllPa>
+        <tDlgDll></tDlgDll>
+        <tDlgPa></tDlgPa>
+        <tIfile></tIfile>
+        <pMon>BIN\UL2CM3.DLL</pMon>
+      </DebugOpt>
+      <TargetDriverDllRegistry>
+        <SetRegEntry>
+          <Number>0</Number>
+          <Key>UL2CM3</Key>
+          <Name>UL2CM3(-S0 -C0 -P0 )  -FN1 -FC1000 -FD20000000 -FF0NEW_DEVICE -FL040000 -FS00 -FP0($$Device:ARMCM0$Device\ARM\Flash\NEW_DEVICE.FLM)</Name>
+        </SetRegEntry>
+      </TargetDriverDllRegistry>
+      <Breakpoint/>
+      <Tracepoint>
+        <THDelay>0</THDelay>
+      </Tracepoint>
+      <DebugFlag>
+        <trace>0</trace>
+        <periodic>1</periodic>
+        <aLwin>0</aLwin>
+        <aCover>0</aCover>
+        <aSer1>0</aSer1>
+        <aSer2>0</aSer2>
+        <aPa>0</aPa>
+        <viewmode>0</viewmode>
+        <vrSel>0</vrSel>
+        <aSym>0</aSym>
+        <aTbox>0</aTbox>
+        <AscS1>0</AscS1>
+        <AscS2>0</AscS2>
+        <AscS3>0</AscS3>
+        <aSer3>0</aSer3>
+        <eProf>0</eProf>
+        <aLa>0</aLa>
+        <aPa1>0</aPa1>
+        <AscS4>0</AscS4>
+        <aSer4>0</aSer4>
+        <StkLoc>0</StkLoc>
+        <TrcWin>0</TrcWin>
+        <newCpu>0</newCpu>
+        <uProt>0</uProt>
+      </DebugFlag>
+      <LintExecutable></LintExecutable>
+      <LintConfigFile></LintConfigFile>
+      <bLintAuto>0</bLintAuto>
+      <Lin2Executable></Lin2Executable>
+      <Lin2ConfigFile></Lin2ConfigFile>
+      <bLin2Auto>0</bLin2Auto>
+    </TargetOption>
+  </Target>
+
+  <Target>
+    <TargetName>CM3_LE</TargetName>
+    <ToolsetNumber>0x3</ToolsetNumber>
+    <ToolsetName>ARM-GNU</ToolsetName>
+    <TargetOption>
+      <CLKARM>12000000</CLKARM>
+      <OPTTT>
+        <gFlags>1</gFlags>
+        <BeepAtEnd>1</BeepAtEnd>
+        <RunSim>0</RunSim>
+        <RunTarget>1</RunTarget>
+        <RunAbUc>0</RunAbUc>
+      </OPTTT>
+      <OPTHX>
+        <HexSelection>1</HexSelection>
+        <FlashByte>65535</FlashByte>
+        <HexRangeLowAddress>0</HexRangeLowAddress>
+        <HexRangeHighAddress>0</HexRangeHighAddress>
+        <HexOffset>0</HexOffset>
+      </OPTHX>
+      <OPTLEX>
+        <PageWidth>120</PageWidth>
+        <PageLength>65</PageLength>
+        <TabStop>8</TabStop>
+        <ListingPath>.\CM3_LE\</ListingPath>
+      </OPTLEX>
+      <ListingPage>
+        <CreateCListing>1</CreateCListing>
+        <CreateAListing>1</CreateAListing>
+        <CreateLListing>1</CreateLListing>
+        <CreateIListing>0</CreateIListing>
+        <AsmCond>1</AsmCond>
+        <AsmSymb>1</AsmSymb>
+        <AsmXref>0</AsmXref>
+        <CCond>1</CCond>
+        <CCode>0</CCode>
+        <CListInc>0</CListInc>
+        <CSymb>0</CSymb>
+        <LinkerCodeListing>0</LinkerCodeListing>
+      </ListingPage>
+      <OPTXL>
+        <LMap>1</LMap>
+        <LComments>1</LComments>
+        <LGenerateSymbols>1</LGenerateSymbols>
+        <LLibSym>1</LLibSym>
+        <LLines>1</LLines>
+        <LLocSym>1</LLocSym>
+        <LPubSym>1</LPubSym>
+        <LXref>0</LXref>
+        <LExpSel>0</LExpSel>
+      </OPTXL>
+      <OPTFL>
+        <tvExp>1</tvExp>
+        <tvExpOptDlg>0</tvExpOptDlg>
+        <IsCurrentTarget>0</IsCurrentTarget>
+      </OPTFL>
+      <CpuCode>7</CpuCode>
+      <DebugOpt>
+        <uSim>0</uSim>
+        <uTrg>1</uTrg>
+        <sLdApp>1</sLdApp>
+        <sGomain>1</sGomain>
+        <sRbreak>1</sRbreak>
+        <sRwatch>1</sRwatch>
+        <sRmem>1</sRmem>
+        <sRfunc>1</sRfunc>
+        <sRbox>1</sRbox>
+        <tLdApp>1</tLdApp>
+        <tGomain>1</tGomain>
+        <tRbreak>1</tRbreak>
+        <tRwatch>1</tRwatch>
+        <tRmem>1</tRmem>
+        <tRfunc>0</tRfunc>
+        <tRbox>1</tRbox>
+        <tRtrace>1</tRtrace>
+        <sRSysVw>1</sRSysVw>
+        <tRSysVw>1</tRSysVw>
+        <sRunDeb>0</sRunDeb>
+        <sLrtime>0</sLrtime>
+        <nTsel>0</nTsel>
+        <sDll></sDll>
+        <sDllPa></sDllPa>
+        <sDlgDll></sDlgDll>
+        <sDlgPa></sDlgPa>
+        <sIfile></sIfile>
+        <tDll></tDll>
+        <tDllPa></tDllPa>
+        <tDlgDll></tDlgDll>
+        <tDlgPa></tDlgPa>
+        <tIfile></tIfile>
+        <pMon>BIN\UL2CM3.DLL</pMon>
+      </DebugOpt>
+      <TargetDriverDllRegistry>
+        <SetRegEntry>
+          <Number>0</Number>
+          <Key>UL2CM3</Key>
+          <Name>UL2CM3(-S0 -C0 -P0 )  -FN1 -FC1000 -FD20000000 -FF0NEW_DEVICE -FL040000 -FS00 -FP0($$Device:ARMCM3$Device\ARM\Flash\NEW_DEVICE.FLM)</Name>
+        </SetRegEntry>
+      </TargetDriverDllRegistry>
+      <Breakpoint/>
+      <Tracepoint>
+        <THDelay>0</THDelay>
+      </Tracepoint>
+      <DebugFlag>
+        <trace>0</trace>
+        <periodic>1</periodic>
+        <aLwin>0</aLwin>
+        <aCover>0</aCover>
+        <aSer1>0</aSer1>
+        <aSer2>0</aSer2>
+        <aPa>0</aPa>
+        <viewmode>0</viewmode>
+        <vrSel>0</vrSel>
+        <aSym>0</aSym>
+        <aTbox>0</aTbox>
+        <AscS1>0</AscS1>
+        <AscS2>0</AscS2>
+        <AscS3>0</AscS3>
+        <aSer3>0</aSer3>
+        <eProf>0</eProf>
+        <aLa>0</aLa>
+        <aPa1>0</aPa1>
+        <AscS4>0</AscS4>
+        <aSer4>0</aSer4>
+        <StkLoc>0</StkLoc>
+        <TrcWin>0</TrcWin>
+        <newCpu>0</newCpu>
+        <uProt>0</uProt>
+      </DebugFlag>
+      <LintExecutable></LintExecutable>
+      <LintConfigFile></LintConfigFile>
+      <bLintAuto>0</bLintAuto>
+      <Lin2Executable></Lin2Executable>
+      <Lin2ConfigFile></Lin2ConfigFile>
+      <bLin2Auto>0</bLin2Auto>
+    </TargetOption>
+  </Target>
+
+  <Target>
+    <TargetName>CM4F_LE</TargetName>
+    <ToolsetNumber>0x3</ToolsetNumber>
+    <ToolsetName>ARM-GNU</ToolsetName>
+    <TargetOption>
+      <CLKARM>12000000</CLKARM>
+      <OPTTT>
+        <gFlags>1</gFlags>
+        <BeepAtEnd>1</BeepAtEnd>
+        <RunSim>0</RunSim>
+        <RunTarget>1</RunTarget>
+        <RunAbUc>0</RunAbUc>
+      </OPTTT>
+      <OPTHX>
+        <HexSelection>1</HexSelection>
+        <FlashByte>65535</FlashByte>
+        <HexRangeLowAddress>0</HexRangeLowAddress>
+        <HexRangeHighAddress>0</HexRangeHighAddress>
+        <HexOffset>0</HexOffset>
+      </OPTHX>
+      <OPTLEX>
+        <PageWidth>120</PageWidth>
+        <PageLength>65</PageLength>
+        <TabStop>8</TabStop>
+        <ListingPath>.\CM4F_LE\</ListingPath>
+      </OPTLEX>
+      <ListingPage>
+        <CreateCListing>1</CreateCListing>
+        <CreateAListing>1</CreateAListing>
+        <CreateLListing>1</CreateLListing>
+        <CreateIListing>0</CreateIListing>
+        <AsmCond>1</AsmCond>
+        <AsmSymb>1</AsmSymb>
+        <AsmXref>0</AsmXref>
+        <CCond>1</CCond>
+        <CCode>0</CCode>
+        <CListInc>0</CListInc>
+        <CSymb>0</CSymb>
+        <LinkerCodeListing>0</LinkerCodeListing>
+      </ListingPage>
+      <OPTXL>
+        <LMap>1</LMap>
+        <LComments>1</LComments>
+        <LGenerateSymbols>1</LGenerateSymbols>
+        <LLibSym>1</LLibSym>
+        <LLines>1</LLines>
+        <LLocSym>1</LLocSym>
+        <LPubSym>1</LPubSym>
+        <LXref>0</LXref>
+        <LExpSel>0</LExpSel>
+      </OPTXL>
+      <OPTFL>
+        <tvExp>1</tvExp>
+        <tvExpOptDlg>0</tvExpOptDlg>
+        <IsCurrentTarget>0</IsCurrentTarget>
+      </OPTFL>
+      <CpuCode>7</CpuCode>
+      <DebugOpt>
+        <uSim>0</uSim>
+        <uTrg>1</uTrg>
+        <sLdApp>1</sLdApp>
+        <sGomain>1</sGomain>
+        <sRbreak>1</sRbreak>
+        <sRwatch>1</sRwatch>
+        <sRmem>1</sRmem>
+        <sRfunc>1</sRfunc>
+        <sRbox>1</sRbox>
+        <tLdApp>1</tLdApp>
+        <tGomain>1</tGomain>
+        <tRbreak>1</tRbreak>
+        <tRwatch>1</tRwatch>
+        <tRmem>1</tRmem>
+        <tRfunc>0</tRfunc>
+        <tRbox>1</tRbox>
+        <tRtrace>1</tRtrace>
+        <sRSysVw>1</sRSysVw>
+        <tRSysVw>1</tRSysVw>
+        <sRunDeb>0</sRunDeb>
+        <sLrtime>0</sLrtime>
+        <nTsel>0</nTsel>
+        <sDll></sDll>
+        <sDllPa></sDllPa>
+        <sDlgDll></sDlgDll>
+        <sDlgPa></sDlgPa>
+        <sIfile></sIfile>
+        <tDll></tDll>
+        <tDllPa></tDllPa>
+        <tDlgDll></tDlgDll>
+        <tDlgPa></tDlgPa>
+        <tIfile></tIfile>
+        <pMon>BIN\UL2CM3.DLL</pMon>
+      </DebugOpt>
+      <TargetDriverDllRegistry>
+        <SetRegEntry>
+          <Number>0</Number>
+          <Key>UL2CM3</Key>
+          <Name>UL2CM3(-S0 -C0 -P0 )  -FN1 -FC1000 -FD20000000 -FF0NEW_DEVICE -FL040000 -FS00 -FP0($$Device:ARMCM4_FP$Device\ARM\Flash\NEW_DEVICE.FLM)</Name>
+        </SetRegEntry>
+      </TargetDriverDllRegistry>
+      <Breakpoint/>
+      <Tracepoint>
+        <THDelay>0</THDelay>
+      </Tracepoint>
+      <DebugFlag>
+        <trace>0</trace>
+        <periodic>1</periodic>
+        <aLwin>0</aLwin>
+        <aCover>0</aCover>
+        <aSer1>0</aSer1>
+        <aSer2>0</aSer2>
+        <aPa>0</aPa>
+        <viewmode>0</viewmode>
+        <vrSel>0</vrSel>
+        <aSym>0</aSym>
+        <aTbox>0</aTbox>
+        <AscS1>0</AscS1>
+        <AscS2>0</AscS2>
+        <AscS3>0</AscS3>
+        <aSer3>0</aSer3>
+        <eProf>0</eProf>
+        <aLa>0</aLa>
+        <aPa1>0</aPa1>
+        <AscS4>0</AscS4>
+        <aSer4>0</aSer4>
+        <StkLoc>0</StkLoc>
+        <TrcWin>0</TrcWin>
+        <newCpu>0</newCpu>
+        <uProt>0</uProt>
+      </DebugFlag>
+      <LintExecutable></LintExecutable>
+      <LintConfigFile></LintConfigFile>
+      <bLintAuto>0</bLintAuto>
+      <Lin2Executable></Lin2Executable>
+      <Lin2ConfigFile></Lin2ConfigFile>
+      <bLin2Auto>0</bLin2Auto>
+    </TargetOption>
+  </Target>
+
+  <Group>
+    <GroupName>Core</GroupName>
+    <tvExp>1</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>1</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_kernel.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_kernel.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>2</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_thread.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_thread.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>3</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_delay.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_delay.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>4</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_timer.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_timer.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>5</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_evflags.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_evflags.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>6</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_mutex.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_mutex.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>7</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_semaphore.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_semaphore.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>8</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_memory.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_memory.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>9</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_mempool.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_mempool.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>10</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_msgqueue.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_msgqueue.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>11</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\rtx_system.c</PathWithFileName>
+      <FilenameWithoutPath>rtx_system.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>12</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\user_svc.c</PathWithFileName>
+      <FilenameWithoutPath>user_svc.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>Handlers</GroupName>
+    <tvExp>1</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>13</FileNumber>
+      <FileType>2</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\GCC\irq_cm0.s</PathWithFileName>
+      <FilenameWithoutPath>irq_cm0.s</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>14</FileNumber>
+      <FileType>2</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\GCC\irq_cm3.s</PathWithFileName>
+      <FilenameWithoutPath>irq_cm3.s</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>15</FileNumber>
+      <FileType>2</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\Source\GCC\irq_cm4f.s</PathWithFileName>
+      <FilenameWithoutPath>irq_cm4f.s</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>::CMSIS</GroupName>
+    <tvExp>0</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>1</RteFlg>
+  </Group>
+
+</ProjectOpt>
diff --git a/CMSIS/RTOS2/RTX/Library/GCC/MDK/RTX_CM.uvprojx b/CMSIS/RTOS2/RTX/Library/GCC/MDK/RTX_CM.uvprojx
new file mode 100644
index 0000000..41e5731
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Library/GCC/MDK/RTX_CM.uvprojx
@@ -0,0 +1,1321 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
+
+  <SchemaVersion>2.1</SchemaVersion>
+
+  <Header>### uVision Project, (C) Keil Software</Header>
+
+  <Targets>
+    <Target>
+      <TargetName>CM0_LE</TargetName>
+      <ToolsetNumber>0x3</ToolsetNumber>
+      <ToolsetName>ARM-GNU</ToolsetName>
+      <pArmCC>6050000::V6.5::.\ARMCLANG_6.5</pArmCC>
+      <pCCUsed>6050000::V6.5::.\ARMCLANG_6.5</pCCUsed>
+      <TargetOption>
+        <TargetCommonOption>
+          <Device>ARMCM0</Device>
+          <Vendor>ARM</Vendor>
+          <PackID>ARM.CMSIS.5.0.0</PackID>
+          <PackURL>http://www.keil.com/pack/</PackURL>
+          <Cpu>IRAM(0x20000000,0x00020000) IROM(0x00000000,0x00040000) CPUTYPE("Cortex-M0") CLOCK(12000000) ESEL ELITTLE</Cpu>
+          <FlashUtilSpec></FlashUtilSpec>
+          <StartupFile></StartupFile>
+          <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0NEW_DEVICE -FS00 -FL040000 -FP0($$Device:ARMCM0$Device\ARM\Flash\NEW_DEVICE.FLM))</FlashDriverDll>
+          <DeviceId>0</DeviceId>
+          <RegisterFile>$$Device:ARMCM0$Device\ARM\ARMCM0\Include\ARMCM0.h</RegisterFile>
+          <MemoryEnv></MemoryEnv>
+          <Cmp></Cmp>
+          <Asm></Asm>
+          <Linker></Linker>
+          <OHString></OHString>
+          <InfinionOptionDll></InfinionOptionDll>
+          <SLE66CMisc></SLE66CMisc>
+          <SLE66AMisc></SLE66AMisc>
+          <SLE66LinkerMisc></SLE66LinkerMisc>
+          <SFDFile>$$Device:ARMCM0$Device\ARM\SVD\ARMCM0.svd</SFDFile>
+          <bCustSvd>0</bCustSvd>
+          <UseEnv>0</UseEnv>
+          <BinPath></BinPath>
+          <IncludePath></IncludePath>
+          <LibPath></LibPath>
+          <RegisterFilePath></RegisterFilePath>
+          <DBRegisterFilePath></DBRegisterFilePath>
+          <TargetStatus>
+            <Error>0</Error>
+            <ExitCodeStop>0</ExitCodeStop>
+            <ButtonStop>0</ButtonStop>
+            <NotGenerated>0</NotGenerated>
+            <InvalidFlash>1</InvalidFlash>
+          </TargetStatus>
+          <OutputDirectory>.\CM0_LE\</OutputDirectory>
+          <OutputName>RTX_CM0</OutputName>
+          <CreateExecutable>0</CreateExecutable>
+          <CreateLib>1</CreateLib>
+          <CreateHexFile>0</CreateHexFile>
+          <DebugInformation>1</DebugInformation>
+          <BrowseInformation>0</BrowseInformation>
+          <ListingPath>.\CM0_LE\</ListingPath>
+          <HexFormatSelection>1</HexFormatSelection>
+          <Merge32K>0</Merge32K>
+          <CreateBatchFile>0</CreateBatchFile>
+          <BeforeCompile>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopU1X>0</nStopU1X>
+            <nStopU2X>0</nStopU2X>
+          </BeforeCompile>
+          <BeforeMake>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopB1X>0</nStopB1X>
+            <nStopB2X>0</nStopB2X>
+          </BeforeMake>
+          <AfterMake>
+            <RunUserProg1>1</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name>cmd.exe /C copy CM0_LE\libRTX_CM0.a ..\.</UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopA1X>0</nStopA1X>
+            <nStopA2X>0</nStopA2X>
+          </AfterMake>
+          <SelectedForBatchBuild>0</SelectedForBatchBuild>
+          <SVCSIdString></SVCSIdString>
+        </TargetCommonOption>
+        <CommonProperty>
+          <UseCPPCompiler>0</UseCPPCompiler>
+          <RVCTCodeConst>0</RVCTCodeConst>
+          <RVCTZI>0</RVCTZI>
+          <RVCTOtherData>0</RVCTOtherData>
+          <ModuleSelection>0</ModuleSelection>
+          <IncludeInBuild>1</IncludeInBuild>
+          <AlwaysBuild>0</AlwaysBuild>
+          <GenerateAssemblyFile>0</GenerateAssemblyFile>
+          <AssembleAssemblyFile>0</AssembleAssemblyFile>
+          <PublicsOnly>0</PublicsOnly>
+          <StopOnExitCode>3</StopOnExitCode>
+          <CustomArgument></CustomArgument>
+          <IncludeLibraryModules></IncludeLibraryModules>
+          <ComprImg>1</ComprImg>
+        </CommonProperty>
+        <DllOption>
+          <SimDllName>SARMCM3.DLL</SimDllName>
+          <SimDllArguments>  </SimDllArguments>
+          <SimDlgDll>DARMCM1.DLL</SimDlgDll>
+          <SimDlgDllArguments>-pCM0</SimDlgDllArguments>
+          <TargetDllName>SARMCM3.DLL</TargetDllName>
+          <TargetDllArguments> </TargetDllArguments>
+          <TargetDlgDll>TARMCM1.DLL</TargetDlgDll>
+          <TargetDlgDllArguments>-pCM0</TargetDlgDllArguments>
+        </DllOption>
+        <DebugOption>
+          <OPTHX>
+            <HexSelection>1</HexSelection>
+            <HexRangeLowAddress>0</HexRangeLowAddress>
+            <HexRangeHighAddress>0</HexRangeHighAddress>
+            <HexOffset>0</HexOffset>
+            <Oh166RecLen>16</Oh166RecLen>
+          </OPTHX>
+        </DebugOption>
+        <Utilities>
+          <Flash1>
+            <UseTargetDll>1</UseTargetDll>
+            <UseExternalTool>0</UseExternalTool>
+            <RunIndependent>0</RunIndependent>
+            <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
+            <Capability>0</Capability>
+            <DriverSelection>-1</DriverSelection>
+          </Flash1>
+          <bUseTDR>1</bUseTDR>
+          <Flash2>BIN\UL2CM3.DLL</Flash2>
+          <Flash3></Flash3>
+          <Flash4></Flash4>
+          <pFcarmOut></pFcarmOut>
+          <pFcarmGrp></pFcarmGrp>
+          <pFcArmRoot></pFcArmRoot>
+          <FcArmLst>0</FcArmLst>
+        </Utilities>
+        <TargetArm>
+          <ArmMisc>
+            <asLst>0</asLst>
+            <asHll>1</asHll>
+            <asAsm>1</asAsm>
+            <asMacX>1</asMacX>
+            <asSyms>1</asSyms>
+            <asFals>1</asFals>
+            <asDbgD>1</asDbgD>
+            <asForm>1</asForm>
+            <ldLst>0</ldLst>
+            <ldmm>1</ldmm>
+            <ldXref>1</ldXref>
+            <BigEnd>0</BigEnd>
+            <GCPUTYP>"Cortex-M0"</GCPUTYP>
+            <mOS>0</mOS>
+            <uocRom>0</uocRom>
+            <uocRam>0</uocRam>
+            <hadIROM>1</hadIROM>
+            <hadIRAM>1</hadIRAM>
+            <hadXRAM>0</hadXRAM>
+            <uocXRam>0</uocXRam>
+            <RvdsVP>0</RvdsVP>
+            <hadIRAM2>0</hadIRAM2>
+            <hadIROM2>0</hadIROM2>
+            <OnChipMemories>
+              <Ocm1>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm1>
+              <Ocm2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm2>
+              <Ocm3>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm3>
+              <Ocm4>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm4>
+              <Ocm5>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm5>
+              <Ocm6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm6>
+              <IRAM>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x20000</Size>
+              </IRAM>
+              <IROM>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x40000</Size>
+              </IROM>
+              <XRAM>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </XRAM>
+              <IRAM2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </IRAM2>
+              <IROM2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </IROM2>
+            </OnChipMemories>
+          </ArmMisc>
+          <Carm>
+            <arpcs>1</arpcs>
+            <stkchk>0</stkchk>
+            <reentr>0</reentr>
+            <interw>0</interw>
+            <bigend>0</bigend>
+            <Strict>0</Strict>
+            <Optim>5</Optim>
+            <wLevel>2</wLevel>
+            <uThumb>1</uThumb>
+            <VariousControls>
+              <MiscControls>-ffunction-sections</MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath>..\..\..\Include</IncludePath>
+            </VariousControls>
+          </Carm>
+          <Aarm>
+            <bBE>0</bBE>
+            <interw>0</interw>
+            <VariousControls>
+              <MiscControls></MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath></IncludePath>
+            </VariousControls>
+          </Aarm>
+          <LDarm>
+            <umfTarg>1</umfTarg>
+            <enaGarb>1</enaGarb>
+            <noStart>1</noStart>
+            <noStLib>0</noStLib>
+            <uMathLib>0</uMathLib>
+            <TextAddressRange></TextAddressRange>
+            <DataAddressRange></DataAddressRange>
+            <BSSAddressRange></BSSAddressRange>
+            <IncludeLibs></IncludeLibs>
+            <IncludeDir></IncludeDir>
+            <Misc></Misc>
+            <ScatterFile></ScatterFile>
+          </LDarm>
+        </TargetArm>
+      </TargetOption>
+      <Groups>
+        <Group>
+          <GroupName>Core</GroupName>
+          <Files>
+            <File>
+              <FileName>rtx_kernel.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_kernel.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_thread.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_thread.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_delay.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_delay.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_timer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_timer.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_evflags.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_evflags.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_mutex.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_mutex.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_semaphore.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_semaphore.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_memory.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_memory.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_mempool.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_mempool.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_msgqueue.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_msgqueue.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_system.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_system.c</FilePath>
+            </File>
+            <File>
+              <FileName>user_svc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\user_svc.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Handlers</GroupName>
+          <Files>
+            <File>
+              <FileName>irq_cm0.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\GCC\irq_cm0.s</FilePath>
+            </File>
+            <File>
+              <FileName>irq_cm3.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\GCC\irq_cm3.s</FilePath>
+              <FileOption>
+                <CommonProperty>
+                  <UseCPPCompiler>2</UseCPPCompiler>
+                  <RVCTCodeConst>0</RVCTCodeConst>
+                  <RVCTZI>0</RVCTZI>
+                  <RVCTOtherData>0</RVCTOtherData>
+                  <ModuleSelection>0</ModuleSelection>
+                  <IncludeInBuild>0</IncludeInBuild>
+                  <AlwaysBuild>2</AlwaysBuild>
+                  <GenerateAssemblyFile>2</GenerateAssemblyFile>
+                  <AssembleAssemblyFile>2</AssembleAssemblyFile>
+                  <PublicsOnly>2</PublicsOnly>
+                  <StopOnExitCode>11</StopOnExitCode>
+                  <CustomArgument></CustomArgument>
+                  <IncludeLibraryModules></IncludeLibraryModules>
+                  <ComprImg>1</ComprImg>
+                </CommonProperty>
+                <FileArm>
+                  <Aarm>
+                    <bBE>2</bBE>
+                    <interw>2</interw>
+                    <VariousControls>
+                      <MiscControls></MiscControls>
+                      <Define></Define>
+                      <Undefine></Undefine>
+                      <IncludePath></IncludePath>
+                    </VariousControls>
+                  </Aarm>
+                </FileArm>
+              </FileOption>
+            </File>
+            <File>
+              <FileName>irq_cm4f.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\GCC\irq_cm4f.s</FilePath>
+              <FileOption>
+                <CommonProperty>
+                  <UseCPPCompiler>2</UseCPPCompiler>
+                  <RVCTCodeConst>0</RVCTCodeConst>
+                  <RVCTZI>0</RVCTZI>
+                  <RVCTOtherData>0</RVCTOtherData>
+                  <ModuleSelection>0</ModuleSelection>
+                  <IncludeInBuild>0</IncludeInBuild>
+                  <AlwaysBuild>2</AlwaysBuild>
+                  <GenerateAssemblyFile>2</GenerateAssemblyFile>
+                  <AssembleAssemblyFile>2</AssembleAssemblyFile>
+                  <PublicsOnly>2</PublicsOnly>
+                  <StopOnExitCode>11</StopOnExitCode>
+                  <CustomArgument></CustomArgument>
+                  <IncludeLibraryModules></IncludeLibraryModules>
+                  <ComprImg>1</ComprImg>
+                </CommonProperty>
+                <FileArm>
+                  <Aarm>
+                    <bBE>2</bBE>
+                    <interw>2</interw>
+                    <VariousControls>
+                      <MiscControls></MiscControls>
+                      <Define></Define>
+                      <Undefine></Undefine>
+                      <IncludePath></IncludePath>
+                    </VariousControls>
+                  </Aarm>
+                </FileArm>
+              </FileOption>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>::CMSIS</GroupName>
+        </Group>
+      </Groups>
+    </Target>
+    <Target>
+      <TargetName>CM3_LE</TargetName>
+      <ToolsetNumber>0x3</ToolsetNumber>
+      <ToolsetName>ARM-GNU</ToolsetName>
+      <pArmCC>6050000::V6.5::.\ARMCLANG_6.5</pArmCC>
+      <pCCUsed>6050000::V6.5::.\ARMCLANG_6.5</pCCUsed>
+      <TargetOption>
+        <TargetCommonOption>
+          <Device>ARMCM3</Device>
+          <Vendor>ARM</Vendor>
+          <PackID>ARM.CMSIS.5.0.0</PackID>
+          <PackURL>http://www.keil.com/pack/</PackURL>
+          <Cpu>IRAM(0x20000000,0x00020000) IROM(0x00000000,0x00040000) CPUTYPE("Cortex-M3") CLOCK(12000000) ESEL ELITTLE</Cpu>
+          <FlashUtilSpec></FlashUtilSpec>
+          <StartupFile></StartupFile>
+          <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0NEW_DEVICE -FS00 -FL040000 -FP0($$Device:ARMCM3$Device\ARM\Flash\NEW_DEVICE.FLM))</FlashDriverDll>
+          <DeviceId>0</DeviceId>
+          <RegisterFile>$$Device:ARMCM3$Device\ARM\ARMCM3\Include\ARMCM3.h</RegisterFile>
+          <MemoryEnv></MemoryEnv>
+          <Cmp></Cmp>
+          <Asm></Asm>
+          <Linker></Linker>
+          <OHString></OHString>
+          <InfinionOptionDll></InfinionOptionDll>
+          <SLE66CMisc></SLE66CMisc>
+          <SLE66AMisc></SLE66AMisc>
+          <SLE66LinkerMisc></SLE66LinkerMisc>
+          <SFDFile>$$Device:ARMCM3$Device\ARM\SVD\ARMCM3.svd</SFDFile>
+          <bCustSvd>0</bCustSvd>
+          <UseEnv>0</UseEnv>
+          <BinPath></BinPath>
+          <IncludePath></IncludePath>
+          <LibPath></LibPath>
+          <RegisterFilePath></RegisterFilePath>
+          <DBRegisterFilePath></DBRegisterFilePath>
+          <TargetStatus>
+            <Error>0</Error>
+            <ExitCodeStop>0</ExitCodeStop>
+            <ButtonStop>0</ButtonStop>
+            <NotGenerated>0</NotGenerated>
+            <InvalidFlash>1</InvalidFlash>
+          </TargetStatus>
+          <OutputDirectory>.\CM3_LE\</OutputDirectory>
+          <OutputName>RTX_CM3</OutputName>
+          <CreateExecutable>0</CreateExecutable>
+          <CreateLib>1</CreateLib>
+          <CreateHexFile>0</CreateHexFile>
+          <DebugInformation>1</DebugInformation>
+          <BrowseInformation>0</BrowseInformation>
+          <ListingPath>.\CM3_LE\</ListingPath>
+          <HexFormatSelection>1</HexFormatSelection>
+          <Merge32K>0</Merge32K>
+          <CreateBatchFile>0</CreateBatchFile>
+          <BeforeCompile>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopU1X>0</nStopU1X>
+            <nStopU2X>0</nStopU2X>
+          </BeforeCompile>
+          <BeforeMake>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopB1X>0</nStopB1X>
+            <nStopB2X>0</nStopB2X>
+          </BeforeMake>
+          <AfterMake>
+            <RunUserProg1>1</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name>cmd.exe /C copy CM3_LE\libRTX_CM3.a ..\.</UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopA1X>0</nStopA1X>
+            <nStopA2X>0</nStopA2X>
+          </AfterMake>
+          <SelectedForBatchBuild>0</SelectedForBatchBuild>
+          <SVCSIdString></SVCSIdString>
+        </TargetCommonOption>
+        <CommonProperty>
+          <UseCPPCompiler>0</UseCPPCompiler>
+          <RVCTCodeConst>0</RVCTCodeConst>
+          <RVCTZI>0</RVCTZI>
+          <RVCTOtherData>0</RVCTOtherData>
+          <ModuleSelection>0</ModuleSelection>
+          <IncludeInBuild>1</IncludeInBuild>
+          <AlwaysBuild>0</AlwaysBuild>
+          <GenerateAssemblyFile>0</GenerateAssemblyFile>
+          <AssembleAssemblyFile>0</AssembleAssemblyFile>
+          <PublicsOnly>0</PublicsOnly>
+          <StopOnExitCode>3</StopOnExitCode>
+          <CustomArgument></CustomArgument>
+          <IncludeLibraryModules></IncludeLibraryModules>
+          <ComprImg>1</ComprImg>
+        </CommonProperty>
+        <DllOption>
+          <SimDllName>SARMCM3.DLL</SimDllName>
+          <SimDllArguments>  -MPU</SimDllArguments>
+          <SimDlgDll>DCM.DLL</SimDlgDll>
+          <SimDlgDllArguments>-pCM3</SimDlgDllArguments>
+          <TargetDllName>SARMCM3.DLL</TargetDllName>
+          <TargetDllArguments> -MPU</TargetDllArguments>
+          <TargetDlgDll>TCM.DLL</TargetDlgDll>
+          <TargetDlgDllArguments>-pCM3</TargetDlgDllArguments>
+        </DllOption>
+        <DebugOption>
+          <OPTHX>
+            <HexSelection>1</HexSelection>
+            <HexRangeLowAddress>0</HexRangeLowAddress>
+            <HexRangeHighAddress>0</HexRangeHighAddress>
+            <HexOffset>0</HexOffset>
+            <Oh166RecLen>16</Oh166RecLen>
+          </OPTHX>
+        </DebugOption>
+        <Utilities>
+          <Flash1>
+            <UseTargetDll>1</UseTargetDll>
+            <UseExternalTool>0</UseExternalTool>
+            <RunIndependent>0</RunIndependent>
+            <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
+            <Capability>0</Capability>
+            <DriverSelection>-1</DriverSelection>
+          </Flash1>
+          <bUseTDR>1</bUseTDR>
+          <Flash2>BIN\UL2CM3.DLL</Flash2>
+          <Flash3></Flash3>
+          <Flash4></Flash4>
+          <pFcarmOut></pFcarmOut>
+          <pFcarmGrp></pFcarmGrp>
+          <pFcArmRoot></pFcArmRoot>
+          <FcArmLst>0</FcArmLst>
+        </Utilities>
+        <TargetArm>
+          <ArmMisc>
+            <asLst>0</asLst>
+            <asHll>1</asHll>
+            <asAsm>1</asAsm>
+            <asMacX>1</asMacX>
+            <asSyms>1</asSyms>
+            <asFals>1</asFals>
+            <asDbgD>1</asDbgD>
+            <asForm>1</asForm>
+            <ldLst>0</ldLst>
+            <ldmm>1</ldmm>
+            <ldXref>1</ldXref>
+            <BigEnd>0</BigEnd>
+            <GCPUTYP>"Cortex-M3"</GCPUTYP>
+            <mOS>0</mOS>
+            <uocRom>0</uocRom>
+            <uocRam>0</uocRam>
+            <hadIROM>1</hadIROM>
+            <hadIRAM>1</hadIRAM>
+            <hadXRAM>0</hadXRAM>
+            <uocXRam>0</uocXRam>
+            <RvdsVP>0</RvdsVP>
+            <hadIRAM2>0</hadIRAM2>
+            <hadIROM2>0</hadIROM2>
+            <OnChipMemories>
+              <Ocm1>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm1>
+              <Ocm2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm2>
+              <Ocm3>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm3>
+              <Ocm4>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm4>
+              <Ocm5>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm5>
+              <Ocm6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm6>
+              <IRAM>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x20000</Size>
+              </IRAM>
+              <IROM>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x40000</Size>
+              </IROM>
+              <XRAM>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </XRAM>
+              <IRAM2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </IRAM2>
+              <IROM2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </IROM2>
+            </OnChipMemories>
+          </ArmMisc>
+          <Carm>
+            <arpcs>1</arpcs>
+            <stkchk>0</stkchk>
+            <reentr>0</reentr>
+            <interw>0</interw>
+            <bigend>0</bigend>
+            <Strict>0</Strict>
+            <Optim>5</Optim>
+            <wLevel>2</wLevel>
+            <uThumb>1</uThumb>
+            <VariousControls>
+              <MiscControls>-ffunction-sections</MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath>..\..\..\Include</IncludePath>
+            </VariousControls>
+          </Carm>
+          <Aarm>
+            <bBE>0</bBE>
+            <interw>0</interw>
+            <VariousControls>
+              <MiscControls></MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath></IncludePath>
+            </VariousControls>
+          </Aarm>
+          <LDarm>
+            <umfTarg>1</umfTarg>
+            <enaGarb>1</enaGarb>
+            <noStart>1</noStart>
+            <noStLib>0</noStLib>
+            <uMathLib>0</uMathLib>
+            <TextAddressRange></TextAddressRange>
+            <DataAddressRange></DataAddressRange>
+            <BSSAddressRange></BSSAddressRange>
+            <IncludeLibs></IncludeLibs>
+            <IncludeDir></IncludeDir>
+            <Misc></Misc>
+            <ScatterFile></ScatterFile>
+          </LDarm>
+        </TargetArm>
+      </TargetOption>
+      <Groups>
+        <Group>
+          <GroupName>Core</GroupName>
+          <Files>
+            <File>
+              <FileName>rtx_kernel.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_kernel.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_thread.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_thread.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_delay.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_delay.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_timer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_timer.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_evflags.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_evflags.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_mutex.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_mutex.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_semaphore.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_semaphore.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_memory.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_memory.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_mempool.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_mempool.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_msgqueue.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_msgqueue.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_system.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_system.c</FilePath>
+            </File>
+            <File>
+              <FileName>user_svc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\user_svc.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Handlers</GroupName>
+          <Files>
+            <File>
+              <FileName>irq_cm0.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\GCC\irq_cm0.s</FilePath>
+              <FileOption>
+                <CommonProperty>
+                  <UseCPPCompiler>2</UseCPPCompiler>
+                  <RVCTCodeConst>0</RVCTCodeConst>
+                  <RVCTZI>0</RVCTZI>
+                  <RVCTOtherData>0</RVCTOtherData>
+                  <ModuleSelection>0</ModuleSelection>
+                  <IncludeInBuild>0</IncludeInBuild>
+                  <AlwaysBuild>2</AlwaysBuild>
+                  <GenerateAssemblyFile>2</GenerateAssemblyFile>
+                  <AssembleAssemblyFile>2</AssembleAssemblyFile>
+                  <PublicsOnly>2</PublicsOnly>
+                  <StopOnExitCode>11</StopOnExitCode>
+                  <CustomArgument></CustomArgument>
+                  <IncludeLibraryModules></IncludeLibraryModules>
+                  <ComprImg>1</ComprImg>
+                </CommonProperty>
+                <FileArm>
+                  <Aarm>
+                    <bBE>2</bBE>
+                    <interw>2</interw>
+                    <VariousControls>
+                      <MiscControls></MiscControls>
+                      <Define></Define>
+                      <Undefine></Undefine>
+                      <IncludePath></IncludePath>
+                    </VariousControls>
+                  </Aarm>
+                </FileArm>
+              </FileOption>
+            </File>
+            <File>
+              <FileName>irq_cm3.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\GCC\irq_cm3.s</FilePath>
+            </File>
+            <File>
+              <FileName>irq_cm4f.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\GCC\irq_cm4f.s</FilePath>
+              <FileOption>
+                <CommonProperty>
+                  <UseCPPCompiler>2</UseCPPCompiler>
+                  <RVCTCodeConst>0</RVCTCodeConst>
+                  <RVCTZI>0</RVCTZI>
+                  <RVCTOtherData>0</RVCTOtherData>
+                  <ModuleSelection>0</ModuleSelection>
+                  <IncludeInBuild>0</IncludeInBuild>
+                  <AlwaysBuild>2</AlwaysBuild>
+                  <GenerateAssemblyFile>2</GenerateAssemblyFile>
+                  <AssembleAssemblyFile>2</AssembleAssemblyFile>
+                  <PublicsOnly>2</PublicsOnly>
+                  <StopOnExitCode>11</StopOnExitCode>
+                  <CustomArgument></CustomArgument>
+                  <IncludeLibraryModules></IncludeLibraryModules>
+                  <ComprImg>1</ComprImg>
+                </CommonProperty>
+                <FileArm>
+                  <Aarm>
+                    <bBE>2</bBE>
+                    <interw>2</interw>
+                    <VariousControls>
+                      <MiscControls></MiscControls>
+                      <Define></Define>
+                      <Undefine></Undefine>
+                      <IncludePath></IncludePath>
+                    </VariousControls>
+                  </Aarm>
+                </FileArm>
+              </FileOption>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>::CMSIS</GroupName>
+          <GroupOption>
+            <CommonProperty>
+              <UseCPPCompiler>0</UseCPPCompiler>
+              <RVCTCodeConst>0</RVCTCodeConst>
+              <RVCTZI>0</RVCTZI>
+              <RVCTOtherData>0</RVCTOtherData>
+              <ModuleSelection>0</ModuleSelection>
+              <IncludeInBuild>1</IncludeInBuild>
+              <AlwaysBuild>2</AlwaysBuild>
+              <GenerateAssemblyFile>2</GenerateAssemblyFile>
+              <AssembleAssemblyFile>2</AssembleAssemblyFile>
+              <PublicsOnly>2</PublicsOnly>
+              <StopOnExitCode>11</StopOnExitCode>
+              <CustomArgument></CustomArgument>
+              <IncludeLibraryModules></IncludeLibraryModules>
+              <ComprImg>1</ComprImg>
+            </CommonProperty>
+            <GroupArm>
+              <Carm>
+                <arpcs>2</arpcs>
+                <stkchk>2</stkchk>
+                <reentr>2</reentr>
+                <interw>2</interw>
+                <bigend>2</bigend>
+                <Strict>0</Strict>
+                <Optim>0</Optim>
+                <wLevel>0</wLevel>
+                <uThumb>2</uThumb>
+                <VariousControls>
+                  <MiscControls></MiscControls>
+                  <Define></Define>
+                  <Undefine></Undefine>
+                  <IncludePath></IncludePath>
+                </VariousControls>
+              </Carm>
+              <Aarm>
+                <bBE>2</bBE>
+                <interw>2</interw>
+                <VariousControls>
+                  <MiscControls></MiscControls>
+                  <Define></Define>
+                  <Undefine></Undefine>
+                  <IncludePath></IncludePath>
+                </VariousControls>
+              </Aarm>
+            </GroupArm>
+          </GroupOption>
+        </Group>
+      </Groups>
+    </Target>
+    <Target>
+      <TargetName>CM4F_LE</TargetName>
+      <ToolsetNumber>0x3</ToolsetNumber>
+      <ToolsetName>ARM-GNU</ToolsetName>
+      <pArmCC>6050000::V6.5::.\ARMCLANG_6.5</pArmCC>
+      <pCCUsed>6050000::V6.5::.\ARMCLANG_6.5</pCCUsed>
+      <TargetOption>
+        <TargetCommonOption>
+          <Device>ARMCM4_FP</Device>
+          <Vendor>ARM</Vendor>
+          <PackID>ARM.CMSIS.5.0.0</PackID>
+          <PackURL>http://www.keil.com/pack/</PackURL>
+          <Cpu>IRAM(0x20000000,0x00020000) IROM(0x00000000,0x00040000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ESEL ELITTLE</Cpu>
+          <FlashUtilSpec></FlashUtilSpec>
+          <StartupFile></StartupFile>
+          <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0NEW_DEVICE -FS00 -FL040000 -FP0($$Device:ARMCM4_FP$Device\ARM\Flash\NEW_DEVICE.FLM))</FlashDriverDll>
+          <DeviceId>0</DeviceId>
+          <RegisterFile>$$Device:ARMCM4_FP$Device\ARM\ARMCM4\Include\ARMCM4_FP.h</RegisterFile>
+          <MemoryEnv></MemoryEnv>
+          <Cmp></Cmp>
+          <Asm></Asm>
+          <Linker></Linker>
+          <OHString></OHString>
+          <InfinionOptionDll></InfinionOptionDll>
+          <SLE66CMisc></SLE66CMisc>
+          <SLE66AMisc></SLE66AMisc>
+          <SLE66LinkerMisc></SLE66LinkerMisc>
+          <SFDFile>$$Device:ARMCM4_FP$Device\ARM\SVD\ARMCM4.svd</SFDFile>
+          <bCustSvd>0</bCustSvd>
+          <UseEnv>0</UseEnv>
+          <BinPath></BinPath>
+          <IncludePath></IncludePath>
+          <LibPath></LibPath>
+          <RegisterFilePath></RegisterFilePath>
+          <DBRegisterFilePath></DBRegisterFilePath>
+          <TargetStatus>
+            <Error>0</Error>
+            <ExitCodeStop>0</ExitCodeStop>
+            <ButtonStop>0</ButtonStop>
+            <NotGenerated>0</NotGenerated>
+            <InvalidFlash>1</InvalidFlash>
+          </TargetStatus>
+          <OutputDirectory>.\CM4F_LE\</OutputDirectory>
+          <OutputName>RTX_CM4F</OutputName>
+          <CreateExecutable>0</CreateExecutable>
+          <CreateLib>1</CreateLib>
+          <CreateHexFile>0</CreateHexFile>
+          <DebugInformation>1</DebugInformation>
+          <BrowseInformation>0</BrowseInformation>
+          <ListingPath>.\CM4F_LE\</ListingPath>
+          <HexFormatSelection>1</HexFormatSelection>
+          <Merge32K>0</Merge32K>
+          <CreateBatchFile>0</CreateBatchFile>
+          <BeforeCompile>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopU1X>0</nStopU1X>
+            <nStopU2X>0</nStopU2X>
+          </BeforeCompile>
+          <BeforeMake>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopB1X>0</nStopB1X>
+            <nStopB2X>0</nStopB2X>
+          </BeforeMake>
+          <AfterMake>
+            <RunUserProg1>1</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name>cmd.exe /C copy CM4F_LE\libRTX_CM4F.a ..\.</UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopA1X>0</nStopA1X>
+            <nStopA2X>0</nStopA2X>
+          </AfterMake>
+          <SelectedForBatchBuild>0</SelectedForBatchBuild>
+          <SVCSIdString></SVCSIdString>
+        </TargetCommonOption>
+        <CommonProperty>
+          <UseCPPCompiler>0</UseCPPCompiler>
+          <RVCTCodeConst>0</RVCTCodeConst>
+          <RVCTZI>0</RVCTZI>
+          <RVCTOtherData>0</RVCTOtherData>
+          <ModuleSelection>0</ModuleSelection>
+          <IncludeInBuild>1</IncludeInBuild>
+          <AlwaysBuild>0</AlwaysBuild>
+          <GenerateAssemblyFile>0</GenerateAssemblyFile>
+          <AssembleAssemblyFile>0</AssembleAssemblyFile>
+          <PublicsOnly>0</PublicsOnly>
+          <StopOnExitCode>3</StopOnExitCode>
+          <CustomArgument></CustomArgument>
+          <IncludeLibraryModules></IncludeLibraryModules>
+          <ComprImg>1</ComprImg>
+        </CommonProperty>
+        <DllOption>
+          <SimDllName>SARMCM3.DLL</SimDllName>
+          <SimDllArguments>  -MPU</SimDllArguments>
+          <SimDlgDll>DCM.DLL</SimDlgDll>
+          <SimDlgDllArguments>-pCM4</SimDlgDllArguments>
+          <TargetDllName>SARMCM3.DLL</TargetDllName>
+          <TargetDllArguments> -MPU</TargetDllArguments>
+          <TargetDlgDll>TCM.DLL</TargetDlgDll>
+          <TargetDlgDllArguments>-pCM4</TargetDlgDllArguments>
+        </DllOption>
+        <DebugOption>
+          <OPTHX>
+            <HexSelection>1</HexSelection>
+            <HexRangeLowAddress>0</HexRangeLowAddress>
+            <HexRangeHighAddress>0</HexRangeHighAddress>
+            <HexOffset>0</HexOffset>
+            <Oh166RecLen>16</Oh166RecLen>
+          </OPTHX>
+        </DebugOption>
+        <Utilities>
+          <Flash1>
+            <UseTargetDll>1</UseTargetDll>
+            <UseExternalTool>0</UseExternalTool>
+            <RunIndependent>0</RunIndependent>
+            <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
+            <Capability>0</Capability>
+            <DriverSelection>-1</DriverSelection>
+          </Flash1>
+          <bUseTDR>1</bUseTDR>
+          <Flash2>BIN\UL2CM3.DLL</Flash2>
+          <Flash3></Flash3>
+          <Flash4></Flash4>
+          <pFcarmOut></pFcarmOut>
+          <pFcarmGrp></pFcarmGrp>
+          <pFcArmRoot></pFcArmRoot>
+          <FcArmLst>0</FcArmLst>
+        </Utilities>
+        <TargetArm>
+          <ArmMisc>
+            <asLst>0</asLst>
+            <asHll>1</asHll>
+            <asAsm>1</asAsm>
+            <asMacX>1</asMacX>
+            <asSyms>1</asSyms>
+            <asFals>1</asFals>
+            <asDbgD>1</asDbgD>
+            <asForm>1</asForm>
+            <ldLst>0</ldLst>
+            <ldmm>1</ldmm>
+            <ldXref>1</ldXref>
+            <BigEnd>0</BigEnd>
+            <GCPUTYP>"Cortex-M4"</GCPUTYP>
+            <mOS>0</mOS>
+            <uocRom>0</uocRom>
+            <uocRam>0</uocRam>
+            <hadIROM>1</hadIROM>
+            <hadIRAM>1</hadIRAM>
+            <hadXRAM>0</hadXRAM>
+            <uocXRam>0</uocXRam>
+            <RvdsVP>2</RvdsVP>
+            <hadIRAM2>0</hadIRAM2>
+            <hadIROM2>0</hadIROM2>
+            <OnChipMemories>
+              <Ocm1>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm1>
+              <Ocm2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm2>
+              <Ocm3>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm3>
+              <Ocm4>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm4>
+              <Ocm5>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm5>
+              <Ocm6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm6>
+              <IRAM>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x20000</Size>
+              </IRAM>
+              <IROM>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x40000</Size>
+              </IROM>
+              <XRAM>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </XRAM>
+              <IRAM2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </IRAM2>
+              <IROM2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </IROM2>
+            </OnChipMemories>
+          </ArmMisc>
+          <Carm>
+            <arpcs>1</arpcs>
+            <stkchk>0</stkchk>
+            <reentr>0</reentr>
+            <interw>0</interw>
+            <bigend>0</bigend>
+            <Strict>0</Strict>
+            <Optim>5</Optim>
+            <wLevel>2</wLevel>
+            <uThumb>1</uThumb>
+            <VariousControls>
+              <MiscControls>-mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections</MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath>..\..\..\Include</IncludePath>
+            </VariousControls>
+          </Carm>
+          <Aarm>
+            <bBE>0</bBE>
+            <interw>0</interw>
+            <VariousControls>
+              <MiscControls>-mfpu=fpv4-sp-d16 -mfloat-abi=hard</MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath></IncludePath>
+            </VariousControls>
+          </Aarm>
+          <LDarm>
+            <umfTarg>1</umfTarg>
+            <enaGarb>1</enaGarb>
+            <noStart>1</noStart>
+            <noStLib>0</noStLib>
+            <uMathLib>0</uMathLib>
+            <TextAddressRange></TextAddressRange>
+            <DataAddressRange></DataAddressRange>
+            <BSSAddressRange></BSSAddressRange>
+            <IncludeLibs></IncludeLibs>
+            <IncludeDir></IncludeDir>
+            <Misc></Misc>
+            <ScatterFile></ScatterFile>
+          </LDarm>
+        </TargetArm>
+      </TargetOption>
+      <Groups>
+        <Group>
+          <GroupName>Core</GroupName>
+          <Files>
+            <File>
+              <FileName>rtx_kernel.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_kernel.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_thread.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_thread.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_delay.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_delay.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_timer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_timer.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_evflags.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_evflags.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_mutex.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_mutex.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_semaphore.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_semaphore.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_memory.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_memory.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_mempool.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_mempool.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_msgqueue.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_msgqueue.c</FilePath>
+            </File>
+            <File>
+              <FileName>rtx_system.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\rtx_system.c</FilePath>
+            </File>
+            <File>
+              <FileName>user_svc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\Source\user_svc.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Handlers</GroupName>
+          <Files>
+            <File>
+              <FileName>irq_cm0.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\GCC\irq_cm0.s</FilePath>
+              <FileOption>
+                <CommonProperty>
+                  <UseCPPCompiler>2</UseCPPCompiler>
+                  <RVCTCodeConst>0</RVCTCodeConst>
+                  <RVCTZI>0</RVCTZI>
+                  <RVCTOtherData>0</RVCTOtherData>
+                  <ModuleSelection>0</ModuleSelection>
+                  <IncludeInBuild>0</IncludeInBuild>
+                  <AlwaysBuild>2</AlwaysBuild>
+                  <GenerateAssemblyFile>2</GenerateAssemblyFile>
+                  <AssembleAssemblyFile>2</AssembleAssemblyFile>
+                  <PublicsOnly>2</PublicsOnly>
+                  <StopOnExitCode>11</StopOnExitCode>
+                  <CustomArgument></CustomArgument>
+                  <IncludeLibraryModules></IncludeLibraryModules>
+                  <ComprImg>1</ComprImg>
+                </CommonProperty>
+                <FileArm>
+                  <Aarm>
+                    <bBE>2</bBE>
+                    <interw>2</interw>
+                    <VariousControls>
+                      <MiscControls></MiscControls>
+                      <Define></Define>
+                      <Undefine></Undefine>
+                      <IncludePath></IncludePath>
+                    </VariousControls>
+                  </Aarm>
+                </FileArm>
+              </FileOption>
+            </File>
+            <File>
+              <FileName>irq_cm3.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\GCC\irq_cm3.s</FilePath>
+              <FileOption>
+                <CommonProperty>
+                  <UseCPPCompiler>2</UseCPPCompiler>
+                  <RVCTCodeConst>0</RVCTCodeConst>
+                  <RVCTZI>0</RVCTZI>
+                  <RVCTOtherData>0</RVCTOtherData>
+                  <ModuleSelection>0</ModuleSelection>
+                  <IncludeInBuild>0</IncludeInBuild>
+                  <AlwaysBuild>2</AlwaysBuild>
+                  <GenerateAssemblyFile>2</GenerateAssemblyFile>
+                  <AssembleAssemblyFile>2</AssembleAssemblyFile>
+                  <PublicsOnly>2</PublicsOnly>
+                  <StopOnExitCode>11</StopOnExitCode>
+                  <CustomArgument></CustomArgument>
+                  <IncludeLibraryModules></IncludeLibraryModules>
+                  <ComprImg>1</ComprImg>
+                </CommonProperty>
+                <FileArm>
+                  <Aarm>
+                    <bBE>2</bBE>
+                    <interw>2</interw>
+                    <VariousControls>
+                      <MiscControls></MiscControls>
+                      <Define></Define>
+                      <Undefine></Undefine>
+                      <IncludePath></IncludePath>
+                    </VariousControls>
+                  </Aarm>
+                </FileArm>
+              </FileOption>
+            </File>
+            <File>
+              <FileName>irq_cm4f.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\..\Source\GCC\irq_cm4f.s</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>::CMSIS</GroupName>
+        </Group>
+      </Groups>
+    </Target>
+  </Targets>
+
+  <RTE>
+    <apis/>
+    <components>
+      <component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="5.0.0" condition="Cortex-M ARMv8-M Device">
+        <package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="5.0.0-Beta4"/>
+        <targetInfos>
+          <targetInfo name="CM0_LE"/>
+          <targetInfo name="CM3_LE"/>
+          <targetInfo name="CM4F_LE"/>
+        </targetInfos>
+      </component>
+    </components>
+    <files/>
+  </RTE>
+
+</Project>
diff --git a/CMSIS/RTOS2/RTX/Library/GCC/libRTX_CM0.a b/CMSIS/RTOS2/RTX/Library/GCC/libRTX_CM0.a
new file mode 100644
index 0000000..3463b7e
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Library/GCC/libRTX_CM0.a
Binary files differ
diff --git a/CMSIS/RTOS2/RTX/Library/GCC/libRTX_CM3.a b/CMSIS/RTOS2/RTX/Library/GCC/libRTX_CM3.a
new file mode 100644
index 0000000..b6ed59c
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Library/GCC/libRTX_CM3.a
Binary files differ
diff --git a/CMSIS/RTOS2/RTX/Library/GCC/libRTX_CM4F.a b/CMSIS/RTOS2/RTX/Library/GCC/libRTX_CM4F.a
new file mode 100644
index 0000000..7d29ede
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Library/GCC/libRTX_CM4F.a
Binary files differ
diff --git a/CMSIS/RTOS2/RTX/Library/cmsis_os1.c b/CMSIS/RTOS2/RTX/Library/cmsis_os1.c
new file mode 100644
index 0000000..d84aab2
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Library/cmsis_os1.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ----------------------------------------------------------------------
+ *
+ * $Date:        30. June 2016
+ * $Revision:    V1.0
+ *
+ * Project:      CMSIS-RTOS API V1
+ * Title:        cmsis_os_v1.c V1 module file
+ *---------------------------------------------------------------------------*/
+
+#include <string.h>
+#include "cmsis_os.h"
+
+#if (osCMSIS >= 0x20000U) && !defined(os1_Disable)
+
+
+// Thread
+#if !defined(os1_Disable_Thread)
+osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument) {
+
+  if (thread_def == NULL) {
+    return (osThreadId)NULL;
+  }
+  return osThreadNew((os_thread_func_t)thread_def->pthread, argument, &thread_def->attr);
+}
+#endif
+
+
+// Signals
+
+#if !defined(os1_Disable_Signal)
+
+#define SignalMask (int32_t)((1U<<osFeature_Signals)-1U)
+
+int32_t osSignalSet (osThreadId thread_id, int32_t signals) {
+  int32_t flags;
+
+  flags = osThreadFlagsGet(thread_id);
+  if (flags < 0) {
+    return (int32_t)0x80000000U;
+  }
+  if (osThreadFlagsSet(thread_id, signals) < 0) {
+    return (int32_t)0x80000000U;
+  }
+  return flags;
+}
+
+int32_t osSignalClear (osThreadId thread_id, int32_t signals) {
+  int32_t flags;
+
+  flags = osThreadFlagsClear(thread_id, signals);
+  if (flags < 0) {
+    return (int32_t)0x80000000U;
+  }
+  return flags;
+}
+
+osEvent osSignalWait (int32_t signals, uint32_t millisec) {
+  osEvent event;
+  int32_t flags;
+
+  if (signals != 0) {
+    flags = osThreadFlagsWait(signals,    osFlagsWaitAll | osFlagsAutoClear, millisec);
+  } else {
+    flags = osThreadFlagsWait(SignalMask, osFlagsWaitAny | osFlagsAutoClear, millisec);
+  }
+  if (flags > 0) {
+    event.status = osEventSignal;
+    event.value.signals = flags;
+  } else {
+    switch (flags) {
+      case osErrorResource:
+        event.status = osOK;
+        break;
+      case osErrorTimeout:
+        event.status = osEventTimeout;
+        break;
+      case osErrorParameter:
+        event.status = osErrorValue;
+        break;
+      default:
+        event.status = (osStatus)flags;
+        break;
+    }
+  }
+  return event;
+}
+
+#endif  // Signal
+
+
+// Timer
+#if !defined(os1_Disable_Timer)
+osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) {
+
+  if (timer_def == NULL) {
+    return (osTimerId)NULL;
+  }
+  return osTimerNew((os_timer_func_t)timer_def->ptimer, type, argument, &timer_def->attr);
+}
+#endif
+
+
+// Mutex
+#if !defined(os1_Disable_Mutex)
+osMutexId osMutexCreate (const osMutexDef_t *mutex_def) {
+
+  if (mutex_def == NULL) {
+    return (osMutexId)NULL;
+  }
+  return osMutexNew(mutex_def);
+}
+#endif
+
+
+// Semaphore
+
+#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0U)) && !defined(os1_Disable_Semaphore)
+
+osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) {
+
+  if (semaphore_def == NULL) {
+    return (osSemaphoreId)NULL;
+  }
+  return osSemaphoreNew((uint32_t)count, (uint32_t)count, semaphore_def);
+}
+
+int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) {
+  osStatus_t status;
+  uint32_t   count;
+
+  status = osSemaphoreAcquire(semaphore_id, millisec);
+  switch (status) {
+    case osOK:
+      count = osSemaphoreGetCount(semaphore_id);
+      return ((int32_t)count + 1);
+    case osErrorResource:
+    case osErrorTimeout:
+      return 0;
+    default:
+      break;
+  }
+  return -1;
+}
+
+#endif  // Semaphore
+
+
+// Memory Pool
+
+#if (defined(osFeature_Pool) && (osFeature_Pool != 0))&& !defined(os1_Disable_Pool)
+
+osPoolId osPoolCreate (const osPoolDef_t *pool_def) {
+
+  if (pool_def == NULL) {
+    return (osPoolId)NULL;
+  }
+  return ((osPoolId)(osMemoryPoolNew(pool_def->pool_sz, pool_def->item_sz, &pool_def->attr)));
+}
+
+void *osPoolAlloc (osPoolId pool_id) {
+  return osMemoryPoolAlloc((osMemoryPoolId_t)pool_id, 0U);
+}
+
+void *osPoolCAlloc (osPoolId pool_id) {
+  void    *block;
+  uint32_t block_size;
+
+  block_size = osMemoryPoolGetBlockSize((osMemoryPoolId_t)pool_id);
+  if (block_size == 0U) {
+    return NULL;
+  }
+  block = osMemoryPoolAlloc((osMemoryPoolId_t)pool_id, 0U);
+  if (block != NULL) {
+    memset(block, 0, block_size);
+  }
+  return block;
+}
+
+osStatus osPoolFree (osPoolId pool_id, void *block) {
+  return osMemoryPoolFree((osMemoryPoolId_t)pool_id, block);
+}
+
+#endif  // Memory Pool
+
+
+// Message Queue
+
+#if (defined(osFeature_MessageQ) && (osFeature_MessageQ != 0)) && !defined(os1_Disable_MessageQ)
+
+osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) {
+  (void)thread_id;
+
+  if (queue_def == NULL) {
+    return (osMessageQId)NULL;
+  }
+  return ((osMessageQId)(osMessageQueueNew(queue_def->queue_sz, sizeof(uint32_t), &queue_def->attr)));
+}
+
+osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
+  return osMessageQueuePut((osMessageQueueId_t)queue_id, &info, 0U, millisec);
+}
+
+osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) {
+  osStatus_t status;
+  osEvent    event;
+  uint32_t   message;
+
+  status = osMessageQueueGet((osMessageQueueId_t)queue_id, &message, NULL, millisec);
+  switch (status) {
+    case osOK:
+      event.status = osEventMessage;
+      event.value.v = message;
+      break;
+    case osErrorResource:
+      event.status = osOK;
+      break;
+    case osErrorTimeout:
+      event.status = osEventTimeout;
+      break;
+    default:
+      event.status = status;
+      break;
+  }
+  return event;
+}
+
+#endif  // Message Queue
+
+
+// Mail Queue
+
+#if (defined(osFeature_MailQ) && (osFeature_MailQ != 0)) && !defined(os1_Disable_MailQ)
+
+typedef struct os_mail_queue_s {
+  osMemoryPoolId_t   mp_id;
+  osMessageQueueId_t mq_id;
+} os_mail_queue_t;
+
+osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) {
+  os_mail_queue_t *ptr;
+  (void)thread_id;
+
+  if (queue_def == NULL) {
+    return (osMailQId)NULL;
+  }
+
+  ptr = queue_def->mail;
+  if (ptr == NULL) {
+    return (osMailQId)NULL;
+  }
+
+  ptr->mp_id = osMemoryPoolNew  (queue_def->queue_sz, queue_def->item_sz, &queue_def->mp_attr);
+  ptr->mq_id = osMessageQueueNew(queue_def->queue_sz, sizeof(void *), &queue_def->mq_attr);
+  if ((ptr->mp_id == (osMemoryPoolId_t)NULL) || (ptr->mq_id == (osMessageQueueId_t)NULL)) {
+    if (ptr->mp_id != (osMemoryPoolId_t)NULL) {
+      osMemoryPoolDelete(ptr->mp_id);
+    }
+    if (ptr->mq_id != (osMessageQueueId_t)NULL) {
+      osMessageQueueDelete(ptr->mq_id);
+    }
+    return (osMailQId)NULL;
+  }
+
+  return (osMailQId)ptr;
+}
+
+void *osMailAlloc (osMailQId queue_id, uint32_t millisec) {
+  os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id;
+
+  if (ptr == NULL) {
+    return NULL;
+  }
+  return osMemoryPoolAlloc(ptr->mp_id, millisec);
+}
+
+void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) {
+  os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id;
+  void            *block;
+  uint32_t         block_size;
+
+  if (ptr == NULL) {
+    return NULL;
+  }
+  block_size = osMemoryPoolGetBlockSize(ptr->mp_id);
+  if (block_size == 0U) {
+    return NULL;
+  }
+  block = osMemoryPoolAlloc(ptr->mp_id, millisec);
+  if (block != NULL) {
+    memset(block, 0, block_size);
+  }
+
+  return block;
+
+}
+
+osStatus osMailPut (osMailQId queue_id, const void *mail) {
+  os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id;
+
+  if (ptr == NULL) {
+    return osErrorParameter;
+  }
+  if (mail == NULL) {
+    return osErrorValue;
+  }
+  return osMessageQueuePut(ptr->mq_id, &mail, 0U, 0U);
+}
+
+osEvent osMailGet (osMailQId queue_id, uint32_t millisec) {
+  os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id;
+  osStatus_t       status;
+  osEvent          event;
+  void            *mail;
+
+  if (ptr == NULL) {
+    event.status = osErrorParameter;
+    return event;
+  }
+
+  status = osMessageQueueGet(ptr->mq_id, &mail, NULL, millisec);
+  switch (status) {
+    case osOK:
+      event.status = osEventMail;
+      event.value.p = mail;
+      break;
+    case osErrorResource:
+      event.status = osOK;
+      break;
+    case osErrorTimeout:
+      event.status = osEventTimeout;
+      break;
+    default:
+      event.status = status;
+      break;
+  }
+  return event;
+}
+
+osStatus osMailFree (osMailQId queue_id, void *mail) {
+  os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id;
+
+  if (ptr == NULL) {
+    return osErrorParameter;
+  }
+  if (mail == NULL) {
+    return osErrorValue;
+  }
+  return osMemoryPoolFree(ptr->mp_id, mail);
+}
+
+#endif  // Mail Queue
+
+
+#endif  // osCMSIS
diff --git a/CMSIS/RTOS2/RTX/Source/ARM/irq_cm0.s b/CMSIS/RTOS2/RTX/Source/ARM/irq_cm0.s
new file mode 100644
index 0000000..630eb60
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/ARM/irq_cm0.s
@@ -0,0 +1,142 @@
+;/*
+; * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+; *
+; * SPDX-License-Identifier: Apache-2.0
+; *
+; * Licensed under the Apache License, Version 2.0 (the License); you may
+; * not use this file except in compliance with the License.
+; * You may obtain a copy of the License at
+; *
+; * http://www.apache.org/licenses/LICENSE-2.0
+; *
+; * Unless required by applicable law or agreed to in writing, software
+; * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; * See the License for the specific language governing permissions and
+; * limitations under the License.
+; *
+; * -----------------------------------------------------------------------------
+; *
+; * Project:     CMSIS-RTOS RTX
+; * Title:       Cortex-M0 Exception handlers
+; *
+; * -----------------------------------------------------------------------------
+; */
+
+
+                PRESERVE8
+                THUMB
+
+I_T_RUN_OFS     EQU     28                      ; osInfo.thread.run offset
+TCB_SP_OFS      EQU     56                      ; TCB.SP offset
+
+                AREA    |.constdata|, DATA, READONLY
+                EXPORT  os_irq_cm
+os_irq_cm       DCB     0                       ; Non weak library reference
+
+                AREA    |.text|, CODE, READONLY
+
+
+SVC_Handler     PROC
+                EXPORT  SVC_Handler
+                IMPORT  os_UserSVC_Table
+                IMPORT  os_Info
+
+                MRS     R0,PSP                  ; Get PSP
+                LDR     R1,[R0,#24]             ; Load saved PC from stack
+                SUBS    R1,R1,#2                ; Point to SVC instruction
+                LDRB    R1,[R1]                 ; Load SVC number
+                CMP     R1,#0
+                BNE     SVC_User                ; Branch if not SVC 0
+
+                LDMIA   R0,{R0-R3}              ; Load function parameters from stack
+                BLX     R7                      ; Call service function
+                MRS     R3,PSP                  ; Get PSP
+                STR     R0,[R3]                 ; Store function return value
+
+SVC_Context
+                LDR     R3,=os_Info+I_T_RUN_OFS ; Load address of os_Info.run
+                LDMIA   R3!,{R1,R2}             ; Load os_Info.thread.run: curr & next
+                CMP     R1,R2                   ; Check if thread switch is required
+                BEQ     SVC_Exit                ; Branch when threads are the same
+
+                SUBS    R3,R3,#8
+                CMP     R1,#0
+                BEQ     SVC_ContextSwitch       ; Branch if running thread is deleted
+
+SVC_ContextSave
+                MRS     R0,PSP                  ; Get PSP
+                SUBS    R0,R0,#32               ; Adjust address
+                STR     R0,[R1,#TCB_SP_OFS]     ; Store SP
+                STMIA   R0!,{R4-R7}             ; Save R4..R7
+                MOV     R4,R8
+                MOV     R5,R9
+                MOV     R6,R10
+                MOV     R7,R11
+                STMIA   R0!,{R4-R7}             ; Save R8..R11
+
+SVC_ContextSwitch
+                STR     R2,[R3]                 ; os_Info.thread.run: curr = next
+
+SVC_ContextRestore
+                LDR     R0,[R2,#TCB_SP_OFS]     ; Load SP
+                ADDS    R0,R0,#16               ; Adjust address
+                LDMIA   R0!,{R4-R7}             ; Restore R8..R11
+                MOV     R8,R4
+                MOV     R9,R5
+                MOV     R10,R6
+                MOV     R11,R7
+                MSR     PSP,R0                  ; Set PSP
+                SUBS    R0,R0,#32               ; Adjust address
+                LDMIA   R0!,{R4-R7}             ; Restore R4..R7
+
+SVC_Exit
+                MOVS    R0,#~0xFFFFFFFD         ; Set EXC_RETURN value
+                MVNS    R0,R0
+                BX      R0                      ; Exit from handler
+
+SVC_User
+                PUSH    {R4,LR}                 ; Save registers
+                LDR     R2,=os_UserSVC_Table    ; Load address of SVC table
+                LDR     R3,[R2]                 ; Load SVC maximum number
+                CMP     R1,R3                   ; Check SVC number range
+                BHI     SVC_Done                ; Branch if out of range
+
+                LSLS    R1,R1,#2
+                LDR     R4,[R2,R1]              ; Load address of SVC function
+
+                LDMIA   R0,{R0-R3}              ; Load function parameters from stack
+                BLX     R4                      ; Call service function
+                MRS     R4,PSP                  ; Get PSP
+                STMIA   R4!,{R0-R3}             ; Store function return values
+
+SVC_Done
+                POP     {R4,PC}                 ; Return from handler
+
+                ALIGN
+                ENDP
+
+
+PendSV_Handler  PROC
+                EXPORT  PendSV_Handler
+                IMPORT  os_PendSV_Handler
+
+                BL      os_PendSV_Handler
+                B       SVC_Context
+
+                ALIGN
+                ENDP
+
+
+SysTick_Handler PROC
+                EXPORT  SysTick_Handler
+                IMPORT  os_Tick_Handler
+
+                BL      os_Tick_Handler
+                B       SVC_Context
+
+                ALIGN
+                ENDP
+
+
+                END
diff --git a/CMSIS/RTOS2/RTX/Source/ARM/irq_cm3.s b/CMSIS/RTOS2/RTX/Source/ARM/irq_cm3.s
new file mode 100644
index 0000000..ba27211
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/ARM/irq_cm3.s
@@ -0,0 +1,124 @@
+;/*
+; * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+; *
+; * SPDX-License-Identifier: Apache-2.0
+; *
+; * Licensed under the Apache License, Version 2.0 (the License); you may
+; * not use this file except in compliance with the License.
+; * You may obtain a copy of the License at
+; *
+; * http://www.apache.org/licenses/LICENSE-2.0
+; *
+; * Unless required by applicable law or agreed to in writing, software
+; * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; * See the License for the specific language governing permissions and
+; * limitations under the License.
+; *
+; * -----------------------------------------------------------------------------
+; *
+; * Project:     CMSIS-RTOS RTX
+; * Title:       Cortex-M3 Exception handlers
+; *
+; * -----------------------------------------------------------------------------
+; */
+
+
+                PRESERVE8
+                THUMB
+
+I_T_RUN_OFS     EQU     28                      ; osInfo.thread.run offset
+TCB_SP_OFS      EQU     56                      ; TCB.SP offset
+
+                AREA    |.constdata|, DATA, READONLY
+                EXPORT  os_irq_cm
+os_irq_cm       DCB     0                       ; Non weak library reference
+
+                AREA    |.text|, CODE, READONLY
+
+
+SVC_Handler     PROC
+                EXPORT  SVC_Handler
+                IMPORT  os_UserSVC_Table
+                IMPORT  os_Info
+
+                MRS     R0,PSP                  ; Get PSP
+                LDR     R1,[R0,#24]             ; Load saved PC from stack
+                LDRB    R1,[R1,#-2]             ; Load SVC number
+                CBNZ    R1,SVC_User             ; Branch if not SVC 0
+
+                LDM     R0,{R0-R3,R12}          ; Load function parameters and address from stack
+                BLX     R12                     ; Call service function
+                MRS     R12,PSP                 ; Get PSP
+                STR     R0,[R12]                ; Store function return value
+
+SVC_Context
+                LDR     R3,=os_Info+I_T_RUN_OFS ; Load address of os_Info.run
+                LDM     R3,{R1,R2}              ; Load os_Info.thread.run: curr & next
+                CMP     R1,R2                   ; Check if thread switch is required
+                BEQ     SVC_Exit                ; Branch when threads are the same
+
+                CBZ     R1,SVC_ContextSwitch    ; Branch if running thread is deleted
+
+SVC_ContextSave
+                STMDB   R12!,{R4-R11}           ; Save R4..R11
+                STR     R12,[R1,#TCB_SP_OFS]    ; Store SP
+
+SVC_ContextSwitch
+                STR     R2,[R3]                 ; os_Info.thread.run: curr = next
+
+SVC_ContextRestore
+                LDR     R12,[R2,#TCB_SP_OFS]    ; Load SP
+                LDMIA   R12!,{R4-R11}           ; Restore R4..R11
+                MSR     PSP,R12                 ; Set PSP
+
+SVC_Exit
+                MVN     LR,#~0xFFFFFFFD         ; Set EXC_RETURN value
+                BX      LR                      ; Exit from handler
+
+SVC_User
+                PUSH    {R4,LR}                 ; Save registers
+                LDR     R2,=os_UserSVC_Table    ; Load address of SVC table
+                LDR     R3,[R2]                 ; Load SVC maximum number
+                CMP     R1,R3                   ; Check SVC number range
+                BHI     SVC_Done                ; Branch if out of range
+
+                LDR     R4,[R2,R1,LSL #2]       ; Load address of SVC function
+
+                LDM     R0,{R0-R3}              ; Load function parameters from stack
+                BLX     R4                      ; Call service function
+                MRS     R12,PSP                 ; Get PSP
+                STM     R12,{R0-R3}             ; Store function return values
+
+SVC_Done
+                POP     {R4,PC}                 ; Return from handler
+
+                ALIGN
+                ENDP
+
+
+PendSV_Handler  PROC
+                EXPORT  PendSV_Handler
+                IMPORT  os_PendSV_Handler
+
+                BL      os_PendSV_Handler
+                MRS     R12,PSP
+                B       SVC_Context
+
+                ALIGN
+                ENDP
+
+
+SysTick_Handler PROC
+                EXPORT  SysTick_Handler
+                IMPORT  os_Tick_Handler
+
+                BL      os_Tick_Handler
+                MRS     R12,PSP
+                B       SVC_Context
+
+                ALIGN
+                ENDP
+
+
+                END
diff --git a/CMSIS/RTOS2/RTX/Source/ARM/irq_cm4f.s b/CMSIS/RTOS2/RTX/Source/ARM/irq_cm4f.s
new file mode 100644
index 0000000..c902631
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/ARM/irq_cm4f.s
@@ -0,0 +1,147 @@
+;/*
+; * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+; *
+; * SPDX-License-Identifier: Apache-2.0
+; *
+; * Licensed under the Apache License, Version 2.0 (the License); you may
+; * not use this file except in compliance with the License.
+; * You may obtain a copy of the License at
+; *
+; * http://www.apache.org/licenses/LICENSE-2.0
+; *
+; * Unless required by applicable law or agreed to in writing, software
+; * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; * See the License for the specific language governing permissions and
+; * limitations under the License.
+; *
+; * -----------------------------------------------------------------------------
+; *
+; * Project:     CMSIS-RTOS RTX
+; * Title:       Cortex-M4F Exception handlers
+; *
+; * -----------------------------------------------------------------------------
+; */
+
+
+                PRESERVE8
+                THUMB
+
+I_T_RUN_OFS     EQU     28                      ; osInfo.thread.run offset
+TCB_SP_OFS      EQU     56                      ; TCB.SP offset
+TCB_SF_OFS      EQU     34                      ; TCB.stack_frame offset
+
+                AREA    |.constdata|, DATA, READONLY
+                EXPORT  os_irq_cm
+os_irq_cm       DCB     0                       ; Non weak library reference
+
+                AREA    |.text|, CODE, READONLY
+
+
+SVC_Handler     PROC
+                EXPORT  SVC_Handler
+                IMPORT  os_UserSVC_Table
+                IMPORT  os_Info
+
+                MRS     R0,PSP                  ; Get PSP
+                LDR     R1,[R0,#24]             ; Load saved PC from stack
+                LDRB    R1,[R1,#-2]             ; Load SVC number
+                CBNZ    R1,SVC_User             ; Branch if not SVC 0
+
+                PUSH    {R0,LR}                 ; Save PSP and EXC_RETURN
+                LDM     R0,{R0-R3,R12}          ; Load function parameters and address from stack
+                BLX     R12                     ; Call service function
+                POP     {R12,LR}                ; Restore PSP and EXC_RETURN
+                STR     R0,[R12]                ; Store function return value
+
+SVC_Context
+                LDR     R3,=os_Info+I_T_RUN_OFS ; Load address of os_Info.run
+                LDM     R3,{R1,R2}              ; Load os_Info.thread.run: curr & next
+                CMP     R1,R2                   ; Check if thread switch is required
+                BEQ     SVC_Exit                ; Branch when threads are the same
+
+                CBNZ    R1,SVC_ContextSave      ; Branch if running thread is not deleted
+
+                TST     LR,#0x10                ; Check if extended stack frame
+                BNE     SVC_ContextSwitch
+                LDR     R1,=0xE000EF34          ; FPCCR Address
+                LDR     R0,[R1]                 ; Load FPCCR
+                BIC     R0,#1                   ; Clear LSPACT (Lazy state)
+                STR     R0,[R1]                 ; Store FPCCR
+                B       SVC_ContextSwitch
+
+SVC_ContextSave
+                TST     LR,#0x10                ; Check if extended stack frame
+                VSTMDBEQ R12!,{S16-S31}         ;  Save VFP S16.S31
+                MOVEQ   R0,#1                   ;  Extended stack frame identifier
+                MOVNE   R0,#0                   ;  Basic stack frame identifier
+                STMDB   R12!,{R4-R11}           ; Save R4..R11
+                STR     R12,[R1,#TCB_SP_OFS]    ; Store SP
+                STRB    R0, [R1,#TCB_SF_OFS]    ; Store stack frame information
+
+SVC_ContextSwitch
+                STR     R2,[R3]                 ; os_Info.thread.run: curr = next
+
+SVC_ContextRestore
+                LDR     R12,[R2,#TCB_SP_OFS]    ; Load SP
+                LDRB    R0, [R2,#TCB_SF_OFS]    ; Load stack frame information
+                LDMIA   R12!,{R4-R11}           ; Restore R4..R11
+                CMP     R0,#1                   ; Check if extended stack frame
+                VLDMIAEQ R12!,{S16-S31}         ;  Restore VFP S16..S31
+                MVNEQ   LR,#~0xFFFFFFED         ;  Set EXC_RETURN value
+                MVNNE   LR,#~0xFFFFFFFD
+                MSR     PSP,R12                 ; Set PSP
+
+SVC_Exit
+                BX      LR                      ; Exit from handler
+
+SVC_User
+                PUSH    {R4,LR}                 ; Save registers
+                LDR     R2,=os_UserSVC_Table    ; Load address of SVC table
+                LDR     R3,[R2]                 ; Load SVC maximum number
+                CMP     R1,R3                   ; Check SVC number range
+                BHI     SVC_Done                ; Branch if out of range
+
+                LDR     R4,[R2,R1,LSL #2]       ; Load address of SVC function
+
+                LDM     R0,{R0-R3}              ; Load function parameters from stack
+                BLX     R4                      ; Call service function
+                MRS     R12,PSP                 ; Get PSP
+                STM     R12,{R0-R3}             ; Store function return values
+
+SVC_Done
+                POP     {R4,PC}                 ; Return from handler
+
+                ALIGN
+                ENDP
+
+
+PendSV_Handler  PROC
+                EXPORT  PendSV_Handler
+                IMPORT  os_PendSV_Handler
+
+                PUSH    {R4,LR}                 ; Save EXC_RETURN
+                BL      os_PendSV_Handler
+                POP     {R4,LR}                 ; Restore EXC_RETURN
+                MRS     R12,PSP
+                B       SVC_Context
+
+                ALIGN
+                ENDP
+
+
+SysTick_Handler PROC
+                EXPORT  SysTick_Handler
+                IMPORT  os_Tick_Handler
+
+                PUSH    {R4,LR}                 ; Save EXC_RETURN
+                BL      os_Tick_Handler
+                POP     {R4,LR}                 ; Restore EXC_RETURN
+                MRS     R12,PSP
+                B       SVC_Context
+
+                ALIGN
+                ENDP
+
+
+                END
diff --git a/CMSIS/RTOS2/RTX/Source/GCC/irq_cm0.s b/CMSIS/RTOS2/RTX/Source/GCC/irq_cm0.s
new file mode 100644
index 0000000..1217b8a
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/GCC/irq_cm0.s
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       Cortex-M0 Exception handlers
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+
+        .file   "irq_cm0.s"
+        .syntax unified
+
+        .equ    I_T_RUN_OFS, 28         // osInfo.thread.run offset
+        .equ    TCB_SP_OFS,  56         // TCB.SP offset
+
+        .section ".rodata"
+        .global os_irq_cm               // Non weak library reference
+os_irq_cm:
+        .byte   0
+
+        .thumb
+        .section ".text"
+        .align  2
+
+
+        .thumb_func
+        .type   SVC_Handler, %function
+        .global SVC_Handler
+        .fnstart
+        .cantunwind
+SVC_Handler:
+
+        MRS     R0,PSP                  // Get PSP
+        LDR     R1,[R0,#24]             // Load saved PC from stack
+        SUBS    R1,R1,#2                // Point to SVC instruction
+        LDRB    R1,[R1]                 // Load SVC number
+        CMP     R1,#0
+        BNE     SVC_User                // Branch if not SVC 0
+        
+        LDMIA   R0,{R0-R3}              // Load function parameters from stack
+        BLX     R7                      // Call service function
+        MRS     R3,PSP                  // Get PSP
+        STR     R0,[R3]                 // Store function return value
+
+SVC_Context:
+        LDR     R3,=os_Info+I_T_RUN_OFS // Load address of os_Info.run
+        LDMIA   R3!,{R1,R2}             // Load os_Info.thread.run: curr & next
+        CMP     R1,R2                   // Check if thread switch is required
+        BEQ     SVC_Exit                // Branch when threads are the same
+       
+        SUBS    R3,R3,#8
+        CMP     R1,#0
+        BEQ     SVC_ContextSwitch       // Branch if running thread is deleted
+
+SVC_ContextSave:
+        MRS     R0,PSP                  // Get PSP
+        SUBS    R0,R0,#32               // Adjust address
+        STR     R0,[R1,#TCB_SP_OFS];    // Store SP
+        STMIA   R0!,{R4-R7}             // Save R4..R7
+        MOV     R4,R8
+        MOV     R5,R9
+        MOV     R6,R10
+        MOV     R7,R11
+        STMIA   R0!,{R4-R7}             // Save R8..R11
+
+SVC_ContextSwitch:
+        STR     R2,[R3]                 // os_Info.thread.run: curr = next
+
+SVC_ContextRestore:
+        LDR     R0,[R2,#TCB_SP_OFS]     // Load SP
+        ADDS    R0,R0,#16               // Adjust address
+        LDMIA   R0!,{R4-R7}             // Restore R8..R11
+        MOV     R8,R4
+        MOV     R9,R5
+        MOV     R10,R6
+        MOV     R11,R7
+        MSR     PSP,R0                  // Set PSP
+        SUBS    R0,R0,#32               // Adjust address
+        LDMIA   R0!,{R4-R7}             // Restore R4..R7
+
+SVC_Exit:
+        MOVS    R0,#~0xFFFFFFFD         // Set EXC_RETURN value
+        MVNS    R0,R0
+        BX      R0                      // Exit from handler
+
+SVC_User:
+        PUSH    {R4,LR}                 // Save registers
+        LDR     R2,=os_UserSVC_Table    // Load address of SVC table
+        LDR     R3,[R2]                 // Load SVC maximum number
+        CMP     R1,R3                   // Check SVC number range
+        BHI     SVC_Done                // Branch if out of range
+        
+        LSLS    R1,R1,#2
+        LDR     R4,[R2,R1]              // Load address of SVC function
+        
+        LDMIA   R0,{R0-R3}              // Load function parameters from stack
+        BLX     R4                      // Call service function
+        MRS     R4,PSP                  // Get PSP
+        STMIA   R4!,{R0-R3}             // Store function return values
+
+SVC_Done:
+        POP     {R4,PC}                 // Return from handler
+
+        .fnend
+        .size   SVC_Handler, .-SVC_Handler
+
+
+        .thumb_func
+        .type   PendSV_Handler, %function
+        .global PendSV_Handler
+        .fnstart
+        .cantunwind
+PendSV_Handler:
+
+        BL      os_PendSV_Handler
+        B       SVC_Context
+
+        .fnend
+        .size   PendSV_Handler, .-PendSV_Handler
+
+
+        .thumb_func
+        .type   SysTick_Handler, %function
+        .global SysTick_Handler
+        .fnstart
+        .cantunwind
+SysTick_Handler:
+
+        BL      os_Tick_Handler
+        B       SVC_Context
+
+        .fnend
+        .size   SysTick_Handler, .-SysTick_Handler
+
+
+        .end
diff --git a/CMSIS/RTOS2/RTX/Source/GCC/irq_cm3.s b/CMSIS/RTOS2/RTX/Source/GCC/irq_cm3.s
new file mode 100644
index 0000000..8ba9b00
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/GCC/irq_cm3.s
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       Cortex-M3 Exception handlers
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+
+        .file   "irq_cm3.s"
+        .syntax unified
+
+        .equ    I_T_RUN_OFS, 28         // osInfo.thread.run offset
+        .equ    TCB_SP_OFS,  56         // TCB.SP offset
+
+        .section ".rodata"
+        .global os_irq_cm               // Non weak library reference
+os_irq_cm:
+        .byte   0
+
+        .thumb
+        .section ".text"
+        .align  2
+
+
+        .thumb_func
+        .type   SVC_Handler, %function
+        .global SVC_Handler
+        .fnstart
+        .cantunwind
+SVC_Handler:
+
+        MRS     R0,PSP                  // Get PSP
+        LDR     R1,[R0,#24]             // Load saved PC from stack
+        LDRB    R1,[R1,#-2]             // Load SVC number
+        CBNZ    R1,SVC_User             // Branch if not SVC 0
+
+        LDM     R0,{R0-R3,R12}          // Load function parameters and address from stack
+        BLX     R12                     // Call service function
+        MRS     R12,PSP                 // Get PSP
+        STR     R0,[R12]                // Store function return value
+
+SVC_Context:
+        LDR     R3,=os_Info+I_T_RUN_OFS // Load address of os_Info.run
+        LDM     R3,{R1,R2}              // Load os_Info.thread.run: curr & next
+        CMP     R1,R2                   // Check if thread switch is required
+        BEQ     SVC_Exit                // Branch when threads are the same
+
+        CBZ     R1,SVC_ContextSwitch    // Branch if running thread is deleted
+
+SVC_ContextSave:
+        STMDB   R12!,{R4-R11}           // Save R4..R11
+        STR     R12,[R1,#TCB_SP_OFS]    // Store SP
+
+SVC_ContextSwitch:
+        STR     R2,[R3]                 // os_Info.thread.run: curr = next
+
+SVC_ContextRestore:
+        LDR     R12,[R2,#TCB_SP_OFS]    // Load SP
+        LDMIA   R12!,{R4-R11}           // Restore R4..R11
+        MSR     PSP,R12                 // Set PSP
+
+SVC_Exit:
+        MVN     LR,#~0xFFFFFFFD         // Set EXC_RETURN value
+        BX      LR                      // Exit from handler
+
+SVC_User:
+        PUSH    {R4,LR}                 // Save registers
+        LDR     R2,=os_UserSVC_Table    // Load address of SVC table
+        LDR     R3,[R2]                 // Load SVC maximum number
+        CMP     R1,R3                   // Check SVC number range
+        BHI     SVC_Done                // Branch if out of range
+   
+        LDR     R4,[R2,R1,LSL #2]       // Load address of SVC function
+   
+        LDM     R0,{R0-R3}              // Load function parameters from stack
+        BLX     R4                      // Call service function
+        MRS     R12,PSP                 // Get PSP
+        STM     R12,{R0-R3}             // Store function return values
+
+SVC_Done:
+        POP     {R4,PC}                 // Return from handler
+
+        .fnend
+        .size   SVC_Handler, .-SVC_Handler
+
+
+        .thumb_func
+        .type   PendSV_Handler, %function
+        .global PendSV_Handler
+        .fnstart
+        .cantunwind
+PendSV_Handler:
+
+        BL      os_PendSV_Handler
+        MRS     R12,PSP
+        B       SVC_Context
+
+        .fnend
+        .size   PendSV_Handler, .-PendSV_Handler
+
+
+        .thumb_func
+        .type   SysTick_Handler, %function
+        .global SysTick_Handler
+        .fnstart
+        .cantunwind
+SysTick_Handler:
+
+        BL      os_Tick_Handler
+        MRS     R12,PSP
+        B       SVC_Context
+
+        .fnend
+        .size   SysTick_Handler, .-SysTick_Handler
+
+
+        .end
diff --git a/CMSIS/RTOS2/RTX/Source/GCC/irq_cm4f.s b/CMSIS/RTOS2/RTX/Source/GCC/irq_cm4f.s
new file mode 100644
index 0000000..da8ea47
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/GCC/irq_cm4f.s
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       Cortex-M4F Exception handlers
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+
+        .file   "irq_cm4f.s"
+        .syntax unified
+
+        .equ    I_T_RUN_OFS, 28         // osInfo.thread.run offset
+        .equ    TCB_SP_OFS,  56         // TCB.SP offset
+        .equ    TCB_SF_OFS,  34         // TCB.stack_frame offset
+
+        .section ".rodata"
+        .global os_irq_cm               // Non weak library reference
+os_irq_cm:
+        .byte   0
+
+        .thumb
+        .section ".text"
+        .align  2
+
+
+        .thumb_func
+        .type   SVC_Handler, %function
+        .global SVC_Handler
+        .fnstart
+        .cantunwind
+SVC_Handler:
+
+        MRS     R0,PSP                  // Get PSP
+        LDR     R1,[R0,#24]             // Load saved PC from stack
+        LDRB    R1,[R1,#-2]             // Load SVC number
+        CBNZ    R1,SVC_User             // Branch if not SVC 0
+    
+        PUSH    {R0,LR}                 // Save PSP and EXC_RETURN
+        LDM     R0,{R0-R3,R12}          // Load function parameters and address from stack
+        BLX     R12                     // Call service function
+        POP     {R12,LR}                // Restore PSP and EXC_RETURN
+        STR     R0,[R12]                // Store function return value
+
+SVC_Context:
+        LDR     R3,=os_Info+I_T_RUN_OFS // Load address of os_Info.run
+        LDM     R3,{R1,R2}              // Load os_Info.thread.run: curr & next
+        CMP     R1,R2                   // Check if thread switch is required
+        BEQ     SVC_Exit                // Branch when threads are the same
+        
+        CBNZ    R1,SVC_ContextSave      // Branch if running thread is not deleted
+        
+        TST     LR,#0x10                // Check if extended stack frame
+        BNE     SVC_ContextSwitch
+        LDR     R1,=0xE000EF34          // FPCCR Address
+        LDR     R0,[R1]                 // Load FPCCR
+        BIC     R0,#1                   // Clear LSPACT (Lazy state)
+        STR     R0,[R1]                 // Store FPCCR
+        B       SVC_ContextSwitch
+
+SVC_ContextSave:
+        TST     LR,#0x10                // Check if extended stack frame
+        ITTE    EQ
+        VSTMDBEQ R12!,{S16-S31}         //  Save VFP S16.S31
+        MOVEQ   R0,#1                   //  Extended stack frame identifier
+        MOVNE   R0,#0                   //  Basic stack frame identifier
+        STMDB   R12!,{R4-R11}           // Save R4..R11
+        STR     R12,[R1,#TCB_SP_OFS]    // Store SP
+        STRB    R0, [R1,#TCB_SF_OFS]    // Store stack frame information
+
+SVC_ContextSwitch:
+        STR     R2,[R3]                 // os_Info.thread.run: curr = next
+
+SVC_ContextRestore:
+        LDR     R12,[R2,#TCB_SP_OFS]    // Load SP
+        LDRB    R0, [R2,#TCB_SF_OFS]    // Load stack frame information
+        LDMIA   R12!,{R4-R11}           // Restore R4..R11
+        CMP     R0,#1                   // Check if extended stack frame
+        ITTE    EQ
+        VLDMIAEQ R12!,{S16-S31}         //  Restore VFP S16..S31
+        MVNEQ   LR,#~0xFFFFFFED         //  Set EXC_RETURN value
+        MVNNE   LR,#~0xFFFFFFFD
+        MSR     PSP,R12                 // Set PSP
+
+SVC_Exit:
+        BX      LR                      // Exit from handler
+
+SVC_User:
+        PUSH    {R4,LR}                 // Save registers
+        LDR     R2,=os_UserSVC_Table    // Load address of SVC table
+        LDR     R3,[R2]                 // Load SVC maximum number
+        CMP     R1,R3                   // Check SVC number range
+        BHI     SVC_Done                // Branch if out of range
+   
+        LDR     R4,[R2,R1,LSL #2]       // Load address of SVC function
+   
+        LDM     R0,{R0-R3}              // Load function parameters from stack
+        BLX     R4                      // Call service function
+        MRS     R12,PSP                 // Get PSP
+        STM     R12,{R0-R3}             // Store function return values
+
+SVC_Done:
+        POP     {R4,PC}                 // Return from handler
+
+        .fnend
+        .size   SVC_Handler, .-SVC_Handler
+
+
+        .thumb_func
+        .type   PendSV_Handler, %function
+        .global PendSV_Handler
+        .fnstart
+        .cantunwind
+PendSV_Handler:
+
+        PUSH    {R4,LR}                 // Save EXC_RETURN
+        BL      os_PendSV_Handler
+        POP     {R4,LR}                 // Restore EXC_RETURN
+        MRS     R12,PSP
+        B       SVC_Context
+
+        .fnend
+        .size   PendSV_Handler, .-PendSV_Handler
+
+
+        .thumb_func
+        .type   SysTick_Handler, %function
+        .global SysTick_Handler
+        .fnstart
+        .cantunwind
+SysTick_Handler:
+
+        PUSH    {R4,LR}                 // Save EXC_RETURN
+        BL      os_Tick_Handler
+        POP     {R4,LR}                 // Restore EXC_RETURN
+        MRS     R12,PSP
+        B       SVC_Context
+
+        .fnend
+        .size   SysTick_Handler, .-SysTick_Handler
+
+
+        .end
diff --git a/CMSIS/RTOS2/RTX/Source/core_cm.h b/CMSIS/RTOS2/RTX/Source/core_cm.h
new file mode 100644
index 0000000..ea2594a
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/core_cm.h
@@ -0,0 +1,570 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       Cortex-M Core definitions
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#ifndef __CORE_CM_H
+#define __CORE_CM_H
+
+#include "RTE_Components.h"
+#include CMSIS_device_header
+
+#if !defined(__NO_EXCLUSIVE_ACCESS) && (__CORTEX_M < 3U)
+#define __NO_EXCLUSIVE_ACCESS
+#endif
+
+
+//  ==== Service Calls definitions ====
+
+#define SVC_ArgN(n) \
+  register uint32_t __r##n __asm("r"#n)
+
+#define SVC_ArgR(n,a) \
+  register uint32_t __r##n __asm("r"#n) = (uint32_t)a
+
+#define SVC_Arg0()                                                             \
+  SVC_ArgN(0);                                                                 \
+  SVC_ArgN(1);                                                                 \
+  SVC_ArgN(2);                                                                 \
+  SVC_ArgN(3)
+
+#define SVC_Arg1(a1)                                                           \
+  SVC_ArgR(0,a1);                                                              \
+  SVC_ArgN(1);                                                                 \
+  SVC_ArgN(2);                                                                 \
+  SVC_ArgN(3)
+
+#define SVC_Arg2(a1,a2)                                                        \
+  SVC_ArgR(0,a1);                                                              \
+  SVC_ArgR(1,a2);                                                              \
+  SVC_ArgN(2);                                                                 \
+  SVC_ArgN(3)
+
+#define SVC_Arg3(a1,a2,a3)                                                     \
+  SVC_ArgR(0,a1);                                                              \
+  SVC_ArgR(1,a2);                                                              \
+  SVC_ArgR(2,a3);                                                              \
+  SVC_ArgN(3)
+
+#define SVC_Arg4(a1,a2,a3,a4)                                                  \
+  SVC_ArgR(0,a1);                                                              \
+  SVC_ArgR(1,a2);                                                              \
+  SVC_ArgR(2,a3);                                                              \
+  SVC_ArgR(3,a4)
+
+#if (__CORTEX_M >= 3U)
+#define SVC_Call0(f)                                                           \
+  __ASM volatile                                                               \
+  (                                                                            \
+    "ldr r12,="#f"\n\t"                                                        \
+    "svc 0"                                                                    \
+    : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3)                       \
+    :  "r" (__r0),  "r" (__r1),  "r" (__r2),  "r" (__r3)                       \
+    : "r12", "lr", "cc"                                                        \
+  )
+#else
+#define SVC_Call0(f)                                                           \
+  __ASM volatile                                                               \
+  (                                                                            \
+    "ldr r7,="#f"\n\t"                                                         \
+    "svc 0"                                                                    \
+    : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3)                       \
+    :  "r" (__r0),  "r" (__r1),  "r" (__r2),  "r" (__r3)                       \
+    : "r7", "lr", "cc"                                                         \
+  )
+#endif
+
+#define SVC0_0N(f,t)                                                           \
+__attribute__((always_inline))                                                 \
+static inline t __svc##f (void) {                                              \
+  SVC_Arg0();                                                                  \
+  SVC_Call0(os_svc##f);                                                        \
+}
+
+#define SVC0_0(f,t)                                                            \
+__attribute__((always_inline))                                                 \
+static inline t __svc##f (void) {                                              \
+  SVC_Arg0();                                                                  \
+  SVC_Call0(os_svc##f);                                                        \
+  return (t) __r0;                                                             \
+}
+
+#define SVC0_1N(f,t,t1)                                                        \
+__attribute__((always_inline))                                                 \
+static inline t __svc##f (t1 a1) {                                             \
+  SVC_Arg1(a1);                                                                \
+  SVC_Call0(os_svc##f);                                                        \
+}
+
+#define SVC0_1(f,t,t1)                                                         \
+__attribute__((always_inline))                                                 \
+static inline t __svc##f (t1 a1) {                                             \
+  SVC_Arg1(a1);                                                                \
+  SVC_Call0(os_svc##f);                                                        \
+  return (t) __r0;                                                             \
+}
+
+#define SVC0_2(f,t,t1,t2)                                                      \
+__attribute__((always_inline))                                                 \
+static inline t __svc##f (t1 a1, t2 a2) {                                      \
+  SVC_Arg2(a1,a2);                                                             \
+  SVC_Call0(os_svc##f);                                                        \
+  return (t) __r0;                                                             \
+}
+
+#define SVC0_3(f,t,t1,t2,t3)                                                   \
+__attribute__((always_inline))                                                 \
+static inline t __svc##f (t1 a1, t2 a2, t3 a3) {                               \
+  SVC_Arg3(a1,a2,a3);                                                          \
+  SVC_Call0(os_svc##f);                                                        \
+  return (t) __r0;                                                             \
+}
+
+#define SVC0_4(f,t,t1,t2,t3,t4)                                                \
+__attribute__((always_inline))                                                 \
+static inline t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) {                        \
+  SVC_Arg4(a1,a2,a3,a4);                                                       \
+  SVC_Call0(os_svc##f);                                                        \
+  return (t) __r0;                                                             \
+}
+
+
+//  ==== Core Peripherals functions ====
+
+#define XPSR_INITIAL_VALUE      0x01000000U
+
+extern uint32_t SystemCoreClock;        // System Clock Frequency (Core Clock)
+
+
+/// Initialize SVC and PendSV System Service Calls
+__STATIC_INLINE void os_SVC_Initialize (void) {
+#if (__CORTEX_M >= 3U)
+  uint32_t p, n;
+
+  SCB->SHP[10] = 0xFFU;
+  n = 32U - (uint32_t)__CLZ(~(SCB->SHP[10] | 0xFFFFFF00U));
+  p = NVIC_GetPriorityGrouping();
+  if (p >= n) {
+    n = p + 1U;
+  }
+  SCB->SHP[7] = (uint8_t)(0xFEU << n);
+#else
+  SCB->SHP[1] |= 0x00FF0000U;
+  SCB->SHP[0] |= (SCB->SHP[1] << (8+1)) & 0xFC000000U;
+#endif
+}
+
+/// Setup SysTick Timer
+/// \param[in] period  Timer Load value
+__STATIC_INLINE void os_SysTick_Setup (uint32_t period) {
+  SysTick->LOAD = period - 1U;
+  SysTick->VAL  = 0U;
+#if (__CORTEX_M >= 3U)
+  SCB->SHP[11]  = 0xFFU;
+#else
+  SCB->SHP[1]  |= 0xFF000000U;
+#endif
+}
+
+/// Get SysTick Period
+/// \return    SysTick Period
+__STATIC_INLINE uint32_t os_SysTick_GetPeriod (void) {
+  return (SysTick->LOAD + 1U);
+}
+
+/// Get SysTick Value
+/// \return    SysTick Value
+__STATIC_INLINE uint32_t os_SysTick_GetVal (void) {
+  return (SysTick->LOAD - SysTick->VAL);
+}
+
+/// Get SysTick Overflow (Auto Clear)
+/// \return    SysTick Overflow flag
+__STATIC_INLINE uint32_t os_SysTick_GetOvf (void) {
+  return ((SysTick->CTRL >> 26) & 1U);
+}
+
+/// Enable SysTick Timer
+__STATIC_INLINE void os_SysTick_Enable (void) {
+  SysTick->CTRL = SysTick_CTRL_ENABLE_Msk     |
+                  SysTick_CTRL_TICKINT_Msk    |
+                  SysTick_CTRL_CLKSOURCE_Msk;
+}
+
+/// Disable SysTick Timer
+__STATIC_INLINE void os_SysTick_Disable (void) {
+  SysTick->CTRL = 0U;
+}
+
+/// Setup External Tick Timer Interrupt
+/// \param[in] irqn  Interrupt number
+__STATIC_INLINE void os_ExtTick_SetupIRQ (int32_t irqn) {
+  NVIC->IP[irqn] = 0xFFU; 
+}
+
+/// Enable External Tick Timer Interrupt
+/// \param[in] irqn  Interrupt number
+__STATIC_INLINE void os_ExtTick_EnableIRQ (int32_t irqn) {
+  NVIC->ISER[irqn >> 5] = 1U << (irqn & 0x1F);
+}
+
+/// Disable External Tick Timer Interrupt
+/// \param[in] irqn  Interrupt number
+__STATIC_INLINE void os_ExtTick_DisableIRQ (int32_t irqn) {
+  NVIC->ICER[irqn >> 5] = 1U << (irqn & 0x1F);
+}
+
+/// Get Pending SV (Service Call) and ST (SysTick) Flags
+/// \return    Pending SV&ST Flags
+__STATIC_INLINE uint8_t os_GetPendSV_ST (void) {
+  return ((uint8_t)((SCB->ICSR & (SCB_ICSR_PENDSVSET_Msk | SCB_ICSR_PENDSTSET_Msk)) >> 24));
+}
+
+/// Get Pending SV (Service Call) Flag
+/// \return    Pending SV Flag
+__STATIC_INLINE uint8_t os_GetPendSV (void) {
+  return ((uint8_t)((SCB->ICSR & (SCB_ICSR_PENDSVSET_Msk)) >> 24));
+}
+
+/// Clear Pending SV (Service Call) and ST (SysTick) Flags
+__STATIC_INLINE void os_ClrPendSV_ST (void) {
+  SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk;
+}
+
+/// Clear Pending SV (Service Call) Flag
+__STATIC_INLINE void os_ClrPendSV (void) {
+  SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk;
+}
+
+/// Set Pending SV (Service Call) Flag
+__STATIC_INLINE void os_SetPendSV (void) {
+  SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
+}
+
+/// Set Pending Flags
+/// \param[in] flags  Flags to set
+__STATIC_INLINE void os_SetPendFlags (uint8_t flags) {
+  SCB->ICSR = ((uint32_t)flags << 24);
+}
+
+
+//  ==== Exclusive Access Operation ====
+
+#if (__CORTEX_M >= 3U)
+
+/// Exclusive Access Operation: Write (8-bit)
+/// \param[in]  mem             Memory address
+/// \param[in]  val             Value to write
+/// \return                     Previous value
+__STATIC_INLINE uint8_t os_exc_wr8 (uint8_t *mem, uint8_t val) {
+  register uint32_t res;
+  register uint8_t  ret;
+
+  __ASM volatile (
+  "loop%=:\n\t"
+    "ldrexb %[ret],[%[mem]]\n\t"
+    "strexb %[res],%[val],[%[mem]]\n\t"
+    "cbz    %[res],exit%=\n\t"
+    "b      loop%=\n\t"
+  "exit%=:"
+  : [ret] "=&l" (ret),
+    [res] "=&l" (res)
+  : [mem] "l"   (mem),
+    [val] "l"   (val)
+  : "memory"
+  );
+
+  return ret;
+}
+
+/// Exclusive Access Operation: Set bits (32-bit)
+/// \param[in]  mem             Memory address
+/// \param[in]  bits            Bit mask
+/// \return                     New value
+__STATIC_INLINE uint32_t os_exc_set32 (uint32_t *mem, uint32_t bits) {
+  register uint32_t val, res;
+  register uint32_t ret;
+
+  __ASM volatile (
+  "loop%=:\n\t"
+    "ldrex %[val],[%[mem]]\n\t"
+    "orr   %[ret],%[val],%[bits]\n\t"
+    "strex %[res],%[ret],[%[mem]]\n\t"
+    "cbz   %[res],exit%=\n\t"
+    "b     loop%=\n\t"
+  "exit%=:"
+  : [ret]  "=&l" (ret),
+    [val]  "=&l" (val),
+    [res]  "=&l" (res)
+  : [mem]  "l"   (mem),
+    [bits] "l"   (bits)
+  : "memory"
+  );
+
+  return ret;
+}
+
+/// Exclusive Access Operation: Clear bits (32-bit)
+/// \param[in]  mem             Memory address
+/// \param[in]  bits            Bit mask
+/// \return                     Previous value
+__STATIC_INLINE uint32_t os_exc_clr32 (uint32_t *mem, uint32_t bits) {
+  register uint32_t val, res;
+  register uint32_t ret;
+
+  __ASM volatile (
+  "loop%=:\n\t"
+    "ldrex %[ret],[%[mem]]\n\t"
+    "bic   %[val],%[ret],%[bits]\n\t"
+    "strex %[res],%[val],[%[mem]]\n\t"
+    "cbz   %[res],exit%=\n\t"
+    "b     loop%=\n\t"
+  "exit%=:"
+  : [ret]  "=&l" (ret),
+    [val]  "=&l" (val),
+    [res]  "=&l" (res)
+  : [mem]  "l"   (mem),
+    [bits] "l"   (bits)
+  : "memory"
+  );
+
+  return ret;
+}
+
+/// Exclusive Access Operation: Check if all specified bits (32-bit) are active and clear them
+/// \param[in]  mem             Memory address
+/// \param[in]  bits            Bit mask
+/// \return                     Active bits before clearing or 0 if not active
+__STATIC_INLINE uint32_t os_exc_chk32_all (uint32_t *mem, uint32_t bits) {
+  register uint32_t val, res;
+  register uint32_t ret;
+
+  __ASM volatile (
+  "loop%=:\n\t"
+    "ldrex %[ret],[%[mem]]\n\t"
+    "and   %[val],%[ret],%[bits]\n\t"
+    "cmp   %[val],%[bits]\n\t"
+    "beq   update%=\n\t"
+    "clrex\n\t"
+    "movs  %[ret],#0\n\t"
+    "b     exit%=\n\t"
+  "update%=:\n\t"
+    "bic   %[val],%[ret],%[bits]\n\t"
+    "strex %[res],%[val],[%[mem]]\n\t"
+    "cbz   %[res],exit%=\n\t"
+    "b     loop%=\n\t"
+  "exit%=:"
+  : [ret]  "=&l" (ret),
+    [val]  "=&l" (val),
+    [res]  "=&l" (res)
+  : [mem]  "l"   (mem),
+    [bits] "l"   (bits)
+  : "cc", "memory"
+  );
+
+  return ret;
+}
+
+/// Exclusive Access Operation: Check if any specified bits (32-bit) are active and clear them
+/// \param[in]  mem             Memory address
+/// \param[in]  bits            Bit mask
+/// \return                     Active bits before clearing or 0 if not active
+__STATIC_INLINE uint32_t os_exc_chk32_any (uint32_t *mem, uint32_t bits) {
+  register uint32_t val, res;
+  register uint32_t ret;
+
+  __ASM volatile (
+  "loop%=:\n\t"
+    "ldrex %[ret],[%[mem]]\n\t"
+    "ands  %[val],%[ret],%[bits]\n\t"
+    "bne   update%=\n\t"
+    "clrex\n\t"
+    "movs  %[ret],#0\n\t"
+    "b     exit%=\n\t"
+  "update%=:\n\t"
+    "bic   %[val],%[ret],%[bits]\n\t"
+    "strex %[res],%[val],[%[mem]]\n\t"
+    "cbz   %[res],exit%=\n\t"
+    "b     loop%=\n\t"
+  "exit%=:"
+  : [ret]  "=&l" (ret),
+    [val]  "=&l" (val),
+    [res]  "=&l" (res)
+  : [mem]  "l"   (mem),
+    [bits] "l"   (bits)
+  : "cc", "memory"
+  );
+
+  return ret;
+}
+
+/// Exclusive Access Operation: Increment (32-bit)
+/// \param[in]  mem             Memory address
+/// \return                     Previous value
+__STATIC_INLINE uint32_t os_exc_inc32 (uint32_t *mem) {
+  register uint32_t val, res;
+  register uint32_t ret;
+
+  __ASM volatile (
+  "loop%=:\n\t"
+    "ldrex %[ret],[%[mem]]\n\t"
+    "adds  %[val],%[ret],#1\n\t"
+    "strex %[res],%[val],[%[mem]]\n\t"
+    "cbz   %[res],exit%=\n\t"
+    "b     loop%=\n\t"
+  "exit%=:"
+  : [ret] "=&l" (ret),
+    [val] "=&l" (val),
+    [res] "=&l" (res)
+  : [mem] "l"   (mem)
+  : "cc", "memory"
+  );
+
+  return ret;
+}
+
+/// Exclusive Access Operation: Increment (16-bit) if Less Than
+/// \param[in]  mem             Memory address
+/// \param[in]  max             Maximum value
+/// \return                     Previous value
+__STATIC_INLINE uint16_t os_exc_inc16_lt (uint16_t *mem, uint16_t max) {
+  register uint32_t val, res;
+  register uint16_t ret;
+
+  __ASM volatile (
+  "loop%=:\n\t"
+    "ldrexh %[ret],[%[mem]]\n\t"
+    "cmp    %[max],%[ret]\n\t"
+    "bhi    update%=\n\t"
+    "clrex\n\t"
+    "b      exit%=\n\t"
+  "update%=:\n\t"
+    "adds   %[val],%[ret],#1\n\t"
+    "strexh %[res],%[val],[%[mem]]\n\t"
+    "cbz    %[res],exit%=\n\t"
+    "b      loop%=\n\t"
+  "exit%=:"
+  : [ret] "=&l" (ret),
+    [val] "=&l" (val),
+    [res] "=&l" (res)
+  : [mem] "l"   (mem),
+    [max] "l"   (max)
+  : "cc", "memory"
+  );
+
+  return ret;
+}
+
+/// Exclusive Access Operation: Increment (16-bit) and clear on Limit
+/// \param[in]  mem             Memory address
+/// \param[in]  max             Maximum value
+/// \return                     Previous value
+__STATIC_INLINE uint16_t os_exc_inc16_lim (uint16_t *mem, uint16_t lim) {
+  register uint32_t val, res;
+  register uint16_t ret;
+
+  __ASM volatile (
+  "loop%=:\n\t"
+    "ldrexh %[ret],[%[mem]]\n\t"
+    "adds   %[val],%[ret],#1\n\t"
+    "cmp    %[lim],%[val]\n\t"
+    "bhi    update%=\n\t"
+    "movs   %[val],#0\n\t"
+  "update%=:\n\t"
+    "strexh %[res],%[val],[%[mem]]\n\t"
+    "cbz    %[res],exit%=\n\t"
+    "b      loop%=\n\t"
+  "exit%=:"
+  : [ret] "=&l" (ret),
+    [val] "=&l" (val),
+    [res] "=&l" (res)
+  : [mem] "l"   (mem),
+    [lim] "l"   (lim)
+  : "cc", "memory"
+  );
+
+  return ret;
+}
+
+/// Exclusive Access Operation: Decrement (32-bit) if Not Zero
+/// \param[in]  mem             Memory address
+/// \return                     Previous value
+__STATIC_INLINE uint32_t os_exc_dec32_nz (uint32_t *mem) {
+  register uint32_t val, res;
+  register uint32_t ret;
+
+  __ASM volatile (
+  "loop%=:\n\t"
+    "ldrex %[ret],[%[mem]]\n\t"
+    "cbnz  %[ret],update%=\n\t"
+    "clrex\n\t"
+    "b     exit%=\n\t"
+  "update%=:\n\t"
+    "subs  %[val],%[ret],#1\n\t"
+    "strex %[res],%[val],[%[mem]]\n\t"
+    "cbz   %[res],exit%=\n\t"
+    "b     loop%=\n\t"
+  "exit%=:"
+  : [ret] "=&l" (ret),
+    [val] "=&l" (val),
+    [res] "=&l" (res)
+  : [mem] "l"   (mem)
+  : "cc", "memory"
+  );
+
+  return ret;
+}
+
+/// Exclusive Access Operation: Decrement (16-bit) if Not Zero
+/// \param[in]  mem             Memory address
+/// \return                     Previous value
+__STATIC_INLINE uint16_t os_exc_dec16_nz (uint16_t *mem) {
+  register uint32_t val, res;
+  register uint16_t ret;
+
+  __ASM volatile (
+  "loop%=:\n\t"
+    "ldrexh %[ret],[%[mem]]\n\t"
+    "cbnz   %[ret],update%=\n\t"
+    "clrex\n\t"
+    "b      exit%=\n\t"
+  "update%=:\n\t"
+    "subs   %[val],%[ret],#1\n\t"
+    "strexh %[res],%[val],[%[mem]]\n\t"
+    "cbz    %[res],exit%=\n\t"
+    "b      loop%=\n\t"
+  "exit%=:"
+  : [ret] "=&l" (ret),
+    [val] "=&l" (val),
+    [res] "=&l" (res)
+  : [mem] "l"   (mem)
+  : "cc", "memory"
+  );
+
+  return ret;
+}
+
+#endif  // __CORTEX_M >= 3U
+
+
+#endif  // __CORE_CM_H
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_delay.c b/CMSIS/RTOS2/RTX/Source/rtx_delay.c
new file mode 100644
index 0000000..4de6c56
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/rtx_delay.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       Delay functions
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#include "rtx_lib.h"
+
+
+//  ==== Service Calls ====
+
+//  Service Calls definitions
+SVC0_1(Delay,      osStatus_t, uint32_t)
+SVC0_1(DelayUntil, osStatus_t, uint64_t)
+
+/// Wait for Timeout (Time Delay).
+/// \note API identical to osDelay
+osStatus_t os_svcDelay (uint32_t millisec) {
+
+  if (millisec == 0U) {
+    return osOK;
+  }
+
+  os_ThreadWaitEnter(os_ThreadWaitingDelay, millisec);
+
+  return osOK;
+}
+
+/// Wait until specified time.
+/// \note API identical to osDelayUntil
+osStatus_t os_svcDelayUntil (uint64_t millisec) {
+
+  millisec -= os_Info.kernel.time;
+  if (millisec >= 0xFFFFFFFFU) {
+    return osError;
+  }
+
+  os_ThreadWaitEnter(os_ThreadWaitingDelay, (uint32_t)millisec);
+
+  return osOK;
+}
+
+
+//  ==== Public API ====
+
+/// Wait for Timeout (Time Delay).
+osStatus_t osDelay (uint32_t millisec) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcDelay(millisec);
+}
+
+/// Wait until specified time.
+osStatus_t osDelayUntil (uint64_t millisec) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcDelayUntil(millisec);
+}
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_evflags.c b/CMSIS/RTOS2/RTX/Source/rtx_evflags.c
new file mode 100644
index 0000000..4d9b757
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/rtx_evflags.c
@@ -0,0 +1,520 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       Event Flags functions
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#include "rtx_lib.h"
+
+
+//  ==== Helper functions ====
+
+/// Set Event Flags.
+/// \param[in]  ef              event flags object.
+/// \param[in]  flags           specifies the flags to set.
+/// \return event flags after setting.
+static int32_t os_EventFlagsSet (os_event_flags_t *ef, int32_t flags) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+  uint32_t primask = __get_PRIMASK();
+#endif
+  int32_t  event_flags;
+
+#ifdef __NO_EXCLUSIVE_ACCESS
+  __disable_irq();
+
+  ef->event_flags |= flags;
+  event_flags = ef->event_flags;
+
+  if (primask == 0U) {
+    __enable_irq();
+  }
+#else
+  event_flags = (int32_t)os_exc_set32((uint32_t *)&ef->event_flags, (uint32_t)flags);
+#endif
+
+  return event_flags;
+}
+
+/// Clear Event Flags.
+/// \param[in]  ef              event flags object.
+/// \param[in]  flags           specifies the flags to clear.
+/// \return event flags before clearing.
+static int32_t os_EventFlagsClear (os_event_flags_t *ef, int32_t flags) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+  uint32_t primask = __get_PRIMASK();
+#endif
+  int32_t  event_flags;
+
+#ifdef __NO_EXCLUSIVE_ACCESS
+  __disable_irq();
+
+  event_flags = ef->event_flags;
+  ef->event_flags &= ~flags;
+
+  if (primask == 0U) {
+    __enable_irq();
+  }
+#else
+  event_flags = (int32_t)os_exc_clr32((uint32_t *)&ef->event_flags, (uint32_t)flags);
+#endif
+
+  return event_flags;
+}
+
+/// Check Event Flags.
+/// \param[in]  ef              event flags object.
+/// \param[in]  flags           specifies the flags to check.
+/// \param[in]  options         specifies flags options (osFlagsXxxx).
+/// \return event flags before clearing or 0 if specified flags have not been set.
+static int32_t os_EventFlagsCheck (os_event_flags_t *ef, int32_t flags, uint32_t options) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+  uint32_t primask;
+#endif
+  int32_t  event_flags;
+
+  if ((options & osFlagsAutoClear) != 0U) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+    primask = __get_PRIMASK();
+    __disable_irq();
+
+    event_flags = ef->event_flags;
+    if ((((options & osFlagsWaitAll) != 0U) && ((event_flags & flags) != flags)) ||
+        (((options & osFlagsWaitAll) == 0U) && ((event_flags & flags) == 0))) {
+      event_flags = 0;
+    } else {
+      ef->event_flags &= ~flags;
+    }
+
+    if (primask == 0U) {
+      __enable_irq();
+    }
+#else
+    if ((options & osFlagsWaitAll) != 0U) {
+      event_flags = (int32_t)os_exc_chk32_all((uint32_t *)&ef->event_flags, (uint32_t)flags);
+    } else {
+      event_flags = (int32_t)os_exc_chk32_any((uint32_t *)&ef->event_flags, (uint32_t)flags);
+    }
+#endif
+  } else {
+    event_flags = ef->event_flags;
+    if ((((options & osFlagsWaitAll) != 0U) && ((event_flags & flags) != flags)) ||
+        (((options & osFlagsWaitAll) == 0U) && ((event_flags & flags) == 0))) {
+      event_flags = 0;
+    }
+  }
+
+  return event_flags;
+}
+
+
+//  ==== Library functions ====
+
+/// Event Flags post ISR processing.
+/// \param[in]  ef              event flags object.
+void os_EventFlagsPostProcess (os_event_flags_t *ef) {
+  os_thread_t *thread;
+  os_thread_t *thread_next;
+  int32_t      event_flags;
+
+  if (ef->state == os_ObjectInactive) {
+    return;
+  }
+
+  // Check if Threads are waiting for Event Flags
+  thread = ef->thread_list;
+  while (thread != NULL) {
+    thread_next = thread->thread_next;
+    event_flags = os_EventFlagsCheck(ef, thread->wait_flags, thread->flags_options);
+    if (event_flags > 0) {
+      os_ThreadListRemove(thread);
+      os_ThreadWaitExit(thread, (uint32_t)event_flags, false);
+    }
+    thread = thread_next;
+  }
+}
+
+
+//  ==== Service Calls ====
+
+//  Service Calls definitions
+SVC0_1(EventFlagsNew,    osEventFlagsId_t, const osEventFlagsAttr_t *)
+SVC0_2(EventFlagsSet,    int32_t,          osEventFlagsId_t, int32_t)
+SVC0_2(EventFlagsClear,  int32_t,          osEventFlagsId_t, int32_t)
+SVC0_1(EventFlagsGet,    int32_t,          osEventFlagsId_t)
+SVC0_4(EventFlagsWait,   int32_t,          osEventFlagsId_t, int32_t, uint32_t, uint32_t)
+SVC0_1(EventFlagsDelete, osStatus_t,       osEventFlagsId_t)
+
+/// Create and Initialize an Event Flags object.
+/// \note API identical to osEventFlagsNew
+osEventFlagsId_t os_svcEventFlagsNew (const osEventFlagsAttr_t *attr) {
+  os_event_flags_t *ef;
+  uint8_t           flags;
+  const char       *name;
+
+  // Process attributes
+  if (attr != NULL) {
+    name = attr->name;
+    ef   = attr->cb_mem;
+    if (ef != NULL) {
+      if (((uint32_t)ef & 3U) || (attr->cb_size < sizeof(os_event_flags_t))) {
+        return (osEventFlagsId_t)NULL;
+      }
+    } else {
+      if (attr->cb_size != 0U) {
+        return (osEventFlagsId_t)NULL;
+      }
+    }
+  } else {
+    name = NULL;
+    ef   = NULL;
+  }
+
+  // Allocate object memory if not provided
+  if (ef == NULL) {
+    if (os_Info.mpi.event_flags != NULL) {
+      ef = os_MemoryPoolAlloc(os_Info.mpi.event_flags);
+    } else {
+      ef = os_MemoryAlloc(os_Info.mem.cb, sizeof(os_event_flags_t));
+    }
+    if (ef == NULL) {
+      return (osEventFlagsId_t)NULL;
+    }
+    flags = os_FlagSystemObject;
+  } else {
+    flags = 0U;
+  }
+
+  // Initialize control block
+  ef->id          = os_IdEventFlags;
+  ef->state       = os_ObjectActive;
+  ef->flags       = flags;
+  ef->name        = name;
+  ef->thread_list = NULL;
+  ef->event_flags = 0;
+
+  // Register post ISR processing function
+  os_Info.post_process.event_flags = os_EventFlagsPostProcess;
+
+  return (osEventFlagsId_t)ef;
+}
+
+/// Set the specified Event Flags.
+/// \note API identical to osEventFlagsSet
+int32_t os_svcEventFlagsSet (osEventFlagsId_t ef_id, int32_t flags) {
+  os_event_flags_t *ef = (os_event_flags_t *)ef_id;
+  os_thread_t      *thread;
+  os_thread_t      *thread_next;
+  int32_t           event_flags;
+  int32_t           event_flags0;
+
+  // Check parameters
+  if ((ef == NULL) ||
+      (ef->id != os_IdEventFlags)) {
+    return osErrorParameter;
+  }
+  if ((uint32_t)flags & ~((1U << os_EventFlagsLimit) - 1U)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (ef->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Set Event Flags
+  event_flags = os_EventFlagsSet(ef, flags);
+
+  // Check if Threads are waiting for Event Flags
+  thread = ef->thread_list;
+  while (thread != NULL) {
+    thread_next = thread->thread_next;
+    event_flags0 = os_EventFlagsCheck(ef, thread->wait_flags, thread->flags_options);
+    if (event_flags0 > 0) {
+      if ((thread->flags_options & osFlagsAutoClear) != 0U) {
+        event_flags = event_flags0 & ~thread->wait_flags;
+      } else {
+        event_flags = event_flags0;
+      }
+      os_ThreadListRemove(thread);
+      os_ThreadWaitExit(thread, (uint32_t)event_flags0, false);
+    }
+    thread = thread_next;
+  }
+  os_ThreadDispatch(NULL);
+
+  return event_flags;
+}
+
+/// Clear the specified Event Flags.
+/// \note API identical to osEventFlagsClear
+int32_t os_svcEventFlagsClear (osEventFlagsId_t ef_id, int32_t flags) {
+  os_event_flags_t *ef = (os_event_flags_t *)ef_id;
+
+  // Check parameters
+  if ((ef == NULL) ||
+      (ef->id != os_IdEventFlags)) {
+    return osErrorParameter;
+  }
+  if ((uint32_t)flags & ~((1U << os_EventFlagsLimit) - 1U)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (ef->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Clear Event Flags
+  return os_EventFlagsClear(ef, flags);
+}
+
+/// Get the current Event Flags.
+/// \note API identical to osEventFlagsGet
+int32_t os_svcEventFlagsGet (osEventFlagsId_t ef_id) {
+  os_event_flags_t *ef = (os_event_flags_t *)ef_id;
+
+  // Check parameters
+  if ((ef == NULL) ||
+      (ef->id != os_IdEventFlags)) {
+    return 0;
+  }
+
+  // Check object state
+  if (ef->state == os_ObjectInactive) {
+    return 0;
+  }
+
+  return ef->event_flags;
+}
+
+/// Wait for one or more Event Flags to become signaled.
+/// \note API identical to osEventFlagsWait
+int32_t os_svcEventFlagsWait (osEventFlagsId_t ef_id, int32_t flags, uint32_t options, uint32_t millisec) {
+  os_event_flags_t *ef = (os_event_flags_t *)ef_id;
+  os_thread_t      *running_thread;
+  int32_t           event_flags;
+
+  running_thread = os_ThreadGetRunning();
+  if (running_thread == NULL) {
+    return osError;
+  }
+
+  // Check parameters
+  if ((ef == NULL) ||
+      (ef->id != os_IdEventFlags)) {
+    return osErrorParameter;
+  }
+  if ((uint32_t)flags & ~((1U << os_EventFlagsLimit) - 1U)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (ef->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Check Event Flags
+  event_flags = os_EventFlagsCheck(ef, flags, options);
+  if (event_flags > 0) {
+    return event_flags;
+  }
+
+  // Check if timeout is specified
+  if (millisec != 0U) {
+    // Store waiting flags and options
+    running_thread->wait_flags = flags;
+    running_thread->flags_options = (uint8_t)options;
+    // Suspend current Thread
+    os_ThreadListPut((os_object_t*)ef, running_thread);
+    os_ThreadWaitEnter(os_ThreadWaitingEventFlags, millisec);
+    return osErrorTimeout;
+  }
+
+  return osErrorResource;
+}
+
+/// Delete an Event Flags object.
+/// \note API identical to osEventFlagsDelete
+osStatus_t os_svcEventFlagsDelete (osEventFlagsId_t ef_id) {
+  os_event_flags_t *ef = (os_event_flags_t *)ef_id;
+  os_thread_t      *thread;
+
+  // Check parameters
+  if ((ef == NULL) ||
+      (ef->id != os_IdEventFlags)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (ef->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Mark object as inactive
+  ef->state = os_ObjectInactive;
+
+  // Unblock waiting threads
+  if (ef->thread_list != NULL) {
+    do {
+      thread = os_ThreadListGet((os_object_t*)ef);
+      os_ThreadWaitExit(thread, (uint32_t)osErrorResource, false);
+    } while (ef->thread_list != NULL);
+    os_ThreadDispatch(NULL);
+  }
+
+  // Free object memory
+  if (ef->flags & os_FlagSystemObject) {
+    if (os_Info.mpi.event_flags != NULL) {
+      os_MemoryPoolFree(os_Info.mpi.event_flags, ef);
+    } else {
+      os_MemoryFree(os_Info.mem.cb, ef);
+    }
+  }
+
+  return osOK;
+}
+
+
+//  ==== ISR Calls ====
+
+/// Set the specified Event Flags.
+/// \note API identical to osEventFlagsSet
+__STATIC_INLINE
+int32_t os_isrEventFlagsSet (osEventFlagsId_t ef_id, int32_t flags) {
+  os_event_flags_t *ef = (os_event_flags_t *)ef_id;
+  int32_t           event_flags;
+
+  // Check parameters
+  if ((ef == NULL) ||
+      (ef->id != os_IdEventFlags)) {
+    return osErrorParameter;
+  }
+  if ((uint32_t)flags & ~((1U << os_EventFlagsLimit) - 1U)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (ef->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Set Event Flags
+  event_flags = os_EventFlagsSet(ef, flags);
+
+  // Register post ISR processing
+  os_PostProcess((os_object_t *)ef);
+
+  return event_flags;
+}
+
+/// Wait for one or more Event Flags to become signaled.
+/// \note API identical to osEventFlagsWait
+__STATIC_INLINE
+int32_t os_isrEventFlagsWait (osEventFlagsId_t ef_id, int32_t flags, uint32_t options, uint32_t millisec) {
+  os_event_flags_t *ef = (os_event_flags_t *)ef_id;
+  int32_t           event_flags;
+
+  // Check parameters
+  if ((ef == NULL) ||
+      (ef->id != os_IdEventFlags)) {
+    return osErrorParameter;
+  }
+  if ((uint32_t)flags & ~((1U << os_EventFlagsLimit) - 1U)) {
+    return osErrorParameter;
+  }
+  if (millisec != 0U) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (ef->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Check Event Flags
+  event_flags = os_EventFlagsCheck(ef, flags, options);
+  if (event_flags > 0) {
+    return event_flags;
+  }
+
+  return osErrorResource;
+}
+
+
+//  ==== Public API ====
+
+/// Create and Initialize an Event Flags object.
+osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr) {
+  if (__get_IPSR() != 0U) {
+    return (osEventFlagsId_t)NULL;              // Not allowed in ISR
+  }
+  if ((os_KernelGetState() == os_KernelReady) && ((__get_CONTROL() & 1U) == 0U)) {
+    // Kernel Ready (not running) and in Privileged mode
+    return os_svcEventFlagsNew(attr);
+  } else {
+    return  __svcEventFlagsNew(attr);
+  }
+}
+
+/// Set the specified Event Flags.
+int32_t osEventFlagsSet (osEventFlagsId_t ef_id, int32_t flags) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_isrEventFlagsSet(ef_id, flags);
+  } else {                                      // in Thread
+    return  __svcEventFlagsSet(ef_id, flags);
+  }
+}
+
+/// Clear the specified Event Flags.
+int32_t osEventFlagsClear (osEventFlagsId_t ef_id, int32_t flags) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_svcEventFlagsClear(ef_id, flags);
+  } else {                                      // in Thread
+    return  __svcEventFlagsClear(ef_id, flags);
+  }
+}
+
+/// Get the current Event Flags.
+int32_t osEventFlagsGet (osEventFlagsId_t ef_id) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_svcEventFlagsGet(ef_id);
+  } else {                                      // in Thread
+    return  __svcEventFlagsGet(ef_id);
+  }
+}
+
+/// Wait for one or more Event Flags to become signaled.
+int32_t osEventFlagsWait (osEventFlagsId_t ef_id, int32_t flags, uint32_t options, uint32_t millisec) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_isrEventFlagsWait(ef_id, flags, options, millisec);
+  } else {                                      // in Thread
+    return  __svcEventFlagsWait(ef_id, flags, options, millisec);
+  }
+}
+
+/// Delete an Event Flags object.
+osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcEventFlagsDelete(ef_id);
+}
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_kernel.c b/CMSIS/RTOS2/RTX/Source/rtx_kernel.c
new file mode 100644
index 0000000..c79ba9f
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/rtx_kernel.c
@@ -0,0 +1,532 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       Kernel functions
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#include "rtx_lib.h"
+
+
+//  OS Runtime Information
+os_info_t os_Info __attribute__((section(".os.data"))) =
+{ .os_id = os_KernelId, .version = os_CMSIS_RTX, .kernel.state = os_KernelInactive };
+
+//  Library reference to irq_cm module
+extern       uint8_t  os_irq_cm;
+extern const uint8_t *os_irq_cm_lib_ref;
+       const uint8_t* os_irq_cm_lib_ref = &os_irq_cm;
+
+
+//  ==== Helper functions ====
+
+/// Block Kernel (disable: thread switching, time tick, post ISR processing).
+static void os_KernelBlock (void) {
+
+  if (os_Info.tick_irqn >= 0) {
+    os_ExtTick_DisableIRQ(os_Info.tick_irqn);
+  }
+  os_TickDisable();
+  os_Info.kernel.blocked = 1U;
+  __DSB();
+  if (os_Info.tick_irqn < 0) {
+    os_Info.kernel.pendISR = os_GetPendSV_ST();
+    os_ClrPendSV_ST();
+  } else {
+    os_Info.kernel.pendISR = os_GetPendSV();
+    os_ClrPendSV();
+  }
+}
+
+/// Unblock Kernel
+static void os_KernelUnblock (void) {
+
+  os_Info.kernel.blocked = 0U;
+  __DSB();
+  if (os_Info.kernel.pendSV != 0U) {
+    os_Info.kernel.pendSV = 0U;
+    os_SetPendSV();
+  }
+  if (os_Info.kernel.pendISR != 0U) {
+    os_SetPendFlags(os_Info.kernel.pendISR);
+  }
+  if (os_Info.tick_irqn >= 0) {
+    os_ExtTick_EnableIRQ(os_Info.tick_irqn);
+  }
+  os_TickEnable();
+}
+
+
+//  ==== Service Calls ====
+
+//  Service Calls definitions
+SVC0_0 (KernelInitialize,   osStatus_t)
+SVC0_3 (KernelGetInfo,      osStatus_t, osVersion_t *, char *, uint32_t)
+SVC0_0 (KernelStart,        osStatus_t)
+SVC0_0 (KernelLock,         uint32_t)
+SVC0_0N(KernelUnlock,       void)
+SVC0_0 (KernelSuspend,      uint32_t)
+SVC0_1N(KernelResume,       void, uint32_t)
+SVC0_0 (KernelGetState,     osKernelState_t)
+SVC0_0 (KernelGetTime,      uint64_t)
+SVC0_0 (KernelGetTick,      uint32_t)
+SVC0_1 (KernelTickMicroSec, uint32_t, uint32_t)
+
+/// Initialize the RTOS Kernel.
+/// \note API identical to osKernelInitialize
+osStatus_t os_svcKernelInitialize (void) {
+
+  if (os_Info.kernel.state == os_KernelReady) {
+    return osOK;
+  }
+  if (os_Info.kernel.state != osKernelInactive) {
+    return osError;
+  }
+
+  // Initialize os_Info
+  memset(&os_Info.kernel, 0, sizeof(os_Info) - offsetof(os_info_t, kernel));
+
+  if (os_Config.thread_stack_size < (64U + 8U)) {
+    return osError;
+  }
+
+  if ((os_Config.isr_queue.data == NULL) || (os_Config.isr_queue.max == 0U)) {
+    return osError;
+  }
+  os_Info.isr_queue.data = os_Config.isr_queue.data;
+  os_Info.isr_queue.max  = os_Config.isr_queue.max;
+
+  os_Info.thread.robin.timeout = os_Config.robin_timeout;
+
+  // Initialize Memory Pools (Variable Block Size)
+  if (os_MemoryInit(os_Config.mem.common_addr, os_Config.mem.common_size) != 0U) {
+    os_Info.mem.common = os_Config.mem.common_addr;
+  }
+  if (os_MemoryInit(os_Config.mem.cb_addr, os_Config.mem.cb_size) != 0U) {
+    os_Info.mem.cb = os_Config.mem.cb_addr;
+  } else {
+    os_Info.mem.cb = os_Info.mem.common;
+  }
+  if (os_MemoryInit(os_Config.mem.data_addr, os_Config.mem.data_size) != 0U) {
+    os_Info.mem.data = os_Config.mem.data_addr;
+  } else {
+    os_Info.mem.data = os_Info.mem.common;
+  }
+  if (os_MemoryInit(os_Config.mem.stack_addr, os_Config.mem.stack_size) != 0U) {
+    os_Info.mem.stack = os_Config.mem.stack_addr;
+  } else {
+    os_Info.mem.stack = os_Info.mem.common;
+  }
+
+  // Initialize Memory Pools (Fixed Block Size)
+  if ((os_Config.mpi.stack != NULL) &&
+      (os_MemoryPoolInit(os_Config.mpi.stack,
+                         os_Config.mpi.stack->max_blocks,
+                         os_Config.mpi.stack->block_size,
+                         os_Config.mpi.stack->block_base) != 0U)) {
+    os_Info.mpi.stack = os_Config.mpi.stack;
+  }
+  if ((os_Config.mpi.thread != NULL) &&
+      (os_MemoryPoolInit(os_Config.mpi.thread,
+                         os_Config.mpi.thread->max_blocks,
+                         os_Config.mpi.thread->block_size,
+                         os_Config.mpi.thread->block_base) != 0U)) {
+    os_Info.mpi.thread = os_Config.mpi.thread;
+  }
+  if ((os_Config.mpi.timer != NULL) &&
+      (os_MemoryPoolInit(os_Config.mpi.timer,
+                         os_Config.mpi.timer->max_blocks,
+                         os_Config.mpi.timer->block_size,
+                         os_Config.mpi.timer->block_base) != 0U)) {
+    os_Info.mpi.timer = os_Config.mpi.timer;
+  }
+  if ((os_Config.mpi.event_flags != NULL) &&
+      (os_MemoryPoolInit(os_Config.mpi.event_flags,
+                         os_Config.mpi.event_flags->max_blocks,
+                         os_Config.mpi.event_flags->block_size,
+                         os_Config.mpi.event_flags->block_base) != 0U)) {
+    os_Info.mpi.event_flags = os_Config.mpi.event_flags;
+  }
+  if ((os_Config.mpi.mutex != NULL) &&
+      (os_MemoryPoolInit(os_Config.mpi.mutex,
+                         os_Config.mpi.mutex->max_blocks,
+                         os_Config.mpi.mutex->block_size,
+                         os_Config.mpi.mutex->block_base) != 0U)) {
+    os_Info.mpi.mutex = os_Config.mpi.mutex;
+  }
+  if ((os_Config.mpi.semaphore != NULL) &&
+      (os_MemoryPoolInit(os_Config.mpi.semaphore,
+                         os_Config.mpi.semaphore->max_blocks,
+                         os_Config.mpi.semaphore->block_size,
+                         os_Config.mpi.semaphore->block_base) != 0U)) {
+    os_Info.mpi.semaphore = os_Config.mpi.semaphore;
+  }
+  if ((os_Config.mpi.memory_pool != NULL) &&
+      (os_MemoryPoolInit(os_Config.mpi.memory_pool,
+                         os_Config.mpi.memory_pool->max_blocks,
+                         os_Config.mpi.memory_pool->block_size,
+                         os_Config.mpi.memory_pool->block_base) != 0U)) {
+    os_Info.mpi.memory_pool = os_Config.mpi.memory_pool;
+  }
+  if ((os_Config.mpi.message_queue != NULL) &&
+      (os_MemoryPoolInit(os_Config.mpi.message_queue,
+                         os_Config.mpi.message_queue->max_blocks,
+                         os_Config.mpi.message_queue->block_size,
+                         os_Config.mpi.message_queue->block_base) != 0U)) {
+    os_Info.mpi.message_queue = os_Config.mpi.message_queue;
+  }
+
+  // Create Idle Thread
+  os_Info.thread.idle = (os_thread_t *)(os_svcThreadNew(
+                                          os_IdleThread,
+                                          NULL,
+                                          os_Config.idle_thread_attr));
+  if (os_Info.thread.idle == NULL) {
+    return osError;
+  }
+
+  // Initialize SVC and PendSV System Service Calls
+  os_SVC_Initialize();
+
+  os_Info.kernel.state = os_KernelReady;
+
+  return osOK;
+}
+
+///  Get RTOS Kernel Information.
+/// \note API identical to osKernelGetInfo
+osStatus_t os_svcKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) {
+
+  if (version != NULL) {
+    version->api    = os_CMSIS_API;
+    version->kernel = os_CMSIS_RTX;
+  }
+
+  if ((id_buf != NULL) && (id_size != 0U)) {
+    if (id_size > sizeof(os_KernelId)) {
+      id_size = sizeof(os_KernelId);
+    }
+    memcpy(id_buf, os_KernelId, id_size);
+  }
+
+  return osOK;
+}
+
+/// Get the current RTOS Kernel state.
+/// \note API identical to osKernelGetState
+osKernelState_t os_svcKernelGetState (void) {
+  return ((osKernelState_t)(os_Info.kernel.state));
+}
+
+/// Start the RTOS Kernel scheduler.
+/// \note API identical to osKernelStart
+osStatus_t os_svcKernelStart (void) {
+  os_thread_t *thread;
+
+  if (os_Info.kernel.state != os_KernelReady) {
+    return osError;
+  }
+
+  // Switch to Ready Thread with highest Priority
+  thread = os_ThreadListGet(&os_Info.thread.ready);
+  if (thread == NULL) {
+    return osError;
+  }
+  os_ThreadSwitch(thread);
+  __set_PSP(thread->sp + (8U*4U));
+
+  if ((os_Config.flags & os_ConfigPrivilegedMode) != 0U) {
+    // Privileged Thread mode & PSP
+    __set_CONTROL(0x02U);
+  } else {
+    // Unprivileged Thread mode & PSP
+    __set_CONTROL(0x03U);
+  }
+  __DSB();
+  __ISB();
+
+  // Setup and Enable Tick Timer
+  os_Info.tick_irqn = os_TickSetup();
+  if (os_Info.tick_irqn >= 0) {
+    os_ExtTick_EnableIRQ(os_Info.tick_irqn);
+  }
+  os_TickEnable();
+
+  os_Info.kernel.state = os_KernelRunning;
+
+  return osOK;
+}
+
+/// Lock the RTOS Kernel scheduler.
+/// \note API identical to osKernelLock
+uint32_t os_svcKernelLock (void) {
+
+  if (os_Info.kernel.state == osKernelRunning) {
+    os_Info.kernel.state = os_KernelLocked;
+    return 1U;
+  }
+
+  return 0U;
+}
+ 
+/// Unlock the RTOS Kernel scheduler.
+/// \note API identical to osKernelUnlock
+void os_svcKernelUnlock (void) {
+
+  if (os_Info.kernel.state == os_KernelLocked) {
+    os_Info.kernel.state = osKernelRunning;
+  }
+}
+
+/// Suspend the RTOS Kernel scheduler.
+/// \note API identical to osKernelSuspend
+uint32_t os_svcKernelSuspend (void) {
+  os_thread_t *thread;
+  os_timer_t  *timer;
+  uint32_t     delay;
+
+  if (os_Info.kernel.state != os_KernelRunning) {
+    return 0U;
+  }
+
+  os_KernelBlock();
+
+  delay = osWaitForever;
+
+  // Check Thread Delay list
+  thread = os_Info.thread.delay_list;
+  if (thread != NULL) {
+    delay = thread->delay;
+  }
+
+  // Check Active Timer list
+  timer = os_Info.timer.list;
+  if (timer != NULL) {
+    if (timer->tick < delay) {
+      delay = timer->tick;
+    }
+  }
+
+  os_Info.kernel.state = os_KernelSuspended;
+
+  return delay;
+}
+
+/// Resume the RTOS Kernel scheduler.
+/// \note API identical to osKernelResume
+void os_svcKernelResume (uint32_t sleep_time) {
+  os_thread_t *thread;
+  os_timer_t  *timer;
+  uint32_t     delay;
+
+  if (os_Info.kernel.state != os_KernelSuspended) {
+    return;
+  }
+
+  // Process Thread Delay list
+  thread = os_Info.thread.delay_list;
+  if (thread != NULL) {
+    delay = sleep_time;
+    if (delay >= thread->delay) {
+        delay -= thread->delay;
+      os_Info.kernel.time += thread->delay;
+      thread->delay = 1U;
+      do {
+        os_ThreadDelayTick();
+        if (delay == 0U) { 
+          break;
+        }
+        delay--;
+        os_Info.kernel.time++;
+      } while (os_Info.thread.delay_list != NULL);
+    } else {
+      thread->delay -= delay;
+      os_Info.kernel.time += delay;
+    }
+  } else {
+    os_Info.kernel.time += sleep_time;
+  }
+
+  // Process Active Timer list
+  timer = os_Info.timer.list;
+  if (timer != NULL) {
+    if (sleep_time >= timer->tick) {
+        sleep_time -= timer->tick;
+      timer->tick = 1U;
+      do {
+        os_TimerTick();
+        if (sleep_time == 0U) {
+          break;
+        }
+        sleep_time--;
+      } while (os_Info.timer.list != NULL);
+    } else {
+      timer->tick -= sleep_time;
+    }
+  }
+
+  os_Info.kernel.state = os_KernelRunning;
+
+  os_ThreadDispatch(NULL);
+
+  os_KernelUnblock();
+}
+
+/// Get the RTOS kernel time.
+/// \note API identical to osKernelGetTime
+uint64_t os_svcKernelGetTime (void) {
+  return os_Info.kernel.time;
+}
+
+/// Get the RTOS kernel system timer counter.
+/// \note API identical to osKernelGetSysTick
+uint32_t os_svcKernelGetTick (void) {
+  return os_TickGetVal();
+}
+
+/// Convert a microseconds value to a RTOS kernel system timer value.
+/// \note API identical to osKernelInitialize
+uint32_t os_svcKernelTickMicroSec (uint32_t microsec) {
+  return os_TickMicroSec(microsec);
+}
+
+
+//  ==== Public API ====
+
+/// Initialize the RTOS Kernel.
+osStatus_t osKernelInitialize (void) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  if ((__get_CONTROL() & 1U) == 0U) {           // Privileged mode
+    return os_svcKernelInitialize();
+  } else {                                      // Unprivileged mode
+    return  __svcKernelInitialize();
+  }
+}
+
+///  Get RTOS Kernel Information.
+osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  if ((__get_CONTROL() & 1U) == 0U) {           // Privileged mode
+    return os_svcKernelGetInfo(version, id_buf, id_size);
+  } else {                                      // Unprivileged mode
+    return  __svcKernelGetInfo(version, id_buf, id_size);
+  }
+}
+
+/// Get the current RTOS Kernel state.
+osKernelState_t osKernelGetState (void) {
+  if (__get_IPSR() != 0U) {
+    return osKernelError;                       // Not allowed in ISR
+  }
+  if ((__get_CONTROL() & 1U) == 0U) {           // Privileged mode
+    return os_svcKernelGetState();
+  } else {
+    return  __svcKernelGetState();
+  }
+}
+
+/// Start the RTOS Kernel scheduler.
+osStatus_t osKernelStart (void) {
+  osStatus_t status;
+  uint32_t   stack[8];
+
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  switch (__get_CONTROL() & 0x03U) {
+    case 0x00U:                                 // Privileged Thread mode & MSP
+      __set_PSP((uint32_t)(stack + 8));         // Initial PSP
+      __set_CONTROL(0x02U);                     // Set Privileged Thread mode & PSP
+      __DSB();
+      __ISB();
+      status = __svcKernelStart();
+      if (status != osOK) {
+        __set_CONTROL(0x00U);                   // Restore Privileged Thread mode & MSP
+      }
+      return status;
+    case 0x01U:                                 // Unprivileged Thread mode & MSP
+      return osError;
+    case 0x02U:                                 // Privileged Thread mode & PSP
+    case 0x03U:                                 // Unprivileged Thread mode & PSP
+      break;
+  }
+  return __svcKernelStart();
+}
+
+/// Lock the RTOS Kernel scheduler.
+uint32_t osKernelLock (void) {
+  if (__get_IPSR() != 0U) {
+    return 0U;                                  // Not allowed in ISR
+  }
+  return __svcKernelLock();
+}
+ 
+/// Unlock the RTOS Kernel scheduler.
+void osKernelUnlock (void) {
+  if (__get_IPSR() != 0U) {
+    return;                                     // Not allowed in ISR
+  }
+  __svcKernelUnlock();
+}
+
+/// Suspend the RTOS Kernel scheduler.
+uint32_t osKernelSuspend (void) {
+  if (__get_IPSR() != 0U) {
+    return 0U;                                  // Not allowed in ISR
+  }
+  return __svcKernelSuspend();
+}
+
+/// Resume the RTOS Kernel scheduler.
+void osKernelResume (uint32_t sleep_time) {
+  if (__get_IPSR() != 0U) {
+    return;                                     // Not allowed in ISR
+  }
+  __svcKernelResume(sleep_time);
+}
+
+/// Get the RTOS kernel time.
+uint64_t osKernelGetTime (void) {
+  if (__get_IPSR() != 0U) {
+    return 0U;                                  // Not allowed in ISR
+  }
+  return  __svcKernelGetTime();
+}
+
+/// Get the RTOS kernel system timer counter.
+uint32_t osKernelGetTick (void) {
+  if (__get_IPSR() != 0U) {
+    return 0U;                                  // Not allowed in ISR
+  }
+  return  __svcKernelGetTick();
+}
+
+/// Convert a microseconds value to a RTOS kernel system timer value.
+uint32_t osKernelTickMicroSec (uint32_t microsec) {
+  if (__get_IPSR() != 0U) {
+    return 0U;                                  // Not allowed in ISR
+  }
+  return  __svcKernelTickMicroSec(microsec);
+}
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_lib.h b/CMSIS/RTOS2/RTX/Source/rtx_lib.h
new file mode 100644
index 0000000..f14d83b
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/rtx_lib.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       RTX Library definitions
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#ifndef __RTX_LIB_H
+#define __RTX_LIB_H
+
+#include <string.h>
+#include <stdbool.h>
+#include "core_cm.h"                    // Cortex-M definitions
+#include "cmsis_os2.h"                  // CMSIS RTOS API
+#include "rtx_os.h"                     // RTX OS definitions
+
+
+//  ==== Inline functions ====
+
+// Kernel Inline functions
+__STATIC_INLINE uint8_t      os_KernelGetState   (void) { return os_Info.kernel.state; }
+
+// Thread Inline functions
+__STATIC_INLINE os_thread_t *os_ThreadGetRunning (void) { return os_Info.thread.run.curr; }
+__STATIC_INLINE void         os_ThreadSetRunning (os_thread_t *thread) { os_Info.thread.run.curr = thread; }
+
+
+//  ==== Library functions ====
+
+// Thread Library functions
+extern void         os_ThreadListPut     (volatile os_object_t *object, os_thread_t *thread);
+extern os_thread_t *os_ThreadListGet     (volatile os_object_t *object);
+extern void         os_ThreadListSort    (os_thread_t  *thread);
+extern void         os_ThreadListRemove  (os_thread_t  *thread);
+extern void         os_ThreadListUnlink  (os_thread_t **thread_list, os_thread_t *thread);
+extern void         os_ThreadReadyPut    (os_thread_t  *thread);
+extern void         os_ThreadDelayInsert (os_thread_t  *thread, uint32_t millisec);
+extern void         os_ThreadDelayRemove (os_thread_t  *thread);
+extern void         os_ThreadDelayTick   (void);
+extern uint32_t    *os_ThreadRegPtr      (os_thread_t  *thread);
+extern void         os_ThreadBlock       (os_thread_t  *thread);
+extern void         os_ThreadSwitch      (os_thread_t  *thread);
+extern void         os_ThreadDispatch    (os_thread_t  *thread);
+extern void         os_ThreadWaitExit    (os_thread_t  *thread, uint32_t ret_val, bool dispatch);
+extern bool         os_ThreadWaitEnter   (uint8_t state, uint32_t millisec);
+extern void         os_ThreadStackCheck  (void);
+
+// Timer Library functions
+extern void  os_TimerTick   (void);
+extern void *os_TimerThread (void *argument);
+
+// Mutex Library functions
+extern void  os_MutexOwnerRelease (os_mutex_t *mutex_list);
+
+// Memory Heap Library functions
+extern uint32_t os_MemoryInit (void *mem, uint32_t size);
+extern void    *os_MemoryAlloc(void *mem, uint32_t size);
+extern uint32_t os_MemoryFree (void *mem, void *block);
+
+// Memory Pool Library functions
+extern uint32_t   os_MemoryPoolInit  (os_mp_info_t *mp_info, uint32_t blocks, uint32_t block_size, void *block_mem);
+extern void      *os_MemoryPoolAlloc (os_mp_info_t *mp_info);
+extern osStatus_t os_MemoryPoolFree  (os_mp_info_t *mp_info, void *block);
+
+// System Library functions
+extern void  os_Tick_Handler   (void);
+extern void  os_PendSV_Handler (void);
+extern void  os_PostProcess    (os_object_t *object);
+
+// Post ISR processing functions
+extern void  os_ThreadPostProcess       (os_thread_t      *thread);
+extern void  os_EventFlagsPostProcess   (os_event_flags_t *ef);
+extern void  os_SemaphorePostProcess    (os_semaphore_t   *semaphore);
+extern void  os_MemoryPoolPostProcess   (os_memory_pool_t *mp);
+extern void  os_MessageQueuePostProcess (os_message_t     *msg);
+
+
+//  ==== Service Calls ====
+
+// Kernel Service Calls
+extern osStatus_t       os_svcKernelInitialize   (void);
+extern osStatus_t       os_svcKernelGetInfo      (osVersion_t *version, char *id_buf, uint32_t id_size);
+extern osKernelState_t  os_svcKernelGetState     (void);
+extern osStatus_t       os_svcKernelStart        (void);
+extern uint32_t         os_svcKernelLock         (void);
+extern void             os_svcKernelUnlock       (void);
+extern uint32_t         os_svcKernelSuspend      (void);
+extern void             os_svcKernelResume       (uint32_t sleep_time);
+extern uint64_t         os_svcKernelGetTime      (void);
+extern uint32_t         os_svcKernelGetTick      (void);
+extern uint32_t         os_svcKernelTickMicroSec (uint32_t microsec);
+
+// Thread Service Calls
+extern osThreadId_t     os_svcThreadNew          (os_thread_func_t func, void *argument, const osThreadAttr_t *attr);
+extern osThreadId_t     os_svcThreadGetId        (void);
+extern osThreadState_t  os_svcThreadGetState     (osThreadId_t thread_id);
+extern osStatus_t       os_svcThreadSetPriority  (osThreadId_t thread_id, osPriority_t priority);
+extern osPriority_t     os_svcThreadGetPriority  (osThreadId_t thread_id);
+extern osStatus_t       os_svcThreadYield        (void);
+extern osStatus_t       os_svcThreadAbortWait    (osThreadId_t thread_id);
+extern osStatus_t       os_svcThreadSuspend      (osThreadId_t thread_id);
+extern osStatus_t       os_svcThreadResume       (osThreadId_t thread_id);
+extern osStatus_t       os_svcThreadDetach       (osThreadId_t thread_id);
+extern osStatus_t       os_svcThreadJoin         (osThreadId_t thread_id, void **exit_ptr);
+extern void             os_svcThreadExit         (void *exit_ptr);
+extern osStatus_t       os_svcThreadTerminate    (osThreadId_t thread_id);
+extern int32_t          os_svcThreadFlagsSet     (osThreadId_t thread_id, int32_t flags);
+extern int32_t          os_svcThreadFlagsClear   (osThreadId_t thread_id, int32_t flags);
+extern int32_t          os_svcThreadFlagsGet     (osThreadId_t thread_id);
+extern int32_t          os_svcThreadFlagsWait    (int32_t flags, uint32_t options, uint32_t millisec);
+
+// Delay Service Calls
+extern osStatus_t       os_svcDelay      (uint32_t millisec);
+extern osStatus_t       os_svcDelayUntil (uint64_t millisec);
+
+// Timer Service Calls
+extern osTimerId_t      os_svcTimerNew       (os_timer_func_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr);
+extern osStatus_t       os_svcTimerStart     (osTimerId_t timer_id, uint32_t millisec);
+extern osStatus_t       os_svcTimerStop      (osTimerId_t timer_id);
+extern uint32_t         os_svcTimerIsRunning (osTimerId_t timer_id);
+extern osStatus_t       os_svcTimerDelete    (osTimerId_t timer_id);
+
+// Event Flags Service Calls
+extern osEventFlagsId_t os_svcEventFlagsNew    (const osEventFlagsAttr_t *attr);
+extern int32_t          os_svcEventFlagsSet    (osEventFlagsId_t ef_id, int32_t flags);
+extern int32_t          os_svcEventFlagsClear  (osEventFlagsId_t ef_id, int32_t flags);
+extern int32_t          os_svcEventFlagsGet    (osEventFlagsId_t ef_id);
+extern int32_t          os_svcEventFlagsWait   (osEventFlagsId_t ef_id, int32_t flags, uint32_t options, uint32_t millisec);
+extern osStatus_t       os_svcEventFlagsDelete (osEventFlagsId_t ef_id);
+
+// Mutex Service Calls
+extern osMutexId_t      os_svcMutexNew      (const osMutexAttr_t *attr);
+extern osStatus_t       os_svcMutexAcquire  (osMutexId_t mutex_id, uint32_t millisec);
+extern osStatus_t       os_svcMutexRelease  (osMutexId_t mutex_id);
+extern osThreadId_t     os_svcMutexGetOwner (osMutexId_t mutex_id);
+extern osStatus_t       os_svcMutexDelete   (osMutexId_t mutex_id);
+
+// Semaphore Service Calls
+extern osSemaphoreId_t  os_svcSemaphoreNew     (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr);
+extern osStatus_t       os_svcSemaphoreRelease (osSemaphoreId_t semaphore_id);
+extern osStatus_t       os_svcSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t millisec);
+extern uint32_t         os_svcSemaphoreGetCount(osSemaphoreId_t semaphore_id);
+extern osStatus_t       os_svcSemaphoreDelete  (osSemaphoreId_t semaphore_id);
+
+// Memory Pool Service Calls
+extern osMemoryPoolId_t os_svcMemoryPoolNew          (uint32_t blocks, uint32_t block_size, const osMemoryPoolAttr_t *attr);
+extern void *           os_svcMemoryPoolAlloc        (osMemoryPoolId_t mp_id, uint32_t millisec);
+extern osStatus_t       os_svcMemoryPoolFree         (osMemoryPoolId_t mp_id, void *block);
+extern uint32_t         os_svcMemoryPoolGetCapacity  (osMemoryPoolId_t mp_id);
+extern uint32_t         os_svcMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id);
+extern uint32_t         os_svcMemoryPoolGetCount     (osMemoryPoolId_t mp_id);
+extern uint32_t         os_svcMemoryPoolGetSpace     (osMemoryPoolId_t mp_id);
+extern osStatus_t       os_svcMemoryPoolDelete       (osMemoryPoolId_t mp_id);
+
+// Message Queue Service Calls
+extern osMessageQueueId_t os_svcMessageQueueNew         (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr);
+extern osStatus_t         os_svcMessageQueuePut         (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t  msg_prio, uint32_t millisec);
+extern osStatus_t         os_svcMessageQueueGet         (osMessageQueueId_t mq_id,       void *msg_ptr, uint8_t *msg_prio, uint32_t millisec);
+extern uint32_t           os_svcMessageQueueGetCapacity (osMessageQueueId_t mq_id);
+extern uint32_t           os_svcMessageQueueGetMsgSize  (osMessageQueueId_t mq_id);
+extern uint32_t           os_svcMessageQueueGetCount    (osMessageQueueId_t mq_id);
+extern uint32_t           os_svcMessageQueueGetSpace    (osMessageQueueId_t mq_id);
+extern osStatus_t         os_svcMessageQueueReset       (osMessageQueueId_t mq_id);
+extern osStatus_t         os_svcMessageQueueDelete      (osMessageQueueId_t mq_id);
+
+
+#endif  // __RTX_LIB_H
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_memory.c b/CMSIS/RTOS2/RTX/Source/rtx_memory.c
new file mode 100644
index 0000000..52e7aea
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/rtx_memory.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       Memory functions
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#include "rtx_lib.h"
+
+
+//  Memory Pool Header structure
+typedef struct mem_head_s {
+  uint32_t size;                // Memory Pool size
+  uint32_t used;                // Used Memory
+} mem_head_t;
+
+//  Memory Block Header structure
+typedef struct mem_block_s {
+  struct mem_block_s *next;     // Next Memory Block in list
+  uint32_t             len;     // Memory Block length
+} mem_block_t;
+
+
+//  ==== Library functions ====
+
+/// Initialize Memory Pool with variable block size.
+/// \param[in]  mem             pointer to memory pool.
+/// \param[in]  size            size of a memory pool in bytes.
+/// \return 1 - success, 0 - failure.
+uint32_t os_MemoryInit (void *mem, uint32_t size) {
+  mem_head_t  *head;
+  mem_block_t *ptr;
+
+  if ((mem == NULL) || ((uint32_t)mem & 3U) || (size & 3U) ||
+      (size < (sizeof(mem_head_t) + sizeof(mem_block_t) + sizeof(mem_block_t *)))) {
+    return 0U;
+  }
+
+  head = (mem_head_t *)mem;
+  head->size = size;
+  head->used = sizeof(mem_head_t) + sizeof(mem_block_t *);
+
+  ptr = (mem_block_t *)((uint32_t)mem + sizeof(mem_head_t));
+  ptr->next = (mem_block_t *)((uint32_t)mem + size - sizeof(mem_block_t *));
+  ptr->next->next = NULL;
+  ptr->len = 0U;
+
+  return 1U;
+}
+
+/// Allocate a memory block from a Memory Pool.
+/// \param[in]  mem             pointer to memory pool.
+/// \param[in]  size            size of a memory block in bytes.
+/// \return allocated memory block or NULL in case of no memory is available.
+void *os_MemoryAlloc (void *mem, uint32_t size) {
+  mem_block_t *p, *p_new, *ptr;
+  uint32_t     hole_size;
+
+  if ((mem == NULL) || (size == 0U)) {
+    return NULL;
+  }
+
+  // Add header to size
+  size += sizeof(mem_block_t);
+  // Make sure that block is 4-byte aligned
+  size = (size + 3U) & ~((uint32_t)3U);
+
+  // Search for hole big enough
+  p = (mem_block_t *)((uint32_t)mem + sizeof(mem_head_t));
+  for (;;) {
+    hole_size  = (uint32_t)p->next - (uint32_t)p;
+    hole_size -= p->len;
+    if (hole_size >= size) {
+      // Hole found
+      break;
+    }
+    p = p->next;
+    if (p->next == NULL) {
+      // Failed (end of list)
+      return NULL;
+    }
+  }
+
+  ((mem_head_t *)mem)->used += size;
+
+  if (p->len == 0U) {
+    // No block allocated, set length of first element
+    p->len = size;
+    ptr = (mem_block_t *)((uint32_t)p + sizeof(mem_block_t));
+  } else {
+    // Insert new element into the list
+    p_new = (mem_block_t *)((uint32_t)p + p->len);
+    p_new->next = p->next;
+    p_new->len  = size;
+    p->next = p_new;
+    ptr = (mem_block_t *)((uint32_t)p_new + sizeof(mem_block_t));
+  }
+
+  return ptr;
+}
+
+/// Return an allocated memory block back to a Memory Pool.
+/// \param[in]  mem             pointer to memory pool.
+/// \param[in]  block           memory block to be returned to the memory pool.
+/// \return 1 - success, 0 - failure.
+uint32_t os_MemoryFree (void *mem, void *block) {
+  mem_block_t *p, *p_prev, *ptr;
+
+  if ((mem == NULL) || (block == NULL)) {
+    return 0U;
+  }
+
+  ptr = (mem_block_t *)((uint32_t)block - sizeof(mem_block_t));
+
+  // Search for header
+  p_prev = NULL;
+  p = (mem_block_t *)((uint32_t)mem + sizeof(mem_head_t));
+  while (p != ptr) {
+    p_prev = p;
+    p = p->next;
+    if (p == NULL) {
+      // Not found
+      return 0U;
+    }
+  }
+
+  ((mem_head_t *)mem)->used -= p->len;
+
+  if (p_prev == NULL) {
+    // Release first block, only set len to 0
+    p->len = 0U;
+  } else {
+    // Discard block from chained list
+    p_prev->next = p->next;
+  }
+
+  return 0U;
+}
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_mempool.c b/CMSIS/RTOS2/RTX/Source/rtx_mempool.c
new file mode 100644
index 0000000..7f95f65
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/rtx_mempool.c
@@ -0,0 +1,648 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       Memory Pool functions
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#include "rtx_lib.h"
+
+
+//  ==== Library functions ====
+
+/// Initialize Memory Pool.
+/// \param[in]  mp_info         memory pool info.
+/// \param[in]  block_count     maximum number of memory blocks in memory pool.
+/// \param[in]  block_size      size of a memory block in bytes.
+/// \param[in]  block_mem       pointer to memory for block storage.
+/// \return 1 - success, 0 - failure.
+uint32_t os_MemoryPoolInit (os_mp_info_t *mp_info, uint32_t block_count, uint32_t block_size, void *block_mem) {
+  void *block;
+
+  // Check parameters
+  if ((mp_info     == NULL) ||
+      (block_count == 0U)   ||
+      (block_size  == 0U)   ||
+      (block_mem   == NULL)) {
+    return 0U;
+  }
+
+  // Initialize information structure
+  mp_info->max_blocks  = block_count;
+  mp_info->used_blocks = 0U;
+  mp_info->block_size  = block_size;
+  mp_info->block_base  = block_mem;
+  mp_info->block_free  = block_mem;
+  mp_info->block_lim   = (uint8_t *)block_mem + (block_count * block_size);
+
+  // Link all free blocks
+  while (--block_count) {
+    block = (uint8_t *)block_mem + block_size;
+    *((void **)block_mem) = block;
+    block_mem = block;
+  }
+  *((void **)block_mem) = NULL;
+
+  return 1U;
+}
+
+/// Allocate a memory block from a Memory Pool.
+/// \param[in]  mp_info         memory pool info.
+/// \return address of the allocated memory block or NULL in case of no memory is available.
+void *os_MemoryPoolAlloc (os_mp_info_t *mp_info) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+  uint32_t primask = __get_PRIMASK();
+#endif
+  void *block;
+
+  if (mp_info == NULL) {
+    return NULL;
+  }
+
+#ifdef __NO_EXCLUSIVE_ACCESS
+  __disable_irq();
+
+  block = mp_info->block_free;
+  if (block != NULL) {
+    mp_info->block_free = *((void **)block);
+    mp_info->used_blocks++;
+  }
+
+  if (primask == 0U) {
+    __enable_irq();
+  }
+#else
+  {
+    register uint32_t val, res;
+
+    __ASM volatile (
+    "loop1%=:\n\t"
+      "ldrex %[block],[%[mp_info],%[_block_free]]\n\t"
+      "cbnz  %[block],update%=\n\t"
+      "clrex\n\t"
+      "b     exit%=\n\t"
+    "update%=:\n\t"
+      "ldr   %[val],[%[block]]\n\t"
+      "strex %[res],%[val],[%[mp_info],%[_block_free]]\n\t"
+      "cbz   %[res],loop2%=\n\t"
+      "b     loop1%=\n\t"
+    "loop2%=:\n\t"
+      "ldrex %[val],[%[mp_info],%[_used_blocks]]\n\t"
+      "adds  %[val],#1\n\t"
+      "strex %[res],%[val],[%[mp_info],%[_used_blocks]]\n\t"
+      "cbz   %[res],exit%=\n\t"
+      "b     loop2%=\n\t"
+    "exit%=:"
+    : [block]        "=&l" (block),
+      [val]          "=&l" (val),
+      [res]          "=&l" (res)
+    : [mp_info]      "l"   (mp_info),
+      [_block_free]  "I"   (offsetof(os_mp_info_t, block_free)),
+      [_used_blocks] "I"   (offsetof(os_mp_info_t, used_blocks))
+    : "cc", "memory"
+    );
+  }
+#endif
+
+  return block;
+}
+
+/// Return an allocated memory block back to a Memory Pool.
+/// \param[in]  mp_info         memory pool info.
+/// \param[in]  block           address of the allocated memory block to be returned to the memory pool.
+/// \return status code that indicates the execution status of the function.
+osStatus_t os_MemoryPoolFree (os_mp_info_t *mp_info, void *block) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+  uint32_t primask = __get_PRIMASK();
+#endif
+
+  if (mp_info == NULL) {
+    return osErrorParameter;
+  }
+  if ((block < mp_info->block_base) || (block >= mp_info->block_lim)) {
+    return osErrorParameter;
+  }
+
+#ifdef __NO_EXCLUSIVE_ACCESS
+  __disable_irq();
+
+  *((void **)block) = mp_info->block_free;
+  mp_info->block_free = block;
+  mp_info->used_blocks--;
+
+  if (primask == 0U) {
+    __enable_irq();
+  }
+#else
+  {
+    register uint32_t val1, val2, res;
+
+    __ASM volatile (
+    "loop1%=:\n\t"
+      "ldr   %[val1],[%[mp_info],%[_block_free]]\n\t"
+      "str   %[val1],[%[block]]\n\t"
+      "dmb\n\t"
+      "ldrex %[val1],[%[mp_info],%[_block_free]]\n\t"
+      "ldr   %[val2],[%[block]]\n\t"
+      "cmp   %[val2],%[val1]\n\t"
+      "bne   loop1%=\n\t"
+      "strex %[res],%[block],[%[mp_info],%[_block_free]]\n\t"
+      "cbz   %[res],loop2%=\n\t"
+      "b     loop1%=\n\t"
+    "loop2%=:\n\t"
+      "ldrex %[val1],[%[mp_info],%[_used_blocks]]\n\t"
+      "subs  %[val1],#1\n\t"
+      "strex %[res],%[val1],[%[mp_info],%[_used_blocks]]\n\t"
+      "cbz   %[res],exit%=\n\t"
+      "b     loop2%=\n\t"
+    "exit%=:"
+    : [val1]         "=&l" (val1),
+      [val2]         "=&l" (val2),
+      [res]          "=&l" (res)
+    : [block]        "l"   (block),
+      [mp_info]      "l"   (mp_info),
+      [_block_free]  "I"   (offsetof(os_mp_info_t, block_free)),
+      [_used_blocks] "I"   (offsetof(os_mp_info_t, used_blocks))
+    : "cc", "memory"
+    );
+  }
+#endif
+
+  return osOK;
+}
+
+/// Memory Pool post ISR processing.
+/// \param[in]  mp              memory pool object.
+void os_MemoryPoolPostProcess (os_memory_pool_t *mp) {
+  void        *block;
+  os_thread_t *thread;
+
+  if (mp->state == os_ObjectInactive) {
+    return;
+  }
+
+  // Check if Thread is waiting to allocate memory
+  if (mp->thread_list != NULL) {
+    // Allocate memory
+    block = os_MemoryPoolAlloc(&mp->mp_info);
+    if (block != NULL) {
+      // Wakeup waiting Thread with highest Priority
+      thread = os_ThreadListGet((os_object_t*)mp);
+      os_ThreadWaitExit(thread, (uint32_t)block, false);
+    }
+  }
+}
+
+
+//  ==== Service Calls ====
+
+//  Service Calls definitions
+SVC0_3(MemoryPoolNew,          osMemoryPoolId_t, uint32_t, uint32_t, const osMemoryPoolAttr_t *)
+SVC0_2(MemoryPoolAlloc,        void *,           osMemoryPoolId_t, uint32_t)
+SVC0_2(MemoryPoolFree,         osStatus_t,       osMemoryPoolId_t, void *)
+SVC0_1(MemoryPoolGetCapacity,  uint32_t,         osMemoryPoolId_t)
+SVC0_1(MemoryPoolGetBlockSize, uint32_t,         osMemoryPoolId_t)
+SVC0_1(MemoryPoolGetCount,     uint32_t,         osMemoryPoolId_t)
+SVC0_1(MemoryPoolGetSpace,     uint32_t,         osMemoryPoolId_t)
+SVC0_1(MemoryPoolDelete,       osStatus_t,       osMemoryPoolId_t)
+
+/// Create and Initialize a Memory Pool object.
+/// \note API identical to osMemoryPoolNew
+osMemoryPoolId_t os_svcMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) {
+  os_memory_pool_t *mp;
+  void             *mp_mem;
+  uint32_t          mp_size;
+  uint32_t          size;
+  uint8_t           flags;
+  const char       *name;
+
+  // Check parameters
+  if ((block_count == 0U) ||
+      (block_size  == 0U)) {
+    return (osMemoryPoolId_t)NULL;
+  }
+  block_size = (block_size + 3U) & ~3UL;
+  if ((__CLZ(block_count) + __CLZ(block_size)) < 32) {
+    return (osMemoryPoolId_t)NULL;
+  }
+
+  size = block_count * block_size;
+
+  // Process attributes
+  if (attr != NULL) {
+    name    = attr->name;
+    mp      = attr->cb_mem;
+    mp_mem  = attr->mp_mem;
+    mp_size = attr->mp_size;
+    if (mp != NULL) {
+      if (((uint32_t)mp & 3U) || (attr->cb_size < sizeof(os_memory_pool_t))) {
+        return (osMemoryPoolId_t)NULL;
+      }
+    } else {
+      if (attr->cb_size != 0U) {
+        return (osMemoryPoolId_t)NULL;
+      }
+    }
+    if (mp_mem != NULL) {
+      if (((uint32_t)mp_mem & 3U) || (mp_size < size)) {
+        return (osMemoryPoolId_t)NULL;
+      }
+    } else {
+      if (mp_size != 0U) {
+        return (osMemoryPoolId_t)NULL;
+      }
+    }
+  } else {
+    name   = NULL;
+    mp     = NULL;
+    mp_mem = NULL;
+  }
+
+  // Allocate object memory if not provided
+  if (mp == NULL) {
+    if (os_Info.mpi.memory_pool != NULL) {
+      mp = os_MemoryPoolAlloc(os_Info.mpi.memory_pool);
+    } else {
+      mp = os_MemoryAlloc(os_Info.mem.cb, sizeof(os_memory_pool_t));
+    }
+    if (mp == NULL) {
+      return (osMemoryPoolId_t)NULL;
+    }
+    flags = os_FlagSystemObject;
+  } else {
+    flags = 0U;
+  }
+
+  // Allocate data memory if not provided
+  if (mp_mem == NULL) {
+    mp_mem = os_MemoryAlloc(os_Info.mem.data, size);
+    if (mp_mem == NULL) {
+      if (flags & os_FlagSystemObject) {
+        if (os_Info.mpi.memory_pool != NULL) {
+          os_MemoryPoolFree(os_Info.mpi.memory_pool, mp);
+        } else {
+          os_MemoryFree(os_Info.mem.cb, mp);
+        }
+      }
+      return (osMemoryPoolId_t)NULL;
+    }
+    memset(mp_mem, 0, size);
+    flags |= os_FlagSystemMemory;
+  }
+
+  // Initialize control block
+  mp->id          = os_IdMemoryPool;
+  mp->state       = os_ObjectActive;
+  mp->flags       = flags;
+  mp->name        = name;
+  mp->thread_list = NULL;
+  os_MemoryPoolInit(&mp->mp_info, block_count, block_size, mp_mem);
+
+  // Register post ISR processing function
+  os_Info.post_process.memory_pool = os_MemoryPoolPostProcess;
+
+  return (osMemoryPoolId_t)mp;
+}
+
+/// Allocate a memory block from a Memory Pool.
+/// \note API identical to osMemoryPoolAlloc
+void *os_svcMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t millisec) {
+  os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
+  void             *block;
+
+  // Check parameters
+  if ((mp == NULL) ||
+      (mp->id != os_IdMemoryPool)) {
+    return NULL;
+  }
+
+  // Check object state
+  if (mp->state == os_ObjectInactive) {
+    return NULL;
+  }
+
+  // Allocate memory
+  block = os_MemoryPoolAlloc(&mp->mp_info);
+  if (block == NULL) {
+    // No memory available
+    if (millisec != 0U) {
+      // Suspend current Thread
+      os_ThreadListPut((os_object_t*)mp, os_ThreadGetRunning());
+      os_ThreadWaitEnter(os_ThreadWaitingMemoryPool, millisec);
+    }
+  }
+
+  return block;
+}
+
+/// Return an allocated memory block back to a Memory Pool.
+/// \note API identical to osMemoryPoolFree
+osStatus_t os_svcMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) {
+  os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
+  os_thread_t      *thread;
+  osStatus_t        status;
+
+  // Check parameters
+  if ((mp == NULL) ||
+      (mp->id != os_IdMemoryPool)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (mp->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Free memory
+  status = os_MemoryPoolFree(&mp->mp_info, block);
+  if (status == osOK) {
+    // Check if Thread is waiting to allocate memory
+    if (mp->thread_list != NULL) {
+      // Allocate memory
+      block = os_MemoryPoolAlloc(&mp->mp_info);
+      if (block != NULL) {
+        // Wakeup waiting Thread with highest Priority
+        thread = os_ThreadListGet((os_object_t*)mp);
+        os_ThreadWaitExit(thread, (uint32_t)block, true);
+      }
+    }
+  }
+
+  return status;
+}
+
+/// Get maximum number of memory blocks in a Memory Pool.
+/// \note API identical to osMemoryPoolGetCapacity
+uint32_t os_svcMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) {
+  os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
+
+  // Check parameters
+  if ((mp == NULL) ||
+      (mp->id != os_IdMemoryPool)) {
+    return 0U;
+  }
+
+  // Check object state
+  if (mp->state == os_ObjectInactive) {
+    return 0U;
+  }
+
+  return mp->mp_info.max_blocks;
+}
+
+/// Get memory block size in a Memory Pool.
+/// \note API identical to osMemoryPoolGetBlockSize
+uint32_t os_svcMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) {
+  os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
+
+  // Check parameters
+  if ((mp == NULL) ||
+      (mp->id != os_IdMemoryPool)) {
+    return 0U;
+  }
+
+  // Check object state
+  if (mp->state == os_ObjectInactive) {
+    return 0U;
+  }
+
+  return mp->mp_info.block_size;
+}
+
+/// Get number of memory blocks used in a Memory Pool.
+/// \note API identical to osMemoryPoolGetCount
+uint32_t os_svcMemoryPoolGetCount (osMemoryPoolId_t mp_id) {
+  os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
+
+  // Check parameters
+  if ((mp == NULL) ||
+      (mp->id != os_IdMemoryPool)) {
+    return 0U;
+  }
+
+  // Check object state
+  if (mp->state == os_ObjectInactive) {
+    return 0U;
+  }
+
+  return mp->mp_info.used_blocks;
+}
+
+/// Get number of memory blocks available in a Memory Pool.
+/// \note API identical to osMemoryPoolGetSpace
+uint32_t os_svcMemoryPoolGetSpace (osMemoryPoolId_t mp_id) {
+  os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
+
+  // Check parameters
+  if ((mp == NULL) ||
+      (mp->id != os_IdMemoryPool)) {
+    return 0U;
+  }
+
+  // Check object state
+  if (mp->state == os_ObjectInactive) {
+    return 0U;
+  }
+
+  return (mp->mp_info.max_blocks - mp->mp_info.used_blocks);
+}
+
+/// Delete a Memory Pool object.
+/// \note API identical to osMemoryPoolDelete
+osStatus_t os_svcMemoryPoolDelete (osMemoryPoolId_t mp_id) {
+  os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
+  os_thread_t      *thread;
+
+  // Check parameters
+  if ((mp == NULL) ||
+      (mp->id != os_IdMemoryPool)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (mp->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Mark object as inactive
+  mp->state = os_ObjectInactive;
+
+  // Unblock waiting threads
+  if (mp->thread_list != NULL) {
+    do {
+      thread = os_ThreadListGet((os_object_t*)mp);
+      os_ThreadWaitExit(thread, 0U, false);
+    } while (mp->thread_list != NULL);
+    os_ThreadDispatch(NULL);
+  }
+
+  // Free data memory
+  if (mp->flags & os_FlagSystemMemory) {
+    os_MemoryFree(os_Info.mem.data, mp->mp_info.block_base);
+  }
+
+  // Free object memory
+  if (mp->flags & os_FlagSystemObject) {
+    if (os_Info.mpi.memory_pool != NULL) {
+      os_MemoryPoolFree(os_Info.mpi.memory_pool, mp);
+    } else {
+      os_MemoryFree(os_Info.mem.cb, mp);
+    }
+  }
+
+  return osOK;
+}
+
+
+//  ==== ISR Calls ====
+
+/// Allocate a memory block from a Memory Pool.
+/// \note API identical to osMemoryPoolAlloc
+__STATIC_INLINE
+void *os_isrMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t millisec) {
+  os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
+  void             *block;
+
+  // Check parameters
+  if ((mp == NULL) ||
+      (mp->id != os_IdMemoryPool)) {
+    return NULL;
+  }
+  if (millisec != 0U) {
+    return NULL;
+  }
+
+  // Check object state
+  if (mp->state == os_ObjectInactive) {
+    return NULL;
+  }
+
+  // Allocate memory
+  block = os_MemoryPoolAlloc(&mp->mp_info);
+
+  return block;
+}
+
+/// Return an allocated memory block back to a Memory Pool.
+/// \note API identical to osMemoryPoolFree
+__STATIC_INLINE
+osStatus_t os_isrMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) {
+  os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
+  osStatus_t        status;
+
+  // Check parameters
+  if ((mp == NULL) ||
+      (mp->id != os_IdMemoryPool)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (mp->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Free memory
+  status = os_MemoryPoolFree(&mp->mp_info, block);
+  if (status == osOK) {
+    // Register post ISR processing
+    os_PostProcess((os_object_t *)mp);
+  }
+
+  return status;
+}
+
+
+//  ==== Public API ====
+
+/// Create and Initialize a Memory Pool object.
+osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) {
+  if (__get_IPSR() != 0U) {
+    return (osMemoryPoolId_t)NULL;              // Not allowed in ISR
+  }
+  if ((os_KernelGetState() == os_KernelReady) && ((__get_CONTROL() & 1U) == 0U)) {
+    // Kernel Ready (not running) and in Privileged mode
+    return os_svcMemoryPoolNew(block_count, block_size, attr);
+  } else {
+    return  __svcMemoryPoolNew(block_count, block_size, attr);
+  }
+}
+
+/// Allocate a memory block from a Memory Pool.
+void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t millisec) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_isrMemoryPoolAlloc(mp_id, millisec);
+  } else {                                      // in Thread
+    return  __svcMemoryPoolAlloc(mp_id, millisec);
+  }
+}
+
+/// Return an allocated memory block back to a Memory Pool.
+osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_isrMemoryPoolFree(mp_id, block);
+  } else {                                      // in Thread
+    return  __svcMemoryPoolFree(mp_id, block);
+  }
+}
+
+/// Get maximum number of memory blocks in a Memory Pool.
+uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_svcMemoryPoolGetCapacity(mp_id);
+  } else {                                      // in Thread
+    return  __svcMemoryPoolGetCapacity(mp_id);
+  }
+}
+
+/// Get memory block size in a Memory Pool.
+uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_svcMemoryPoolGetBlockSize(mp_id);
+  } else {                                      // in Thread
+    return  __svcMemoryPoolGetBlockSize(mp_id);
+  }
+}
+
+/// Get number of memory blocks used in a Memory Pool.
+uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_svcMemoryPoolGetCount(mp_id);
+  } else {                                      // in Thread
+    return  __svcMemoryPoolGetCount(mp_id);
+  }
+}
+
+/// Get number of memory blocks available in a Memory Pool.
+uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_svcMemoryPoolGetSpace(mp_id);
+  } else {                                      // in Thread
+    return  __svcMemoryPoolGetSpace(mp_id);
+  }
+}
+
+/// Delete a Memory Pool object.
+osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcMemoryPoolDelete(mp_id);
+}
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_msgqueue.c b/CMSIS/RTOS2/RTX/Source/rtx_msgqueue.c
new file mode 100644
index 0000000..83376ab
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/rtx_msgqueue.c
@@ -0,0 +1,828 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       Message Queue functions
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#include "rtx_lib.h"
+
+
+//  ==== Helper functions ====
+
+/// Put a Message into Queue sorted by Priority (Highest at Head).
+/// \param[in]  mq              message queue object.
+/// \param[in]  msg             message object.
+static void os_MessageQueuePut (os_message_queue_t *mq, os_message_t *msg) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+  uint32_t      primask = __get_PRIMASK();
+#endif
+  os_message_t *prev, *next;
+
+  if (mq->msg_last != NULL) {
+    prev = mq->msg_last;
+    next = NULL;
+    while ((prev != NULL) && (prev->priority < msg->priority)) {
+      next = prev;
+      prev = prev->prev;
+    }
+    msg->prev = prev;
+    msg->next = next;
+    if (prev != NULL) {
+      prev->next = msg;
+    } else {
+      mq->msg_first = msg;
+    }
+    if (next != NULL) {
+      next->prev = msg;
+    } else {
+      mq->msg_last = msg;
+    }
+  } else {
+    msg->prev = NULL;
+    msg->next = NULL;
+    mq->msg_first= msg;
+    mq->msg_last = msg;
+  }
+
+#ifdef __NO_EXCLUSIVE_ACCESS
+  __disable_irq();
+
+  mq->msg_count++;
+
+  if (primask == 0U) {
+    __enable_irq();
+  }
+#else
+  os_exc_inc32(&mq->msg_count);
+#endif
+}
+
+/// Get a Message from Queue with Highest Priority.
+/// \param[in]  mq              message queue object.
+/// \return message object or NULL.
+static os_message_t *os_MessageQueueGet (os_message_queue_t *mq) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+  uint32_t      primask = __get_PRIMASK();
+#endif
+  os_message_t *msg;
+  uint32_t      count;
+  uint8_t       flags;
+
+#ifdef __NO_EXCLUSIVE_ACCESS
+  __disable_irq();
+
+  count = mq->msg_count;
+  if (count != 0U) {
+    mq->msg_count--;
+  }
+
+  if (primask == 0U) {
+    __enable_irq();
+  }
+#else
+  count = os_exc_dec32_nz(&mq->msg_count);
+#endif
+
+  if (count == 0U) {
+    return NULL;
+  }
+
+  msg = mq->msg_first;
+
+  while (msg != NULL) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+    __disable_irq();
+
+    flags = msg->flags;
+    msg->flags = 1U;
+
+    if (primask == 0U) {
+      __enable_irq();
+    }
+#else
+    flags = os_exc_wr8(&msg->flags, 1U);
+#endif
+    if (flags == 0U) {
+      break;
+    }
+    msg = msg->next;
+  }
+
+  return msg;
+}
+
+/// Remove a Message from Queue
+/// \param[in]  mq              message queue object.
+/// \param[in]  msg             message object.
+static void os_MessageQueueRemove (os_message_queue_t *mq, os_message_t *msg) {
+
+  if (msg->prev != NULL) {
+    msg->prev->next = msg->next;
+  } else {
+    mq->msg_first = msg->next;
+  }
+  if (msg->next != NULL) {
+    msg->next->prev = msg->prev;
+  } else {
+    mq->msg_last = msg->prev;
+  }
+}
+
+
+//  ==== Library functions ====
+
+/// Message Queue post ISR processing.
+/// \param[in]  msg             message object.
+void os_MessageQueuePostProcess (os_message_t *msg) {
+  os_message_queue_t *mq;
+  os_thread_t        *thread;
+  uint32_t           *reg;
+  void              **ptr;
+
+  if (msg->state == os_ObjectInactive) {
+    return;
+  }
+
+  if (msg->flags != 0U) {
+    // Remove Message
+    ptr = (void *)((uint8_t *)msg + sizeof(os_message_t));
+    mq = *ptr;
+    if (mq->state == os_ObjectInactive) {
+      return;
+    }
+    os_MessageQueueRemove(mq, msg);
+    // Free memory
+    msg->state = os_ObjectInactive;
+    os_MemoryPoolFree(&mq->mp_info, msg);
+    // Check if Thread is waiting to send a Message
+    if ((mq->thread_list != NULL) && (mq->thread_list->state == os_ThreadWaitingMessagePut)) {
+      // Try to allocate memory
+      msg = os_MemoryPoolAlloc(&mq->mp_info);
+      if (msg != NULL) {
+        // Wakeup waiting Thread with highest Priority
+        thread = os_ThreadListGet((os_object_t*)mq);
+        os_ThreadWaitExit(thread, (uint32_t)osOK, false);
+        // Copy Message (R1 = const void *msg_ptr, R2 = msg_prio)
+        reg = os_ThreadRegPtr(thread);
+        memcpy((uint8_t *)msg + sizeof(os_message_t), (void *)reg[1], mq->msg_size);
+        // Store Message into Queue
+        msg->id       = os_IdMessage;
+        msg->state    = os_ObjectActive;
+        msg->flags    = 0U;
+        msg->priority = (uint8_t)reg[2];
+        os_MessageQueuePut(mq, msg);
+      }
+    }
+  } else {
+    // New Message
+    ptr = (void *)((uint8_t *)msg + sizeof(os_message_t) - sizeof(os_message_queue_t *));
+    mq = *ptr;
+    if (mq->state == os_ObjectInactive) {
+      return;
+    }
+    // Check if Thread is waiting to receive a Message
+    if ((mq->thread_list != NULL) && (mq->thread_list->state == os_ThreadWaitingMessageGet)) {
+      // Wakeup waiting Thread with highest Priority
+      thread = os_ThreadListGet((os_object_t*)mq);
+      os_ThreadWaitExit(thread, (uint32_t)osOK, false);
+      // Copy Message (R1 = void *msg_ptr, R2 = *msg_prio)
+      reg = os_ThreadRegPtr(thread);
+      memcpy((void *)reg[1], (uint8_t *)msg + sizeof(os_message_t), mq->msg_size);
+      if (reg[2] != 0U) {
+        *((uint8_t *)reg[2]) = msg->priority;
+      }
+      // Free memory
+      msg->state = os_ObjectInactive;
+      os_MemoryPoolFree(&mq->mp_info, msg);
+    } else {
+      os_MessageQueuePut(mq, msg);
+    }
+  }
+}
+
+
+//  ==== Service Calls ====
+
+SVC0_3(MessageQueueNew,         osMessageQueueId_t, uint32_t, uint32_t, const osMessageQueueAttr_t *)
+SVC0_4(MessageQueuePut,         osStatus_t,         osMessageQueueId_t, const void *, uint8_t,   uint32_t)
+SVC0_4(MessageQueueGet,         osStatus_t,         osMessageQueueId_t,       void *, uint8_t *, uint32_t)
+SVC0_1(MessageQueueGetCapacity, uint32_t,           osMessageQueueId_t)
+SVC0_1(MessageQueueGetMsgSize,  uint32_t,           osMessageQueueId_t)
+SVC0_1(MessageQueueGetCount,    uint32_t,           osMessageQueueId_t)
+SVC0_1(MessageQueueGetSpace,    uint32_t,           osMessageQueueId_t)
+SVC0_1(MessageQueueReset,       osStatus_t,         osMessageQueueId_t)
+SVC0_1(MessageQueueDelete,      osStatus_t,         osMessageQueueId_t)
+
+/// Create and Initialize a Message Queue object.
+/// \note API identical to osMessageQueueNew
+osMessageQueueId_t os_svcMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) {
+  os_message_queue_t *mq;
+  void               *mq_mem;
+  uint32_t            mq_size;
+  uint32_t            block_size;
+  uint32_t            size;
+  uint8_t             flags;
+  const char         *name;
+
+  // Check parameters
+  if ((msg_count == 0U) ||
+      (msg_size  == 0U)) {
+    return (osMessageQueueId_t)NULL;
+  }
+  msg_size = (msg_size + 3U) & ~3UL;
+  block_size = msg_size + sizeof(os_message_t);
+  if ((__CLZ(msg_count) + __CLZ(block_size)) < 32) {
+    return (osMessageQueueId_t)NULL;
+  }
+
+  size = msg_count * block_size;
+
+  // Process attributes
+  if (attr != NULL) {
+    name    = attr->name;
+    mq      = attr->cb_mem;
+    mq_mem  = attr->mq_mem;
+    mq_size = attr->mq_size;
+    if (mq != NULL) {
+      if (((uint32_t)mq & 3U) || (attr->cb_size < sizeof(os_message_queue_t))) {
+        return (osMessageQueueId_t)NULL;
+      }
+    } else {
+      if (attr->cb_size != 0U) {
+        return (osMessageQueueId_t)NULL;
+      }
+    }
+    if (mq_mem != NULL) {
+      if (((uint32_t)mq_mem & 3U) || (mq_size < size)) {
+        return (osMessageQueueId_t)NULL;
+      }
+    } else {
+      if (mq_size != 0U) {
+        return (osMessageQueueId_t)NULL;
+      }
+    }
+  } else {
+    name   = NULL;
+    mq     = NULL;
+    mq_mem = NULL;
+  }
+
+  // Allocate object memory if not provided
+  if (mq == NULL) {
+    if (os_Info.mpi.message_queue != NULL) {
+      mq = os_MemoryPoolAlloc(os_Info.mpi.message_queue);
+    } else {
+      mq = os_MemoryAlloc(os_Info.mem.cb, sizeof(os_message_queue_t));
+    }
+    if (mq == NULL) {
+      return (osMessageQueueId_t)NULL;
+    }
+    flags = os_FlagSystemObject;
+  } else {
+    flags = 0U;
+  }
+
+  // Allocate data memory if not provided
+  if (mq_mem == NULL) {
+    mq_mem = os_MemoryAlloc(os_Info.mem.data, size);
+    if (mq_mem == NULL) {
+      if (flags & os_FlagSystemObject) {
+        if (os_Info.mpi.message_queue != NULL) {
+          os_MemoryPoolFree(os_Info.mpi.message_queue, mq);
+        } else {
+          os_MemoryFree(os_Info.mem.cb, mq);
+        }
+      }
+      return (osMessageQueueId_t)NULL;
+    }
+    memset(mq_mem, 0, size);
+    flags |= os_FlagSystemMemory;
+  }
+
+  // Initialize control block
+  mq->id          = os_IdMessageQueue;
+  mq->state       = os_ObjectActive;
+  mq->flags       = flags;
+  mq->name        = name;
+  mq->thread_list = NULL;
+  mq->msg_size    = msg_size;
+  mq->msg_count   = 0U;
+  mq->msg_first   = NULL;
+  mq->msg_last    = NULL;
+  os_MemoryPoolInit(&mq->mp_info, msg_count, block_size, mq_mem);
+
+  // Register post ISR processing function
+  os_Info.post_process.message_queue = os_MessageQueuePostProcess;
+
+  return (osMessageQueueId_t)mq;
+}
+
+/// Put a Message into a Queue or timeout if Queue is full.
+/// \note API identical to osMessageQueuePut
+osStatus_t os_svcMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t millisec) {
+  os_message_queue_t *mq = (os_message_queue_t *)mq_id;
+  os_message_t       *msg;
+  os_thread_t        *thread;
+  uint32_t           *reg;
+
+  // Check parameters
+  if ((mq == NULL) ||
+      (mq->id != os_IdMessageQueue)) {
+    return osErrorParameter;
+  }
+  if (msg_ptr == NULL) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (mq->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Check if Thread is waiting to receive a Message
+  if ((mq->thread_list != NULL) && (mq->thread_list->state == os_ThreadWaitingMessageGet)) {
+    // Wakeup waiting Thread with highest Priority
+    thread = os_ThreadListGet((os_object_t*)mq);
+    os_ThreadWaitExit(thread, (uint32_t)osOK, true);
+    // Copy Message (R1 = void *msg_ptr, R2 = *msg_prio)
+    reg = os_ThreadRegPtr(thread);
+    memcpy((void *)reg[1], msg_ptr, mq->msg_size);
+    if (reg[2] != 0U) {
+      *((uint8_t *)reg[2]) = msg_prio;
+    }
+    return osOK;
+  }
+
+  // Try to allocate memory
+  msg = os_MemoryPoolAlloc(&mq->mp_info);
+  if (msg != NULL) {
+    // Copy Message
+    memcpy((uint8_t *)msg + sizeof(os_message_t), msg_ptr, mq->msg_size);
+    // Put Message into Queue
+    msg->id       = os_IdMessage;
+    msg->state    = os_ObjectActive;
+    msg->flags    = 0U;
+    msg->priority = msg_prio;
+    os_MessageQueuePut(mq, msg);
+  } else {
+    // No memory available
+    if (millisec != 0U) {
+      // Suspend current Thread
+      os_ThreadListPut((os_object_t*)mq, os_ThreadGetRunning());
+      os_ThreadWaitEnter(os_ThreadWaitingMessagePut, millisec);
+      return osErrorTimeout;
+    } else {
+      return osErrorResource;
+    }
+  }
+
+  return osOK;
+}
+
+/// Get a Message from a Queue or timeout if Queue is empty.
+/// \note API identical to osMessageQueueGet
+osStatus_t os_svcMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t millisec) {
+  os_message_queue_t *mq = (os_message_queue_t *)mq_id;
+  os_message_t       *msg;
+  os_thread_t        *thread;
+  uint32_t           *reg;
+
+  // Check parameters
+  if ((mq == NULL) ||
+      (mq->id != os_IdMessageQueue)) {
+    return osErrorParameter;
+  }
+  if (msg_ptr == NULL) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (mq->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Get Message from Queue
+  msg = os_MessageQueueGet(mq);
+  if (msg != NULL) {
+    os_MessageQueueRemove(mq, msg);
+    // Copy Message
+    memcpy(msg_ptr, (uint8_t *)msg + sizeof(os_message_t), mq->msg_size);
+    if (msg_prio != NULL) {
+      *msg_prio = msg->priority;
+    }
+    // Free memory
+    msg->state = os_ObjectInactive;
+    os_MemoryPoolFree(&mq->mp_info, msg);
+  } else {
+    // No Message available
+    if (millisec != 0U) {
+      // Suspend current Thread
+      os_ThreadListPut((os_object_t*)mq, os_ThreadGetRunning());
+      os_ThreadWaitEnter(os_ThreadWaitingMessageGet, millisec);
+      return osErrorTimeout;
+    } else {
+      return osErrorResource;
+    }
+  }
+
+  // Check if Thread is waiting to send a Message
+  if ((mq->thread_list != NULL) && (mq->thread_list->state == os_ThreadWaitingMessagePut)) {
+    // Try to allocate memory
+    msg = os_MemoryPoolAlloc(&mq->mp_info);
+    if (msg != NULL) {
+      // Wakeup waiting Thread with highest Priority
+      thread = os_ThreadListGet((os_object_t*)mq);
+      os_ThreadWaitExit(thread, (uint32_t)osOK, true);
+      // Copy Message (R1 = const void *msg_ptr, R2 = msg_prio)
+      reg = os_ThreadRegPtr(thread);
+      memcpy((uint8_t *)msg + sizeof(os_message_t), (void *)reg[1], mq->msg_size);
+      // Store Message into Queue
+      msg->id       = os_IdMessage;
+      msg->state    = os_ObjectActive;
+      msg->flags    = 0U;
+      msg->priority = (uint8_t)reg[2];
+      os_MessageQueuePut(mq, msg);
+    }
+  }
+
+  return osOK;
+}
+
+/// Get maximum number of messages in a Message Queue.
+/// \note API identical to osMessageGetCapacity
+uint32_t os_svcMessageQueueGetCapacity (osMessageQueueId_t mq_id) {
+  os_message_queue_t *mq = (os_message_queue_t *)mq_id;
+
+  // Check parameters
+  if ((mq == NULL) ||
+      (mq->id != os_IdMessageQueue)) {
+    return 0U;
+  }
+
+  // Check object state
+  if (mq->state == os_ObjectInactive) {
+    return 0U;
+  }
+
+  return mq->mp_info.max_blocks;
+}
+
+/// Get maximum message size in a Memory Pool.
+/// \note API identical to osMessageGetMsgSize
+uint32_t os_svcMessageQueueGetMsgSize (osMessageQueueId_t mq_id) {
+  os_message_queue_t *mq = (os_message_queue_t *)mq_id;
+
+  // Check parameters
+  if ((mq == NULL) ||
+      (mq->id != os_IdMessageQueue)) {
+    return 0U;
+  }
+
+  // Check object state
+  if (mq->state == os_ObjectInactive) {
+    return 0U;
+  }
+
+  return mq->msg_size;
+}
+
+/// Get number of queued messages in a Message Queue.
+/// \note API identical to osMessageGetCount
+uint32_t os_svcMessageQueueGetCount (osMessageQueueId_t mq_id) {
+  os_message_queue_t *mq = (os_message_queue_t *)mq_id;
+
+  // Check parameters
+  if ((mq == NULL) ||
+      (mq->id != os_IdMessageQueue)) {
+    return 0U;
+  }
+
+  // Check object state
+  if (mq->state == os_ObjectInactive) {
+    return 0U;
+  }
+
+  return mq->msg_count;
+}
+
+/// Get number of available slots for messages in a Message Queue.
+/// \note API identical to osMessageGetSpace
+uint32_t os_svcMessageQueueGetSpace (osMessageQueueId_t mq_id) {
+  os_message_queue_t *mq = (os_message_queue_t *)mq_id;
+
+  // Check parameters
+  if ((mq == NULL) ||
+      (mq->id != os_IdMessageQueue)) {
+    return 0U;
+  }
+
+  // Check object state
+  if (mq->state == os_ObjectInactive) {
+    return 0U;
+  }
+
+  return (mq->mp_info.max_blocks - mq->msg_count);
+}
+
+/// Reset a Message Queue to initial empty state.
+/// \note API identical to osMessageQueueReset
+osStatus_t os_svcMessageQueueReset (osMessageQueueId_t mq_id) {
+  os_message_queue_t *mq = (os_message_queue_t *)mq_id;
+  os_message_t       *msg;
+  os_thread_t        *thread;
+  uint32_t           *reg;
+
+  // Check parameters
+  if ((mq == NULL) ||
+      (mq->id != os_IdMessageQueue)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (mq->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Remove Messages from Queue
+  for (;;) {
+    // Get Message from Queue
+    msg = os_MessageQueueGet(mq);
+    if (msg == NULL) {
+      break;
+    }
+    os_MessageQueueRemove(mq, msg);
+    // Free memory
+    msg->state = os_ObjectInactive;
+    os_MemoryPoolFree(&mq->mp_info, msg);
+  }
+
+  // Check if Threads are waiting to send Messages
+  if ((mq->thread_list != NULL) && (mq->thread_list->state == os_ThreadWaitingMessagePut)) {
+    do {
+      // Try to allocate memory
+      msg = os_MemoryPoolAlloc(&mq->mp_info);
+      if (msg != NULL) {
+        // Wakeup waiting Thread with highest Priority
+        thread = os_ThreadListGet((os_object_t*)mq);
+        os_ThreadWaitExit(thread, (uint32_t)osOK, false);
+        // Copy Message (R1 = const void *msg_ptr, R2 = msg_prio)
+        reg = os_ThreadRegPtr(thread);
+        memcpy((uint8_t *)msg + sizeof(os_message_t), (void *)reg[1], mq->msg_size);
+        // Store Message into Queue
+        msg->id       = os_IdMessage;
+        msg->state    = os_ObjectActive;
+        msg->flags    = 0U;
+        msg->priority = (uint8_t)reg[2];
+        os_MessageQueuePut(mq, msg);
+      }
+    } while ((msg != NULL) && (mq->thread_list != NULL));
+    os_ThreadDispatch(NULL);
+  }
+
+  return osOK;
+}
+
+/// Delete a Message Queue object.
+/// \note API identical to osMessageQueueDelete
+osStatus_t os_svcMessageQueueDelete (osMessageQueueId_t mq_id) {
+  os_message_queue_t *mq = (os_message_queue_t *)mq_id;
+  os_thread_t        *thread;
+
+  // Check parameters
+  if ((mq == NULL) ||
+      (mq->id != os_IdMessageQueue)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (mq->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Mark object as inactive
+  mq->state = os_ObjectInactive;
+
+  // Unblock waiting threads
+  if (mq->thread_list != NULL) {
+    do {
+      thread = os_ThreadListGet((os_object_t*)mq);
+      os_ThreadWaitExit(thread, (uint32_t)osErrorResource, false);
+    } while (mq->thread_list != NULL);
+    os_ThreadDispatch(NULL);
+  }
+
+  // Free data memory
+  if (mq->flags & os_FlagSystemMemory) {
+    os_MemoryFree(os_Info.mem.data, mq->mp_info.block_base);
+  }
+
+  // Free object memory
+  if (mq->flags & os_FlagSystemObject) {
+    if (os_Info.mpi.message_queue != NULL) {
+      os_MemoryPoolFree(os_Info.mpi.message_queue, mq);
+    } else {
+      os_MemoryFree(os_Info.mem.cb, mq);
+    }
+  }
+
+  return osOK;
+}
+
+
+//  ==== ISR Calls ====
+
+/// Put a Message into a Queue or timeout if Queue is full.
+/// \note API identical to osMessageQueuePut
+__STATIC_INLINE
+osStatus_t os_isrMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t millisec) {
+  os_message_queue_t *mq = (os_message_queue_t *)mq_id;
+  os_message_t       *msg;
+  void              **ptr;
+
+  // Check parameters
+  if ((mq == NULL) ||
+      (mq->id != os_IdMessageQueue)) {
+    return osErrorParameter;
+  }
+  if (msg_ptr == NULL) {
+    return osErrorParameter;
+  }
+  if (millisec != 0U) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (mq->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Try to allocate memory
+  msg = os_MemoryPoolAlloc(&mq->mp_info);
+  if (msg != NULL) {
+    // Copy Message
+    memcpy((uint8_t *)msg + sizeof(os_message_t), msg_ptr, mq->msg_size);
+    msg->id       = os_IdMessage;
+    msg->state    = os_ObjectActive;
+    msg->flags    = 0U;
+    msg->priority = msg_prio;
+    // Register post ISR processing
+     ptr = (void *)((uint8_t *)msg + sizeof(os_message_t) - sizeof(os_message_queue_t *));
+    *ptr = mq;
+    os_PostProcess((os_object_t *)msg);
+  } else {
+    // No memory available
+    return osErrorResource;
+  }
+
+  return osOK;
+}
+
+/// Get a Message from a Queue or timeout if Queue is empty.
+/// \note API identical to osMessageQueueGet
+__STATIC_INLINE
+osStatus_t os_isrMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t millisec) {
+  os_message_queue_t *mq = (os_message_queue_t *)mq_id;
+  os_message_t       *msg;
+  void              **ptr;
+
+  // Check parameters
+  if ((mq == NULL) ||
+      (mq->id != os_IdMessageQueue)) {
+    return osErrorParameter;
+  }
+  if (msg_ptr == NULL) {
+    return osErrorParameter;
+  }
+  if (millisec != 0U) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (mq->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Get Message from Queue
+  msg = os_MessageQueueGet(mq);
+  if (msg != NULL) {
+    // Copy Message
+    memcpy(msg_ptr, (uint8_t *)msg + sizeof(os_message_t), mq->msg_size);
+    if (msg_prio != NULL) {
+      *msg_prio = msg->priority;
+    }
+    // Register post ISR processing
+     ptr = (void *)((uint8_t *)msg + sizeof(os_message_t));
+    *ptr = mq;
+    os_PostProcess((os_object_t *)msg);
+  } else {
+    // No Message available
+    return osErrorResource;
+  }
+
+  return osOK;
+}
+
+
+//  ==== Public API ====
+
+/// Create and Initialize a Message Queue object.
+osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) {
+  if (__get_IPSR() != 0U) {
+    return (osMessageQueueId_t)NULL;            // Not allowed in ISR
+  }
+  if ((os_KernelGetState() == os_KernelReady) && ((__get_CONTROL() & 1U) == 0U)) {
+    // Kernel Ready (not running) and in Privileged mode
+    return os_svcMessageQueueNew(msg_count, msg_size, attr);
+  } else {
+    return  __svcMessageQueueNew(msg_count, msg_size, attr);
+  }
+}
+
+/// Put a Message into a Queue or timeout if Queue is full.
+osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t millisec) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_isrMessageQueuePut(mq_id, msg_ptr, msg_prio, millisec);
+  } else {                                      // in Thread
+    return  __svcMessageQueuePut(mq_id, msg_ptr, msg_prio, millisec);
+  }
+}
+
+/// Get a Message from a Queue or timeout if Queue is empty.
+osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t millisec) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_isrMessageQueueGet(mq_id, msg_ptr, msg_prio, millisec);
+  } else {                                      // in Thread
+    return  __svcMessageQueueGet(mq_id, msg_ptr, msg_prio, millisec);
+  }
+}
+
+/// Get maximum number of messages in a Message Queue.
+uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_svcMessageQueueGetCapacity(mq_id);
+  } else {                                      // in Thread
+    return  __svcMessageQueueGetCapacity(mq_id);
+  }
+}
+
+/// Get maximum message size in a Memory Pool.
+uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_svcMessageQueueGetMsgSize(mq_id);
+  } else {                                      // in Thread
+    return  __svcMessageQueueGetMsgSize(mq_id);
+  }
+}
+
+/// Get number of queued messages in a Message Queue.
+uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_svcMessageQueueGetCount(mq_id);
+  } else {                                      // in Thread
+    return  __svcMessageQueueGetCount(mq_id);
+  }
+}
+
+/// Get number of available slots for messages in a Message Queue.
+uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_svcMessageQueueGetSpace(mq_id);
+  } else {                                      // in Thread
+    return  __svcMessageQueueGetSpace(mq_id);
+  }
+}
+
+/// Reset a Message Queue to initial empty state.
+osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcMessageQueueReset(mq_id);
+}
+
+/// Delete a Message Queue object.
+osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcMessageQueueDelete(mq_id);
+}
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_mutex.c b/CMSIS/RTOS2/RTX/Source/rtx_mutex.c
new file mode 100644
index 0000000..cda9b5c
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/rtx_mutex.c
@@ -0,0 +1,419 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       Mutex functions
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#include "rtx_lib.h"
+
+
+//  ==== Library functions ====
+
+/// Release Mutex list when owner Thread terminates.
+/// \param[in]  mutex           mutex object.
+/// \return 1 - success, 0 - failure.
+void os_MutexOwnerRelease (os_mutex_t *mutex_list) {
+  os_mutex_t  *mutex;
+  os_thread_t *thread;
+
+  mutex = mutex_list;
+  while (mutex) {
+    mutex_list = mutex->owner_next;
+    // Check if Mutex is Robust
+    if (mutex->attr & osMutexRobust) {
+      // Clear Lock counter
+      mutex->lock = 0U;
+      // Check if Thread is waiting for a Mutex
+      if (mutex->thread_list != NULL) {
+        // Wakeup waiting Thread with highest Priority
+        thread = os_ThreadListGet((os_object_t*)mutex);
+        os_ThreadWaitExit(thread, (uint32_t)osOK, false);
+        // Thread is the new Mutex owner
+        mutex->owner_thread = thread;
+        mutex->owner_next   = thread->mutex_list;
+        mutex->owner_prev   = NULL;
+        thread->mutex_list  = mutex;
+        mutex->lock = 1U;
+      }
+    }
+    mutex = mutex_list;
+  }
+}
+
+
+//  ==== Service Calls ====
+
+//  Service Calls definitions
+SVC0_1(MutexNew,      osMutexId_t,  const osMutexAttr_t *)
+SVC0_2(MutexAcquire,  osStatus_t,   osMutexId_t, uint32_t)
+SVC0_1(MutexRelease,  osStatus_t,   osMutexId_t)
+SVC0_1(MutexGetOwner, osThreadId_t, osMutexId_t)
+SVC0_1(MutexDelete,   osStatus_t,   osMutexId_t)
+
+/// Create and Initialize a Mutex object.
+/// \note API identical to osMutexNew
+osMutexId_t os_svcMutexNew (const osMutexAttr_t *attr) {
+  os_mutex_t *mutex;
+  uint32_t    attr_bits;
+  uint8_t     flags;
+  const char *name;
+
+  // Process attributes
+  if (attr != NULL) {
+    name      = attr->name;
+    attr_bits = attr->attr_bits;
+    mutex     = attr->cb_mem;
+    if (mutex != NULL) {
+      if (((uint32_t)mutex & 3U) || (attr->cb_size < sizeof(os_mutex_t))) {
+        return (osMutexId_t)NULL;
+      }
+    } else {
+      if (attr->cb_size != 0U) {
+        return (osMutexId_t)NULL;
+      }
+    }
+  } else {
+    name      = NULL;
+    attr_bits = 0U;
+    mutex     = NULL;
+  }
+
+  // Allocate object memory if not provided
+  if (mutex == NULL) {
+    if (os_Info.mpi.mutex != NULL) {
+      mutex = os_MemoryPoolAlloc(os_Info.mpi.mutex);
+    } else {
+      mutex = os_MemoryAlloc(os_Info.mem.cb, sizeof(os_mutex_t));
+    }
+    if (mutex == NULL) {
+      return (osMutexId_t)NULL;
+    }
+    flags = os_FlagSystemObject;
+  } else {
+    flags = 0U;
+  }
+
+  // Initialize control block
+  mutex->id           = os_IdMutex;
+  mutex->state        = os_ObjectActive;
+  mutex->flags        = flags;
+  mutex->attr         = (uint8_t)attr_bits;
+  mutex->name         = name;
+  mutex->thread_list  = NULL;
+  mutex->owner_thread = NULL;
+  mutex->owner_prev   = NULL;
+  mutex->owner_next   = NULL;
+  mutex->lock         = 0U;
+
+  return (osMutexId_t)mutex;
+}
+
+/// Acquire a Mutex or timeout if it is locked.
+/// \note API identical to osMutexAcquire
+osStatus_t os_svcMutexAcquire (osMutexId_t mutex_id, uint32_t millisec) {
+  os_mutex_t  *mutex = (os_mutex_t *)mutex_id;
+  os_thread_t *runnig_thread;
+
+  runnig_thread = os_ThreadGetRunning();
+  if (runnig_thread == NULL) {
+    return osError;
+  }
+
+  // Check parameters
+  if ((mutex == NULL) ||
+      (mutex->id != os_IdMutex)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (mutex->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Check if Mutex is not locked
+  if (mutex->lock == 0U) {
+    // Acquire Mutex
+    mutex->owner_thread = runnig_thread;
+    mutex->owner_next   = runnig_thread->mutex_list;
+    mutex->owner_prev   = NULL;
+    runnig_thread->mutex_list = mutex;
+    mutex->lock = 1U;
+    return osOK;
+  }
+
+  // Check if Mutex is recursive and running Thread is the owner
+  if ((mutex->attr & osMutexRecursive) && (mutex->owner_thread == runnig_thread)) {
+    // Increment lock counter
+    if (mutex->lock == os_MutexLockLimit) {
+      return osErrorResource;
+    }
+    mutex->lock++;
+    return osOK;
+  }
+
+  // Check if timeout is specified
+  if (millisec != 0U) {
+    // Check if Priority inheritance protocol is enabled
+    if (mutex->attr & osMutexPrioInherit) {
+      // Raise priority of owner Thread if lower than priority of running Thread
+      if (mutex->owner_thread->priority < runnig_thread->priority) {
+        mutex->owner_thread->priority = runnig_thread->priority;
+        os_ThreadListSort(mutex->owner_thread);
+      }
+    }
+    // Suspend current Thread
+    os_ThreadListPut((os_object_t*)mutex, runnig_thread);
+    os_ThreadWaitEnter(os_ThreadWaitingMutex, millisec);
+    return osErrorTimeout;
+  }
+
+  // Mutex was not acquired
+  return osErrorResource;
+}
+
+/// Release a Mutex that was acquired by osMutexAcquire.
+/// \note API identical to osMutexRelease
+osStatus_t os_svcMutexRelease (osMutexId_t mutex_id) {
+  os_mutex_t  *mutex = (os_mutex_t *)mutex_id;
+  os_mutex_t  *mutex0;
+  os_thread_t *thread;
+  os_thread_t *runnig_thread;
+  int8_t       priority;
+
+  runnig_thread = os_ThreadGetRunning();
+  if (runnig_thread == NULL) {
+    return osError;
+  }
+
+  // Check parameters
+  if ((mutex == NULL) ||
+      (mutex->id != os_IdMutex)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (mutex->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Check if Mutex is not locked or running Thread is not the owner
+  if ((mutex->lock == 0U) || (mutex->owner_thread != runnig_thread)) {
+    return osErrorResource;
+  }
+
+  // Decrement Lock counter
+  if (--mutex->lock != 0U) {
+    return osOK;
+  }
+
+  // Remove Mutex from Thread owner list
+  if (mutex->owner_next != NULL) {
+    mutex->owner_next->owner_prev = mutex->owner_prev;
+  }
+  if (mutex->owner_prev != NULL) {
+    mutex->owner_prev->owner_next = mutex->owner_next;
+  } else {
+    runnig_thread->mutex_list = mutex->owner_next;
+  }
+
+  // Restore running Thread priority
+  if (mutex->attr & osMutexPrioInherit) {
+    priority = runnig_thread->priority_base;
+    mutex0   = runnig_thread->mutex_list;
+    while (mutex0) {
+      // Mutexes owned by running Thread
+      if ((mutex0->thread_list != NULL) && (mutex0->thread_list->priority > priority)) {
+        // Higher priority Thread is waiting for Mutex
+        priority = mutex0->thread_list->priority;
+      }
+      mutex0 = mutex0->owner_next;
+    }
+    runnig_thread->priority = priority;
+  }
+
+  // Check if Thread is waiting for a Mutex
+  if (mutex->thread_list != NULL) {
+    // Wakeup waiting Thread with highest Priority
+    thread = os_ThreadListGet((os_object_t*)mutex);
+    os_ThreadWaitExit(thread, (uint32_t)osOK, false);
+    // Thread is the new Mutex owner
+    mutex->owner_thread = thread;
+    mutex->owner_next   = thread->mutex_list;
+    mutex->owner_prev   = NULL;
+    thread->mutex_list  = mutex;
+    mutex->lock = 1U;
+  }
+
+  os_ThreadDispatch(NULL);
+
+  return osOK;
+}
+
+/// Get Thread which owns a Mutex object.
+/// \note API identical to osMutexGetOwner
+osThreadId_t os_svcMutexGetOwner (osMutexId_t mutex_id) {
+  os_mutex_t *mutex = (os_mutex_t *)mutex_id;
+
+  // Check parameters
+  if ((mutex == NULL) ||
+      (mutex->id != os_IdMutex)) {
+    return (osThreadId_t)NULL;
+  }
+
+  // Check object state
+  if (mutex->state == os_ObjectInactive) {
+    return (osThreadId_t)NULL;
+  }
+
+  // Check if Mutex is locked
+  if (mutex->lock != 0U) {
+    return (osThreadId_t)mutex->owner_thread;
+  }
+
+  return (osThreadId_t)NULL;
+}
+
+/// Delete a Mutex object.
+/// \note API identical to osMutexDelete
+osStatus_t os_svcMutexDelete (osMutexId_t mutex_id) {
+  os_mutex_t  *mutex = (os_mutex_t *)mutex_id;
+  os_mutex_t  *mutex0;
+  os_thread_t *thread;
+  int8_t       priority;
+
+  // Check parameters
+  if ((mutex == NULL) ||
+      (mutex->id != os_IdMutex)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (mutex->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Mark object as inactive
+  mutex->state = os_ObjectInactive;
+
+  // Check if Mutex is locked
+  if (mutex->lock != 0U) {
+
+    thread = mutex->owner_thread;
+
+    // Remove Mutex from Thread owner list
+    if (mutex->owner_next != NULL) {
+      mutex->owner_next->owner_prev = mutex->owner_prev;
+    }
+    if (mutex->owner_prev != NULL) {
+      mutex->owner_prev->owner_next = mutex->owner_next;
+    } else {
+      thread->mutex_list = mutex->owner_next;
+    }
+
+    // Restore owner Thread priority
+    if (mutex->attr & osMutexPrioInherit) {
+      priority = thread->priority_base;
+      mutex0   = thread->mutex_list;
+      while (mutex0) {
+        // Mutexes owned by running Thread
+        if ((mutex0->thread_list != NULL) && (mutex0->thread_list->priority > priority)) {
+          // Higher priority Thread is waiting for Mutex
+          priority = mutex0->thread_list->priority;
+        }
+        mutex0 = mutex0->owner_next;
+      }
+      if (thread->priority != priority) {
+        thread->priority = priority;
+        os_ThreadListSort(thread);
+      }
+    }
+
+    // Unblock waiting threads
+    if (mutex->thread_list != NULL) {
+      do {
+        thread = os_ThreadListGet((os_object_t*)mutex);
+        os_ThreadWaitExit(thread, (uint32_t)osErrorResource, false);
+      } while (mutex->thread_list != NULL);
+    }
+
+    os_ThreadDispatch(NULL);
+  }
+
+  // Free object memory
+  if (mutex->flags & os_FlagSystemObject) {
+    if (os_Info.mpi.mutex != NULL) {
+      os_MemoryPoolFree(os_Info.mpi.mutex, mutex);
+    } else {
+      os_MemoryFree(os_Info.mem.cb, mutex);
+    }
+  }
+
+  return osOK;
+}
+
+
+//  ==== Public API ====
+
+/// Create and Initialize a Mutex object.
+osMutexId_t osMutexNew (const osMutexAttr_t *attr) {
+  if (__get_IPSR() != 0U) {
+    return (osMutexId_t)NULL;                   // Not allowed in ISR
+  }
+  if ((os_KernelGetState() == os_KernelReady) && ((__get_CONTROL() & 1U) == 0U)) {
+    // Kernel Ready (not running) and in Privileged mode
+    return os_svcMutexNew(attr);
+  } else {
+    return  __svcMutexNew(attr);
+  }
+}
+
+/// Acquire a Mutex or timeout if it is locked.
+osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t millisec) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return  __svcMutexAcquire(mutex_id, millisec);
+}
+
+/// Release a Mutex that was acquired by \ref osMutexAcquire.
+osStatus_t osMutexRelease (osMutexId_t mutex_id) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return  __svcMutexRelease(mutex_id);
+}
+
+/// Get Thread which owns a Mutex object.
+osThreadId_t osMutexGetOwner (osMutexId_t mutex_id) {
+  if (__get_IPSR() != 0U) {
+    return (osThreadId_t)NULL;                  // Not allowed in ISR
+  }
+  return  __svcMutexGetOwner(mutex_id);
+}
+
+/// Delete a Mutex object.
+osStatus_t osMutexDelete (osMutexId_t mutex_id) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcMutexDelete(mutex_id);
+}
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_semaphore.c b/CMSIS/RTOS2/RTX/Source/rtx_semaphore.c
new file mode 100644
index 0000000..93e1a5b
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/rtx_semaphore.c
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       Semaphore functions
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#include "rtx_lib.h"
+
+
+//  ==== Helper functions ====
+
+/// Decrement Semaphore tokens.
+/// \param[in]  semaphore       semaphore object.
+/// \return 1 - success, 0 - failure.
+static uint32_t os_SemaphoreTokenDecrement (os_semaphore_t *semaphore) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+  uint32_t primask = __get_PRIMASK();
+#endif
+  uint32_t ret;
+
+#ifdef __NO_EXCLUSIVE_ACCESS
+  __disable_irq();
+
+  if (semaphore->tokens != 0U) {
+    semaphore->tokens--;
+    ret = 1U;
+  } else {
+    ret = 0U;
+  }
+
+  if (primask == 0U) {
+    __enable_irq();
+  }
+#else
+  if (os_exc_dec16_nz(&semaphore->tokens) != 0U) {
+    ret = 1U;
+  } else {
+    ret = 0U;
+  }
+#endif
+
+  return ret;
+}
+
+/// Increment Semaphore tokens.
+/// \param[in]  semaphore       semaphore object.
+/// \return 1 - success, 0 - failure.
+static uint32_t os_SemaphoreTokenIncrement (os_semaphore_t *semaphore) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+  uint32_t primask = __get_PRIMASK();
+#endif
+  uint32_t ret;
+
+#ifdef __NO_EXCLUSIVE_ACCESS
+  __disable_irq();
+
+  if (semaphore->tokens < semaphore->max_tokens) {
+    semaphore->tokens++;
+    ret = 1U;
+  } else {
+    ret = 0U;
+  }
+
+  if (primask == 0U) {
+    __enable_irq();
+  }
+#else
+  if (os_exc_inc16_lt(&semaphore->tokens, semaphore->max_tokens) < semaphore->max_tokens) {
+    ret = 1U;
+  } else {
+    ret = 0U;
+  }
+#endif
+
+  return ret;
+}
+
+
+//  ==== Library functions ====
+
+/// Semaphore post ISR processing.
+/// \param[in]  semaphore       semaphore object.
+void os_SemaphorePostProcess (os_semaphore_t *semaphore) {
+  os_thread_t *thread;
+
+  if (semaphore->state == os_ObjectInactive) {
+    return;
+  }
+
+  // Check if Thread is waiting for a token
+  if (semaphore->thread_list != NULL) {
+    // Try to acquire token
+    if (os_SemaphoreTokenDecrement(semaphore) != 0U) {
+      // Wakeup waiting Thread with highest Priority
+      thread = os_ThreadListGet((os_object_t*)semaphore);
+      os_ThreadWaitExit(thread, (uint32_t)osOK, false);
+    }
+  }
+}
+
+
+//  ==== Service Calls ====
+
+//  Service Calls definitions
+SVC0_3(SemaphoreNew,      osSemaphoreId_t, uint32_t, uint32_t, const osSemaphoreAttr_t *)
+SVC0_2(SemaphoreAcquire,  osStatus_t,      osSemaphoreId_t, uint32_t)
+SVC0_1(SemaphoreRelease,  osStatus_t,      osSemaphoreId_t)
+SVC0_1(SemaphoreGetCount, uint32_t,        osSemaphoreId_t)
+SVC0_1(SemaphoreDelete,   osStatus_t,      osSemaphoreId_t)
+
+/// Create and Initialize a Semaphore object.
+/// \note API identical to osSemaphoreNew
+osSemaphoreId_t os_svcSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) {
+  os_semaphore_t *semaphore;
+  uint8_t         flags;
+  const char     *name;
+
+  // Check parameters
+  if ((max_count     > os_SemaphoreTokenLimit) ||
+      (initial_count > max_count)) {
+    return (osSemaphoreId_t)NULL;
+  }
+
+  // Process attributes
+  if (attr != NULL) {
+    name      = attr->name;
+    semaphore = attr->cb_mem;
+    if (semaphore != NULL) {
+      if (((uint32_t)semaphore & 3U) || (attr->cb_size < sizeof(os_semaphore_t))) {
+        return (osSemaphoreId_t)NULL;
+      }
+    } else {
+      if (attr->cb_size != 0U) {
+        return (osSemaphoreId_t)NULL;
+      }
+    }
+  } else {
+    name      = NULL;
+    semaphore = NULL;
+  }
+
+  // Allocate object memory if not provided
+  if (semaphore == NULL) {
+    if (os_Info.mpi.semaphore != NULL) {
+      semaphore = os_MemoryPoolAlloc(os_Info.mpi.semaphore);
+    } else {
+      semaphore = os_MemoryAlloc(os_Info.mem.cb, sizeof(os_semaphore_t));
+    }
+    if (semaphore == NULL) {
+      return (osSemaphoreId_t)NULL;
+    }
+    flags = os_FlagSystemObject;
+  } else {
+    flags = 0U;
+  }
+
+  // Initialize control block
+  semaphore->id          = os_IdSemaphore;
+  semaphore->state       = os_ObjectActive;
+  semaphore->flags       = flags;
+  semaphore->name        = name;
+  semaphore->thread_list = NULL;
+  semaphore->tokens      = (uint16_t)initial_count;
+  semaphore->max_tokens  = (uint16_t)max_count;
+
+  // Register post ISR processing function
+  os_Info.post_process.semaphore = os_SemaphorePostProcess;
+
+  return (osSemaphoreId_t)semaphore;
+}
+
+/// Acquire a Semaphore token or timeout if no tokens are available.
+/// \note API identical to osSemaphoreAcquire
+osStatus_t os_svcSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t millisec) {
+  os_semaphore_t *semaphore = (os_semaphore_t *)semaphore_id;
+
+  // Check parameters
+  if ((semaphore == NULL) ||
+      (semaphore->id != os_IdSemaphore)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (semaphore->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Try to acquire token
+  if (os_SemaphoreTokenDecrement(semaphore) == 0U) {
+    // No token available
+    if (millisec != 0U) {
+      // Suspend current Thread
+      os_ThreadListPut((os_object_t*)semaphore, os_ThreadGetRunning());
+      os_ThreadWaitEnter(os_ThreadWaitingSemaphore, millisec);
+      return osErrorTimeout;
+    } else {
+      return osErrorResource;
+    }
+  }
+
+  return osOK;
+}
+
+/// Release a Semaphore token that was acquired by osSemaphoreAcquire.
+/// \note API identical to osSemaphoreRelease
+osStatus_t os_svcSemaphoreRelease (osSemaphoreId_t semaphore_id) {
+  os_semaphore_t *semaphore = (os_semaphore_t *)semaphore_id;
+  os_thread_t    *thread;
+
+  // Check parameters
+  if ((semaphore == NULL) ||
+      (semaphore->id != os_IdSemaphore)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (semaphore->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Check if Thread is waiting for a token
+  if (semaphore->thread_list != NULL) {
+    // Wakeup waiting Thread with highest Priority
+    thread = os_ThreadListGet((os_object_t*)semaphore);
+    os_ThreadWaitExit(thread, (uint32_t)osOK, true);
+  } else {
+    // Try to release token
+    if (os_SemaphoreTokenIncrement(semaphore) == 0U) {
+      return osErrorResource;
+    }
+  }
+
+  return osOK;
+}
+
+/// Get current Semaphore token count.
+/// \note API identical to osSemaphoreGetCount
+uint32_t os_svcSemaphoreGetCount (osSemaphoreId_t semaphore_id) {
+  os_semaphore_t *semaphore = (os_semaphore_t *)semaphore_id;
+
+  // Check parameters
+  if ((semaphore == NULL) ||
+      (semaphore->id != os_IdSemaphore)) {
+    return 0U;
+  }
+
+  // Check object state
+  if (semaphore->state == os_ObjectInactive) {
+    return 0U;
+  }
+
+  return semaphore->tokens;
+}
+
+/// Delete a Semaphore object.
+/// \note API identical to osSemaphoreDelete
+osStatus_t os_svcSemaphoreDelete (osSemaphoreId_t semaphore_id) {
+  os_semaphore_t *semaphore = (os_semaphore_t *)semaphore_id;
+  os_thread_t    *thread;
+
+  // Check parameters
+  if ((semaphore == NULL) ||
+      (semaphore->id != os_IdSemaphore)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (semaphore->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Mark object as inactive
+  semaphore->state = os_ObjectInactive;
+
+  // Unblock waiting threads
+  if (semaphore->thread_list != NULL) {
+    do {
+      thread = os_ThreadListGet((os_object_t*)semaphore);
+      os_ThreadWaitExit(thread, (uint32_t)osErrorResource, false);
+    } while (semaphore->thread_list != NULL);
+    os_ThreadDispatch(NULL);
+  }
+
+  // Free object memory
+  if (semaphore->flags & os_FlagSystemObject) {
+    if (os_Info.mpi.semaphore != NULL) {
+      os_MemoryPoolFree(os_Info.mpi.semaphore, semaphore);
+    } else {
+      os_MemoryFree(os_Info.mem.cb, semaphore);
+    }
+  }
+
+  return osOK;
+}
+
+
+//  ==== ISR Calls ====
+
+/// Acquire a Semaphore token or timeout if no tokens are available.
+/// \note API identical to osSemaphoreAcquire
+__STATIC_INLINE
+osStatus_t os_isrSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t millisec) {
+  os_semaphore_t *semaphore = (os_semaphore_t *)semaphore_id;
+
+  // Check parameters
+  if ((semaphore == NULL) ||
+      (semaphore->id != os_IdSemaphore)) {
+    return osErrorParameter;
+  }
+  if (millisec != 0U) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (semaphore->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Try to acquire token
+  if (os_SemaphoreTokenDecrement(semaphore) == 0U) {
+    // No token available
+    return osErrorResource;
+  }
+
+  return osOK;
+}
+
+/// Release a Semaphore token that was acquired by osSemaphoreAcquire.
+/// \note API identical to osSemaphoreRelease
+__STATIC_INLINE
+osStatus_t os_isrSemaphoreRelease (osSemaphoreId_t semaphore_id) {
+  os_semaphore_t *semaphore = (os_semaphore_t *)semaphore_id;
+
+  // Check parameters
+  if ((semaphore == NULL) ||
+      (semaphore->id != os_IdSemaphore)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (semaphore->state == os_ObjectInactive) {
+    return osErrorResource;
+  }
+
+  // Try to release token
+  if (os_SemaphoreTokenIncrement(semaphore) != 0U) {
+    // Register post ISR processing
+    os_PostProcess((os_object_t *)semaphore);
+  } else {
+    return osErrorResource;
+  }
+
+  return osOK;
+}
+
+
+//  ==== Public API ====
+
+/// Create and Initialize a Semaphore object.
+osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) {
+  if (__get_IPSR() != 0U) {
+    return (osSemaphoreId_t)NULL;               // Not allowed in ISR
+  }
+  if ((os_KernelGetState() == os_KernelReady) && ((__get_CONTROL() & 1U) == 0U)) {
+    // Kernel Ready (not running) and in Privileged mode
+    return os_svcSemaphoreNew(max_count, initial_count, attr);
+  } else {
+    return  __svcSemaphoreNew(max_count, initial_count, attr);
+  }
+}
+
+/// Acquire a Semaphore token or timeout if no tokens are available.
+osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t millisec) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_isrSemaphoreAcquire(semaphore_id, millisec);
+  } else {                                      // in Thread
+    return  __svcSemaphoreAcquire(semaphore_id, millisec);
+  }
+}
+
+/// Release a Semaphore token that was acquired by osSemaphoreAcquire.
+osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_isrSemaphoreRelease(semaphore_id);
+  } else {                                      // in Thread
+    return  __svcSemaphoreRelease(semaphore_id);
+  }
+}
+
+/// Get current Semaphore token count.
+uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_svcSemaphoreGetCount(semaphore_id);
+  } else {                                      // in Thread
+    return  __svcSemaphoreGetCount(semaphore_id);
+  }
+}
+
+/// Delete a Semaphore object.
+osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcSemaphoreDelete(semaphore_id);
+}
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_system.c b/CMSIS/RTOS2/RTX/Source/rtx_system.c
new file mode 100644
index 0000000..6a37c6d
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/rtx_system.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       System functions
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#include "rtx_lib.h"
+
+
+//  ==== Helper functions ====
+
+/// Put Object into ISR Queue.
+/// \param[in]  object          object.
+/// \return 1 - success, 0 - failure.
+static uint32_t os_isr_queue_put (void *object) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+  uint32_t primask = __get_PRIMASK();
+#else
+  uint32_t n;
+#endif
+  uint16_t max;
+  uint32_t ret;
+
+  max = os_Info.isr_queue.max;
+
+#ifdef __NO_EXCLUSIVE_ACCESS
+  __disable_irq();
+
+  if (os_Info.isr_queue.cnt < max) {
+    os_Info.isr_queue.cnt++;
+    os_Info.isr_queue.data[os_Info.isr_queue.in] = object;
+    if (++os_Info.isr_queue.in == max) {
+      os_Info.isr_queue.in = 0U;
+    }
+    ret = 1U;
+  } else {
+    ret = 0U;
+  }
+  
+  if (primask == 0U) {
+    __enable_irq();
+  }
+#else
+  if (os_exc_inc16_lt(&os_Info.isr_queue.cnt, max) < max) {
+    n = os_exc_inc16_lim(&os_Info.isr_queue.in, max);
+    os_Info.isr_queue.data[n] = object;
+    ret = 1U;
+  } else {
+    ret = 0U;
+  }
+#endif
+
+  return ret;
+}
+
+/// Get Object from ISR Queue.
+/// \return object or NULL.
+static void *os_isr_queue_get (void) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+  uint32_t primask = __get_PRIMASK();
+#else
+  uint32_t n;
+#endif
+  uint16_t max;
+  void    *ret;
+
+  max = os_Info.isr_queue.max;
+
+#ifdef __NO_EXCLUSIVE_ACCESS
+  __disable_irq();
+
+  if (os_Info.isr_queue.cnt != 0U) {
+    os_Info.isr_queue.cnt--;
+    ret = os_Info.isr_queue.data[os_Info.isr_queue.out];
+    if (++os_Info.isr_queue.out == max) {
+      os_Info.isr_queue.out = 0U;
+    }
+  } else {
+    ret = NULL;
+  }
+  
+  if (primask == 0U) {
+    __enable_irq();
+  }
+#else
+  if (os_exc_dec16_nz(&os_Info.isr_queue.cnt) != 0U) {
+    n = os_exc_inc16_lim(&os_Info.isr_queue.out, max);
+    ret = os_Info.isr_queue.data[n];
+  } else {
+    ret = NULL;
+  }
+#endif
+
+  return ret;
+}
+
+
+//  ==== Library Functions ====
+
+/// Tick Handler.
+void os_Tick_Handler (void) {
+  os_thread_t *thread;
+
+  os_TickAckIRQ();
+  os_Info.kernel.time++;
+
+  // Process Thread Delays
+  os_ThreadDelayTick();
+
+  // Process Timers
+  os_TimerTick();
+
+  os_ThreadDispatch(NULL);
+
+  // Check Round Robin timeout
+  if (os_Info.thread.robin.timeout != 0U) {
+    if (os_Info.thread.robin.thread != os_Info.thread.run.next) {
+      // Reset Round Robin
+      os_Info.thread.robin.thread = os_Info.thread.run.next;
+      os_Info.thread.robin.tick   = os_Info.thread.robin.timeout;
+    } else {
+      if (os_Info.thread.robin.tick != 0U) {
+        os_Info.thread.robin.tick--;
+      }
+      if (os_Info.thread.robin.tick == 0U) {
+        // Round Robin Timeout
+        if (os_KernelGetState() == os_KernelRunning) {
+          thread = os_Info.thread.ready.thread_list;
+          if ((thread != NULL) && (thread->priority == os_Info.thread.robin.thread->priority)) {
+            os_ThreadListRemove(thread);
+            os_ThreadReadyPut(os_Info.thread.robin.thread);
+            os_ThreadSwitch(thread);
+            os_Info.thread.robin.thread = thread;
+            os_Info.thread.robin.tick   = os_Info.thread.robin.timeout;
+          }
+        }
+      }
+    }
+  }
+}
+
+/// Pending Service Call Handler.
+void os_PendSV_Handler (void) {
+  os_object_t *object;
+
+  for (;;) {
+    object = os_isr_queue_get();
+    if (object == NULL) {
+      break;
+    }
+    switch (object->id) {
+      case os_IdThread:
+        os_Info.post_process.thread((os_thread_t *)object);
+        break;
+      case os_IdEventFlags:
+        os_Info.post_process.event_flags((os_event_flags_t *)object);
+        break;
+      case os_IdSemaphore:
+        os_Info.post_process.semaphore((os_semaphore_t *)object);
+        break;
+      case os_IdMemoryPool:
+        os_Info.post_process.memory_pool((os_memory_pool_t *)object);
+        break;
+      case os_IdMessage:
+        os_Info.post_process.message_queue((os_message_t *)object);
+        break;
+      default:
+        break;
+    }
+  }
+
+  os_ThreadDispatch(NULL);
+}
+
+/// Register post ISR processing.
+/// \param[in]  object          generic object.
+void os_PostProcess (os_object_t *object) {
+
+  if (os_isr_queue_put(object) != 0U) {
+    if (os_Info.kernel.blocked == 0U) {
+      os_SetPendSV();
+    } else {
+      os_Info.kernel.pendSV = 1U;
+    }
+  } else {
+    os_Error(os_ErrorISRQueueOverflow, object);
+  }
+}
+
+
+//  ==== Public API ====
+
+/// Setup Tick Timer.
+__WEAK int32_t os_TickSetup (void) {
+
+  // Setup SysTick Timer with 1ms tick
+  os_SysTick_Setup(SystemCoreClock/1000U);
+
+  os_Info.kernel.usec_ticks = ((4295U * (SystemCoreClock & 0xFFFF)) >> 16) +
+                               (4295U * (SystemCoreClock >> 16));
+
+  return SysTick_IRQn;                  // Return IRQ number of SysTick
+}
+
+/// Enable Tick Timer.
+__WEAK void os_TickEnable (void) {
+  os_SysTick_Enable();
+}
+
+/// Disable Tick Timer.
+__WEAK void os_TickDisable (void) {
+  os_SysTick_Disable();
+}
+
+/// Acknowledge Tick Timer IRQ.
+__WEAK void os_TickAckIRQ (void) {
+  os_SysTick_GetOvf();
+}
+
+/// Get Tick Timer Value.
+__WEAK uint32_t os_TickGetVal (void) {
+  uint32_t tick;
+  uint32_t time;
+
+  time = (uint32_t)os_Info.kernel.time;
+  tick = os_SysTick_GetVal();
+  if (os_SysTick_GetOvf()) {
+    tick = os_SysTick_GetVal();
+    time++;
+  }
+  tick += time * os_SysTick_GetPeriod();
+
+  return tick;
+}
+
+/// Convert microseconds value to Tick Timer value.
+__WEAK uint32_t os_TickMicroSec (uint32_t microsec) {
+  return (uint32_t)(((uint64_t)microsec * (uint64_t)os_Info.kernel.usec_ticks) >> 16);
+}
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_thread.c b/CMSIS/RTOS2/RTX/Source/rtx_thread.c
new file mode 100644
index 0000000..7587bd7
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/rtx_thread.c
@@ -0,0 +1,1337 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       Thread functions
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#include "rtx_lib.h"
+
+
+//  ==== Helper functions ====
+
+/// Set Thread Flags.
+/// \param[in]  thread          thread object.
+/// \param[in]  flags           specifies the flags to set.
+/// \return thread flags after setting.
+static int32_t os_ThreadFlagsSet (os_thread_t *thread, int32_t flags) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+  uint32_t primask = __get_PRIMASK();
+#endif
+  int32_t  thread_flags;
+
+#ifdef __NO_EXCLUSIVE_ACCESS
+  __disable_irq();
+
+  thread->thread_flags |= flags;
+  thread_flags = thread->thread_flags;
+
+  if (primask == 0U) {
+    __enable_irq();
+  }
+#else
+  thread_flags = (int32_t)os_exc_set32((uint32_t *)&thread->thread_flags, (uint32_t)flags);
+#endif
+
+  return thread_flags;
+}
+
+/// Clear Thread Flags.
+/// \param[in]  thread          thread object.
+/// \param[in]  flags           specifies the flags to clear.
+/// \return thread flags before clearing.
+static int32_t os_ThreadFlagsClear (os_thread_t *thread, int32_t flags) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+  uint32_t primask = __get_PRIMASK();
+#endif
+  int32_t  thread_flags;
+
+#ifdef __NO_EXCLUSIVE_ACCESS
+  __disable_irq();
+
+  thread_flags = thread->thread_flags;
+  thread->thread_flags &= ~flags;
+
+  if (primask == 0U) {
+    __enable_irq();
+  }
+#else
+  thread_flags = (int32_t)os_exc_clr32((uint32_t *)&thread->thread_flags, (uint32_t)flags);
+#endif
+
+  return thread_flags;
+}
+
+/// Check Thread Flags.
+/// \param[in]  thread          thread object.
+/// \param[in]  flags           specifies the flags to check.
+/// \param[in]  options         specifies flags options (osFlagsXxxx).
+/// \return thread flags before clearing or 0 if specified flags have not been set.
+static int32_t os_ThreadFlagsCheck (os_thread_t *thread, int32_t flags, uint32_t options) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+  uint32_t primask;
+#endif
+  int32_t  thread_flags;
+
+  if ((options & osFlagsAutoClear) != 0U) {
+#ifdef __NO_EXCLUSIVE_ACCESS
+    primask = __get_PRIMASK();
+    __disable_irq();
+
+    thread_flags = thread->thread_flags;
+    if ((((options & osFlagsWaitAll) != 0U) && ((thread_flags & flags) != flags)) ||
+        (((options & osFlagsWaitAll) == 0U) && ((thread_flags & flags) == 0))) {
+      thread_flags = 0;
+    } else {
+      thread->thread_flags &= ~flags;
+    }
+
+    if (primask == 0U) {
+      __enable_irq();
+    }
+#else
+    if ((options & osFlagsWaitAll) != 0U) {
+      thread_flags = (int32_t)os_exc_chk32_all((uint32_t *)&thread->thread_flags, (uint32_t)flags);
+    } else {
+      thread_flags = (int32_t)os_exc_chk32_any((uint32_t *)&thread->thread_flags, (uint32_t)flags);
+    }
+#endif
+  } else {
+    thread_flags = thread->thread_flags;
+    if ((((options & osFlagsWaitAll) != 0U) && ((thread_flags & flags) != flags)) ||
+        (((options & osFlagsWaitAll) == 0U) && ((thread_flags & flags) == 0))) {
+      thread_flags = 0;
+    }
+  }
+
+  return thread_flags;
+}
+
+
+//  ==== Library functions ====
+
+/// Put a Thread into specified Object list sorted by Priority (Highest at Head).
+/// \param[in]  object          generic object.
+/// \param[in]  thread          thread object.
+void os_ThreadListPut (volatile os_object_t *object, os_thread_t *thread) {
+  os_thread_t *prev, *next;
+  int32_t      priority;
+
+  if (thread == NULL) {
+    return;
+  }
+
+  priority = thread->priority;
+
+  prev = (os_thread_t *)(uint32_t)object;
+  next = object->thread_list;
+  while ((next != NULL) && (next->priority >= priority)) {
+    prev = next;
+    next = next->thread_next;
+  }
+  thread->thread_prev = prev;
+  thread->thread_next = next;
+  prev->thread_next = thread;
+  if (next != NULL) {
+    next->thread_prev = thread;
+  }
+}
+
+/// Get a Thread with Highest Priority from specified Object list and remove it.
+/// \param[in]  object          generic object.
+/// \return thread object. 
+os_thread_t *os_ThreadListGet (volatile os_object_t *object) {
+  os_thread_t *thread;
+
+  thread = object->thread_list;
+  if (thread != NULL) {
+    object->thread_list = thread->thread_next;
+    if (thread->thread_next != NULL) {
+      thread->thread_next->thread_prev = (os_thread_t *)(uint32_t)object;
+    }
+    thread->thread_prev = NULL;
+  }
+
+  return thread;
+}
+
+/// Re-sort a Thread in linked Object list by Priority (Highest at Head).
+/// \param[in]  thread          thread object.
+void os_ThreadListSort (os_thread_t *thread) {
+  os_object_t *object;
+  os_thread_t *thread0;
+
+  // Search for object
+  thread0 = thread;
+  while (thread0->id == os_IdThread) {
+    thread0 = thread0->thread_prev;
+    if (thread0 == NULL) { 
+      return;
+    }
+  }
+  object = (os_object_t *)thread0;
+
+  os_ThreadListRemove(thread);
+  os_ThreadListPut(object, thread);
+}
+
+/// Remove a Thread from linked Object list.
+/// \param[in]  thread          thread object.
+void os_ThreadListRemove (os_thread_t *thread) {
+
+  if (thread->thread_prev != NULL) {
+    thread->thread_prev->thread_next = thread->thread_next;
+    if (thread->thread_next != NULL) {
+      thread->thread_next->thread_prev = thread->thread_prev;
+    }
+    thread->thread_prev = NULL;
+  }
+}
+
+/// Unlink a Thread from specified linked list.
+/// \param[in]  thread          thread object.
+void os_ThreadListUnlink (os_thread_t **thread_list, os_thread_t *thread) {
+
+  if (thread->thread_next != NULL) {
+    thread->thread_next->thread_prev = thread->thread_prev;
+  }
+  if (thread->thread_prev != NULL) {
+    thread->thread_prev->thread_next = thread->thread_next;
+    thread->thread_prev = NULL;
+  } else {
+    *thread_list = thread->thread_next;
+  }
+}
+
+/// Mark a Thread as Ready and put it into Ready list (sorted by Priority).
+/// \param[in]  thread          thread object.
+void os_ThreadReadyPut (os_thread_t *thread) {
+
+  thread->state = os_ThreadReady;
+  os_ThreadListPut(&os_Info.thread.ready, thread);
+}
+
+/// Insert a Thread into the Delay list sorted by Delay (Lowest at Head).
+/// \param[in]  thread          thread object.
+/// \param[in]  millisec        delay value.
+void os_ThreadDelayInsert (os_thread_t *thread, uint32_t millisec) {
+  os_thread_t *prev, *next;
+
+  if (os_Info.thread.delay_list != NULL) {
+    prev = NULL;
+    next = os_Info.thread.delay_list;
+    while ((next != NULL) && (next->delay <= millisec)) {
+      millisec -= next->delay;
+      prev = next;
+      next = next->delay_next;
+    }
+    thread->delay = millisec;
+    thread->delay_prev = prev;
+    thread->delay_next = next;
+    if (prev != NULL) {
+      prev->delay_next = thread;
+    } else {
+      os_Info.thread.delay_list = thread;
+    }
+    if (next != NULL) {
+      next->delay -= millisec;
+      next->delay_prev = thread;
+    }
+  } else {
+    os_Info.thread.delay_list = thread;
+    thread->delay = millisec;
+    thread->delay_prev = NULL;
+    thread->delay_next = NULL;
+  }
+}
+
+/// Remove a Thread from the Delay list.
+/// \param[in]  thread          thread object.
+void os_ThreadDelayRemove (os_thread_t *thread) {
+
+  if ((thread->delay_prev == NULL) && (os_Info.thread.delay_list != thread)) {
+    return;
+  }
+
+  if (thread->delay_next != NULL) {
+    thread->delay_next->delay += thread->delay;
+    thread->delay_next->delay_prev = thread->delay_prev;
+  }
+  if (thread->delay_prev != NULL) {
+    thread->delay_prev->delay_next = thread->delay_next;
+    thread->delay_prev = NULL;
+  } else {
+    os_Info.thread.delay_list = thread->delay_next;
+  }
+}
+
+/// Process Thread Delay Tick (executed each System Tick).
+void os_ThreadDelayTick (void) {
+  os_thread_t *thread;
+
+  thread = os_Info.thread.delay_list;
+  if (thread == NULL) {
+    return;
+  }
+
+  thread->delay--;
+
+  if (thread->delay == 0U) {
+    do {
+      os_ThreadListRemove(thread);
+      os_ThreadReadyPut(thread);
+      thread = thread->delay_next;
+    } while ((thread != NULL) && (thread->delay == 0U));
+    if (thread != NULL) {
+      thread->delay_prev = NULL;
+    }
+    os_Info.thread.delay_list = thread;
+  }
+}
+
+/// Get pointer to Thread registers (R0..R3)
+/// \param[in]  thread          thread object.
+/// \return pointer to registers R0-R3.
+uint32_t *os_ThreadRegPtr (os_thread_t *thread) {
+
+#if (__FPU_USED != 0U)
+  if (thread->stack_frame & os_StackFrameExtended) {
+    // Extended Stack Frame: R4-R11, S16-S31, R0-R3, R12, LR, PC, xPSR, S0-S15, FPSCR
+    return ((uint32_t *)(thread->sp + 8U*4U + 16U*4U));
+  } else {
+    // Basic Stack Frame:    R4-R11,          R0-R3, R12, LR, PC, xPSR
+    return ((uint32_t *)(thread->sp + 8U*4U));
+  }
+#else
+  // Stack Frame: R4-R11, R0-R3, R12, LR, PC, xPSR
+  return ((uint32_t *)(thread->sp + 8U*4U));
+#endif
+}
+
+/// Block running Thread execution and register it as Ready to Run.
+/// \param[in]  thread          running thread object.
+void os_ThreadBlock (os_thread_t *thread) {
+  os_thread_t *prev, *next;
+  int32_t      priority;
+
+  thread->state = os_ThreadReady;
+
+  priority = thread->priority;
+
+  prev = (os_thread_t *)(uint32_t)&os_Info.thread.ready;
+  next = prev->thread_next;
+
+  while ((next != NULL) && (next->priority > priority)) {
+    prev = next;
+    next = next->thread_next;
+  }
+  thread->thread_prev = prev;
+  thread->thread_next = next;
+  prev->thread_next = thread;
+  if (next != NULL) {
+    next->thread_prev = thread;
+  }
+}
+
+/// Switch to specified Thread.
+/// \param[in]  thread          thread object.
+void os_ThreadSwitch (os_thread_t *thread) {
+
+  thread->state = os_ThreadRunning;
+  os_Info.thread.run.next = thread;
+  os_ThreadStackCheck();
+}
+
+/// Dispatch specified Thread or Ready Thread with Highest Priority.
+/// \param[in]  thread          thread object or NULL.
+void os_ThreadDispatch (os_thread_t *thread) {
+  uint8_t      kernel_state;
+  os_thread_t *thread_running;
+
+  kernel_state   = os_KernelGetState();
+  thread_running = os_ThreadGetRunning();
+
+  if (thread == NULL) {
+    thread = os_Info.thread.ready.thread_list;
+    if ((kernel_state == os_KernelRunning) &&
+        (thread_running != NULL) && (thread != NULL) && 
+        (thread->priority > thread_running->priority)) {
+      // Preempt running Thread
+      os_ThreadListRemove(thread);
+      os_ThreadBlock(thread_running);
+      os_ThreadSwitch(thread);
+    }
+  } else {
+    if ((kernel_state == os_KernelRunning) &&
+        (thread_running != NULL) &&
+        (thread->priority > thread_running->priority)) {
+      // Preempt running Thread
+      os_ThreadBlock(thread_running);
+      os_ThreadSwitch(thread);
+    } else {
+      // Put Thread into Ready list
+      os_ThreadReadyPut(thread);
+    }
+  }
+}
+
+/// Exit Thread wait state.
+/// \param[in]  thread          thread object.
+/// \param[in]  ret_val         return value.
+/// \param[in]  dispatch        dispatch flag.
+void os_ThreadWaitExit (os_thread_t *thread, uint32_t ret_val, bool dispatch) {
+  uint32_t *reg;
+
+  reg = os_ThreadRegPtr(thread);
+  reg[0] = ret_val;
+
+  os_ThreadDelayRemove(thread);
+  if (dispatch) {
+    os_ThreadDispatch(thread);
+  } else {
+    os_ThreadReadyPut(thread);
+  }
+}
+
+/// Enter Thread wait state.
+/// \param[in]  state           new thread state.
+/// \param[in]  millisec        wait time.
+/// \return true - success, false - failure.
+bool os_ThreadWaitEnter (uint8_t state, uint32_t millisec) {
+  os_thread_t *thread;
+
+  thread = os_ThreadGetRunning();
+  if (thread == NULL) {
+    return false;
+  }
+
+  if (os_KernelGetState() != os_KernelRunning) {
+    os_ThreadListRemove(thread);
+    return false;
+  }
+
+  if (os_Info.thread.ready.thread_list == NULL) {
+    return false;
+  }
+
+  thread->state = state;
+  if (millisec != osWaitForever) {
+    os_ThreadDelayInsert(thread, millisec);
+  }
+  thread = os_ThreadListGet(&os_Info.thread.ready);
+  os_ThreadSwitch(thread);
+
+  return true;
+}
+
+/// Check current running Thread Stack.
+void os_ThreadStackCheck (void) {
+  os_thread_t *thread;
+
+  thread = os_ThreadGetRunning();
+  if (thread != NULL) {
+    if ((thread->sp <= (uint32_t)thread->stack_mem) ||
+        (*((uint32_t *)thread->stack_mem) != os_StackMagicWord)) {
+      os_Error(os_ErrorStackUnderflow, thread);
+    }
+  }
+}
+
+/// Thread post ISR processing.
+/// \param[in]  thread          thread object.
+void os_ThreadPostProcess (os_thread_t *thread) {
+  int32_t thread_flags;
+
+  if ((thread->state == os_ThreadInactive) ||
+      (thread->state == os_ThreadTerminated)) {
+    return;
+  }
+
+  // Check if Thread is waiting for Thread Flags
+  if (thread->state == os_ThreadWaitingThreadFlags) {
+    thread_flags = os_ThreadFlagsCheck(thread, thread->wait_flags, thread->flags_options);
+    if (thread_flags > 0) {
+      os_ThreadWaitExit(thread, (uint32_t)thread_flags, false);
+    }
+  }
+}
+
+
+//  ==== Service Calls ====
+
+//  Service Calls definitions
+SVC0_3 (ThreadNew,         osThreadId_t,    os_thread_func_t, void *, const osThreadAttr_t *)
+SVC0_0 (ThreadGetId,       osThreadId_t)
+SVC0_1 (ThreadGetState,    osThreadState_t, osThreadId_t)
+SVC0_2 (ThreadSetPriority, osStatus_t,      osThreadId_t, osPriority_t)
+SVC0_1 (ThreadGetPriority, osPriority_t,    osThreadId_t)
+SVC0_0 (ThreadYield,       osStatus_t)
+SVC0_1 (ThreadAbortWait,   osStatus_t,      osThreadId_t)
+SVC0_1 (ThreadSuspend,     osStatus_t,      osThreadId_t)
+SVC0_1 (ThreadResume,      osStatus_t,      osThreadId_t)
+SVC0_1 (ThreadDetach,      osStatus_t,      osThreadId_t)
+SVC0_2 (ThreadJoin,        osStatus_t,      osThreadId_t, void **)
+SVC0_1N(ThreadExit,        void,            void *)
+SVC0_1 (ThreadTerminate,   osStatus_t,      osThreadId_t)
+SVC0_2 (ThreadFlagsSet,    int32_t,         osThreadId_t, int32_t)
+SVC0_2 (ThreadFlagsClear,  int32_t,         osThreadId_t, int32_t)
+SVC0_1 (ThreadFlagsGet,    int32_t,         osThreadId_t)
+SVC0_3 (ThreadFlagsWait,   int32_t,         int32_t, uint32_t, uint32_t)
+
+/// Create a thread and add it to Active Threads.
+/// \note API identical to osThreadNew
+osThreadId_t os_svcThreadNew (os_thread_func_t func, void *argument, const osThreadAttr_t *attr) {
+  os_thread_t *thread;
+  uint32_t     attr_bits;
+  void        *stack_mem;
+  uint32_t     stack_size;
+  osPriority_t priority;
+  uint8_t      flags;
+  const char  *name;
+  uint32_t    *ptr;
+  uint32_t     n;
+
+  // Check parameters
+  if (func == NULL) {
+    return (osThreadId_t)NULL;
+  }
+
+  // Process attributes
+  if (attr != NULL) {
+    name       = attr->name;
+    attr_bits  = attr->attr_bits;
+    thread     = attr->cb_mem;
+    stack_mem  = attr->stack_mem;
+    stack_size = attr->stack_size;
+    priority   = attr->priority;
+    if (thread != NULL) {
+      if (((uint32_t)thread & 3U) || (attr->cb_size < sizeof(os_thread_t))) {
+        return (osThreadId_t)NULL;
+      }
+    } else {
+      if (attr->cb_size != 0U) {
+        return (osThreadId_t)NULL;
+      }
+    }
+    if (stack_mem != NULL) {
+      if (((uint32_t)stack_mem & 7U) || (stack_size == 0U)) {
+        return (osThreadId_t)NULL;
+      }
+    }
+    if ((priority < osPriorityIdle) || (priority > osPriorityISR)) {
+      return (osThreadId_t)NULL;
+    }
+  } else {
+    name       = NULL;
+    attr_bits  = 0U;
+    thread     = NULL;
+    stack_mem  = NULL;
+    stack_size = 0U;
+    priority   = osPriorityNormal;
+  }
+
+  // Check stack size
+  if ((stack_size != 0U) && ((stack_size & 7U) || (stack_size < (64U + 8U)))) {
+    return (osThreadId_t)NULL;
+  }
+
+  // Allocate object memory if not provided
+  if (thread == NULL) {
+    if (os_Info.mpi.thread != NULL) {
+      thread = os_MemoryPoolAlloc(os_Info.mpi.thread);
+    } else {
+      thread = os_MemoryAlloc(os_Info.mem.cb, sizeof(os_thread_t));
+    }
+    if (thread == NULL) {
+      return (osThreadId_t)NULL;
+    }
+    flags = os_FlagSystemObject;
+  } else {
+    flags = 0U;
+  }
+
+  // Allocate stack memory if not provided
+  if (stack_mem == NULL) {
+    if (stack_size == 0U) {
+      stack_size = os_Config.thread_stack_size;
+      if (os_Info.mpi.stack != NULL) {
+        stack_mem = os_MemoryPoolAlloc(os_Info.mpi.stack);
+        if (stack_mem != NULL) {
+          flags |= os_ThreadFlagDefStack;
+        }
+      }
+    }
+    if (stack_mem == NULL) {
+      stack_mem = os_MemoryAlloc(os_Info.mem.stack, stack_size);
+    }
+    if (stack_mem == NULL) {
+      if (flags & os_FlagSystemObject) {
+        if (os_Info.mpi.thread != NULL) {
+          os_MemoryPoolFree(os_Info.mpi.thread, thread);
+        } else {
+          os_MemoryFree(os_Info.mem.cb, thread);
+        }
+      }
+      return (osThreadId_t)NULL;
+    }
+    flags |= os_FlagSystemMemory;
+  }
+
+  // Initialize control block
+  thread->id            = os_IdThread;
+  thread->state         = os_ThreadReady;
+  thread->flags         = flags;
+  thread->attr          = (uint8_t)attr_bits;
+  thread->name          = name;
+  thread->thread_next   = NULL;
+  thread->thread_prev   = NULL;
+  thread->delay_next    = NULL;
+  thread->delay_prev    = NULL;
+  thread->thread_join   = NULL;
+  thread->delay         = 0U;
+  thread->priority      = (int8_t)priority;
+  thread->priority_base = (int8_t)priority;
+  thread->stack_frame   = os_StackFrameBasic;
+  thread->flags_options = 0U;
+  thread->wait_flags    = 0;
+  thread->thread_flags  = 0;
+  thread->mutex_list    = NULL;
+  thread->stack_mem     = stack_mem;
+  thread->stack_size    = stack_size;
+  thread->sp            = (uint32_t)stack_mem + stack_size - 64U;
+
+  // Initialize stack
+   ptr   = (uint32_t *)stack_mem;
+  *ptr++ = os_StackMagicWord;
+  if (os_Config.flags & os_ConfigStackWatermark) {
+    for (n = (stack_size/4U) - (16U + 1U); n; n--) {
+      *ptr++ = os_StackFillPattern;
+    }
+  } else {
+    ptr = (uint32_t *)thread->sp;
+  }
+  for (n = 13U; n; n--) {
+    *ptr++ = 0U;                        // R4..R11, R0..R3, R12, LR
+  }
+  *ptr++   = (uint32_t)osThreadExit;    // LR
+  *ptr++   = (uint32_t)func;            // PC
+  *ptr++   = XPSR_INITIAL_VALUE;        // xPSR
+  *(ptr-8) = (uint32_t)argument;        // R0
+
+  // Register post ISR processing function
+  os_Info.post_process.thread = os_ThreadPostProcess;
+
+  os_ThreadDispatch(thread);
+
+  return (osThreadId_t)thread;
+}
+
+/// Return the thread ID of the current running thread.
+/// \note API identical to osThreadGetId
+osThreadId_t os_svcThreadGetId (void) {
+  os_thread_t *thread;
+
+  thread = os_ThreadGetRunning();
+  return (osThreadId_t)thread;
+}
+
+/// Get current thread state of a thread.
+/// \note API identical to osThreadGetState
+osThreadState_t os_svcThreadGetState (osThreadId_t thread_id) {
+  os_thread_t *thread = (os_thread_t *)thread_id;
+
+  // Check parameters
+  if ((thread == NULL) ||
+      (thread->id != os_IdThread)) {
+    return osThreadError;
+  }
+
+  return ((osThreadState_t)(thread->state & os_ThreadStateMask));
+}
+
+/// Change priority of a thread.
+/// \note API identical to osThreadSetPriority
+osStatus_t os_svcThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) {
+  os_thread_t *thread = (os_thread_t *)thread_id;
+
+  // Check parameters
+  if ((thread == NULL) ||
+      (thread->id != os_IdThread)) {
+    return osErrorParameter;
+  }
+  if ((priority < osPriorityIdle) || (priority > osPriorityISR)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if ((thread->state == os_ThreadInactive) ||
+      (thread->state == os_ThreadTerminated)) {
+    return osErrorResource;
+  }
+
+  if (thread->priority   != (int8_t)priority) {
+    thread->priority      = (int8_t)priority;
+    thread->priority_base = (int8_t)priority;
+    os_ThreadListSort(thread);
+    os_ThreadDispatch(NULL);
+  }
+
+  return osOK;
+}
+
+/// Get current priority of a thread.
+/// \note API identical to osThreadGetPriority
+osPriority_t os_svcThreadGetPriority (osThreadId_t thread_id) {
+  os_thread_t *thread = (os_thread_t *)thread_id;
+
+  // Check parameters
+  if ((thread == NULL) ||
+      (thread->id != os_IdThread)) {
+    return osPriorityError;
+  }
+
+  // Check object state
+  if ((thread->state == os_ThreadInactive) ||
+      (thread->state == os_ThreadTerminated)) {
+    return osPriorityError;
+  }
+
+  return ((osPriority_t)thread->priority);
+}
+
+/// Pass control to next thread that is in state READY.
+/// \note API identical to osThreadYield
+osStatus_t os_svcThreadYield (void) {
+  uint8_t      kernel_state;
+  os_thread_t *thread_running;
+  os_thread_t *thread_ready;
+
+  kernel_state   = os_KernelGetState();
+  thread_running = os_ThreadGetRunning();
+  thread_ready   = os_Info.thread.ready.thread_list;
+  if ((kernel_state == os_KernelRunning) &&
+      (thread_ready != NULL) && (thread_running != NULL) &&
+      (thread_ready->priority == thread_running->priority)) {
+    os_ThreadListRemove(thread_ready);
+    os_ThreadReadyPut(thread_running);
+    os_ThreadSwitch(thread_ready);
+  }
+
+  return osOK;
+}
+
+/// Abort waiting operation of a thread.
+/// \note API identical to osThreadAbortWait
+osStatus_t os_svcThreadAbortWait (osThreadId_t thread_id) {
+  os_thread_t *thread = (os_thread_t *)thread_id;
+
+  // Check parameters
+  if ((thread == NULL) ||
+      (thread->id != os_IdThread)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if ((thread->state & os_ThreadStateMask) != os_ThreadWaiting) {
+    return osErrorResource;
+  }
+
+  // Wakeup Thread
+  os_ThreadListRemove(thread);
+  os_ThreadDelayRemove(thread);
+  os_ThreadDispatch(thread);
+
+  return osOK;
+}
+
+/// Suspend execution of a thread.
+/// \note API identical to osThreadSuspend
+osStatus_t os_svcThreadSuspend (osThreadId_t thread_id) {
+  os_thread_t *thread = (os_thread_t *)thread_id;
+
+  // Check parameters
+  if ((thread == NULL) ||
+      (thread->id != os_IdThread)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  switch (thread->state & os_ThreadStateMask) {
+    case os_ThreadRunning:
+      if ((os_KernelGetState() != os_KernelRunning) ||
+          (os_Info.thread.ready.thread_list == NULL)) {
+        return osErrorResource;
+      }
+      os_ThreadSwitch(os_ThreadListGet(&os_Info.thread.ready));
+      break;
+    case os_ThreadReady:
+      os_ThreadListRemove(thread);
+      break;
+    case os_ThreadWaiting:
+      os_ThreadListRemove(thread);
+      os_ThreadDelayRemove(thread);
+      break;
+    case os_ThreadSuspended:
+    case os_ThreadInactive:
+    case os_ThreadTerminated:
+    default:
+      return osErrorResource;
+  }
+
+  // Update Thread State and put it into Suspended Thread list
+  thread->state = os_ThreadSuspended;
+  thread->thread_prev = NULL;
+  thread->thread_next = os_Info.thread.suspended_list;
+  os_Info.thread.suspended_list = thread;
+
+  return osOK;
+}
+
+/// Resume execution of a thread.
+/// \note API identical to osThreadResume
+osStatus_t os_svcThreadResume (osThreadId_t thread_id) {
+  os_thread_t *thread = (os_thread_t *)thread_id;
+
+  // Check parameters
+  if ((thread == NULL) ||
+      (thread->id != os_IdThread)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (thread->state != os_ThreadSuspended) {
+    return osErrorResource;
+  }
+
+  // Remove Thread from Suspended Thread List
+  os_ThreadListUnlink(&os_Info.thread.suspended_list, thread);
+
+  // Dispatch Thread
+  os_ThreadDispatch(thread);
+
+  return osOK;
+}
+
+/// Free Thread resources.
+/// \param[in]  thread          thread object.
+static void os_ThreadFree (os_thread_t *thread) {
+
+  // Mark object as inactive
+  thread->state = os_ThreadInactive;
+
+  // Free stack memory
+  if (thread->flags & os_FlagSystemMemory) {
+    if (thread->flags & os_ThreadFlagDefStack) {
+      os_MemoryPoolFree(os_Info.mpi.stack, thread->stack_mem);
+    } else {
+      os_MemoryFree(os_Info.mem.stack, thread->stack_mem);
+    }
+  }
+
+  // Free object memory
+  if (thread->flags & os_FlagSystemObject) {
+    if (os_Info.mpi.thread != NULL) {
+      os_MemoryPoolFree(os_Info.mpi.thread, thread);
+    } else {
+      os_MemoryFree(os_Info.mem.cb, thread);
+    }
+  }
+}
+
+/// Detach a thread (thread storage can be reclaimed when thread terminates).
+/// \note API identical to osThreadDetach
+osStatus_t os_svcThreadDetach (osThreadId_t thread_id) {
+  os_thread_t *thread = (os_thread_t *)thread_id;
+
+  // Check parameters
+  if ((thread == NULL) ||
+      (thread->id != os_IdThread)) {
+    return osErrorParameter;
+  }
+
+  if (thread->attr & osThreadDetached) {
+    return osErrorResource;
+  }
+
+  // Check object state
+  if (thread->state == os_ThreadInactive) {
+    return osErrorResource;
+  }
+
+  if (thread->state == os_ThreadTerminated) {
+    os_ThreadListUnlink(&os_Info.thread.terminated_list, thread);
+    os_ThreadFree(thread);
+  } else {
+    thread->attr |= osThreadDetached;
+  }
+
+  return osOK;
+}
+
+/// Wait for specified thread to terminate.
+/// \note API identical to osThreadJoin
+osStatus_t os_svcThreadJoin (osThreadId_t thread_id, void **exit_ptr) {
+  os_thread_t *thread = (os_thread_t *)thread_id;
+  uint32_t    *reg;
+
+  // Check parameters
+  if ((thread == NULL) ||
+      (thread->id != os_IdThread)) {
+    return osErrorParameter;
+  }
+
+  if (thread->attr & osThreadDetached) {
+    return osErrorResource;
+  }
+
+  // Check object state
+  if ((thread->state == os_ThreadInactive) ||
+      (thread->state == os_ThreadRunning)) {
+    return osErrorResource;
+  }
+
+  if (thread->state == os_ThreadTerminated) {
+    if ((thread->flags & os_ThreadFlagExitPtr) && (exit_ptr != NULL)) {
+      reg = os_ThreadRegPtr(thread);
+      *exit_ptr = (void *)reg[0];
+    }
+    os_ThreadListUnlink(&os_Info.thread.terminated_list, thread);
+    os_ThreadFree(thread);
+  } else {
+    // Suspend current Thread
+    if (os_ThreadWaitEnter(os_ThreadWaitingJoin, osWaitForever)) {
+      thread->thread_join = os_ThreadGetRunning();
+    }
+    return osErrorResource;
+  }
+
+  return osOK;
+}
+
+/// Terminate execution of current running thread.
+/// \note API identical to osThreadExit
+void os_svcThreadExit (void *exit_ptr) {
+  os_thread_t *thread;
+  uint32_t    *reg;
+  void       **ptr;
+
+  thread = os_ThreadGetRunning();
+  if (thread == NULL) {
+    return;
+  }
+
+  // Release owned Mutexes
+  os_MutexOwnerRelease(thread->mutex_list);
+
+  // Wakeup Thread waiting to Join
+  if (thread->thread_join != NULL) {
+    reg = os_ThreadRegPtr(thread->thread_join);
+    ptr = (void **)reg[1];
+    if (ptr != NULL) {
+      *ptr = exit_ptr;
+    }
+    os_ThreadWaitExit(thread->thread_join, (uint32_t)osOK, false);
+  }
+
+  // Switch to next Ready Thread
+  if ((os_KernelGetState() != os_KernelRunning) ||
+      (os_Info.thread.ready.thread_list == NULL)) {
+    return;
+  }
+  thread->sp = __get_PSP();
+  os_ThreadSwitch(os_ThreadListGet(&os_Info.thread.ready));
+  os_ThreadSetRunning(NULL);
+
+  if (thread->attr & osThreadDetached) {
+    os_ThreadFree(thread);
+  } else {
+    // Update Thread State and put it into Terminated Thread list
+    thread->state  = os_ThreadTerminated;
+    thread->flags |= os_ThreadFlagExitPtr;
+    thread->thread_prev = NULL;
+    thread->thread_next = os_Info.thread.terminated_list;
+    os_Info.thread.terminated_list = thread;
+  }
+}
+
+/// Terminate execution of a thread.
+/// \note API identical to osThreadTerminate
+osStatus_t os_svcThreadTerminate (osThreadId_t thread_id) {
+  os_thread_t *thread = (os_thread_t *)thread_id;
+
+  // Check parameters
+  if ((thread == NULL) ||
+      (thread->id != os_IdThread)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  switch (thread->state & os_ThreadStateMask) {
+    case os_ThreadRunning:
+      break;
+    case os_ThreadReady:
+      os_ThreadListRemove(thread);
+      break;
+    case os_ThreadWaiting:
+      os_ThreadListRemove(thread);
+      os_ThreadDelayRemove(thread);
+      break;
+    case os_ThreadSuspended:
+      os_ThreadListUnlink(&os_Info.thread.suspended_list, thread);
+      break;
+    case os_ThreadInactive:
+    case os_ThreadTerminated:
+    default:
+      return osErrorResource;
+  }
+
+  // Release owned Mutexes
+  os_MutexOwnerRelease(thread->mutex_list);
+
+  // Wakeup Thread waiting to Join
+  if (thread->thread_join != NULL) {
+    os_ThreadWaitExit(thread->thread_join, (uint32_t)osOK, false);
+  }
+
+  // Switch to next Ready Thread when terminating running Thread
+  if (thread->state == os_ThreadRunning) {
+    if ((os_KernelGetState() != os_KernelRunning) ||
+        (os_Info.thread.ready.thread_list == NULL)) {
+      return osErrorResource;
+    }
+    thread->sp = __get_PSP();
+    os_ThreadSwitch(os_ThreadListGet(&os_Info.thread.ready));
+    os_ThreadSetRunning(NULL);
+  } else {
+    os_ThreadDispatch(NULL);
+  }
+
+  if (thread->attr & osThreadDetached) {
+    os_ThreadFree(thread);
+  } else {
+    // Update Thread State and put it into Terminated Thread list
+    thread->state = os_ThreadTerminated;
+    thread->thread_prev = NULL;
+    thread->thread_next = os_Info.thread.terminated_list;
+    os_Info.thread.terminated_list = thread;
+  }
+
+  return osOK;
+}
+
+/// Set the specified Thread Flags of a thread.
+/// \note API identical to osThreadFlagsSet
+int32_t os_svcThreadFlagsSet (osThreadId_t thread_id, int32_t flags) {
+  os_thread_t *thread = (os_thread_t *)thread_id;
+  int32_t      thread_flags;
+  int32_t      thread_flags0;
+
+  // Check parameters
+  if ((thread == NULL) ||
+      (thread->id != os_IdThread)) {
+    return osErrorParameter;
+  }
+  if ((uint32_t)flags & ~((1U << os_ThreadFlagsLimit) - 1U)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if ((thread->state == os_ThreadInactive) ||
+      (thread->state == os_ThreadTerminated)) {
+    return osErrorResource;
+  }
+
+  // Set Thread Flags
+  thread_flags = os_ThreadFlagsSet(thread, flags);
+
+  // Check if Thread is waiting for Thread Flags
+  if (thread->state == os_ThreadWaitingThreadFlags) {
+    thread_flags0 = os_ThreadFlagsCheck(thread, thread->wait_flags, thread->flags_options);
+    if (thread_flags0 > 0) {
+      if ((thread->flags_options & osFlagsAutoClear) != 0U) {
+        thread_flags = thread_flags0 & ~thread->wait_flags;
+      } else {
+        thread_flags = thread_flags0;
+      }
+      os_ThreadWaitExit(thread, (uint32_t)thread_flags0, true);
+    }
+  }
+
+  return thread_flags;
+}
+
+/// Clear the specified Thread Flags of a thread.
+/// \note API identical to osThreadFlagsClear
+int32_t os_svcThreadFlagsClear (osThreadId_t thread_id, int32_t flags) {
+  os_thread_t *thread = (os_thread_t *)thread_id;
+
+  // Check parameters
+  if ((thread == NULL) ||
+      (thread->id != os_IdThread)) {
+    return osErrorParameter;
+  }
+  if ((uint32_t)flags & ~((1U << os_ThreadFlagsLimit) - 1U)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if ((thread->state == os_ThreadInactive) ||
+      (thread->state == os_ThreadTerminated)) {
+    return osErrorResource;
+  }
+
+  // Clear Thread Flags
+  return os_ThreadFlagsClear(thread, flags);
+}
+
+/// Get the current Thread Flags of a thread.
+/// \note API identical to osThreadFlagsGet
+int32_t os_svcThreadFlagsGet (osThreadId_t thread_id) {
+  os_thread_t *thread = (os_thread_t *)thread_id;
+
+  // Check parameters
+  if ((thread == NULL) ||
+      (thread->id != os_IdThread)) {
+    return 0;
+  }
+
+  // Check object state
+  if ((thread->state == os_ThreadInactive) ||
+      (thread->state == os_ThreadTerminated)) {
+    return 0;
+  }
+
+  return thread->thread_flags;
+}
+
+/// Wait for one or more Thread Flags of the current running thread to become signaled.
+/// \note API identical to osThreadFlagsWait
+int32_t os_svcThreadFlagsWait (int32_t flags, uint32_t options, uint32_t millisec) {
+  os_thread_t *thread;
+  int32_t      thread_flags;
+
+  thread = os_ThreadGetRunning();
+  if (thread == NULL) {
+    return osError;
+  }
+
+  // Check parameters
+  if ((uint32_t)flags & ~((1U << os_ThreadFlagsLimit) - 1U)) {
+    return osErrorParameter;
+  }
+
+  // Check Thread Flags
+  thread_flags = os_ThreadFlagsCheck(thread, flags, options);
+  if (thread_flags > 0) {
+    return thread_flags;
+  }
+
+  // Check if timeout is specified
+  if (millisec != 0U) {
+    // Store waiting flags and options
+    thread->wait_flags = flags;
+    thread->flags_options = (uint8_t)options;
+    // Suspend current Thread
+    os_ThreadWaitEnter(os_ThreadWaitingThreadFlags, millisec);
+    return osErrorTimeout;
+  }
+
+  return osErrorResource;
+}
+
+
+//  ==== ISR Calls ====
+
+/// Set the specified Thread Flags of a thread.
+/// \note API identical to osThreadFlagsSet
+__STATIC_INLINE
+int32_t os_isrThreadFlagsSet (osThreadId_t thread_id, int32_t flags) {
+  os_thread_t *thread = (os_thread_t *)thread_id;
+  int32_t      thread_flags;
+
+  // Check parameters
+  if ((thread == NULL) ||
+      (thread->id != os_IdThread)) {
+    return osErrorParameter;
+  }
+  if ((uint32_t)flags & ~((1U << os_ThreadFlagsLimit) - 1U)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if ((thread->state == os_ThreadInactive) ||
+      (thread->state == os_ThreadTerminated)) {
+    return osErrorResource;
+  }
+
+  // Set Thread Flags
+  thread_flags = os_ThreadFlagsSet(thread, flags);
+
+  // Register post ISR processing
+  os_PostProcess((os_object_t *)thread);
+
+  return thread_flags;
+}
+
+
+//  ==== Public API ====
+
+/// Create a thread and add it to Active Threads.
+osThreadId_t osThreadNew (os_thread_func_t func, void *argument, const osThreadAttr_t *attr) {
+  if (__get_IPSR() != 0U) {
+    return (osThreadId_t)NULL;                  // Not allowed in ISR
+  }
+  if ((os_KernelGetState() == os_KernelReady) && ((__get_CONTROL() & 1U) == 0U)) {
+    // Kernel Ready (not running) and in Privileged mode
+    return os_svcThreadNew(func, argument, attr);
+  } else {
+    return  __svcThreadNew(func, argument, attr);
+  }
+}
+
+/// Return the thread ID of the current running thread.
+osThreadId_t osThreadGetId (void) {
+  if (__get_IPSR() != 0U) {
+    return (osThreadId_t)NULL;                  // Not allowed in ISR
+  }
+  return __svcThreadGetId();
+}
+
+/// Get current thread state of a thread.
+osThreadState_t osThreadGetState (osThreadId_t thread_id) {
+  if (__get_IPSR() != 0U) {
+    return osThreadError;                       // Not allowed in ISR
+  }
+  return __svcThreadGetState(thread_id);
+}
+
+/// Change priority of a thread.
+osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcThreadSetPriority(thread_id, priority);
+}
+
+/// Get current priority of a thread.
+osPriority_t osThreadGetPriority (osThreadId_t thread_id) {
+  if (__get_IPSR() != 0U) {
+    return osPriorityError;                     // Not allowed in ISR
+  }
+  return __svcThreadGetPriority(thread_id);
+}
+
+/// Pass control to next thread that is in state READY.
+osStatus_t osThreadYield (void) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcThreadYield();
+}
+
+/// Abort waiting operation of a thread.
+osStatus_t osThreadAbortWait (osThreadId_t thread_id) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcThreadAbortWait(thread_id);
+}
+
+/// Suspend execution of a thread.
+osStatus_t osThreadSuspend (osThreadId_t thread_id) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcThreadSuspend(thread_id);
+}
+
+/// Resume execution of a thread.
+osStatus_t osThreadResume (osThreadId_t thread_id) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcThreadResume(thread_id);
+}
+
+/// Detach a thread (thread storage can be reclaimed when thread terminates).
+osStatus_t osThreadDetach (osThreadId_t thread_id) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcThreadDetach(thread_id);
+}
+
+/// Wait for specified thread to terminate.
+osStatus_t osThreadJoin (osThreadId_t thread_id, void **exit_ptr) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcThreadJoin(thread_id, exit_ptr);
+}
+
+/// Terminate execution of current running thread.
+__NO_RETURN void osThreadExit (void *exit_ptr) {
+  __svcThreadExit(exit_ptr);
+  for (;;);
+}
+
+/// Terminate execution of a thread.
+osStatus_t osThreadTerminate (osThreadId_t thread_id) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcThreadTerminate(thread_id);
+}
+
+/// Set the specified Thread Flags of a thread.
+int32_t osThreadFlagsSet (osThreadId_t thread_id, int32_t flags) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_isrThreadFlagsSet(thread_id, flags);
+  } else {                                      // in Thread
+    return  __svcThreadFlagsSet(thread_id, flags);
+  }
+}
+
+/// Clear the specified Thread Flags of a thread.
+int32_t osThreadFlagsClear (osThreadId_t thread_id, int32_t flags) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_svcThreadFlagsClear(thread_id, flags);
+  } else {                                      // in Thread
+    return  __svcThreadFlagsClear(thread_id, flags);
+  }
+}
+
+/// Get the current Thread Flags of a thread.
+int32_t osThreadFlagsGet (osThreadId_t thread_id) {
+  if (__get_IPSR() != 0U) {                     // in ISR
+    return os_svcThreadFlagsGet(thread_id);
+  } else {                                      // in Thread
+    return  __svcThreadFlagsGet(thread_id);
+  }
+}
+
+/// Wait for one or more Thread Flags of the current running thread to become signaled.
+int32_t osThreadFlagsWait (int32_t flags, uint32_t options, uint32_t millisec) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return  __svcThreadFlagsWait(flags, options, millisec);
+}
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_timer.c b/CMSIS/RTOS2/RTX/Source/rtx_timer.c
new file mode 100644
index 0000000..b557663
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/rtx_timer.c
@@ -0,0 +1,384 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       Timer functions
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#include "rtx_lib.h"
+
+
+//  ==== Helper functions ====
+
+/// Insert Timer into the Timer List sorted by Time.
+/// \param[in]  timer           timer object.
+/// \param[in]  tick            timer tick.
+static void os_TimerInsert (os_timer_t *timer, uint32_t tick) {
+  os_timer_t *prev, *next;
+
+  prev = NULL;
+  next = os_Info.timer.list;
+  while ((next != NULL) && (next->tick <= tick)) {
+    tick -= next->tick;
+    prev  = next;
+    next  = next->next;
+  }
+  timer->tick = tick;
+  timer->prev = prev;
+  timer->next = next;
+  if (next != NULL) {
+    next->tick -= timer->tick;
+    next->prev  = timer;
+  }
+  if (prev != NULL) {
+    prev->next = timer;
+  } else {
+    os_Info.timer.list = timer;
+  }
+}
+
+/// Remove Timer from the Timer List.
+/// \param[in]  timer           timer object.
+static void os_TimerRemove (os_timer_t *timer) {
+
+  if (timer->next != NULL) {
+    timer->next->tick += timer->tick;
+    timer->next->prev  = timer->prev;
+  }
+  if (timer->prev != NULL) {
+    timer->prev->next  = timer->next;
+  } else {
+    os_Info.timer.list = timer->next;
+  }
+}
+
+/// Unlink Timer from the Timer List Head.
+/// \param[in]  timer           timer object.
+static void os_TimerUnlink (os_timer_t *timer) {
+
+  if (timer->next != NULL) {
+    timer->next->prev = timer->prev;
+  }
+  os_Info.timer.list = timer->next;
+}
+
+
+//  ==== Library functions ====
+
+/// Timer Tick (called each SysTick).
+void os_TimerTick (void) {
+  os_timer_t *timer;
+  osStatus_t  status;
+
+  timer = os_Info.timer.list;
+  if (timer == NULL) {
+    return;
+  }
+
+  timer->tick--;
+  while ((timer != NULL) && (timer->tick == 0U)) {
+    os_TimerUnlink(timer);
+    status = osMessageQueuePut((osMessageQueueId_t)os_Info.timer.mq, &timer->finfo, 0U, 0U);
+    if (status != osOK) {
+      os_Error(os_ErrorTimerQueueOverflow, timer);
+    }
+    if (timer->type == os_TimerPeriodic) {
+      os_TimerInsert(timer, timer->load);
+    } else {
+      timer->state = os_TimerStopped;
+    }
+    timer = os_Info.timer.list;
+  }
+}
+
+/// Timer Thread
+void *os_TimerThread (void *argument) {
+  os_timer_finfo_t finfo;
+  osStatus_t       status;
+  (void)           argument;
+
+  for (;;) {
+    status = osMessageQueueGet((osMessageQueueId_t)os_Info.timer.mq, &finfo, NULL, osWaitForever);
+    if (status == osOK) {
+      (*(os_timer_func_t)finfo.fp)(finfo.arg);
+    }
+  }
+  
+  return NULL;
+}
+
+//  ==== Service Calls ====
+
+//  Service Calls definitions
+SVC0_4(TimerNew,       osTimerId_t, os_timer_func_t, osTimerType_t, void *, const osTimerAttr_t *)
+SVC0_2(TimerStart,     osStatus_t,  osTimerId_t, uint32_t)
+SVC0_1(TimerStop,      osStatus_t,  osTimerId_t)
+SVC0_1(TimerIsRunning, uint32_t,    osTimerId_t)
+SVC0_1(TimerDelete,    osStatus_t,  osTimerId_t)
+
+/// Create and Initialize a timer.
+/// \note API identical to osTimerNew
+osTimerId_t os_svcTimerNew (os_timer_func_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) {
+  os_timer_t *timer;
+  uint8_t     flags;
+  const char *name;
+
+  // Create common timer message queue if not yet active
+  if (os_Info.timer.mq == NULL) {
+    os_Info.timer.mq = (os_message_queue_t *)(os_svcMessageQueueNew(
+                                                os_Config.timer_mq_mcnt,
+                                                sizeof(os_timer_finfo_t),
+                                                os_Config.timer_mq_attr));
+    if (os_Info.timer.mq == NULL) {
+      return (osTimerId_t)NULL;
+    }
+  }
+
+  // Create common timer thread if not yet active
+  if (os_Info.timer.thread == NULL) {
+    os_Info.timer.thread = (os_thread_t *)(os_svcThreadNew(
+                                             os_TimerThread,
+                                             NULL,
+                                             os_Config.timer_thread_attr));
+    if (os_Info.timer.thread == NULL) {
+      return (osTimerId_t)NULL;
+    }
+  }
+
+  // Check parameters
+  if ((func == NULL) || ((type != osTimerOnce) && (type != osTimerPeriodic))) {
+    return (osTimerId_t)NULL;
+  }
+
+  // Check timer objects
+  if ((os_Info.timer.thread == NULL) || (os_Info.timer.mq == NULL)) {
+    return (osTimerId_t)NULL;
+  }
+
+  // Process attributes
+  if (attr != NULL) {
+    name  = attr->name;
+    timer = attr->cb_mem;
+    if (timer != NULL) {
+      if (((uint32_t)timer & 3U) || (attr->cb_size < sizeof(os_timer_t))) {
+        return (osTimerId_t)NULL;
+      }
+    } else {
+      if (attr->cb_size != 0U) {
+        return (osTimerId_t)NULL;
+      }
+    }
+  } else {
+    name  = NULL;
+    timer = NULL;
+  }
+
+  // Allocate object memory if not provided
+  if (timer == NULL) {
+    if (os_Info.mpi.timer != NULL) {
+      timer = os_MemoryPoolAlloc(os_Info.mpi.timer);
+    } else {
+      timer = os_MemoryAlloc(os_Info.mem.cb, sizeof(os_timer_t));
+    }
+    if (timer == NULL) {
+      return (osTimerId_t)NULL;
+    }
+    flags = os_FlagSystemObject;
+  } else {
+    flags = 0U;
+  }
+
+  // Initialize control block
+  timer->id        = os_IdTimer;
+  timer->state     = os_TimerStopped;
+  timer->flags     = flags;
+  timer->type      = (uint8_t)type;
+  timer->name      = name;
+  timer->prev      = NULL;
+  timer->next      = NULL;
+  timer->tick      = 0U;
+  timer->load      = 0U;
+  timer->finfo.fp  = (void *)func;
+  timer->finfo.arg = argument;
+
+  return (osTimerId_t)timer;
+}
+
+/// Start or restart a timer.
+/// \note API identical to osTimerStart
+osStatus_t os_svcTimerStart (osTimerId_t timer_id, uint32_t millisec) {
+  os_timer_t *timer = (os_timer_t *)timer_id;
+
+  // Check parameters
+  if ((timer == NULL) ||
+      (timer->id != os_IdTimer)) {
+    return osErrorParameter;
+  }
+  if (millisec == 0U) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  switch (timer->state) {
+    case os_TimerStopped:
+      timer->state = os_TimerRunning;
+      timer->load  = millisec;
+      break;
+    case os_TimerRunning:
+      os_TimerRemove(timer);
+      break;
+    case os_TimerInactive:
+    default:
+      return osErrorResource;
+  }
+
+  os_TimerInsert(timer, millisec);
+
+  return osOK;
+}
+
+/// Stop a timer.
+/// \note API identical to osTimerStop
+osStatus_t os_svcTimerStop (osTimerId_t timer_id) {
+  os_timer_t *timer = (os_timer_t *)timer_id;
+
+  // Check parameters
+  if ((timer == NULL) ||
+      (timer->id != os_IdTimer)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  if (timer->state != os_TimerRunning) {
+    return osErrorResource;
+  }
+
+  timer->state = os_TimerStopped;
+
+  os_TimerRemove(timer);
+
+  return osOK;
+}
+
+/// Check if a timer is running.
+/// \note API identical to osTimerIsRunning
+uint32_t os_svcTimerIsRunning (osTimerId_t timer_id) {
+  os_timer_t *timer = (os_timer_t *)timer_id;
+
+  // Check parameters
+  if ((timer == NULL) ||
+      (timer->id != os_IdTimer)) {
+    return 0U;
+  }
+
+  // Check object state
+  if (timer->state == os_TimerRunning) {
+    return 1U;
+  }
+
+  return 0U;
+}
+
+/// Delete a timer.
+/// \note API identical to osTimerDelete
+osStatus_t os_svcTimerDelete (osTimerId_t timer_id) {
+  os_timer_t *timer = (os_timer_t *)timer_id;
+
+  // Check parameters
+  if ((timer == NULL) ||
+      (timer->id != os_IdTimer)) {
+    return osErrorParameter;
+  }
+
+  // Check object state
+  switch (timer->state) {
+    case os_TimerStopped:
+      break;
+    case os_TimerRunning:
+      os_TimerRemove(timer);
+      break;
+    case os_TimerInactive:
+    default:
+      return osErrorResource;
+  }
+
+  // Mark object as inactive
+  timer->state = os_TimerInactive;
+
+  // Free object memory
+  if (timer->flags & os_FlagSystemObject) {
+    if (os_Info.mpi.timer != NULL) {
+      os_MemoryPoolFree(os_Info.mpi.timer, timer);
+    } else {
+      os_MemoryFree(os_Info.mem.cb, timer);
+    }
+  }
+
+  return osOK;
+}
+
+
+//  ==== Public API ====
+
+/// Create and Initialize a timer.
+osTimerId_t osTimerNew (os_timer_func_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) {
+  if (__get_IPSR() != 0U) {
+    return (osTimerId_t)NULL;                   // Not allowed in ISR
+  }
+  if ((os_KernelGetState() == os_KernelReady) && ((__get_CONTROL() & 1U) == 0U)) {
+    // Kernel Ready (not running) and in Priviledged mode
+    return os_svcTimerNew(func, type, argument, attr);
+  } else {
+    return  __svcTimerNew(func, type, argument, attr);
+  }
+}
+
+/// Start or restart a timer.
+osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t millisec) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcTimerStart(timer_id, millisec);
+}
+
+/// Stop a timer.
+osStatus_t osTimerStop (osTimerId_t timer_id) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcTimerStop(timer_id);
+}
+
+/// Check if a timer is running.
+uint32_t osTimerIsRunning (osTimerId_t timer_id) {
+  if (__get_IPSR() != 0U) {
+    return 0U;                                  // Not allowed in ISR
+  }
+  return __svcTimerIsRunning(timer_id);
+}
+
+/// Delete a timer.
+osStatus_t osTimerDelete (osTimerId_t timer_id) {
+  if (__get_IPSR() != 0U) {
+    return osErrorISR;                          // Not allowed in ISR
+  }
+  return __svcTimerDelete(timer_id);
+}
diff --git a/CMSIS/RTOS2/RTX/Source/user_svc.c b/CMSIS/RTOS2/RTX/Source/user_svc.c
new file mode 100644
index 0000000..bae4d29
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Source/user_svc.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Project:     CMSIS-RTOS RTX
+ * Title:       User SVC Table
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#define USER_SVC_COUNT  0       // Number of user SVC functions
+
+extern void * const os_UserSVC_Table[1+USER_SVC_COUNT];
+       void * const os_UserSVC_Table[1+USER_SVC_COUNT] = {
+  (void *)USER_SVC_COUNT,
+//(void *)user_function1,
+// ...
+};
diff --git a/CMSIS/RTOS2/RTX/Template/main.c b/CMSIS/RTOS2/RTX/Template/main.c
new file mode 100644
index 0000000..09094ee
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Template/main.c
@@ -0,0 +1,28 @@
+/*----------------------------------------------------------------------------
+ * CMSIS-RTOS 'main' function template
+ *---------------------------------------------------------------------------*/
+
+#include "RTE_Components.h"
+#include  CMSIS_device_header
+#include "cmsis_os2.h"
+
+/*----------------------------------------------------------------------------
+ * Application main thread
+ *---------------------------------------------------------------------------*/
+void *app_main (void *argument) {
+
+  // ...
+  for (;;) {}
+}
+
+int main (void) {
+
+  // System Initialization
+  SystemCoreClockUpdate();
+  // ...
+
+  osKernelInitialize();                 // Initialize CMSIS-RTOS
+  osThreadNew(app_main, NULL, NULL);    // Create application main thread
+  osKernelStart();                      // Start thread execution
+  for (;;) {}
+}