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 (;;) {}
+}