RTX5: updated to use OS Tick API
diff --git a/ARM.CMSIS.pdsc b/ARM.CMSIS.pdsc
index 84c7fc6..dbbeccd 100644
--- a/ARM.CMSIS.pdsc
+++ b/ARM.CMSIS.pdsc
@@ -843,18 +843,6 @@
       <require Dcore="ARMV8MML" Ddsp="DSP" Dfpu="SP_FPU"/>
     </condition>
 
-    <!-- Cortex-A Devices -->
-    <condition id="RZ_A Device">
-      <description>Renesas RZ_A Device</description>
-      <require Dvendor="Renesas:117"/>
-      <require Dfamily="RZ_A"/>
-    </condition>
-    <condition id="Unknown Cortex-A Device">
-      <description>Unknown Cortex-A Device</description>
-      <require condition="ARMv7-A Device"/>
-      <deny    condition="RZ_A Device"/>
-    </condition>
-
     <!-- ARMCC compiler -->
     <condition id="CA_ARMCC5">
       <description>Cortex-A5, Cortex-A7 or Cortex-A9 processor based device for the ARM Compiler 5</description>
@@ -1834,12 +1822,19 @@
     </condition>
     <condition id="RTOS2 RTX5">
       <description>Components required for RTOS2 RTX5</description>
-      <accept condition="ARMv6_7_8-M Device"/>
-      <accept condition="ARMv7-A Device"/>
+      <require condition="ARMv6_7_8-M Device"/>
       <require condition="ARMCC GCC IAR"/>
       <require Cclass="CMSIS"  Cgroup="CORE"/>
       <require Cclass="Device" Cgroup="Startup"/>
     </condition>
+    <condition id="RTOS2 RTX5 v7-A">
+      <description>Components required for RTOS2 RTX5 v7-A</description>
+      <require condition="ARMv7-A Device"/>
+      <require condition="ARMCC GCC IAR"/>
+      <require Cclass="CMSIS"  Cgroup="CORE"/>
+      <require Cclass="Device" Cgroup="Startup"/>
+      <require Cclass="Device" Cgroup="OS Tick"/>
+    </condition>
     <condition id="RTOS2 RTX5 Lib">
       <description>Components required for RTOS2 RTX5 Library</description>
       <require condition="ARMv6_7_8-M Device"/>
@@ -2526,12 +2521,8 @@
         <file category="header" name="CMSIS/RTOS2/RTX/Include/rtx_os.h"/>
 
         <!-- RTX configuration -->
-        <file category="header" attr="config"   name="CMSIS/RTOS2/RTX/Config/RTX_Config.h"               version="5.1.0"/>
-        <file category="source" attr="config"   name="CMSIS/RTOS2/RTX/Config/RTX_Config.c"               version="5.1.0" condition="ARMv6_7_8-M Device" />
-        <file category="source" attr="config"   name="CMSIS/RTOS2/RTX/Config/Cortex_A/RTX_Config.c"      version="5.1.0" condition="Unknown Cortex-A Device"/>
-        <file category="source" attr="config"   name="CMSIS/RTOS2/RTX/Config/Renesas/RZ_A/RTX_Config.c"  version="5.1.0" condition="RZ_A Device"/>
-
-        <file category="source" attr="config"   name="CMSIS/RTOS2/RTX/Config/handlers.c"                 version="5.1.0" condition="ARMv7-A Device"/>
+        <file category="header" attr="config"   name="CMSIS/RTOS2/RTX/Config/RTX_Config.h"  version="5.1.0"/>
+        <file category="source" attr="config"   name="CMSIS/RTOS2/RTX/Config/RTX_Config.c"  version="5.1.0"/>
 
         <!-- RTX templates -->
         <file category="source" attr="template" name="CMSIS/RTOS2/RTX/Template/main.c"      version="2.0.0" select="CMSIS-RTOS2 'main' function"/>
@@ -2557,12 +2548,9 @@
         <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_msgqueue.c"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_system.c"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_evr.c"/>
-        <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_gic.c"             condition="ARMv7-A Device"/>
         <!-- RTX sources (library configuration) -->
         <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_lib.c"/>
         <!-- RTX sources (handlers ARMCC) -->
-        <file category="source" name="CMSIS/RTOS2/RTX/Source/ARM/irq_ca.s"          condition="CA_ARMCC5"/>
-        <file category="source" name="CMSIS/RTOS2/RTX/Source/GCC/irq_ca.S"          condition="CA_ARMCC6"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/ARM/irq_cm0.s"         condition="CM0_ARMCC"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/ARM/irq_cm3.s"         condition="CM3_ARMCC"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/ARM/irq_cm3.s"         condition="CM4_ARMCC"/>
@@ -2576,7 +2564,6 @@
         <file category="source" name="CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mml.s"    condition="ARMv8MML_ARMCC"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mml.s"    condition="ARMv8MML_FP_ARMCC"/>
         <!-- RTX sources (handlers GCC) -->
-        <file category="source" name="CMSIS/RTOS2/RTX/Source/GCC/irq_ca.S"          condition="CA_GCC"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/GCC/irq_cm0.S"         condition="CM0_GCC"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/GCC/irq_cm3.S"         condition="CM3_GCC"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/GCC/irq_cm3.S"         condition="CM4_GCC"/>
@@ -2590,13 +2577,71 @@
         <file category="source" name="CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mml.S"    condition="ARMv8MML_GCC"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mml_fp.S" condition="ARMv8MML_FP_GCC"/>
         <!-- RTX sources (handlers IAR) -->
-        <file category="source" name="CMSIS/RTOS2/RTX/Source/IAR/irq_ca.s"          condition="CA_IAR"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/IAR/irq_cm0.s"         condition="CM0_IAR"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/IAR/irq_cm3.s"         condition="CM3_IAR"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/IAR/irq_cm3.s"         condition="CM4_IAR"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/IAR/irq_cm4f.s"        condition="CM4_FP_IAR"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/IAR/irq_cm3.s"         condition="CM7_IAR"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/IAR/irq_cm4f.s"        condition="CM7_FP_IAR"/>
+        <!-- OS Tick (SysTick) -->
+        <file category="source" name="CMSIS/RTOS2/Source/os_systick.c"/>
+      </files>
+    </component>
+    <component Cclass="CMSIS" Cgroup="RTOS2" Csub="Keil RTX5" Cvariant="Source" Cversion="5.2.0" Capiversion="2.1.1" condition="RTOS2 RTX5 v7-A">
+      <description>CMSIS-RTOS2 RTX5 for ARMv7-A (Source)</description>
+      <RTE_Components_h>
+        <!-- the following content goes into file 'RTE_Components.h' -->
+        #define RTE_CMSIS_RTOS2                 /* CMSIS-RTOS2 */
+        #define RTE_CMSIS_RTOS2_RTX5            /* CMSIS-RTOS2 Keil RTX5 */
+        #define RTE_CMSIS_RTOS2_RTX5_SOURCE     /* CMSIS-RTOS2 Keil RTX5 Source */
+      </RTE_Components_h>
+      <files>
+        <!-- RTX documentation -->
+        <file category="doc"    name="CMSIS/Documentation/RTOS2/html/rtx5_impl.html"/>
+
+        <!-- RTX header files -->
+        <file category="header" name="CMSIS/RTOS2/RTX/Include/rtx_os.h"/>
+
+        <!-- RTX configuration -->
+        <file category="header" attr="config"   name="CMSIS/RTOS2/RTX/Config/RTX_Config.h"  version="5.1.0"/>
+        <file category="source" attr="config"   name="CMSIS/RTOS2/RTX/Config/RTX_Config.c"  version="5.1.0"/>
+
+        <file category="source" attr="config"   name="CMSIS/RTOS2/RTX/Config/handlers.c"    version="5.1.0"/>
+
+        <!-- RTX templates -->
+        <file category="source" attr="template" name="CMSIS/RTOS2/RTX/Template/main.c"      version="2.0.0" select="CMSIS-RTOS2 'main' function"/>
+        <file category="source" attr="template" name="CMSIS/RTOS2/RTX/Template/Events.c"    version="2.0.0" select="CMSIS-RTOS2 Events"/>
+        <file category="source" attr="template" name="CMSIS/RTOS2/RTX/Template/MemPool.c"   version="2.0.0" select="CMSIS-RTOS2 Memory Pool"/>
+        <file category="source" attr="template" name="CMSIS/RTOS2/RTX/Template/MsgQueue.c"  version="2.0.0" select="CMSIS-RTOS2 Message Queue"/>
+        <file category="source" attr="template" name="CMSIS/RTOS2/RTX/Template/Mutex.c"     version="2.0.0" select="CMSIS-RTOS2 Mutex"/>
+        <file category="source" attr="template" name="CMSIS/RTOS2/RTX/Template/Semaphore.c" version="2.0.0" select="CMSIS-RTOS2 Semaphore"/>
+        <file category="source" attr="template" name="CMSIS/RTOS2/RTX/Template/Thread.c"    version="2.0.0" select="CMSIS-RTOS2 Thread"/>
+        <file category="source" attr="template" name="CMSIS/RTOS2/RTX/Template/Timer.c"     version="2.0.0" select="CMSIS-RTOS2 Timer"/>
+        <file category="other"  name="CMSIS/RTOS2/RTX/RTX5.scvd"/>
+
+        <!-- RTX sources (core) -->
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_kernel.c"/>
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_thread.c"/>
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_delay.c"/>
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_timer.c"/>
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_evflags.c"/>
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_mutex.c"/>
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_semaphore.c"/>
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_memory.c"/>
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_mempool.c"/>
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_msgqueue.c"/>
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_system.c"/>
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_evr.c"/>
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_gic.c"/>
+        <!-- RTX sources (library configuration) -->
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/rtx_lib.c"/>
+        <!-- RTX sources (handlers ARMCC) -->
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/ARM/irq_ca.s"          condition="CA_ARMCC5"/>
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/GCC/irq_ca.S"          condition="CA_ARMCC6"/>
+        <!-- RTX sources (handlers GCC) -->
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/GCC/irq_ca.S"          condition="CA_GCC"/>
+        <!-- RTX sources (handlers IAR) -->
+        <file category="source" name="CMSIS/RTOS2/RTX/Source/IAR/irq_ca.s"          condition="CA_IAR"/>
       </files>
     </component>
     <component Cclass="CMSIS" Cgroup="RTOS2" Csub="Keil RTX5" Cvariant="Source_NS" Cversion="5.2.0" Capiversion="2.1.1" condition="RTOS2 RTX5 NS">
@@ -2659,6 +2704,8 @@
         <file category="source" name="CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mbl_ns.S"    condition="ARMv8MBL_GCC"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mml_ns.S"    condition="ARMv8MML_GCC"/>
         <file category="source" name="CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mml_fp_ns.S" condition="ARMv8MML_FP_GCC"/>
+        <!-- OS Tick (SysTick) -->
+        <file category="source" name="CMSIS/RTOS2/Source/os_systick.c"/>
       </files>
     </component>
 
diff --git a/CMSIS/RTOS2/RTX/Config/Cortex_A/RTX_Config.c b/CMSIS/RTOS2/RTX/Config/Cortex_A/RTX_Config.c
deleted file mode 100644
index 7e640ad..0000000
--- a/CMSIS/RTOS2/RTX/Config/Cortex_A/RTX_Config.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2013-2017 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
- *
- * 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.1.0
- *
- * Project:     CMSIS-RTOS RTX
- * Title:       RTX Configuration
- *
- * -----------------------------------------------------------------------------
- */
- 
-#include "RTE_Components.h"
-#include CMSIS_device_header
-
-#include "rtx_os.h"
-
-
-// Setup System Timer.
-// \return system timer IRQ number.
-int32_t osRtxSysTimerSetup (void) {
-  // ...
-  return (0);
-}
-
-// Enable System Timer.
-void osRtxSysTimerEnable (void) {
-  // ...
-}
-
-// Disable System Timer.
-void osRtxSysTimerDisable (void) {
-  // ...
-}
-
-// Acknowledge System Timer IRQ.
-void osRtxSysTimerAckIRQ (void) {
-  // ...
-}
-
-// Get System Timer count.
-// \return system timer count.
-uint32_t osRtxSysTimerGetCount (void) {
-  // ...
-  return (0U);
-}
-
-// Get System Timer frequency.
-// \return system timer frequency.
-uint32_t osRtxSysTimerGetFreq (void) {
-  // ...
-  return (1000000U);
-}
-
-
-// OS Idle Thread
-__WEAK __NO_RETURN void osRtxIdleThread (void *argument) {
-  (void)argument;
-
-  for (;;) {}
-}
- 
-// OS Error Callback function
-__WEAK uint32_t osRtxErrorNotify (uint32_t code, void *object_id) {
-  (void)object_id;
-
-  switch (code) {
-    case osRtxErrorStackUnderflow:
-      // Stack underflow detected for thread (thread_id=object_id)
-      break;
-    case osRtxErrorISRQueueOverflow:
-      // ISR Queue overflow detected when inserting object (object_id)
-      break;
-    case osRtxErrorTimerQueueOverflow:
-      // User Timer Callback Queue overflow detected for timer (timer_id=object_id)
-      break;
-    case osRtxErrorClibSpace:
-      // Standard C/C++ library libspace not available: increase OS_THREAD_LIBSPACE_NUM
-      break;
-    case osRtxErrorClibMutex:
-      // Standard C/C++ library mutex initialization failed
-      break;
-    default:
-      break;
-  }
-  for (;;) {}
-//return 0U;
-}
diff --git a/CMSIS/RTOS2/RTX/Config/Renesas/RZ_A/RTX_Config.c b/CMSIS/RTOS2/RTX/Config/Renesas/RZ_A/RTX_Config.c
deleted file mode 100644
index 8058771..0000000
--- a/CMSIS/RTOS2/RTX/Config/Renesas/RZ_A/RTX_Config.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (c) 2013-2017 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
- *
- * 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.1.0
- *
- * Project:     CMSIS-RTOS RTX
- * Title:       RTX Configuration
- *
- * -----------------------------------------------------------------------------
- */
- 
-#include "RTE_Components.h"
-#include CMSIS_device_header
-
-#include "rtx_os.h"
-
-
-// Define OS Timer channel and interrupt number
-#define OSTM                        OSTM0
-#define OSTM_IRQn                   OSTMI0TINT_IRQn
-
-static uint32_t ExtTim_Cnt;         // Timer count used for overflow detection
-static uint32_t ExtTim_Freq;        // Timer frequency
-
-
-// Get OS Timer current count value
-__STATIC_INLINE uint32_t OSTM_GetCount(void) {
-  ExtTim_Cnt = OSTM.OSTMnCNT;
-  return  (OSTM.OSTMnCMP - ExtTim_Cnt);
-}
-
-// Check if OS Timer counter was reloaded
-__STATIC_INLINE uint32_t OSTM_GetOverflow(void) {
-  return ((OSTM.OSTMnCNT > ExtTim_Cnt) ? (1U) : (0U));
-}
-
-// Get OS Timer period
-__STATIC_INLINE uint32_t OSTM_GetPeriod(void) {
-  return (OSTM.OSTMnCMP + 1U);
-}
-
-
-// Setup System Timer.
-// \return system timer IRQ number.
-int32_t osRtxSysTimerSetup (void) {
-  uint32_t freq;
-
-  // Get CPG.FRQCR[IFC] bits
-  freq = (CPG.FRQCR >> 8) & 0x03;
-
-  // Determine Divider 2 output clock by using SystemCoreClock
-  if (freq == 0x03U) {
-    freq = (SystemCoreClock * 3U);
-  }
-  else if (freq == 0x01U) {
-    freq = (SystemCoreClock * 3U)/2U;
-  }
-  else {
-    freq = SystemCoreClock;
-  }
-  // Peripheral clock 0C = (Divider 2 clock * 1/12)
-  freq = freq / 12U;
-
-  // Determine tick frequency
-  freq = freq / osRtxConfig.tick_freq;
-
-  // Save frequency for later
-  ExtTim_Freq = freq;
-
-  // Enable OSTM clock
-  CPG.STBCR5 &= ~(CPG_STBCR5_BIT_MSTP51);
-
-  // Stop the OSTM counter
-  OSTM.OSTMnTT  = 0x01U;
-
-  // Set interval timer mode and disable interrupts when counting starts
-  OSTM.OSTMnCTL = 0x00U;
-
-  // Set compare value
-  OSTM.OSTMnCMP = freq - 1U;
-
-  return (OSTM_IRQn);
-}
-
-// Enable System Timer.
-void osRtxSysTimerEnable (void) {
-  /* Start the OSTM counter */
-  OSTM.OSTMnTS = 0x01U;
-}
-
-// Disable System Timer.
-void osRtxSysTimerDisable (void) {
-  // Stop the OSTM counter
-  OSTM.OSTMnTT = 0x01U;
-}
-
-// Acknowledge System Timer IRQ.
-void osRtxSysTimerAckIRQ (void) {
-  // Acknowledge OSTM interrupt
-  GIC_ClearPendingIRQ (OSTM_IRQn);
-}
-
-// Get System Timer count.
-// \return system timer count.
-uint32_t osRtxSysTimerGetCount (void) {
-  uint32_t tick;
-  uint32_t val;
-
-  tick = (uint32_t)osRtxInfo.kernel.tick;
-  val  = OSTM_GetCount();
-  if (OSTM_GetOverflow()) {
-    val = OSTM_GetCount();
-    tick++;
-  }
-  val += tick * OSTM_GetPeriod();
-
-  return val;
-}
-
-// Get System Timer frequency.
-// \return system timer frequency.
-uint32_t osRtxSysTimerGetFreq (void) {
-  return ExtTim_Freq;
-}
-
-
-// OS Idle Thread
-__WEAK __NO_RETURN void osRtxIdleThread (void *argument) {
-  (void)argument;
-
-  for (;;) {}
-}
- 
-// OS Error Callback function
-__WEAK uint32_t osRtxErrorNotify (uint32_t code, void *object_id) {
-  (void)object_id;
-
-  switch (code) {
-    case osRtxErrorStackUnderflow:
-      // Stack underflow detected for thread (thread_id=object_id)
-      break;
-    case osRtxErrorISRQueueOverflow:
-      // ISR Queue overflow detected when inserting object (object_id)
-      break;
-    case osRtxErrorTimerQueueOverflow:
-      // User Timer Callback Queue overflow detected for timer (timer_id=object_id)
-      break;
-    case osRtxErrorClibSpace:
-      // Standard C/C++ library libspace not available: increase OS_THREAD_LIBSPACE_NUM
-      break;
-    case osRtxErrorClibMutex:
-      // Standard C/C++ library mutex initialization failed
-      break;
-    default:
-      break;
-  }
-  for (;;) {}
-//return 0U;
-}
diff --git a/CMSIS/RTOS2/RTX/Include/rtx_os.h b/CMSIS/RTOS2/RTX/Include/rtx_os.h
index 2ce7de1..f4cfbad 100644
--- a/CMSIS/RTOS2/RTX/Include/rtx_os.h
+++ b/CMSIS/RTOS2/RTX/Include/rtx_os.h
@@ -38,7 +38,7 @@
  
 /// Kernel Information
 #define osRtxVersionAPI      20010001   ///< API version (2.1.1)
-#define osRtxVersionKernel   50020001   ///< Kernel version (5.2.0)
+#define osRtxVersionKernel   50020000   ///< Kernel version (5.2.0)
 #define osRtxKernelId     "RTX V5.2.0"  ///< Kernel identification string
  
  
@@ -282,11 +282,9 @@
   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                 sys_freq;  ///< System Frequency
+    uint8_t                  reserved;
     uint32_t                     tick;  ///< Tick counter
-    uint32_t                 reserved;
   } kernel;
   int32_t                   tick_irqn;  ///< Tick Timer IRQ Number
   struct {                              ///< Thread Info
@@ -341,7 +339,6 @@
     osRtxMpInfo_t        *memory_pool;  ///< Memory Pool Control Blocks
     osRtxMpInfo_t      *message_queue;  ///< Message Queue Control Blocks
   } mpi;
-  uint32_t                    padding;
 } osRtxInfo_t;
  
 extern osRtxInfo_t osRtxInfo;           ///< OS Runtime Information
@@ -398,30 +395,6 @@
 extern void SysTick_Handler (void);
  
  
-/// OS System Timer functions (default implementation uses SysTick)
- 
-/// Setup System Timer.
-/// \return system timer IRQ number.
-extern int32_t osRtxSysTimerSetup (void);
- 
-/// Enable System Timer.
-extern void osRtxSysTimerEnable (void);
- 
-/// Disable System Timer.
-extern void osRtxSysTimerDisable (void);
- 
-/// Acknowledge System Timer IRQ.
-extern void osRtxSysTimerAckIRQ (void);
- 
-/// Get System Timer count.
-/// \return system timer count.
-extern uint32_t osRtxSysTimerGetCount (void);
- 
-/// Get System Timer frequency.
-/// \return system timer frequency.
-extern uint32_t osRtxSysTimerGetFreq (void);
- 
- 
 //  ==== OS External Configuration ====
  
 /// OS Configuration flags
diff --git a/CMSIS/RTOS2/RTX/RTX5.scvd b/CMSIS/RTOS2/RTX/RTX5.scvd
index b75b9a2..27eb2e9 100644
--- a/CMSIS/RTOS2/RTX/RTX5.scvd
+++ b/CMSIS/RTOS2/RTX/RTX5.scvd
@@ -342,7 +342,7 @@
     </typedef>
 
     <!-- OS Runtime Information structure -->
-    <typedef name="osRtxInfo_t" info="OS Runtime Information" size="172">
+    <typedef name="osRtxInfo_t" info="OS Runtime Information" size="164">
       <member name="os_id"                      type="uint32_t"             offset="0" info="OS Identification (type is *uint8_t)"/>
       <member name="version"                    type="uint32_t"             offset="4" info="OS Version"/>
       <member name="kernel_state"               type="uint8_t"              offset="8" info="Kernel state">
@@ -354,61 +354,59 @@
         <enum name="osKernelError"     value="5"  info="Error"/>
       </member>
       <member name="kernel_blocked"             type="uint8_t"              offset="9"  info="Kernel blocked"/>
-      <member name="kernel_pendISR"             type="uint8_t"              offset="10" info="Kernel pending ISR"/>
-      <member name="kernel_pendSV"              type="uint8_t"              offset="11" info="Kernel pending SV"/>
-      <member name="kernel_sys_freq"            type="uint32_t"             offset="12" info="Kernel system frequency"/>
-      <member name="kernel_tick"                type="uint32_t"             offset="16" info="Kernel tick counter"/>
-      <member name="tick_irqn"                  type="int32_t"              offset="24" info="Tick timer IRQ number"/>
-      <member name="thread_run_curr"            type="*osRtxThread_t"       offset="28" info="Current running thread"/>
-      <member name="thread_run_next"            type="*osRtxThread_t"       offset="32" info="Next thread to run"/>
+      <member name="kernel_pendSV"              type="uint8_t"              offset="10" info="Kernel pending SV"/>
+      <member name="kernel_tick"                type="uint32_t"             offset="12" info="Kernel tick counter"/>
+      <member name="tick_irqn"                  type="int32_t"              offset="16" info="Tick timer IRQ number"/>
+      <member name="thread_run_curr"            type="*osRtxThread_t"       offset="20" info="Current running thread"/>
+      <member name="thread_run_next"            type="*osRtxThread_t"       offset="24" info="Next thread to run"/>
 
-      <!-- Inlined "osRtxObject_t" structure at offset: 36 -->
-      <member name="thread_ready_id"            type="uint8_t"              offset="36+0" info="Object Identifier" />
-      <member name="thread_ready_state"         type="uint8_t"              offset="36+1" info="Object State" />
-      <member name="thread_ready_flags"         type="uint8_t"              offset="36+2" info="Object Flags" />
-      <member name="thread_ready_rsvd"          type="uint8_t"              offset="36+3" info="Reserved" />
-      <member name="thread_ready_name"          type="uint32_t"             offset="36+4" info="Object Name (type is *uint8_t)" />
-      <member name="thread_ready_thread_list"   type="*osRtxThread_t"       offset="36+8" info="Threads List" />
+      <!-- Inlined "osRtxObject_t" structure at offset: 28 -->
+      <member name="thread_ready_id"            type="uint8_t"              offset="28+0" info="Object Identifier" />
+      <member name="thread_ready_state"         type="uint8_t"              offset="28+1" info="Object State" />
+      <member name="thread_ready_flags"         type="uint8_t"              offset="28+2" info="Object Flags" />
+      <member name="thread_ready_rsvd"          type="uint8_t"              offset="28+3" info="Reserved" />
+      <member name="thread_ready_name"          type="uint32_t"             offset="28+4" info="Object Name (type is *uint8_t)" />
+      <member name="thread_ready_thread_list"   type="*osRtxThread_t"       offset="28+8" info="Threads List" />
 
-      <member name="thread_idle"                type="*osRtxThread_t"       offset="48"  info="Idle thread"/>
-      <member name="thread_delay_list"          type="*osRtxThread_t"       offset="52"  info="Delay list"/>
-      <member name="thread_wait_list"           type="*osRtxThread_t"       offset="56"  info="Wait list (no timeout)"/>
-      <member name="thread_terminate_list"      type="*osRtxThread_t"       offset="60"  info="Terminate list"/>
+      <member name="thread_idle"                type="*osRtxThread_t"       offset="40"  info="Idle thread"/>
+      <member name="thread_delay_list"          type="*osRtxThread_t"       offset="44"  info="Delay list"/>
+      <member name="thread_wait_list"           type="*osRtxThread_t"       offset="48"  info="Wait list (no timeout)"/>
+      <member name="thread_terminate_list"      type="*osRtxThread_t"       offset="52"  info="Terminate list"/>
 
-      <member name="thread_robin_thread"        type="*osRtxThread_t"       offset="64"  info="Round Robin thread"/>
-      <member name="thread_robin_tick"          type="uint32_t"             offset="68"  info="Round Robin time tick"/>
-      <member name="thread_timeout"             type="uint32_t"             offset="72"  info="Round Robin timeout"/>
+      <member name="thread_robin_thread"        type="*osRtxThread_t"       offset="56"  info="Round Robin thread"/>
+      <member name="thread_robin_tick"          type="uint32_t"             offset="60"  info="Round Robin time tick"/>
+      <member name="thread_timeout"             type="uint32_t"             offset="64"  info="Round Robin timeout"/>
 
-      <member name="timer_list"                 type="*osRtxTimer_t"        offset="76"  info="Active timer list"/>
-      <member name="timer_thread"               type="*osRtxThread_t"       offset="80"  info="Timer thread"/>
-      <member name="timer_mq"                   type="*osRtxMessageQueue_t" offset="84"  info="Timer message queue"/>
-      <member name="timer_tick"                 type="uint32_t"             offset="88"  info="Timer tick function (type is func *)"/>
+      <member name="timer_list"                 type="*osRtxTimer_t"        offset="68"  info="Active timer list"/>
+      <member name="timer_thread"               type="*osRtxThread_t"       offset="72"  info="Timer thread"/>
+      <member name="timer_mq"                   type="*osRtxMessageQueue_t" offset="76"  info="Timer message queue"/>
+      <member name="timer_tick"                 type="uint32_t"             offset="80"  info="Timer tick function (type is func *)"/>
 
-      <member name="isr_queue_max"              type="uint16_t"             offset="92"  info="Maximum items"/>
-      <member name="isr_queue_cnt"              type="uint16_t"             offset="94"  info="Item count"/>
-      <member name="isr_queue_in"               type="uint16_t"             offset="96"  info="Incoming item index"/>
-      <member name="isr_queue_out"              type="uint16_t"             offset="98"  info="Outgoing item index"/>
-      <member name="isr_queue_data"             type="uint32_t"             offset="100" info="Queue data (type is void **)"/>
+      <member name="isr_queue_max"              type="uint16_t"             offset="84"  info="Maximum items"/>
+      <member name="isr_queue_cnt"              type="uint16_t"             offset="86"  info="Item count"/>
+      <member name="isr_queue_in"               type="uint16_t"             offset="88"  info="Incoming item index"/>
+      <member name="isr_queue_out"              type="uint16_t"             offset="90"  info="Outgoing item index"/>
+      <member name="isr_queue_data"             type="uint32_t"             offset="92"  info="Queue data (type is void **)"/>
 
-      <member name="post_process_thread"        type="uint32_t"             offset="104" info="Thread post processing function (type is func *)"/>
-      <member name="post_process_event_flags"   type="uint32_t"             offset="108" info="Event flags post processing function (type is func *)"/>
-      <member name="post_process_semaphore"     type="uint32_t"             offset="112" info="Semaphore post processing function (type is func *)"/>
-      <member name="post_process_memory_pool"   type="uint32_t"             offset="116" info="Memory pool post processing function (type is func *)"/>
-      <member name="post_process_message_queue" type="uint32_t"             offset="120" info="Message queue post processing function (type is func *)"/>
+      <member name="post_process_thread"        type="uint32_t"             offset="96"  info="Thread post processing function (type is func *)"/>
+      <member name="post_process_event_flags"   type="uint32_t"             offset="100" info="Event flags post processing function (type is func *)"/>
+      <member name="post_process_semaphore"     type="uint32_t"             offset="104" info="Semaphore post processing function (type is func *)"/>
+      <member name="post_process_memory_pool"   type="uint32_t"             offset="108" info="Memory pool post processing function (type is func *)"/>
+      <member name="post_process_message_queue" type="uint32_t"             offset="112" info="Message queue post processing function (type is func *)"/>
 
-      <member name="mem_stack"                  type="uint32_t"             offset="124" info="Stack memory (type is void *)"/>
-      <member name="mem_mp_data"                type="uint32_t"             offset="128" info="Memory pool data memory (type is void *)"/>
-      <member name="mem_mq_data"                type="uint32_t"             offset="132" info="Message queue Data memory (type is void *)"/>
-      <member name="mem_common"                 type="uint32_t"             offset="136" info="Common memory address (type is void *)"/>
+      <member name="mem_stack"                  type="uint32_t"             offset="116" info="Stack memory (type is void *)"/>
+      <member name="mem_mp_data"                type="uint32_t"             offset="120" info="Memory pool data memory (type is void *)"/>
+      <member name="mem_mq_data"                type="uint32_t"             offset="124" info="Message queue Data memory (type is void *)"/>
+      <member name="mem_common"                 type="uint32_t"             offset="128" info="Common memory address (type is void *)"/>
 
-      <member name="mpi_stack"                  type="*osRtxMpInfo_t"       offset="140" info="Stack for threads"/>
-      <member name="mpi_thread"                 type="*osRtxMpInfo_t"       offset="144" info="Thread control blocks"/>
-      <member name="mpi_timer"                  type="*osRtxMpInfo_t"       offset="148" info="Timer control blocks"/>
-      <member name="mpi_event_flags"            type="*osRtxMpInfo_t"       offset="152" info="Event flags control blocks"/>
-      <member name="mpi_mutex"                  type="*osRtxMpInfo_t"       offset="156" info="Mutex control blocks"/>
-      <member name="mpi_semaphore"              type="*osRtxMpInfo_t"       offset="160" info="Semaphore control blocks"/>
-      <member name="mpi_memory_pool"            type="*osRtxMpInfo_t"       offset="164" info="Memory pool control blocks"/>
-      <member name="mpi_message_queue"          type="*osRtxMpInfo_t"       offset="168" info="Message queue control blocks"/>
+      <member name="mpi_stack"                  type="*osRtxMpInfo_t"       offset="132" info="Stack for threads"/>
+      <member name="mpi_thread"                 type="*osRtxMpInfo_t"       offset="136" info="Thread control blocks"/>
+      <member name="mpi_timer"                  type="*osRtxMpInfo_t"       offset="140" info="Timer control blocks"/>
+      <member name="mpi_event_flags"            type="*osRtxMpInfo_t"       offset="144" info="Event flags control blocks"/>
+      <member name="mpi_mutex"                  type="*osRtxMpInfo_t"       offset="148" info="Mutex control blocks"/>
+      <member name="mpi_semaphore"              type="*osRtxMpInfo_t"       offset="152" info="Semaphore control blocks"/>
+      <member name="mpi_memory_pool"            type="*osRtxMpInfo_t"       offset="156" info="Memory pool control blocks"/>
+      <member name="mpi_message_queue"          type="*osRtxMpInfo_t"       offset="160" info="Message queue control blocks"/>
     </typedef>
 
     <!-- OS Configuration structure -->
@@ -1070,7 +1068,6 @@
           <item property="Kernel State" value="%E[os_Info.kernel_state]" cond="RTX_En != 0"/>
           <item property="Kernel Tick Count"      value="%d[os_Info.kernel_tick]"     cond="RTX_En != 0"/>
           <item property="Kernel Tick Frequency"  value="%d[os_Config.tick_freq]"     cond="RTX_En != 0" />          
-          <item property="System Timer Frequency" value="%d[os_Info.kernel_sys_freq]" cond="RTX_En != 0" />
           <item property="Round Robin"            value="Disabled"                      cond="(os_Config.robin_timeout == 0) &amp;&amp; (RTX_En != 0)" />
           <item property="Round Robin Tick Count" value="%d[os_Info.thread_robin_tick]" cond="(os_Config.robin_timeout > 0)  &amp;&amp; (RTX_En != 0)" />
           <item property="Round Robin Timeout"    value="%d[os_Config.robin_timeout]"   cond="(os_Config.robin_timeout > 0)  &amp;&amp; (RTX_En != 0)" />
diff --git a/CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mbl.s b/CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mbl.s
index 22baabd..1586a95 100644
--- a/CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mbl.s
+++ b/CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mbl.s
@@ -28,7 +28,7 @@
 __DOMAIN_NS     EQU      0
                 ENDIF
 
-I_T_RUN_OFS     EQU      28                     ; osRtxInfo.thread.run offset
+I_T_RUN_OFS     EQU      20                     ; osRtxInfo.thread.run offset
 TCB_SM_OFS      EQU      48                     ; TCB.stack_mem offset
 TCB_SP_OFS      EQU      56                     ; TCB.SP offset
 TCB_SF_OFS      EQU      34                     ; TCB.stack_frame offset
diff --git a/CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mml.s b/CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mml.s
index f6d7c95..b8b25a1 100644
--- a/CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mml.s
+++ b/CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mml.s
@@ -34,7 +34,7 @@
 __FPU_USED      EQU      0
                 ENDIF
 
-I_T_RUN_OFS     EQU      28                     ; osRtxInfo.thread.run offset
+I_T_RUN_OFS     EQU      20                     ; osRtxInfo.thread.run offset
 TCB_SM_OFS      EQU      48                     ; TCB.stack_mem offset
 TCB_SP_OFS      EQU      56                     ; TCB.SP offset
 TCB_SF_OFS      EQU      34                     ; TCB.stack_frame offset
diff --git a/CMSIS/RTOS2/RTX/Source/ARM/irq_ca.s b/CMSIS/RTOS2/RTX/Source/ARM/irq_ca.s
index b7e89e8..87f7c07 100644
--- a/CMSIS/RTOS2/RTX/Source/ARM/irq_ca.s
+++ b/CMSIS/RTOS2/RTX/Source/ARM/irq_ca.s
@@ -18,17 +18,11 @@
 ; * -----------------------------------------------------------------------------
 ; *
 ; * Project:     CMSIS-RTOS RTX
-; * Title:       Cortex-A Exception handlers (using GIC)
+; * Title:       Cortex-A Exception handlers
 ; *
 ; * -----------------------------------------------------------------------------
 ; */
 
-ICDABR0_OFFSET  EQU      0x00000300                 ; GICD: Active Bit Register 0 offset
-ICDIPR0_OFFSET  EQU      0x00000400                 ; GICD: Interrupt Priority Register 0 offset
-ICCIAR_OFFSET   EQU      0x0000000C                 ; GICI: Interrupt Acknowledge Register offset
-ICCEOIR_OFFSET  EQU      0x00000010                 ; GICI: End of Interrupt Register offset
-ICCHPIR_OFFSET  EQU      0x00000018                 ; GICI: Highest Pending Interrupt Register offset
-
 MODE_FIQ        EQU      0x11
 MODE_IRQ        EQU      0x12
 MODE_SVC        EQU      0x13
@@ -37,7 +31,7 @@
 
 CPSR_BIT_T      EQU      0x20
 
-I_T_RUN_OFS     EQU      28                         ; osRtxInfo.thread.run offset
+I_T_RUN_OFS     EQU      20                         ; osRtxInfo.thread.run offset
 TCB_SP_FRAME    EQU      34                         ; osRtxThread_t.stack_frame offset
 TCB_SP_OFS      EQU      56                         ; osRtxThread_t.sp offset
 
@@ -52,7 +46,10 @@
 
 
                 AREA     |.data|, DATA, READWRITE
-ID0_Active      DCB      4                          ; Flag used to workaround GIC 390 errata 733075
+                EXPORT   IRQ_PendSV
+IRQ_NestLevel   DCD      0                          ; IRQ nesting level counter
+IRQ_PendSV      DCB      0                          ; Pending SVC flag
+SVC_Active      DCB      0                          ; SVC handler execution active flag
 
 
                 AREA     |.text|, CODE, READONLY
@@ -168,100 +165,96 @@
 IRQ_Handler\
                 PROC
                 EXPORT  IRQ_Handler
-                IMPORT  IRQTable
-                IMPORT  IRQCount
-                IMPORT  osRtxIrqHandler
-                IMPORT  irqRtxGicBase
+                IMPORT  osRtxInfo
+                IMPORT  osRtxIrqGetId
+                IMPORT  osRtxIrqGetHandler
+                IMPORT  osRtxIrqSetEnd
 
                 SUB     LR, LR, #4                  ; Pre-adjust LR
                 SRSFD   SP!, #MODE_IRQ              ; Save LR_irq and SPRS_irq
                 PUSH    {R0-R3, R12, LR}            ; Save APCS corruptible registers
 
-                ; Identify and acknowledge interrupt
-                LDR     R1, =irqRtxGicBase;
-                LDR     R1, [R1, #4]
-                LDR     R0, [R1, #ICCHPIR_OFFSET]   ; Dummy Read GICI ICCHPIR to avoid GIC 390 errata 801120
-                LDR     R0, [R1, #ICCIAR_OFFSET]    ; Read GICI ICCIAR
-                DSB                                 ; Ensure that interrupt acknowledge completes before re-enabling interrupts
+                MOV     R3, SP                      ; Move SP into R3
+                AND     R3, R3, #4                  ; Get stack adjustment to ensure 8-byte alignment
+                SUB     SP, SP, R3                  ; Adjust stack
+                PUSH    {R3, R4}                    ; Store stack adjustment(R3) and user data(R4)
 
-                ; Workaround GIC 390 errata 733075 - see GIC-390_Errata_Notice_v6.pdf dated 09-Jul-2014
-                ; The following workaround code is for a single-core system.  It would be different in a multi-core system.
-                ; If the ID is 0 or 0x3FE or 0x3FF, then the GIC CPU interface may be locked-up so unlock it, otherwise service the interrupt as normal
-                ; Special IDs 1020=0x3FC and 1021=0x3FD are reserved values in GICv1 and GICv2 so will not occur here
-                CMP     R0, #0
-                BEQ     IRQ_Unlock
-                MOV     R2, #0x3FE
-                CMP     R0, R2
-                BLT     IRQ_Normal
-IRQ_Unlock
-                ; Unlock the CPU interface with a dummy write to ICDIPR0
-                LDR     R2, =irqRtxGicBase
-                LDR     R2, [R2]
-                LDR     R3, [R2, #ICDIPR0_OFFSET]
-                STR     R3, [R2, #ICDIPR0_OFFSET]
-                DSB                                 ; Ensure the write completes before continuing
+                BLX     osRtxIrqGetId               ; Retrieve interrupt ID into R0
+                CMP     R0, #-1                     ; Check if interrupt valid
+                BEQ     IRQ_Exit                    ; Spurious interrupt if -1, exit IRQ
+                MOV     R4, R0                      ; Move interrupt ID to R4
 
-                ; If the ID is 0 and it is active and has not been seen before, then service it as normal,
-                ; otherwise the interrupt should be treated as spurious and not serviced.
-                CMP     R0, #0
-                BNE     IRQ_Exit                    ; Not 0, so spurious
-                LDR     R3, [R2, #ICDABR0_OFFSET]   ; Get the interrupt state
-                TST     R3, #1
-                BEQ     IRQ_Exit                    ; Not active, so spurious
-                LDR     R2, =ID0_Active
-                LDRB    R3, [R2]
-                CMP     R3, #1
-                BEQ     IRQ_Exit                    ; Seen it before, so spurious
+                LDR     R1, =IRQ_NestLevel
+                LDR     R3, [R1]                    ; Load IRQ nest level and increment it
+                ADD     R3, R3, #1
+                STR     R3, [R1]
 
-                ; Record that ID0 has now been seen, then service it as normal
-                MOV     R3, #1
-                STRB    R3, [R2]
-                ; End of Workaround GIC 390 errata 733075
-
-IRQ_Normal
-                LDR     R2, =IRQCount               ; Read number of entries in IRQ handler table
-                LDR     R2, [R2]
-                CMP     R0, R2                      ; Check if IRQ ID is within range
-                MOV     R2, #0
-                BHS     IRQ_End                     ; Out of range, return as normal
-                LDR     R2, =IRQTable               ; Read IRQ handler address from IRQ table
-                LDR     R2, [R2, R0, LSL #2]
-                CMP     R2, #0                      ; Check if handler address is 0
+                BLX     osRtxIrqGetHandler          ; Retrieve interrupt handler address for current ID
+                CMP     R0, #0                      ; Check if handler address is 0
                 BEQ     IRQ_End                     ; If 0, end interrupt and return
-                PUSH    {R0, R1}                    ; Store IRQ ID and GIC CPU Interface base address
 
                 CPS     #MODE_SVC                   ; Change to SVC mode
 
                 MOV     R3, SP                      ; Move SP into R3
                 AND     R3, R3, #4                  ; Get stack adjustment to ensure 8-byte alignment
                 SUB     SP, SP, R3                  ; Adjust stack
-                PUSH    {R2, R3, R12, LR}           ; Store handler address(R2), stack adjustment(R3) and user R12, LR
+                PUSH    {R3, R4}                    ; Store stack adjustment(R3) and alignment dummy(R4)
 
                 CPSIE   i                           ; Re-enable interrupts
-                BLX     R2                          ; Call IRQ handler
+                BLX     R0                          ; Call IRQ handler
                 CPSID   i                           ; Disable interrupts
 
-                POP     {R2, R3, R12, LR}           ; Restore handler address(R2), stack adjustment(R3) and user R12, LR
+                POP     {R3, R4}
                 ADD     SP, SP, R3                  ; Unadjust stack
 
                 CPS     #MODE_IRQ                   ; Change to IRQ mode
-                POP     {R0, R1}                    ; Restore IRQ ID and GIC CPU Interface base address
-                DSB                                 ; Ensure that interrupt source is cleared before signalling End Of Interrupt
+
 IRQ_End
-                ; R0 =IRQ ID, R1 =GICI_BASE
-                ; EOI does not need to be written for IDs 1020 to 1023 (0x3FC to 0x3FF)
-                STR     R0, [R1, #ICCEOIR_OFFSET]   ; Normal end-of-interrupt write to EOIR (GIC CPU Interface register) to clear the active bit
+                MOV     R0, R4                      ; Move interrupt ID to R0
+                BLX     osRtxIrqSetEnd
 
-                ; If it was ID0, clear the seen flag, otherwise return as normal
+                LDR     R2, =IRQ_NestLevel
+                LDR     R1, [R2]                    ; Load IRQ nest level and
+                SUBS    R1, R1, #1                  ; decrement it
+                STR     R1, [R2]
+                BNE     IRQ_Exit                    ; Not zero, exit from IRQ handler
+
+                LDR     R0, =SVC_Active
+                LDRB    R0, [R0]                    ; Load SVC_Active flag
                 CMP     R0, #0
-                LDREQ   R1, =ID0_Active
-                STRBEQ  R0, [R1]                    ; Clear the seen flag, using R0 (which is 0), to save loading another register
+                BNE     IRQ_SwitchCheck             ; Skip post processing when SVC active
 
-                LDR     R3, =osRtxIrqHandler        ; Load osRtxIrqHandler function address
-                CMP     R2, R3                      ; If is the same ass current IRQ handler
-                BEQ     osRtxContextSwitch          ; Call context switcher
+                ; RTX IRQ post processing check
+                PUSH    {R5, R6}                    ; Save user R5 and R6
+                MOV     R6, #0
+                LDR     R5, =IRQ_PendSV             ; Load address of IRQ_PendSV flag
+                B       IRQ_PendCheck
+IRQ_PendExec
+                STRB    R6, [R5]                    ; Clear PendSV flag
+                CPSIE   i                           ; Re-enable interrupts
+                BLX     osRtxPendSV_Handler         ; Post process pending objects
+                CPSID   i                           ; Disable interrupts
+IRQ_PendCheck
+                LDRB    R0, [R5]                    ; Load PendSV flag
+                CMP     R0, #1                      ; Compare PendSV value
+                BEQ     IRQ_PendExec                ; Branch to IRQ_PendExec if PendSV is set
+                POP     {R5, R6}                    ; Restore user R5 and R6
+
+IRQ_SwitchCheck
+                ; RTX IRQ context switch check
+                LDR     R12, =osRtxInfo+I_T_RUN_OFS ; Load address of osRtxInfo.run
+                LDM     R12, {R0, R1}               ; Load osRtxInfo.thread.run: curr & next
+                CMP     R0, R1                      ; Check if context switch is required
+                BEQ     IRQ_Exit
+
+                POP     {R3, R4}                    ; Restore stack adjustment(R3) and user data(R4)
+                ADD     SP, SP, R3                  ; Unadjust stack
+                B       osRtxContextSwitch
 
 IRQ_Exit
+                POP     {R3, R4}                    ; Restore stack adjustment(R3) and user data(R4)
+                ADD     SP, SP, R3                  ; Unadjust stack
+
                 POP     {R0-R3, R12, LR}            ; Restore stacked APCS registers
                 RFEFD   SP!                         ; Return from IRQ handler
 
@@ -271,8 +264,9 @@
 SVC_Handler\
                 PROC
                 EXPORT  SVC_Handler
-                IMPORT  osRtxIrqLock
-                IMPORT  osRtxIrqUnlock
+                IMPORT  osRtxIrqEnableTick
+                IMPORT  osRtxIrqDisableTick
+                IMPORT  osRtxPendSV_Handler
                 IMPORT  osRtxUserSVC
                 IMPORT  osRtxInfo
 
@@ -289,7 +283,10 @@
                 BNE     SVC_User                    ; Branch if User SVC
 
                 PUSH    {R0-R3}
-                BLX     osRtxIrqLock                ; Disable RTX interrupt (timer, PendSV)
+                BLX     osRtxIrqDisableTick         ; Disable System Timer interrupt
+                LDR     R0, =SVC_Active
+                MOV     R1, #1
+                STRB    R1, [R0]                    ; Set SVC_Active flag
                 POP     {R0-R3}
 
                 LDR     R12, [SP]                   ; Reload R12 from stack
@@ -305,7 +302,30 @@
                 LDMDB   R12, {R2,R3}                ; Load return values from SVC function
                 PUSH    {R0-R3}                     ; Push return values to stack
 
-                BLX     osRtxIrqUnlock              ; Enable RTX interrupt (timer, PendSV)
+                PUSH    {R4, R5}                    ; Save R4 and R5
+                MOV     R5, #0
+                LDR     R4, =IRQ_PendSV             ; Load address of IRQ_PendSV
+                B       SVC_PendCheck
+SVC_PendExec
+                STRB    R5, [R4]                    ; Clear IRQ_PendSV flag
+                CPSIE   i                           ; Re-enable interrupts
+                BLX     osRtxPendSV_Handler         ; Post process pending objects
+                CPSID   i                           ; Disable interrupts
+SVC_PendCheck
+                LDRB    R0, [R4]                    ; Load IRQ_PendSV flag
+                CMP     R0, #1                      ; Compare IRQ_PendSV value
+                BEQ     SVC_PendExec                ; Branch to SVC_PendExec if IRQ_PendSV is set
+                POP     {R4, R5}                    ; Restore R4 and R5
+
+                LDR     R0, =SVC_Active
+                MOV     R1, #0
+                STRB    R1, [R0]                    ; Clear SVC_Active flag
+                BLX     osRtxIrqEnableTick          ; Enable System Timer interrupt
+
+                LDR     R12, =osRtxInfo+I_T_RUN_OFS ; Load address of osRtxInfo.run
+                LDM     R12, {R0, R1}               ; Load osRtxInfo.thread.run: curr & next
+                CMP     R0, R1                      ; Check if context switch is required
+                BEQ     osRtxContextExit            ; Exit if curr and next are equal
                 B       osRtxContextSwitch          ; Continue in context switcher
 
 SVC_User
@@ -329,10 +349,9 @@
                 PROC
                 EXPORT  osRtxContextSwitch
 
-                LDR     R12, =osRtxInfo+I_T_RUN_OFS ; Load address of osRtxInfo.run
-                LDM     R12, {R0, R1}               ; Load osRtxInfo.thread.run: curr & next
-                CMP     R0, R1                      ; Check if context switch is required
-                BEQ     osRtxContextExit            ; Exit if curr and next are equal
+                ; R0  = osRtxInfo.thread.run.curr
+                ; R1  = osRtxInfo.thread.run.next
+                ; R12 = &osRtxInfo.thread.run
 
                 CMP     R0, #0                      ; Is osRtxInfo.thread.run.curr == 0
                 ADDEQ   SP, SP, #32                 ; Equal, curr deleted, adjust current SP
diff --git a/CMSIS/RTOS2/RTX/Source/ARM/irq_cm0.s b/CMSIS/RTOS2/RTX/Source/ARM/irq_cm0.s
index 74c8a84..8fab32a 100644
--- a/CMSIS/RTOS2/RTX/Source/ARM/irq_cm0.s
+++ b/CMSIS/RTOS2/RTX/Source/ARM/irq_cm0.s
@@ -24,7 +24,7 @@
 ; */
 
 
-I_T_RUN_OFS     EQU      28                     ; osRtxInfo.thread.run offset
+I_T_RUN_OFS     EQU      20                     ; osRtxInfo.thread.run offset
 TCB_SP_OFS      EQU      56                     ; TCB.SP offset
 
 
diff --git a/CMSIS/RTOS2/RTX/Source/ARM/irq_cm3.s b/CMSIS/RTOS2/RTX/Source/ARM/irq_cm3.s
index b951538..2fd6618 100644
--- a/CMSIS/RTOS2/RTX/Source/ARM/irq_cm3.s
+++ b/CMSIS/RTOS2/RTX/Source/ARM/irq_cm3.s
@@ -24,7 +24,7 @@
 ; */
 
 
-I_T_RUN_OFS     EQU      28                     ; osRtxInfo.thread.run offset
+I_T_RUN_OFS     EQU      20                     ; osRtxInfo.thread.run offset
 TCB_SP_OFS      EQU      56                     ; TCB.SP offset
 
 
diff --git a/CMSIS/RTOS2/RTX/Source/ARM/irq_cm4f.s b/CMSIS/RTOS2/RTX/Source/ARM/irq_cm4f.s
index 746c7c1..f0df8aa 100644
--- a/CMSIS/RTOS2/RTX/Source/ARM/irq_cm4f.s
+++ b/CMSIS/RTOS2/RTX/Source/ARM/irq_cm4f.s
@@ -24,7 +24,7 @@
 ; */
 
 
-I_T_RUN_OFS     EQU      28                     ; osRtxInfo.thread.run offset
+I_T_RUN_OFS     EQU      20                     ; osRtxInfo.thread.run offset
 TCB_SP_OFS      EQU      56                     ; TCB.SP offset
 TCB_SF_OFS      EQU      34                     ; TCB.stack_frame offset
 
diff --git a/CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mbl.S b/CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mbl.S
index c5f852d..497e5c9 100644
--- a/CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mbl.S
+++ b/CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mbl.S
@@ -31,7 +31,7 @@
         .equ     __DOMAIN_NS, 0
         .endif
 
-        .equ     I_T_RUN_OFS, 28        // osRtxInfo.thread.run offset
+        .equ     I_T_RUN_OFS, 20        // osRtxInfo.thread.run offset
         .equ     TCB_SM_OFS,  48        // TCB.stack_mem offset
         .equ     TCB_SP_OFS,  56        // TCB.SP offset
         .equ     TCB_SF_OFS,  34        // TCB.stack_frame offset
diff --git a/CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mml.S b/CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mml.S
index c01721b..3248b9e 100644
--- a/CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mml.S
+++ b/CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mml.S
@@ -35,7 +35,7 @@
         .equ     __FPU_USED,  0
         .endif
 
-        .equ     I_T_RUN_OFS, 28        // osRtxInfo.thread.run offset
+        .equ     I_T_RUN_OFS, 20        // osRtxInfo.thread.run offset
         .equ     TCB_SM_OFS,  48        // TCB.stack_mem offset
         .equ     TCB_SP_OFS,  56        // TCB.SP offset
         .equ     TCB_SF_OFS,  34        // TCB.stack_frame offset
diff --git a/CMSIS/RTOS2/RTX/Source/GCC/irq_ca.S b/CMSIS/RTOS2/RTX/Source/GCC/irq_ca.S
index 4c54505..972a398 100644
--- a/CMSIS/RTOS2/RTX/Source/GCC/irq_ca.S
+++ b/CMSIS/RTOS2/RTX/Source/GCC/irq_ca.S
@@ -18,414 +18,433 @@
  * -----------------------------------------------------------------------------
  *
  * Project:     CMSIS-RTOS RTX
- * Title:       Cortex-A Exception handlers (using GIC)
+ * Title:       Cortex-A Exception handlers
  *
  * -----------------------------------------------------------------------------
  */
 
-        .file    "irq_ca.S"
-        .syntax  unified
+                .file    "irq_ca.S"
+                .syntax  unified
 
-        .equ   ICDABR0_OFFSET,  0x00000300  // GICD: Active Bit Register 0 offset
-        .equ   ICDIPR0_OFFSET,  0x00000400  // GICD: Interrupt Priority Register 0 offset
-        .equ   ICCIAR_OFFSET,   0x0000000C  // GICI: Interrupt Acknowledge Register offset
-        .equ   ICCEOIR_OFFSET,  0x00000010  // GICI: End of Interrupt Register offset
-        .equ   ICCHPIR_OFFSET,  0x00000018  // GICI: Highest Pending Interrupt Register offset
+                .equ   MODE_FIQ,        0x11
+                .equ   MODE_IRQ,        0x12
+                .equ   MODE_SVC,        0x13
+                .equ   MODE_ABT,        0x17
+                .equ   MODE_UND,        0x1B
 
-        .equ   MODE_FIQ,        0x11
-        .equ   MODE_IRQ,        0x12
-        .equ   MODE_SVC,        0x13
-        .equ   MODE_ABT,        0x17
-        .equ   MODE_UND,        0x1B
+                .equ   CPSR_BIT_T,      0x20
 
-        .equ   CPSR_BIT_T,      0x20
-
-        .equ   I_T_RUN_OFS,     28          // osRtxInfo.thread.run offset
-        .equ   TCB_SP_FRAME,    34          // osRtxThread_t.stack_frame offset
-        .equ   TCB_SP_OFS,      56          // osRtxThread_t.sp offset
+                .equ   I_T_RUN_OFS,     20          // osRtxInfo.thread.run offset
+                .equ   TCB_SP_FRAME,    34          // osRtxThread_t.stack_frame offset
+                .equ   TCB_SP_OFS,      56          // osRtxThread_t.sp offset
 
 
-        .section ".rodata"
-        .global  irqRtxLib                  // Non weak library reference
+                .section ".rodata"
+                .global  irqRtxLib                  // Non weak library reference
 irqRtxLib:
-        .byte    0
+                .byte    0
 
-       .section ".data"
-ID0_Active:
-        .byte    4                          // Flag used to workaround GIC 390 errata 733075
+                .section ".data"
+IRQ_NestLevel:
+                .word    0                          // IRQ nesting level counter
+IRQ_PendSV:
+                .byte    0                          // Pending SVC flag
+SVC_Active:
+                .byte    0                          // SVC handler execution active flag
 
-        .arm
-        .section ".text"
-        .align   4
+                .arm
+                .section ".text"
+                .align   4
 
 
-        .type    Undef_Handler, %function
-        .global  Undef_Handler
-        .fnstart
-        .cantunwind
+                .type    Undef_Handler, %function
+                .global  Undef_Handler
+                .fnstart
+                .cantunwind
 Undef_Handler:
 
-        SRSFD   SP!, #MODE_UND
-        PUSH    {R0-R4, R12}                // Save APCS corruptible registers to UND mode stack
+                SRSFD   SP!, #MODE_UND
+                PUSH    {R0-R4, R12}                // Save APCS corruptible registers to UND mode stack
 
-        MRS     R0, SPSR
-        TST     R0, #CPSR_BIT_T             // Check mode
-        MOVEQ   R1, #4                      // R1 = 4 ARM mode
-        MOVNE   R1, #2                      // R1 = 2 Thumb mode
-        SUB     R0, LR, R1
-        LDREQ   R0, [R0]                    // ARM mode - R0 points to offending instruction
-        BEQ     Undef_Cont
+                MRS     R0, SPSR
+                TST     R0, #CPSR_BIT_T             // Check mode
+                MOVEQ   R1, #4                      // R1 = 4 ARM mode
+                MOVNE   R1, #2                      // R1 = 2 Thumb mode
+                SUB     R0, LR, R1
+                LDREQ   R0, [R0]                    // ARM mode - R0 points to offending instruction
+                BEQ     Undef_Cont
 
-        // Thumb instruction
-        // Determine if it is a 32-bit Thumb instruction
-        LDRH    R0, [R0]
-        MOV     R2, #0x1C
-        CMP     R2, R0, LSR #11
-        BHS     Undef_Cont                  // 16-bit Thumb instruction
+                // Thumb instruction
+                // Determine if it is a 32-bit Thumb instruction
+                LDRH    R0, [R0]
+                MOV     R2, #0x1C
+                CMP     R2, R0, LSR #11
+                BHS     Undef_Cont                  // 16-bit Thumb instruction
 
-        // 32-bit Thumb instruction. Unaligned - reconstruct the offending instruction
-        LDRH    R2, [LR]
-        ORR     R0, R2, R0, LSL #16
+                // 32-bit Thumb instruction. Unaligned - reconstruct the offending instruction
+                LDRH    R2, [LR]
+                ORR     R0, R2, R0, LSL #16
 Undef_Cont:
-        MOV     R2, LR                      // Set LR to third argument
+                MOV     R2, LR                      // Set LR to third argument
 
-        AND     R12, SP, #4                 // Ensure stack is 8-byte aligned
-        SUB     SP, SP, R12                 // Adjust stack
-        PUSH    {R12, LR}                   // Store stack adjustment and dummy LR
+                AND     R12, SP, #4                 // Ensure stack is 8-byte aligned
+                SUB     SP, SP, R12                 // Adjust stack
+                PUSH    {R12, LR}                   // Store stack adjustment and dummy LR
 
-        // R0 =Offending instruction, R1 =2(Thumb) or =4(ARM)
-        BL      CUndefHandler
+                // R0 =Offending instruction, R1 =2(Thumb) or =4(ARM)
+                BL      CUndefHandler
 
-        POP     {R12, LR}                   // Get stack adjustment & discard dummy LR
-        ADD     SP, SP, R12                 // Unadjust stack
+                POP     {R12, LR}                   // Get stack adjustment & discard dummy LR
+                ADD     SP, SP, R12                 // Unadjust stack
 
-        LDR     LR, [SP, #24]               // Restore stacked LR and possibly adjust for retry
-        SUB     LR, LR, R0
-        LDR     R0, [SP, #28]               // Restore stacked SPSR
-        MSR     SPSR_cxsf, R0
-        POP     {R0-R4, R12}                // Restore stacked APCS registers
-        ADD     SP, SP, #8                  // Adjust SP for already-restored banked registers
-        MOVS    PC, LR
+                LDR     LR, [SP, #24]               // Restore stacked LR and possibly adjust for retry
+                SUB     LR, LR, R0
+                LDR     R0, [SP, #28]               // Restore stacked SPSR
+                MSR     SPSR_cxsf, R0
+                POP     {R0-R4, R12}                // Restore stacked APCS registers
+                ADD     SP, SP, #8                  // Adjust SP for already-restored banked registers
+                MOVS    PC, LR
 
-        .fnend
-        .size    Undef_Handler, .-Undef_Handler
+                .fnend
+                .size    Undef_Handler, .-Undef_Handler
 
 
-        .type    PAbt_Handler, %function
-        .global  PAbt_Handler
-        .fnstart
-        .cantunwind
+                .type    PAbt_Handler, %function
+                .global  PAbt_Handler
+                .fnstart
+                .cantunwind
 PAbt_Handler:
 
-        SUB     LR, LR, #4                  // Pre-adjust LR
-        SRSFD   SP!, #MODE_ABT              // Save LR and SPRS to ABT mode stack
-        PUSH    {R0-R4, R12}                // Save APCS corruptible registers to ABT mode stack
-        MRC     p15, 0, R0, c5, c0, 1       // IFSR
-        MRC     p15, 0, R1, c6, c0, 2       // IFAR
+                SUB     LR, LR, #4                  // Pre-adjust LR
+                SRSFD   SP!, #MODE_ABT              // Save LR and SPRS to ABT mode stack
+                PUSH    {R0-R4, R12}                // Save APCS corruptible registers to ABT mode stack
+                MRC     p15, 0, R0, c5, c0, 1       // IFSR
+                MRC     p15, 0, R1, c6, c0, 2       // IFAR
 
-        MOV     R2, LR                      // Set LR to third argument
+                MOV     R2, LR                      // Set LR to third argument
 
-        AND     R12, SP, #4                 // Ensure stack is 8-byte aligned
-        SUB     SP, SP, R12                 // Adjust stack
-        PUSH    {R12, LR}                   // Store stack adjustment and dummy LR
+                AND     R12, SP, #4                 // Ensure stack is 8-byte aligned
+                SUB     SP, SP, R12                 // Adjust stack
+                PUSH    {R12, LR}                   // Store stack adjustment and dummy LR
 
-        BL      CPAbtHandler
+                BL      CPAbtHandler
 
-        POP     {R12, LR}                   // Get stack adjustment & discard dummy LR
-        ADD     SP, SP, R12                 // Unadjust stack
+                POP     {R12, LR}                   // Get stack adjustment & discard dummy LR
+                ADD     SP, SP, R12                 // Unadjust stack
 
-        POP     {R0-R4, R12}                // Restore stack APCS registers
-        RFEFD   SP!                         // Return from exception
+                POP     {R0-R4, R12}                // Restore stack APCS registers
+                RFEFD   SP!                         // Return from exception
 
-        .fnend
-        .size    PAbt_Handler, .-PAbt_Handler
+                .fnend
+                .size    PAbt_Handler, .-PAbt_Handler
 
 
-        .type    DAbt_Handler, %function
-        .global  DAbt_Handler
-        .fnstart
-        .cantunwind
+                .type    DAbt_Handler, %function
+                .global  DAbt_Handler
+                .fnstart
+                .cantunwind
 DAbt_Handler:
-        SUB     LR, LR, #8                  // Pre-adjust LR
-        SRSFD   SP!, #MODE_ABT              // Save LR and SPRS to ABT mode stack
-        PUSH    {R0-R4, R12}                // Save APCS corruptible registers to ABT mode stack
-        CLREX                               // State of exclusive monitors unknown after taken data abort
-        MRC     p15, 0, R0, c5, c0, 0       // DFSR
-        MRC     p15, 0, R1, c6, c0, 0       // DFAR
+                SUB     LR, LR, #8                  // Pre-adjust LR
+                SRSFD   SP!, #MODE_ABT              // Save LR and SPRS to ABT mode stack
+                PUSH    {R0-R4, R12}                // Save APCS corruptible registers to ABT mode stack
+                CLREX                               // State of exclusive monitors unknown after taken data abort
+                MRC     p15, 0, R0, c5, c0, 0       // DFSR
+                MRC     p15, 0, R1, c6, c0, 0       // DFAR
 
-        MOV     R2, LR                      // Set LR to third argument
+                MOV     R2, LR                      // Set LR to third argument
 
-        AND     R12, SP, #4                 // Ensure stack is 8-byte aligned
-        SUB     SP, SP, R12                 // Adjust stack
-        PUSH    {R12, LR}                   // Store stack adjustment and dummy LR
+                AND     R12, SP, #4                 // Ensure stack is 8-byte aligned
+                SUB     SP, SP, R12                 // Adjust stack
+                PUSH    {R12, LR}                   // Store stack adjustment and dummy LR
 
-        BL      CDAbtHandler
+                BL      CDAbtHandler
 
-        POP     {R12, LR}                   // Get stack adjustment & discard dummy LR
-        ADD     SP, SP, R12                 // Unadjust stack
+                POP     {R12, LR}                   // Get stack adjustment & discard dummy LR
+                ADD     SP, SP, R12                 // Unadjust stack
 
-        POP     {R0-R4, R12}                // Restore stacked APCS registers
-        RFEFD   SP!                         // Return from exception
+                POP     {R0-R4, R12}                // Restore stacked APCS registers
+                RFEFD   SP!                         // Return from exception
 
-        .fnend
-        .size    DAbt_Handler, .-DAbt_Handler
+                .fnend
+                .size    DAbt_Handler, .-DAbt_Handler
 
 
-        .type    IRQ_Handler, %function
-        .global  IRQ_Handler
-        .fnstart
-        .cantunwind
+                .type    IRQ_Handler, %function
+                .global  IRQ_Handler
+                .fnstart
+                .cantunwind
 IRQ_Handler:
 
-        SUB     LR, LR, #4                  // Pre-adjust LR
-        SRSFD   SP!, #MODE_IRQ              // Save LR_irq and SPRS_irq
-        PUSH    {R0-R3, R12, LR}            // Save APCS corruptible registers
+                SUB     LR, LR, #4                  // Pre-adjust LR
+                SRSFD   SP!, #MODE_IRQ              // Save LR_irq and SPRS_irq
+                PUSH    {R0-R3, R12, LR}            // Save APCS corruptible registers
 
-        // Identify and acknowledge interrupt
-        LDR     R1, =irqRtxGicBase;
-        LDR     R1, [R1, #4]
-        LDR     R0, [R1, #ICCHPIR_OFFSET]   // Dummy Read GICI ICCHPIR to avoid GIC 390 errata 801120
-        LDR     R0, [R1, #ICCIAR_OFFSET]    // Read GICI ICCIAR
-        DSB                                 // Ensure that interrupt acknowledge completes before re-enabling interrupts
+                MOV     R3, SP                      // Move SP into R3
+                AND     R3, R3, #4                  // Get stack adjustment to ensure 8-byte alignment
+                SUB     SP, SP, R3                  // Adjust stack
+                PUSH    {R3, R4}                    // Store stack adjustment(R3) and user data(R4)
 
-        // Workaround GIC 390 errata 733075 - see GIC-390_Errata_Notice_v6.pdf dated 09-Jul-2014
-        // The following workaround code is for a single-core system.  It would be different in a multi-core system.
-        // If the ID is 0 or 0x3FE or 0x3FF, then the GIC CPU interface may be locked-up so unlock it, otherwise service the interrupt as normal
-        // Special IDs 1020=0x3FC and 1021=0x3FD are reserved values in GICv1 and GICv2 so will not occur here
-        CMP     R0, #0
-        BEQ     IRQ_Unlock
-        MOVW    R2, #0x3FE
-        CMP     R0, R2
-        BLT     IRQ_Normal
-IRQ_Unlock:
-        // Unlock the CPU interface with a dummy write to ICDIPR0
-        LDR     R2, =irqRtxGicBase
-        LDR     R2, [R2]
-        LDR     R3, [R2, #ICDIPR0_OFFSET]
-        STR     R3, [R2, #ICDIPR0_OFFSET]
-        DSB                                 // Ensure the write completes before continuing
+                BLX     osRtxIrqGetId               // Retrieve interrupt ID into R0
+                CMP     R0, #-1                     // Check if interrupt valid
+                BEQ     IRQ_Exit                    // Spurious interrupt if -1, exit IRQ
+                MOV     R4, R0                      // Move interrupt ID to R4
 
-        // If the ID is 0 and it is active and has not been seen before, then service it as normal,
-        // otherwise the interrupt should be treated as spurious and not serviced.
-        CMP     R0, #0
-        BNE     IRQ_Exit                    // Not 0, so spurious
-        LDR     R3, [R2, #ICDABR0_OFFSET]   // Get the interrupt state
-        TST     R3, #1
-        BEQ     IRQ_Exit                    // Not active, so spurious
-        LDR     R2, =ID0_Active
-        LDRB    R3, [R2]
-        CMP     R3, #1
-        BEQ     IRQ_Exit                    // Seen it before, so spurious
+                LDR     R1, =IRQ_NestLevel
+                LDR     R3, [R1]                    // Load IRQ nest level and increment it
+                ADD     R3, R3, #1
+                STR     R3, [R1]
 
-        // Record that ID0 has now been seen, then service it as normal
-        MOV     R3, #1
-        STRB    R3, [R2]
-        // End of Workaround GIC 390 errata 733075
+                BLX     osRtxIrqGetHandler          // Retrieve interrupt handler address for current ID
+                CMP     R0, #0                      // Check if handler address is 0
+                BEQ     IRQ_End                     // If 0, end interrupt and return
 
-IRQ_Normal:
-        LDR     R2, =IRQCount               // Read number of entries in IRQ handler table
-        LDR     R2, [R2]
-        CMP     R0, R2                      // Check if IRQ ID is within range
-        MOV     R2, #0
-        BHS     IRQ_End                     // Out of range, return as normal
-        LDR     R2, =IRQTable               // Read IRQ handler address from IRQ table
-        LDR     R2, [R2, R0, LSL #2]
-        CMP     R2, #0                      // Check if handler address is 0
-        BEQ     IRQ_End                     // If 0, end interrupt and return
-        PUSH    {R0, R1}                    // Store IRQ ID and GIC CPU Interface base address
+                CPS     #MODE_SVC                   // Change to SVC mode
 
-        CPS     #MODE_SVC                   // Change to SVC mode
+                MOV     R3, SP                      // Move SP into R3
+                AND     R3, R3, #4                  // Get stack adjustment to ensure 8-byte alignment
+                SUB     SP, SP, R3                  // Adjust stack
+                PUSH    {R3, R4}                    // Store stack adjustment(R3) and alignment dummy(R4)
 
-        MOV     R3, SP                      // Move SP into R3
-        AND     R3, R3, #4                  // Get stack adjustment to ensure 8-byte alignment
-        SUB     SP, SP, R3                  // Adjust stack
-        PUSH    {R2, R3, R12, LR}           // Store handler address(R2), stack adjustment(R3) and user R12, LR
+                CPSIE   i                           // Re-enable interrupts
+                BLX     R0                          // Call IRQ handler
+                CPSID   i                           // Disable interrupts
 
-        CPSIE   i                           // Re-enable interrupts
-        BLX     R2                          // Call IRQ handler
-        CPSID   i                           // Disable interrupts
+                POP     {R3, R4}
+                ADD     SP, SP, R3                  // Unadjust stack
 
-        POP     {R2, R3, R12, LR}           // Restore handler address(R2), stack adjustment(R3) and user R12, LR
-        ADD     SP, SP, R3                  // Unadjust stack
+                CPS     #MODE_IRQ                   // Change to IRQ mode
 
-        CPS     #MODE_IRQ                   // Change to IRQ mode
-        POP     {R0, R1}                    // Restore IRQ ID and GIC CPU Interface base address
-        DSB                                 // Ensure that interrupt source is cleared before signalling End Of Interrupt
 IRQ_End:
-        // R0 =IRQ ID, R1 =GICI_BASE
-        // EOI does not need to be written for IDs 1020 to 1023 (0x3FC to 0x3FF)
-        STR     R0, [R1, #ICCEOIR_OFFSET]   // Normal end-of-interrupt write to EOIR (GIC CPU Interface register) to clear the active bit
+                MOV     R0, R4                      // Move interrupt ID to R0
+                BLX     osRtxIrqSetEnd
 
-        // If it was ID0, clear the seen flag, otherwise return as normal
-        CMP     R0, #0
-        LDREQ   R1, =ID0_Active
-        STRBEQ  R0, [R1]                    // Clear the seen flag, using R0 (which is 0), to save loading another register
+                LDR     R2, =IRQ_NestLevel
+                LDR     R1, [R2]                    // Load IRQ nest level and
+                SUBS    R1, R1, #1                  // decrement it
+                STR     R1, [R2]
+                BNE     IRQ_Exit                    // Not zero, exit from IRQ handler
 
-        LDR     R3, =osRtxIrqHandler        // Load osRtxIrqHandler function address
-        CMP     R2, R3                      // If is the same ass current IRQ handler
-        BEQ     osRtxContextSwitch          // Call context switcher
+                LDR     R0, =SVC_Active
+                LDRB    R0, [R0]                    // Load SVC_Active flag
+                CMP     R0, #0
+                BNE     IRQ_SwitchCheck             // Skip post processing when SVC active
+
+                // RTX IRQ post processing check
+                PUSH    {R5, R6}                    // Save user R5 and R6
+                MOV     R6, #0
+                LDR     R5, =IRQ_PendSV             // Load address of IRQ_PendSV flag
+                B       IRQ_PendCheck
+IRQ_PendExec:
+                STRB    R6, [R5]                    // Clear PendSV flag
+                CPSIE   i                           // Re-enable interrupts
+                BLX     osRtxPendSV_Handler         // Post process pending objects
+                CPSID   i                           // Disable interrupts
+IRQ_PendCheck:
+                LDRB    R0, [R5]                    // Load PendSV flag
+                CMP     R0, #1                      // Compare PendSV value
+                BEQ     IRQ_PendExec                // Branch to IRQ_PendExec if PendSV is set
+                POP     {R5, R6}                    // Restore user R5 and R6
+
+IRQ_SwitchCheck:
+                // RTX IRQ context switch check
+                LDR     R12, =osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run
+                LDM     R12, {R0, R1}               // Load osRtxInfo.thread.run: curr & next
+                CMP     R0, R1                      // Check if context switch is required
+                BEQ     IRQ_Exit
+
+                POP     {R3, R4}                    // Restore stack adjustment(R3) and user data(R4)
+                ADD     SP, SP, R3                  // Unadjust stack
+                B       osRtxContextSwitch
 
 IRQ_Exit:
-        POP     {R0-R3, R12, LR}            // Restore stacked APCS registers
-        RFEFD   SP!                         // Return from IRQ handler
+                POP     {R3, R4}                    // Restore stack adjustment(R3) and user data(R4)
+                ADD     SP, SP, R3                  // Unadjust stack
 
-        .fnend
-        .size    IRQ_Handler, .-IRQ_Handler
+                POP     {R0-R3, R12, LR}            // Restore stacked APCS registers
+                RFEFD   SP!                         // Return from IRQ handler
+
+                .fnend
+                .size    IRQ_Handler, .-IRQ_Handler
 
 
-        .type    SVC_Handler, %function
-        .global  SVC_Handler
-        .fnstart
-        .cantunwind
+                .type    SVC_Handler, %function
+                .global  SVC_Handler
+                .fnstart
+                .cantunwind
 SVC_Handler:
 
-        SRSFD    SP!, #MODE_SVC             // Store SPSR_svc and LR_svc onto SVC stack
-        PUSH     {R12, LR}
+                SRSFD   SP!, #MODE_SVC              // Store SPSR_svc and LR_svc onto SVC stack
+                PUSH    {R12, LR}
 
-        MRS      R12, SPSR                  // Load SPSR
-        TST      R12, #CPSR_BIT_T           // Thumb bit set?
-        LDRHNE   R12, [LR,#-2]              // Thumb: load halfword
-        BICNE    R12, R12, #0xFF00          //        extract SVC number
-        LDREQ    R12, [LR,#-4]              // ARM:   load word
-        BICEQ    R12, R12, #0xFF000000      //        extract SVC number
-        CMP      R12, #0                    // Compare SVC number
-        BNE      SVC_User                   // Branch if User SVC
+                MRS     R12, SPSR                   // Load SPSR
+                TST     R12, #CPSR_BIT_T            // Thumb bit set?
+                LDRHNE  R12, [LR,#-2]               // Thumb: load halfword
+                BICNE   R12, R12, #0xFF00           //        extract SVC number
+                LDREQ   R12, [LR,#-4]               // ARM:   load word
+                BICEQ   R12, R12, #0xFF000000       //        extract SVC number
+                CMP     R12, #0                     // Compare SVC number
+                BNE     SVC_User                    // Branch if User SVC
 
-        PUSH     {R0-R3}
-        BLX      osRtxIrqLock               // Disable RTX interrupt (timer, PendSV)
-        POP      {R0-R3}
+                PUSH    {R0-R3}
+                BLX     osRtxIrqDisableTick         // Disable System Timer interrupt
+                LDR     R0, =SVC_Active
+                MOV     R1, #1
+                STRB    R1, [R0]                    // Set SVC_Active flag
+                POP     {R0-R3}
 
-        LDR      R12, [SP]                  // Reload R12 from stack
+                LDR     R12, [SP]                   // Reload R12 from stack
 
-        CPSIE    i                          // Re-enable interrupts
-        BLX      R12                        // Branch to SVC function
-        CPSID    i                          // Disable interrupts
+                CPSIE   i                           // Re-enable interrupts
+                BLX     R12                         // Branch to SVC function
+                CPSID   i                           // Disable interrupts
 
-        SUB      SP, SP, #4                 // Adjust SP
-        STM      SP, {SP}^                  // Store SP_usr onto stack
-        POP      {R12}                      // Pop SP_usr into R12
-        SUB      R12, R12, #16              // Adjust pointer to SP_usr
-        LDMDB    R12, {R2,R3}               // Load return values from SVC function
-        PUSH     {R0-R3}                    // Push return values to stack
+                SUB     SP, SP, #4                  // Adjust SP
+                STM     SP, {SP}^                   // Store SP_usr onto stack
+                POP     {R12}                       // Pop SP_usr into R12
+                SUB     R12, R12, #16               // Adjust pointer to SP_usr
+                LDMDB   R12, {R2,R3}                // Load return values from SVC function
+                PUSH    {R0-R3}                     // Push return values to stack
 
-        BLX      osRtxIrqUnlock             // Enable RTX interrupt (timer, PendSV)
-        B        osRtxContextSwitch         // Continue in context switcher
+                PUSH    {R4, R5}                    // Save R4 and R5
+                MOV     R5, #0
+                LDR     R4, =IRQ_PendSV             // Load address of IRQ_PendSV
+                B       SVC_PendCheck
+SVC_PendExec:
+                STRB    R5, [R4]                    // Clear IRQ_PendSV flag
+                CPSIE   i                           // Re-enable interrupts
+                BLX     osRtxPendSV_Handler         // Post process pending objects
+                CPSID   i                           // Disable interrupts
+SVC_PendCheck:
+                LDRB    R0, [R4]                    // Load IRQ_PendSV flag
+                CMP     R0, #1                      // Compare IRQ_PendSV value
+                BEQ     SVC_PendExec                // Branch to SVC_PendExec if IRQ_PendSV is set
+                POP     {R4, R5}                    // Restore R4 and R5
+
+                LDR     R0, =SVC_Active
+                MOV     R1, #0
+                STRB    R1, [R0]                    // Clear SVC_Active flag
+                BLX     osRtxIrqEnableTick          // Enable System Timer interrupt
+
+                LDR     R12, =osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run
+                LDM     R12, {R0, R1}               // Load osRtxInfo.thread.run: curr & next
+                CMP     R0, R1                      // Check if context switch is required
+                BEQ     osRtxContextExit            // Exit if curr and next are equal
+                B       osRtxContextSwitch          // Continue in context switcher
 
 SVC_User:
-        PUSH     {R4, R5}
-        LDR      R5,=osRtxUserSVC           // Load address of SVC table
-        LDR      R4,[R5]                    // Load SVC maximum number
-        CMP      R12,R4                     // Check SVC number range
-        BHI      SVC_Done                   // Branch if out of range
+                PUSH    {R4, R5}
+                LDR     R5,=osRtxUserSVC            // Load address of SVC table
+                LDR     R4,[R5]                     // Load SVC maximum number
+                CMP     R12,R4                      // Check SVC number range
+                BHI     SVC_Done                    // Branch if out of range
 
-        LDR      R12,[R5,R12,LSL #2]        // Load SVC Function Address
-        BLX      R12                        // Call SVC Function
+                LDR     R12,[R5,R12,LSL #2]         // Load SVC Function Address
+                BLX     R12                         // Call SVC Function
 
 SVC_Done:
-        POP      {R4, R5, R12, LR}
-        RFEFD    SP!                        // Return from exception
+                POP     {R4, R5, R12, LR}
+                RFEFD   SP!                         // Return from exception
 
-        .fnend
-        .size    SVC_Handler, .-SVC_Handler
+                .fnend
+                .size    SVC_Handler, .-SVC_Handler
 
 
-        .type    osRtxContextSwitch, %function
-        .global  osRtxContextSwitch
-        .fnstart
-        .cantunwind
+                .type    osRtxContextSwitch, %function
+                .global  osRtxContextSwitch
+                .fnstart
+                .cantunwind
 osRtxContextSwitch:
 
-        LDR      R12,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run
-        LDM      R12, {R0, R1}              // Load osRtxInfo.thread.run: curr & next
-        CMP      R0, R1                     // Check if context switch is required
-        BEQ      osRtxContextExit           // Exit if curr and next are equal
+                // R0  = osRtxInfo.thread.run.curr
+                // R1  = osRtxInfo.thread.run.next
+                //  R12 = &osRtxInfo.thread.run
 
-        CMP      R0, #0                     // Is osRtxInfo.thread.run.curr == 0
-        ADDEQ    SP, SP, #32                // Equal, curr deleted, adjust current SP
-        BEQ      osRtxContextRestore        // Restore context, run.curr = run.next;
+                CMP     R0, #0                     // Is osRtxInfo.thread.run.curr == 0
+                ADDEQ   SP, SP, #32                // Equal, curr deleted, adjust current SP
+                BEQ     osRtxContextRestore        // Restore context, run.curr = run.next;
 
 osRtxContextSave:
-        SUB      SP, SP, #4
-        STM      SP, {SP}^                  // Save SP_usr to current stack
-        POP      {R3}                       // Pop SP_usr into R3
+                SUB     SP, SP, #4
+                STM     SP, {SP}^                  // Save SP_usr to current stack
+                POP     {R3}                       // Pop SP_usr into R3
 
-        SUB      R3, R3, #64                // Adjust user sp to end of basic frame (R4)
-        STMIA    R3!, {R4-R11}              // Save R4-R11 to user
-        POP      {R4-R8}                    // Pop current R0-R12 into R4-R8
-        STMIA    R3!, {R4-R8}               // Store them to user stack
-        STM      R3, {LR}^                  // Store LR_usr directly
-        ADD      R3, R3, #4                 // Adjust user sp to PC
-        POP      {R4-R6}                    // Pop current LR, PC, CPSR
-        STMIA    R3!, {R5-R6}               // Restore user PC and CPSR
+                SUB     R3, R3, #64                // Adjust user sp to end of basic frame (R4)
+                STMIA   R3!, {R4-R11}              // Save R4-R11 to user
+                POP     {R4-R8}                    // Pop current R0-R12 into R4-R8
+                STMIA   R3!, {R4-R8}               // Store them to user stack
+                STM     R3, {LR}^                  // Store LR_usr directly
+                ADD     R3, R3, #4                 // Adjust user sp to PC
+                POP     {R4-R6}                    // Pop current LR, PC, CPSR
+                STMIA   R3!, {R5-R6}               // Restore user PC and CPSR
 
-        SUB      R3, R3, #64                // Adjust user sp to R4
+                SUB     R3, R3, #64                // Adjust user sp to R4
 
-        // Check if VFP state need to be saved
-        MRC      p15, 0, R2, c1, c0, 2      // VFP/NEON access enabled? (CPACR)
-        AND      R2, R2, #0x00F00000
-        CMP      R2, #0x00F00000
-        BNE      osRtxContextSave1          // Continue, no VFP
+                // Check if VFP state need to be saved
+                MRC     p15, 0, R2, c1, c0, 2      // VFP/NEON access enabled? (CPACR)
+                AND     R2, R2, #0x00F00000
+                CMP     R2, #0x00F00000
+                BNE     osRtxContextSave1          // Continue, no VFP
 
-        VMRS     R2, FPSCR
-        STMDB    R3!, {R2,R12}              // Push FPSCR, maintain 8-byte alignment
-        #if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 16
-        VSTMDB   R3!, {D0-D15}
-        LDRB     R2, [R0, #TCB_SP_FRAME]    // Record in TCB that VFP/D16 state is stacked
-        ORR      R2, R2, #2
-        STRB     R2, [R0, #TCB_SP_FRAME]
-        #endif
-        #if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 32
-        VSTMDB   R3!, {D0-D15}
-        VSTMDB   R3!, {D16-D31}
-        LDRB     R2, [R0, #TCB_SP_FRAME]    // Record in TCB that NEON/D32 state is stacked
-        ORR      R2, R2, #4
-        STRB     R2, [R0, #TCB_SP_FRAME]
-        #endif
+                VMRS    R2, FPSCR
+                STMDB   R3!, {R2,R12}              // Push FPSCR, maintain 8-byte alignment
+                #if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 16
+                VSTMDB  R3!, {D0-D15}
+                LDRB    R2, [R0, #TCB_SP_FRAME]    // Record in TCB that VFP/D16 state is stacked
+                ORR     R2, R2, #2
+                STRB    R2, [R0, #TCB_SP_FRAME]
+                #endif
+                #if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 32
+                VSTMDB  R3!, {D0-D15}
+                VSTMDB  R3!, {D16-D31}
+                LDRB    R2, [R0, #TCB_SP_FRAME]    // Record in TCB that NEON/D32 state is stacked
+                ORR     R2, R2, #4
+                STRB    R2, [R0, #TCB_SP_FRAME]
+                #endif
 
 osRtxContextSave1:
-        STR      R3, [R0, #TCB_SP_OFS]      // Store user sp to osRtxInfo.thread.run.curr
+                STR     R3, [R0, #TCB_SP_OFS]      // Store user sp to osRtxInfo.thread.run.curr
 
 osRtxContextRestore:
-        STR      R1, [R12]                  // Store run.next to run.curr
-        LDR      R3, [R1, #TCB_SP_OFS]      // Load next osRtxThread_t.sp
-        LDRB     R2, [R1, #TCB_SP_FRAME]    // Load next osRtxThread_t.stack_frame
+                STR     R1, [R12]                  // Store run.next to run.curr
+                LDR     R3, [R1, #TCB_SP_OFS]      // Load next osRtxThread_t.sp
+                LDRB    R2, [R1, #TCB_SP_FRAME]    // Load next osRtxThread_t.stack_frame
 
-        ANDS     R2, R2, #0x6               // Check stack frame for VFP context
-        MRC      p15, 0, R2, c1, c0, 2      // Read CPACR
-        ANDEQ    R2, R2, #0xFF0FFFFF        // Disable VFP/NEON access if incoming task does not have stacked VFP/NEON state
-        ORRNE    R2, R2, #0x00F00000        // Enable VFP/NEON access if incoming task does have stacked VFP/NEON state
-        MCR      p15, 0, R2, c1, c0, 2      // Write CPACR
-        BEQ      osRtxContextRestore1       // No VFP
-        ISB                                 // Only sync if we enabled VFP, otherwise we will context switch before next VFP instruction anyway
-        #if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 32
-        VLDMIA   R3!, {D16-D31}
-        #endif
-        VLDMIA   R3!, {D0-D15}
-        LDR      R2, [R3]
-        VMSR     FPSCR, R2
-        ADD      R3, R3, #8
+                ANDS    R2, R2, #0x6               // Check stack frame for VFP context
+                MRC     p15, 0, R2, c1, c0, 2      // Read CPACR
+                ANDEQ   R2, R2, #0xFF0FFFFF        // Disable VFP/NEON access if incoming task does not have stacked VFP/NEON state
+                ORRNE   R2, R2, #0x00F00000        // Enable VFP/NEON access if incoming task does have stacked VFP/NEON state
+                MCR     p15, 0, R2, c1, c0, 2      // Write CPACR
+                BEQ     osRtxContextRestore1       // No VFP
+                ISB                                // Only sync if we enabled VFP, otherwise we will context switch before next VFP instruction anyway
+                #if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 32
+                VLDMIA  R3!, {D16-D31}
+                #endif
+                VLDMIA  R3!, {D0-D15}
+                LDR     R2, [R3]
+                VMSR    FPSCR, R2
+                ADD     R3, R3, #8
 
 osRtxContextRestore1:
-        LDMIA    R3!, {R4-R11}              // Restore R4-R11
-        MOV      R12, R3                    // Move sp pointer to R12
-        ADD      R3, R3, #32                // Adjust sp
-        PUSH     {R3}                       // Push sp onto stack
-        LDMIA    SP, {SP}^                  // Restore SP_usr
-        LDMIA    R12!, {R0-R3}              // Restore User R0-R3
-        LDR      LR, [R12, #12]             // Load SPSR into LR
-        MSR      SPSR_cxsf, LR              // Restore SPSR
-        ADD      R12, R12, #4               // Adjust pointer to LR
-        LDM      R12, {LR}^                 // Restore LR_usr directly into LR
-        LDR      LR, [R12, #4]              // Restore LR
-        LDR      R12, [R12, #-4]            // Restore R12
+                LDMIA   R3!, {R4-R11}              // Restore R4-R11
+                MOV     R12, R3                    // Move sp pointer to R12
+                ADD     R3, R3, #32                // Adjust sp
+                PUSH    {R3}                       // Push sp onto stack
+                LDMIA   SP, {SP}^                  // Restore SP_usr
+                LDMIA   R12!, {R0-R3}              // Restore User R0-R3
+                LDR     LR, [R12, #12]             // Load SPSR into LR
+                MSR     SPSR_cxsf, LR              // Restore SPSR
+                ADD     R12, R12, #4               // Adjust pointer to LR
+                LDM     R12, {LR}^                 // Restore LR_usr directly into LR
+                LDR     LR, [R12, #4]              // Restore LR
+                LDR     R12, [R12, #-4]            // Restore R12
 
-        MOVS     PC, LR                     // Return from exception
+                MOVS    PC, LR                     // Return from exception
 
 osRtxContextExit:
-        POP      {R0-R3, R12, LR}           // Restore stacked APCS registers
-        RFEFD    SP!                        // Return from exception
+                POP     {R0-R3, R12, LR}           // Restore stacked APCS registers
+                RFEFD   SP!                        // Return from exception
 
-        .fnend
-        .size    osRtxContextSwitch, .-osRtxContextSwitch
+                .fnend
+                .size    osRtxContextSwitch, .-osRtxContextSwitch
 
-        .end
+                .end
diff --git a/CMSIS/RTOS2/RTX/Source/GCC/irq_cm0.S b/CMSIS/RTOS2/RTX/Source/GCC/irq_cm0.S
index 5362c19..59288e2 100644
--- a/CMSIS/RTOS2/RTX/Source/GCC/irq_cm0.S
+++ b/CMSIS/RTOS2/RTX/Source/GCC/irq_cm0.S
@@ -27,7 +27,7 @@
         .file    "irq_cm0.S"
         .syntax  unified
 
-        .equ     I_T_RUN_OFS, 28        // osRtxInfo.thread.run offset
+        .equ     I_T_RUN_OFS, 20        // osRtxInfo.thread.run offset
         .equ     TCB_SP_OFS,  56        // TCB.SP offset
 
         .section ".rodata"
diff --git a/CMSIS/RTOS2/RTX/Source/GCC/irq_cm3.S b/CMSIS/RTOS2/RTX/Source/GCC/irq_cm3.S
index 22ccf36..0bdf091 100644
--- a/CMSIS/RTOS2/RTX/Source/GCC/irq_cm3.S
+++ b/CMSIS/RTOS2/RTX/Source/GCC/irq_cm3.S
@@ -27,7 +27,7 @@
         .file    "irq_cm3.S"
         .syntax  unified
 
-        .equ     I_T_RUN_OFS, 28        // osRtxInfo.thread.run offset
+        .equ     I_T_RUN_OFS, 20        // osRtxInfo.thread.run offset
         .equ     TCB_SP_OFS,  56        // TCB.SP offset
 
         .section ".rodata"
diff --git a/CMSIS/RTOS2/RTX/Source/GCC/irq_cm4f.S b/CMSIS/RTOS2/RTX/Source/GCC/irq_cm4f.S
index 23942f7..8d10213 100644
--- a/CMSIS/RTOS2/RTX/Source/GCC/irq_cm4f.S
+++ b/CMSIS/RTOS2/RTX/Source/GCC/irq_cm4f.S
@@ -27,7 +27,7 @@
         .file    "irq_cm4f.S"
         .syntax  unified
 
-        .equ     I_T_RUN_OFS, 28        // osRtxInfo.thread.run offset
+        .equ     I_T_RUN_OFS, 20        // osRtxInfo.thread.run offset
         .equ     TCB_SP_OFS,  56        // TCB.SP offset
         .equ     TCB_SF_OFS,  34        // TCB.stack_frame offset
 
diff --git a/CMSIS/RTOS2/RTX/Source/IAR/irq_ca.s b/CMSIS/RTOS2/RTX/Source/IAR/irq_ca.s
index aa8dbfc..324fcbc 100644
--- a/CMSIS/RTOS2/RTX/Source/IAR/irq_ca.s
+++ b/CMSIS/RTOS2/RTX/Source/IAR/irq_ca.s
@@ -18,19 +18,13 @@
 ; * -----------------------------------------------------------------------------
 ; *
 ; * Project:     CMSIS-RTOS RTX
-; * Title:       Cortex-A Exception handlers (using GIC)
+; * Title:       Cortex-A Exception handlers
 ; *
 ; * -----------------------------------------------------------------------------
 ; */
 
                 NAME     irq_ca.s
 
-ICDABR0_OFFSET  EQU      0x00000300                 ; GICD: Active Bit Register 0 offset
-ICDIPR0_OFFSET  EQU      0x00000400                 ; GICD: Interrupt Priority Register 0 offset
-ICCIAR_OFFSET   EQU      0x0000000C                 ; GICI: Interrupt Acknowledge Register offset
-ICCEOIR_OFFSET  EQU      0x00000010                 ; GICI: End of Interrupt Register offset
-ICCHPIR_OFFSET  EQU      0x00000018                 ; GICI: Highest Pending Interrupt Register offset
-
 MODE_FIQ        EQU      0x11
 MODE_IRQ        EQU      0x12
 MODE_SVC        EQU      0x13
@@ -39,7 +33,7 @@
 
 CPSR_BIT_T      EQU      0x20
 
-I_T_RUN_OFS     EQU      28                         ; osRtxInfo.thread.run offset
+I_T_RUN_OFS     EQU      20                         ; osRtxInfo.thread.run offset
 TCB_SP_FRAME    EQU      34                         ; osRtxThread_t.stack_frame offset
 TCB_SP_OFS      EQU      56                         ; osRtxThread_t.sp offset
 
@@ -54,7 +48,10 @@
 
 
                 SECTION .data:DATA:NOROOT(2)
-ID0_Active      DCB      4                          ; Flag used to workaround GIC 390 errata 733075
+                EXPORT   IRQ_PendSV
+IRQ_NestLevel   DCD      0                          ; IRQ nesting level counter
+IRQ_PendSV      DCB      0                          ; Pending SVC flag
+SVC_Active      DCB      0                          ; SVC handler execution active flag
 
 
                 SECTION .text:CODE:NOROOT(2)
@@ -160,108 +157,105 @@
 
 IRQ_Handler
                 EXPORT  IRQ_Handler
-                IMPORT  IRQTable
-                IMPORT  IRQCount
-                IMPORT  osRtxIrqHandler
-                IMPORT  irqRtxGicBase
+                IMPORT  osRtxInfo
+                IMPORT  osRtxIrqGetId
+                IMPORT  osRtxIrqGetHandler
+                IMPORT  osRtxIrqSetEnd
 
                 SUB     LR, LR, #4                  ; Pre-adjust LR
                 SRSFD   SP!, #MODE_IRQ              ; Save LR_irq and SPRS_irq
                 PUSH    {R0-R3, R12, LR}            ; Save APCS corruptible registers
 
-                ; Identify and acknowledge interrupt
-                LDR     R1, =irqRtxGicBase;
-                LDR     R1, [R1, #4]
-                LDR     R0, [R1, #ICCHPIR_OFFSET]   ; Dummy Read GICI ICCHPIR to avoid GIC 390 errata 801120
-                LDR     R0, [R1, #ICCIAR_OFFSET]    ; Read GICI ICCIAR
-                DSB                                 ; Ensure that interrupt acknowledge completes before re-enabling interrupts
+                MOV     R3, SP                      ; Move SP into R3
+                AND     R3, R3, #4                  ; Get stack adjustment to ensure 8-byte alignment
+                SUB     SP, SP, R3                  ; Adjust stack
+                PUSH    {R3, R4}                    ; Store stack adjustment(R3) and user data(R4)
 
-                ; Workaround GIC 390 errata 733075 - see GIC-390_Errata_Notice_v6.pdf dated 09-Jul-2014
-                ; The following workaround code is for a single-core system.  It would be different in a multi-core system.
-                ; If the ID is 0 or 0x3FE or 0x3FF, then the GIC CPU interface may be locked-up so unlock it, otherwise service the interrupt as normal
-                ; Special IDs 1020=0x3FC and 1021=0x3FD are reserved values in GICv1 and GICv2 so will not occur here
-                CMP     R0, #0
-                BEQ     IRQ_Unlock
-                MOV     R2, #0x3FE
-                CMP     R0, R2
-                BLT     IRQ_Normal
-IRQ_Unlock
-                ; Unlock the CPU interface with a dummy write to ICDIPR0
-                LDR     R2, =irqRtxGicBase
-                LDR     R2, [R2]
-                LDR     R3, [R2, #ICDIPR0_OFFSET]
-                STR     R3, [R2, #ICDIPR0_OFFSET]
-                DSB                                 ; Ensure the write completes before continuing
+                BLX     osRtxIrqGetId               ; Retrieve interrupt ID into R0
+                CMP     R0, #-1                     ; Check if interrupt valid
+                BEQ     IRQ_Exit                    ; Spurious interrupt if -1, exit IRQ
+                MOV     R4, R0                      ; Move interrupt ID to R4
 
-                ; If the ID is 0 and it is active and has not been seen before, then service it as normal,
-                ; otherwise the interrupt should be treated as spurious and not serviced.
-                CMP     R0, #0
-                BNE     IRQ_Exit                    ; Not 0, so spurious
-                LDR     R3, [R2, #ICDABR0_OFFSET]   ; Get the interrupt state
-                TST     R3, #1
-                BEQ     IRQ_Exit                    ; Not active, so spurious
-                LDR     R2, =ID0_Active
-                LDRB    R3, [R2]
-                CMP     R3, #1
-                BEQ     IRQ_Exit                    ; Seen it before, so spurious
+                LDR     R1, =IRQ_NestLevel
+                LDR     R3, [R1]                    ; Load IRQ nest level and increment it
+                ADD     R3, R3, #1
+                STR     R3, [R1]
 
-                ; Record that ID0 has now been seen, then service it as normal
-                MOV     R3, #1
-                STRB    R3, [R2]
-                ; End of Workaround GIC 390 errata 733075
-
-IRQ_Normal
-                LDR     R2, =IRQCount               ; Read number of entries in IRQ handler table
-                LDR     R2, [R2]
-                CMP     R0, R2                      ; Check if IRQ ID is within range
-                MOV     R2, #0
-                BHS     IRQ_End                     ; Out of range, return as normal
-                LDR     R2, =IRQTable               ; Read IRQ handler address from IRQ table
-                LDR     R2, [R2, R0, LSL #2]
-                CMP     R2, #0                      ; Check if handler address is 0
+                BLX     osRtxIrqGetHandler          ; Retrieve interrupt handler address for current ID
+                CMP     R0, #0                      ; Check if handler address is 0
                 BEQ     IRQ_End                     ; If 0, end interrupt and return
-                PUSH    {R0, R1}                    ; Store IRQ ID and GIC CPU Interface base address
 
                 CPS     #MODE_SVC                   ; Change to SVC mode
 
                 MOV     R3, SP                      ; Move SP into R3
                 AND     R3, R3, #4                  ; Get stack adjustment to ensure 8-byte alignment
                 SUB     SP, SP, R3                  ; Adjust stack
-                PUSH    {R2, R3, R12, LR}           ; Store handler address(R2), stack adjustment(R3) and user R12, LR
+                PUSH    {R3, R4}                    ; Store stack adjustment(R3) and alignment dummy(R4)
 
                 CPSIE   i                           ; Re-enable interrupts
-                BLX     R2                          ; Call IRQ handler
+                BLX     R0                          ; Call IRQ handler
                 CPSID   i                           ; Disable interrupts
 
-                POP     {R2, R3, R12, LR}           ; Restore handler address(R2), stack adjustment(R3) and user R12, LR
+                POP     {R3, R4}
                 ADD     SP, SP, R3                  ; Unadjust stack
 
                 CPS     #MODE_IRQ                   ; Change to IRQ mode
-                POP     {R0, R1}                    ; Restore IRQ ID and GIC CPU Interface base address
-                DSB                                 ; Ensure that interrupt source is cleared before signalling End Of Interrupt
+
 IRQ_End
-                ; R0 =IRQ ID, R1 =GICI_BASE
-                ; EOI does not need to be written for IDs 1020 to 1023 (0x3FC to 0x3FF)
-                STR     R0, [R1, #ICCEOIR_OFFSET]   ; Normal end-of-interrupt write to EOIR (GIC CPU Interface register) to clear the active bit
+                MOV     R0, R4                      ; Move interrupt ID to R0
+                BLX     osRtxIrqSetEnd
 
-                ; If it was ID0, clear the seen flag, otherwise return as normal
+                LDR     R2, =IRQ_NestLevel
+                LDR     R1, [R2]                    ; Load IRQ nest level and
+                SUBS    R1, R1, #1                  ; decrement it
+                STR     R1, [R2]
+                BNE     IRQ_Exit                    ; Not zero, exit from IRQ handler
+
+                LDR     R0, =SVC_Active
+                LDRB    R0, [R0]                    ; Load SVC_Active flag
                 CMP     R0, #0
-                LDREQ   R1, =ID0_Active
-                STRBEQ  R0, [R1]                    ; Clear the seen flag, using R0 (which is 0), to save loading another register
+                BNE     IRQ_SwitchCheck             ; Skip post processing when SVC active
 
-                LDR     R3, =osRtxIrqHandler        ; Load osRtxIrqHandler function address
-                CMP     R2, R3                      ; If is the same ass current IRQ handler
-                BEQ     osRtxContextSwitch          ; Call context switcher
+                ; RTX IRQ post processing check
+                PUSH    {R5, R6}                    ; Save user R5 and R6
+                MOV     R6, #0
+                LDR     R5, =IRQ_PendSV             ; Load address of IRQ_PendSV flag
+                B       IRQ_PendCheck
+IRQ_PendExec
+                STRB    R6, [R5]                    ; Clear PendSV flag
+                CPSIE   i                           ; Re-enable interrupts
+                BLX     osRtxPendSV_Handler         ; Post process pending objects
+                CPSID   i                           ; Disable interrupts
+IRQ_PendCheck
+                LDRB    R0, [R5]                    ; Load PendSV flag
+                CMP     R0, #1                      ; Compare PendSV value
+                BEQ     IRQ_PendExec                ; Branch to IRQ_PendExec if PendSV is set
+                POP     {R5, R6}                    ; Restore user R5 and R6
+
+IRQ_SwitchCheck
+                ; RTX IRQ context switch check
+                LDR     R12, =osRtxInfo+I_T_RUN_OFS ; Load address of osRtxInfo.run
+                LDM     R12, {R0, R1}               ; Load osRtxInfo.thread.run: curr & next
+                CMP     R0, R1                      ; Check if context switch is required
+                BEQ     IRQ_Exit
+
+                POP     {R3, R4}                    ; Restore stack adjustment(R3) and user data(R4)
+                ADD     SP, SP, R3                  ; Unadjust stack
+                B       osRtxContextSwitch
 
 IRQ_Exit
+                POP     {R3, R4}                    ; Restore stack adjustment(R3) and user data(R4)
+                ADD     SP, SP, R3                  ; Unadjust stack
+
                 POP     {R0-R3, R12, LR}            ; Restore stacked APCS registers
                 RFEFD   SP!                         ; Return from IRQ handler
-                
+
 
 SVC_Handler
                 EXPORT  SVC_Handler
-                IMPORT  osRtxIrqLock
-                IMPORT  osRtxIrqUnlock
+                IMPORT  osRtxIrqEnableTick
+                IMPORT  osRtxIrqDisableTick
+                IMPORT  osRtxPendSV_Handler
                 IMPORT  osRtxUserSVC
                 IMPORT  osRtxInfo
 
@@ -278,7 +272,10 @@
                 BNE     SVC_User                    ; Branch if User SVC
 
                 PUSH    {R0-R3}
-                BLX     osRtxIrqLock                ; Disable RTX interrupt (timer, PendSV)
+                BLX     osRtxIrqDisableTick         ; Disable System Timer interrupt
+                LDR     R0, =SVC_Active
+                MOV     R1, #1
+                STRB    R1, [R0]                    ; Set SVC_Active flag
                 POP     {R0-R3}
 
                 LDR     R12, [SP]                   ; Reload R12 from stack
@@ -294,7 +291,30 @@
                 LDMDB   R12, {R2,R3}                ; Load return values from SVC function
                 PUSH    {R0-R3}                     ; Push return values to stack
 
-                BLX     osRtxIrqUnlock              ; Enable RTX interrupt (timer, PendSV)
+                PUSH    {R4, R5}                    ; Save R4 and R5
+                MOV     R5, #0
+                LDR     R4, =IRQ_PendSV             ; Load address of IRQ_PendSV
+                B       SVC_PendCheck
+SVC_PendExec
+                STRB    R5, [R4]                    ; Clear IRQ_PendSV flag
+                CPSIE   i                           ; Re-enable interrupts
+                BLX     osRtxPendSV_Handler         ; Post process pending objects
+                CPSID   i                           ; Disable interrupts
+SVC_PendCheck
+                LDRB    R0, [R4]                    ; Load IRQ_PendSV flag
+                CMP     R0, #1                      ; Compare IRQ_PendSV value
+                BEQ     SVC_PendExec                ; Branch to SVC_PendExec if IRQ_PendSV is set
+                POP     {R4, R5}                    ; Restore R4 and R5
+
+                LDR     R0, =SVC_Active
+                MOV     R1, #0
+                STRB    R1, [R0]                    ; Clear SVC_Active flag
+                BLX     osRtxIrqEnableTick          ; Enable System Timer interrupt
+
+                LDR     R12, =osRtxInfo+I_T_RUN_OFS ; Load address of osRtxInfo.run
+                LDM     R12, {R0, R1}               ; Load osRtxInfo.thread.run: curr & next
+                CMP     R0, R1                      ; Check if context switch is required
+                BEQ     osRtxContextExit            ; Exit if curr and next are equal
                 B       osRtxContextSwitch          ; Continue in context switcher
 
 SVC_User
@@ -315,10 +335,9 @@
 osRtxContextSwitch
                 EXPORT  osRtxContextSwitch
 
-                LDR     R12, =osRtxInfo+I_T_RUN_OFS ; Load address of osRtxInfo.run
-                LDM     R12, {R0, R1}               ; Load osRtxInfo.thread.run: curr & next
-                CMP     R0, R1                      ; Check if context switch is required
-                BEQ     osRtxContextExit            ; Exit if curr and next are equal
+                ; R0  = osRtxInfo.thread.run.curr
+                ; R1  = osRtxInfo.thread.run.next
+                ; R12 = &osRtxInfo.thread.run
 
                 CMP     R0, #0                      ; Is osRtxInfo.thread.run.curr == 0
                 ADDEQ   SP, SP, #32                 ; Equal, curr deleted, adjust current SP
diff --git a/CMSIS/RTOS2/RTX/Source/IAR/irq_cm0.s b/CMSIS/RTOS2/RTX/Source/IAR/irq_cm0.s
index 023aae3..9d11699 100644
--- a/CMSIS/RTOS2/RTX/Source/IAR/irq_cm0.s
+++ b/CMSIS/RTOS2/RTX/Source/IAR/irq_cm0.s
@@ -27,7 +27,7 @@
                 NAME    irq_cm0.s
 
 
-I_T_RUN_OFS     EQU      28                     ; osRtxInfo.thread.run offset
+I_T_RUN_OFS     EQU      20                     ; osRtxInfo.thread.run offset
 TCB_SP_OFS      EQU      56                     ; TCB.SP offset
 
 
diff --git a/CMSIS/RTOS2/RTX/Source/IAR/irq_cm3.s b/CMSIS/RTOS2/RTX/Source/IAR/irq_cm3.s
index bfc3b33..0bffcb3 100644
--- a/CMSIS/RTOS2/RTX/Source/IAR/irq_cm3.s
+++ b/CMSIS/RTOS2/RTX/Source/IAR/irq_cm3.s
@@ -27,7 +27,7 @@
                 NAME    irq_cm3.s
 
 
-I_T_RUN_OFS     EQU      28                     ; osRtxInfo.thread.run offset
+I_T_RUN_OFS     EQU      20                     ; osRtxInfo.thread.run offset
 TCB_SP_OFS      EQU      56                     ; TCB.SP offset
 
 
diff --git a/CMSIS/RTOS2/RTX/Source/IAR/irq_cm4f.s b/CMSIS/RTOS2/RTX/Source/IAR/irq_cm4f.s
index 4af4386..0d84409 100644
--- a/CMSIS/RTOS2/RTX/Source/IAR/irq_cm4f.s
+++ b/CMSIS/RTOS2/RTX/Source/IAR/irq_cm4f.s
@@ -27,7 +27,7 @@
                 NAME    irq_cm4f.s
 
 
-I_T_RUN_OFS     EQU      28                     ; osRtxInfo.thread.run offset
+I_T_RUN_OFS     EQU      20                     ; osRtxInfo.thread.run offset
 TCB_SP_OFS      EQU      56                     ; TCB.SP offset
 TCB_SF_OFS      EQU      34                     ; TCB.stack_frame offset
 
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_core_ca.h b/CMSIS/RTOS2/RTX/Source/rtx_core_ca.h
index 10731ae..1eaaaa0 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_core_ca.h
+++ b/CMSIS/RTOS2/RTX/Source/rtx_core_ca.h
@@ -32,10 +32,6 @@
 #define __DOMAIN_NS             0U
 #define __EXCLUSIVE_ACCESS      1U
 
-/* CPSR initial state */
-#define CPSR_INIT_USER          0x00000010U
-#define CPSR_INIT_SYSTEM        0x0000001FU
-
 /* CPSR bit definitions */
 #define CPSR_T_BIT              0x20U
 #define CPSR_I_BIT              0x80U
@@ -50,10 +46,22 @@
 #define IS_IRQ_MODE()           ((__get_mode() != CPSR_MODE_USER) && (__get_mode() != CPSR_MODE_SYSTEM))
 #define IS_IRQ_MASKED()         (0U)
 
+#define xPSR_INIT(privileged, thumb)                                \
+  ((privileged) != 0U) ? (CPSR_MODE_SYSTEM | (((thumb) != 0U) ? CPSR_T_BIT : 0U)) : \
+                         (CPSR_MODE_USER   | (((thumb) != 0U) ? CPSR_T_BIT : 0U))
+
 #define STACK_FRAME_INIT        0x00U
 
-#define IS_VFP_D32_STACK_FRAME(n) (((n) & 0x04U) != 0U)
-#define IS_VFP_D16_STACK_FRAME(n) (((n) & 0x02U) != 0U)
+// Stack Frame:
+//  - VFP-D32: D16-31, D0-D15, FPSCR, Reserved, R4-R11, R0-R3, R12, LR, PC, CPSR
+//  - VFP-D16:         D0-D15, FPSCR, Reserved, R4-R11, R0-R3, R12, LR, PC, CPSR
+//  - Basic:                                    R4-R11, R0-R3, R12, LR, PC, CPSR
+#define STACK_OFFSET_R0(stack_frame)                                 \
+  (((stack_frame) & 0x04U) != 0U) ? ((32U*8U) + (2U*4U) + (8U*4U)) : \
+  (((stack_frame) & 0x02U) != 0U) ? ((16U*8U) + (2U*4U) + (8U*4U)) : \
+                                                          (8U*4U)
+
+#define OS_TICK_HANDLER         osRtxTick_Handler
 
 /* Emulate M profile get_PSP: SP_usr - (8*4) */
 #if defined(__CC_ARM)
@@ -85,6 +93,9 @@
 }
 #endif
 
+__STATIC_INLINE void __set_CONTROL(uint32_t control) {
+}
+
 
 //  ==== Service Calls definitions ====
 
@@ -341,47 +352,27 @@
 
 //  ==== Core Peripherals functions ====
 
-extern uint32_t SystemCoreClock;        // System Clock Frequency (Core Clock)
+extern uint8_t IRQ_PendSV;
 
 /// Initialize SVC and PendSV System Service Calls (not needed on Cortex-A)
 __STATIC_INLINE void SVC_Initialize (void) {
 }
 
-/// Setup External Tick Timer Interrupt
-/// \param[in] irqn  Interrupt number
-extern void ExtTick_SetupIRQ (int32_t irqn);
-
-/// Enable External Tick Timer Interrupt
-/// \param[in] irqn  Interrupt number
-extern void ExtTick_EnableIRQ (int32_t irqn);
-
-/// Disable External Tick Timer Interrupt
-/// \param[in] irqn  Interrupt number
-extern void ExtTick_DisableIRQ (int32_t irqn);
-
-/// Get Pending SV (Service Call) and ST (SysTick) Flags
-/// \return    Pending SV&ST Flags
-__STATIC_INLINE uint8_t GetPendSV_ST (void) {
-  return (0U);
-}
-
 /// Get Pending SV (Service Call) Flag
 /// \return    Pending SV Flag
-extern uint8_t GetPendSV (void);
-
-/// Clear Pending SV (Service Call) and ST (SysTick) Flags
-__STATIC_INLINE void ClrPendSV_ST (void) {
+__STATIC_INLINE uint8_t GetPendSV (void) {
+  return (IRQ_PendSV);
 }
 
 /// Clear Pending SV (Service Call) Flag
-extern void ClrPendSV (void);
+__STATIC_INLINE void ClrPendSV (void) {
+  IRQ_PendSV = 0U;
+}
 
 /// Set Pending SV (Service Call) Flag
-extern void SetPendSV (void);
-
-/// Set Pending Flags
-/// \param[in] flags  Flags to set
-extern void SetPendFlags (uint8_t flags);
+__STATIC_INLINE void SetPendSV (void) {
+  IRQ_PendSV = 1U;
+}
 
 
 //  ==== Exclusive Access Operation ====
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_core_cm.h b/CMSIS/RTOS2/RTX/Source/rtx_core_cm.h
index 759f90f..9b9d715 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_core_cm.h
+++ b/CMSIS/RTOS2/RTX/Source/rtx_core_cm.h
@@ -53,7 +53,6 @@
 #endif
 #endif
 
-
 #define IS_PRIVILEGED()         ((__get_CONTROL() & 1U) == 0U)
 
 #define IS_IRQ_MODE()            (__get_IPSR() != 0U)
@@ -66,7 +65,7 @@
 #define IS_IRQ_MASKED()          (__get_PRIMASK() != 0U) 
 #endif
 
-#define XPSR_INITIAL_VALUE      0x01000000U
+#define xPSR_INIT(...)          0x01000000U
 
 #if    (__DOMAIN_NS == 1U)
 #define STACK_FRAME_INIT        0xBCU
@@ -74,7 +73,18 @@
 #define STACK_FRAME_INIT        0xFDU
 #endif
 
-#define IS_EXTENDED_STACK_FRAME(n) (((n) & 0x10U) == 0U)
+// Stack Frame:
+//  - Extended: S16-S31, R4-R11, R0-R3, R12, LR, PC, xPSR, S0-S15, FPSCR
+//  - Basic:             R4-R11, R0-R3, R12, LR, PC, xPSR
+#if (__FPU_USED == 1U)
+#define STACK_OFFSET_R0(stack_frame)                \
+  (((stack_frame) & 0x10U) == 0U) ? ((16U+8U)*4U) : \
+                                         (8U *4U)
+#else
+#define STACK_OFFSET_R0(stack_frame)     (8U *4U)
+#endif
+
+#define OS_TICK_HANDLER         SysTick_Handler
 
 
 //  ==== Service Calls definitions ====
@@ -569,9 +579,6 @@
 
 //  ==== Core Peripherals functions ====
 
-extern uint32_t SystemCoreClock;        // System Clock Frequency (Core Clock)
-
-
 /// Initialize SVC and PendSV System Service Calls
 __STATIC_INLINE void SVC_Initialize (void) {
 #if   ((__ARM_ARCH_8M_MAIN__ == 1U) || (defined(__CORTEX_M) && (__CORTEX_M == 7U)))
@@ -604,100 +611,12 @@
 #endif
 }
 
-/// Setup SysTick Timer
-/// \param[in] period  Timer Load value
-__STATIC_INLINE void SysTick_Setup (uint32_t period) {
-  SysTick->LOAD = period - 1U;
-  SysTick->VAL  = 0U;
-#if   ((__ARM_ARCH_8M_MAIN__ == 1U) || (defined(__CORTEX_M) && (__CORTEX_M == 7U)))
-  SCB->SHPR[11] = 0xFFU;
-#elif  (__ARM_ARCH_8M_BASE__ == 1U)
-  SCB->SHPR[1] |= 0xFF000000U;
-#elif ((__ARM_ARCH_7M__      == 1U) || \
-       (__ARM_ARCH_7EM__     == 1U))
-  SCB->SHP[11]  = 0xFFU;
-#elif  (__ARM_ARCH_6M__      == 1U)
-  SCB->SHP[1]  |= 0xFF000000U;
-#endif
-}
-
-/// Get SysTick Period
-/// \return    SysTick Period
-__STATIC_INLINE uint32_t SysTick_GetPeriod (void) {
-  return (SysTick->LOAD + 1U);
-}
-
-/// Get SysTick Value
-/// \return    SysTick Value
-__STATIC_INLINE uint32_t SysTick_GetVal (void) {
-  uint32_t load = SysTick->LOAD;
-  return  (load - SysTick->VAL);
-}
-
-/// Get SysTick Overflow (Auto Clear)
-/// \return    SysTick Overflow flag
-__STATIC_INLINE uint32_t SysTick_GetOvf (void) {
-  return ((SysTick->CTRL >> 16) & 1U);
-}
-
-/// Enable SysTick Timer
-__STATIC_INLINE void SysTick_Enable (void) {
-  SysTick->CTRL = SysTick_CTRL_ENABLE_Msk     |
-                  SysTick_CTRL_TICKINT_Msk    |
-                  SysTick_CTRL_CLKSOURCE_Msk;
-}
-
-/// Disable SysTick Timer
-__STATIC_INLINE void SysTick_Disable (void) {
-  SysTick->CTRL = 0U;
-}
-
-/// Setup External Tick Timer Interrupt
-/// \param[in] irqn  Interrupt number
-__STATIC_INLINE void ExtTick_SetupIRQ (int32_t irqn) {
-#if    (__ARM_ARCH_8M_MAIN__ == 1U)
-  NVIC->IPR[irqn] = 0xFFU;
-#elif  (__ARM_ARCH_8M_BASE__ == 1U)
-  NVIC->IPR[irqn >> 2] = (NVIC->IPR[irqn >> 2]  & ~(0xFFU << ((irqn & 3) << 3))) |
-                                                   (0xFFU << ((irqn & 3) << 3));
-#elif ((__ARM_ARCH_7M__      == 1U) || \
-       (__ARM_ARCH_7EM__     == 1U))
-  NVIC->IP[irqn] = 0xFFU;
-#elif  (__ARM_ARCH_6M__      == 1U)
-  NVIC->IP[irqn >> 2] = (NVIC->IP[irqn >> 2]  & ~(0xFFU << ((irqn & 3) << 3))) |
-                                                 (0xFFU << ((irqn & 3) << 3));
-#endif
-}
-
-/// Enable External Tick Timer Interrupt
-/// \param[in] irqn  Interrupt number
-__STATIC_INLINE void 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 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 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 GetPendSV (void) {
   return ((uint8_t)((SCB->ICSR & (SCB_ICSR_PENDSVSET_Msk)) >> 24));
 }
 
-/// Clear Pending SV (Service Call) and ST (SysTick) Flags
-__STATIC_INLINE void ClrPendSV_ST (void) {
-  SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk;
-}
-
 /// Clear Pending SV (Service Call) Flag
 __STATIC_INLINE void ClrPendSV (void) {
   SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk;
@@ -708,12 +627,6 @@
   SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
 }
 
-/// Set Pending Flags
-/// \param[in] flags  Flags to set
-__STATIC_INLINE void SetPendFlags (uint8_t flags) {
-  SCB->ICSR = ((uint32_t)flags << 24);
-}
-
 
 //  ==== Exclusive Access Operation ====
 
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_gic.c b/CMSIS/RTOS2/RTX/Source/rtx_gic.c
index 7246892..aac3184 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_gic.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_gic.c
@@ -26,121 +26,93 @@
 #include "RTE_Components.h"
 #include CMSIS_device_header
 
-#include "rtx_lib.h"
+#include "rtx_os.h"
+
 
 #if ((__ARM_ARCH_7A__ == 1U) && (__GIC_PRESENT == 1U))
 
-extern const uint32_t irqRtxGicBase[];
-       const uint32_t irqRtxGicBase[2] = {
-  GIC_DISTRIBUTOR_BASE,
-  GIC_INTERFACE_BASE
-};
+extern IRQHandler IRQTable[];
+extern uint32_t   IRQCount;
 
+static uint32_t ID0_Active;
 
-static IRQn_Type PendSV_IRQn;
-static uint8_t   PendSV_Flag = 0U;
-
-
-// Pending supervisor call interface
-// =================================
-
-/// Get Pending SV (Service Call) Flag
-/// \return    Pending SV Flag
-uint8_t GetPendSV (void) {
-  uint32_t pend;
-
-  pend = GIC_GetIRQStatus(PendSV_IRQn);
-
-  return ((uint8_t)(pend & 1U));
-}
-
-/// Clear Pending SV (Service Call) Flag
-void ClrPendSV (void) {
-  GIC_ClearPendingIRQ(PendSV_IRQn);
-  PendSV_Flag = 0U;
-}
-
-/// Set Pending SV (Service Call) Flag
-void SetPendSV (void) {
-  PendSV_Flag = 1U;
-  GIC_SetPendingIRQ(PendSV_IRQn);
-}
-
-/// Set Pending Flags
-/// \param[in] flags  Flags to set
-void SetPendFlags (uint8_t flags) {
-  if ((flags & 1U) != 0U) {
-    PendSV_Flag = 1U;
-    GIC_SetPendingIRQ(PendSV_IRQn);
-  }
-}
-
-
-// External IRQ handling interface
-// =================================
-
-/// Enable RTX interrupts
-void osRtxIrqUnlock (void) {
-  GIC_EnableIRQ(PendSV_IRQn);
-}
-
-/// Disable RTX interrupts
-void osRtxIrqLock (void) {
-  GIC_DisableIRQ(PendSV_IRQn);
-}
-
-/// Timer/PendSV interrupt handler
-void osRtxIrqHandler (void) {
-
-  if (PendSV_Flag == 0U) {
-    osRtxTick_Handler();
-  } else {
-    ClrPendSV();
-    osRtxPendSV_Handler();
-  }
-}
-
-
-// External tick timer IRQ interface
-// =================================
-
-/// Setup External Tick Timer Interrupt
-/// \param[in] irqn  Interrupt number
-void ExtTick_SetupIRQ (int32_t irqn) {
-  IRQn_Type irq = (IRQn_Type)irqn;
+int32_t osRtxIrqGetId (void) {
+  IRQn_Type irq;
+  int32_t id;
   uint32_t prio;
 
-  PendSV_IRQn = irq;
+  /* Dummy read to avoid GIC 390 errata 801120 */
+  GIC_GetHighPendingIRQ();
 
-  // Disable corresponding IRQ first
-  GIC_DisableIRQ     (irq);
-  GIC_ClearPendingIRQ(irq);
+  irq = GIC_AcknowledgePending();
 
-  // Write 0xFF to determine priority level
-  GIC_SetPriority(irq, 0xFFU);
+  __DSB();
 
-  // Read back the number of priority bits
-  prio = GIC_GetPriority(irq);
+  /* Workaround GIC 390 errata 733075 (GIC-390_Errata_Notice_v6.pdf, 09-Jul-2014)  */
+  /* The following workaround code is for a single-core system.  It would be       */
+  /* different in a multi-core system.                                             */
+  /* If the ID is 0 or 0x3FE or 0x3FF, then the GIC CPU interface may be locked-up */
+  /* so unlock it, otherwise service the interrupt as normal.                      */
+  /* Special IDs 1020=0x3FC and 1021=0x3FD are reserved values in GICv1 and GICv2  */
+  /* so will not occur here.                                                       */
+  id = (int32_t)irq;
 
-  // Set lowest possible priority
-  GIC_SetPriority(irq, prio - 1);
+  if ((irq == 0U) || (irq >= 0x3FEU)) {
+    /* Unlock the CPU interface with a dummy write to Interrupt Priority Register */
+    prio = GIC_GetPriority((IRQn_Type)0);
+    GIC_SetPriority ((IRQn_Type)0, prio);
 
-  // Set edge-triggered and 1-N model bits
-  GIC_SetLevelModel(irq, 1, 1);
+    __DSB();
 
-  InterruptHandlerRegister(irq, osRtxIrqHandler);
+    if (id != 0U) {
+      /* Not 0 (spurious interrupt) */
+      id = -1;
+    }
+    else if ((GIC_GetIRQStatus (irq) & 1U) == 0U) {
+      /* Not active (spurious interrupt) */
+      id = -1;
+    }
+    else if (ID0_Active == 1U) {
+      /* Already seen (spurious interrupt) */
+      id = -1;
+    }
+    else {
+      ID0_Active = 1U;
+    }
+    /* End of Workaround GIC 390 errata 733075 */
+  }
+
+  return (id);
 }
 
-/// Enable External Tick Timer Interrupt
-/// \param[in] irqn  Interrupt number
-void ExtTick_EnableIRQ (int32_t irqn) {
-  GIC_EnableIRQ((IRQn_Type)irqn);
+uint32_t osRtxIrqGetHandler (int32_t id) {
+  IRQHandler h;
+
+  if (id < IRQCount) {
+    h = IRQTable[id];
+  } else {
+    h = NULL;
+  }
+
+  return ((uint32_t)h);
 }
 
-/// Disable External Tick Timer Interrupt
-/// \param[in] irqn  Interrupt number
-void ExtTick_DisableIRQ (int32_t irqn) {
-  GIC_DisableIRQ((IRQn_Type)irqn);
+void osRtxIrqSetEnd (int32_t id) {
+
+  GIC_EndInterrupt ((IRQn_Type)id);
+
+  if (id == 0) {
+    ID0_Active = 0U;
+  }
+}
+
+void osRtxIrqEnableTick  (void) {
+  GIC_EnableIRQ((IRQn_Type)osRtxInfo.tick_irqn);
+}
+
+void osRtxIrqDisableTick (void) {
+  GIC_DisableIRQ((IRQn_Type)osRtxInfo.tick_irqn);
 }
 
 #endif
+
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_kernel.c b/CMSIS/RTOS2/RTX/Source/rtx_kernel.c
index 24883ad..fad3160 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_kernel.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_kernel.c
@@ -36,18 +36,14 @@
 /// Block Kernel (disable: thread switching, time tick, post ISR processing).
 static void KernelBlock (void) {
 
-  if (osRtxInfo.tick_irqn >= 0) {
-    ExtTick_DisableIRQ(osRtxInfo.tick_irqn);
-  }
-  osRtxSysTimerDisable();
+  OS_Tick_Disable();
+
   osRtxInfo.kernel.blocked = 1U;
   __DSB();
-  if (osRtxInfo.tick_irqn < 0) {
-    osRtxInfo.kernel.pendISR = GetPendSV_ST();
-    ClrPendSV_ST();
-  } else {
-    osRtxInfo.kernel.pendISR = GetPendSV();
+
+  if (GetPendSV() != 0U) {
     ClrPendSV();
+    osRtxInfo.kernel.pendSV = 1U;
   }
 }
 
@@ -56,17 +52,13 @@
 
   osRtxInfo.kernel.blocked = 0U;
   __DSB();
+
   if (osRtxInfo.kernel.pendSV != 0U) {
     osRtxInfo.kernel.pendSV = 0U;
     SetPendSV();
   }
-  if (osRtxInfo.kernel.pendISR != 0U) {
-    SetPendFlags(osRtxInfo.kernel.pendISR);
-  }
-  if (osRtxInfo.tick_irqn >= 0) {
-    ExtTick_EnableIRQ(osRtxInfo.tick_irqn);
-  }
-  osRtxSysTimerEnable();
+
+  OS_Tick_Enable();
 }
 
 
@@ -271,6 +263,17 @@
     }
   }
 
+  // Setup RTOS Tick
+  if (OS_Tick_Setup(osRtxConfig.tick_freq, OS_TICK_HANDLER) != 0U) {
+    return osError;
+  }
+  osRtxInfo.tick_irqn = OS_Tick_GetIRQn();
+
+  // Enable RTOS Tick
+  if (OS_Tick_Enable() != 0U) {
+    return osError;
+  }
+
   // Switch to Ready Thread with highest Priority
   thread = osRtxThreadListGet(&osRtxInfo.thread.ready);
   if (thread == NULL) {
@@ -279,7 +282,6 @@
   }
   osRtxThreadSwitch(thread);
 
-#if (__ARM_ARCH_7A__ == 0U)
   if ((osRtxConfig.flags & osRtxConfigPrivilegedMode) != 0U) {
     // Privileged Thread mode & PSP
     __set_CONTROL(0x02U);
@@ -287,17 +289,6 @@
     // Unprivileged Thread mode & PSP
     __set_CONTROL(0x03U);
   }
-#endif
-
-  osRtxInfo.kernel.sys_freq = SystemCoreClock;
-
-  // Setup and Enable System Timer
-  osRtxInfo.tick_irqn = osRtxSysTimerSetup();
-  if (osRtxInfo.tick_irqn >= 0) {
-    ExtTick_SetupIRQ (osRtxInfo.tick_irqn);
-    ExtTick_EnableIRQ(osRtxInfo.tick_irqn);
-  }
-  osRtxSysTimerEnable();
 
   osRtxInfo.kernel.state = osRtxKernelRunning;
 
@@ -483,7 +474,16 @@
 /// Get the RTOS kernel system timer count.
 /// \note API identical to osKernelGetSysTimerCount
 uint32_t svcRtxKernelGetSysTimerCount (void) {
-  uint32_t count = osRtxSysTimerGetCount();
+  uint32_t tick;
+  uint32_t count;
+
+  tick  = (uint32_t)osRtxInfo.kernel.tick;
+  count = OS_Tick_GetCount();
+  if (OS_Tick_GetOverflow()) {
+    count = OS_Tick_GetCount();
+    tick++;
+  }
+  count += tick * OS_Tick_GetInterval();
   EvrRtxKernelGetSysTimerCount(count);
   return count;
 }
@@ -491,7 +491,7 @@
 /// Get the RTOS kernel system timer frequency.
 /// \note API identical to osKernelGetSysTimerFreq
 uint32_t svcRtxKernelGetSysTimerFreq (void) {
-  uint32_t freq = osRtxSysTimerGetFreq();
+  uint32_t freq = OS_Tick_GetClock();
   EvrRtxKernelGetSysTimerFreq(freq);
   return freq;
 }
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_lib.h b/CMSIS/RTOS2/RTX/Source/rtx_lib.h
index 5c5f81b..17bfc00 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_lib.h
+++ b/CMSIS/RTOS2/RTX/Source/rtx_lib.h
@@ -32,6 +32,7 @@
 #if ((__ARM_ARCH_8M_BASE__ != 0) || (__ARM_ARCH_8M_MAIN__ != 0))
 #include "tz_context.h"                 // TrustZone Context API
 #endif
+#include "os_tick.h"
 #include "cmsis_os2.h"                  // CMSIS RTOS API
 #include "rtx_os.h"                     // RTX OS definitions
 #include "rtx_evr.h"                    // RTX Event Recorder definitions
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_system.c b/CMSIS/RTOS2/RTX/Source/rtx_system.c
index f92b30b..fc64c93 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_system.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_system.c
@@ -120,7 +120,7 @@
 void osRtxTick_Handler (void) {
   os_thread_t *thread;
 
-  osRtxSysTimerAckIRQ();
+  OS_Tick_AcknowledgeIRQ();
   osRtxInfo.kernel.tick++;
 
   // Process Timers
@@ -207,68 +207,3 @@
     osRtxErrorNotify(osRtxErrorISRQueueOverflow, object);
   }
 }
-
-
-//  ==== Public API ====
-
-/// Setup System Timer.
-__WEAK int32_t osRtxSysTimerSetup (void) {
-#ifdef SysTick
-  // Setup SysTick Timer
-  SysTick_Setup(osRtxInfo.kernel.sys_freq / osRtxConfig.tick_freq);
-
-  return SysTick_IRQn;                  // Return IRQ number of SysTick
-#else
-  return 0;
-#endif
-}
-
-/// Enable System Timer.
-__WEAK void osRtxSysTimerEnable (void) {
-#ifdef SysTick
-  SysTick_Enable();
-#endif
-}
-
-/// Disable System Timer.
-__WEAK void osRtxSysTimerDisable (void) {
-#ifdef SysTick
-  SysTick_Disable();
-#endif
-}
-
-/// Acknowledge System Timer IRQ.
-__WEAK void osRtxSysTimerAckIRQ (void) {
-#ifdef SysTick
-  SysTick_GetOvf();
-#endif
-}
-
-/// Get System Timer count.
-__WEAK uint32_t osRtxSysTimerGetCount (void) {
-#ifdef SysTick
-  uint32_t tick;
-  uint32_t val;
-
-  tick = osRtxInfo.kernel.tick;
-  val  = SysTick_GetVal();
-  if (SysTick_GetOvf()) {
-    val = SysTick_GetVal();
-    tick++;
-  }
-  val += tick * SysTick_GetPeriod();
-
-  return val;
-#else
-  return 0U;
-#endif
-}
-
-/// Get System Timer frequency.
-__WEAK uint32_t osRtxSysTimerGetFreq (void) {
-#ifdef SysTick
-  return osRtxInfo.kernel.sys_freq;
-#else
-  return 0U;
-#endif
-}
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_thread.c b/CMSIS/RTOS2/RTX/Source/rtx_thread.c
index 264e404..06d2d93 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_thread.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_thread.c
@@ -377,33 +377,7 @@
 /// \param[in]  thread          thread object.
 /// \return pointer to registers R0-R3.
 uint32_t *osRtxThreadRegPtr (os_thread_t *thread) {
-#if (__ARM_ARCH_7A__ == 0U) /* Cortex-M */
-#if (__FPU_USED == 1U)
-  if (IS_EXTENDED_STACK_FRAME(thread->stack_frame)) {
-    // Extended Stack Frame: S16-S31, R4-R11, R0-R3, R12, LR, PC, xPSR, S0-S15, FPSCR
-    return ((uint32_t *)(thread->sp + (16U+8U)*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
-#else /* Cortex-A */
-  if (IS_VFP_D32_STACK_FRAME(thread->stack_frame)) {
-    /* VFP-D32 Stack Frame: D16-31, D0-D15, FPSCR, Reserved, R4-R11, R0-R3, R12, LR, PC, CPSR */
-    return (uint32_t *)(thread->sp + (8U*4U) + (2U*4U) + (32U*8U));
-  }
-  else if (IS_VFP_D16_STACK_FRAME(thread->stack_frame)) {
-    /* VFP-D16 Stack Frame:         D0-D15, FPSCR, Reserved, R4-R11, R0-R3, R12, LR, PC, CPSR */
-    return (uint32_t *)(thread->sp + (8U*4U) + (2U*4U) + (16U*8U));
-  }
-  else {
-    /* Basic Stack Frame:                                    R4-R11, R0-R3, R12, LR, PC, CPSR */
-    return (uint32_t *)(thread->sp + (8U*4U));
-  }
-#endif
+  return ((uint32_t *)(thread->sp + STACK_OFFSET_R0(thread->stack_frame)));
 }
 
 /// Block running Thread execution and register it as Ready to Run.
@@ -775,19 +749,10 @@
   }
   *ptr++   = (uint32_t)osThreadExit;    // LR
   *ptr++   = (uint32_t)func;            // PC
-#if (__ARM_ARCH_7A__ == 0U)
-  *ptr++   = XPSR_INITIAL_VALUE;        // xPSR
-#else
-  if ((osRtxConfig.flags & osRtxConfigPrivilegedMode) != 0U) {
-    *ptr   = CPSR_INIT_SYSTEM;          // CPSR (Mode=System))
-  } else {
-    *ptr   = CPSR_INIT_USER;            // CPSR (Mode=User)
-  }
-  if (((uint32_t)func & 1U) != 0U) {
-    *ptr  |= CPSR_T_BIT;                // CPSR (Thumb=1)
-  }
-  ptr++;
-#endif
+  *ptr++   = xPSR_INIT(
+              (osRtxConfig.flags & osRtxConfigPrivilegedMode),
+              ((uint32_t)func & 1U)
+             );                         // xPSR
   *(ptr-8) = (uint32_t)argument;        // R0
 
   // Register post ISR processing function
diff --git a/CMSIS/RTOS2/Source/os_systick.c b/CMSIS/RTOS2/Source/os_systick.c
new file mode 100644
index 0000000..a560e96
--- /dev/null
+++ b/CMSIS/RTOS2/Source/os_systick.c
@@ -0,0 +1,121 @@
+/**************************************************************************//**
+ * @file     os_systick.c
+ * @brief    CMSIS OS Tick SysTick implementation
+ * @version  V1.0.0
+ * @date     05. June 2017
+ ******************************************************************************/
+/*
+ * Copyright (c) 2017-2017 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
+ *
+ * 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.
+ */
+
+#include "os_tick.h"
+
+#include "RTE_Components.h"
+#include CMSIS_device_header
+
+#ifdef  SysTick
+
+#ifndef SYSTICK_IRQ_PRIORITY
+#define SYSTICK_IRQ_PRIORITY    0xFFU
+#endif
+
+static uint8_t PendST;
+
+// Setup OS Tick.
+__WEAK int32_t  OS_Tick_Setup (uint32_t freq, IRQHandler_t handler) {
+  (void)handler;
+  uint32_t load;
+
+  if (freq == 0U) {
+    return (-1);
+  }
+
+  load = (SystemCoreClock / freq) - 1U;
+  if (load > 0x00FFFFFFU) {
+    return (-1);
+  }
+
+  NVIC_SetPriority(SysTick_IRQn, SYSTICK_IRQ_PRIORITY);
+
+  SysTick->CTRL =  SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk;
+  SysTick->LOAD =  load;
+  SysTick->VAL  =  0U;
+
+  PendST = 0U;
+
+  return (0);
+}
+
+/// Enable OS Tick.
+__WEAK int32_t  OS_Tick_Enable (void) {
+
+  if (PendST != 0U) {
+    PendST = 0U;
+    SCB->ICSR = SCB_ICSR_PENDSTSET_Msk;
+  }
+
+  SysTick->CTRL |=  SysTick_CTRL_ENABLE_Msk;
+
+  return (0);
+}
+
+/// Disable OS Tick.
+__WEAK int32_t  OS_Tick_Disable (void) {
+
+  SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
+
+  if ((SCB->ICSR & SCB_ICSR_PENDSTSET_Msk) != 0U) {
+    SCB->ICSR = SCB_ICSR_PENDSTCLR_Msk;
+    PendST = 1U;
+  }
+
+  return (0);
+}
+
+// Acknowledge OS Tick IRQ.
+__WEAK int32_t  OS_Tick_AcknowledgeIRQ (void) {
+  (void)SysTick->CTRL;
+  return (0);
+}
+
+// Get OS Tick IRQ number.
+__WEAK int32_t  OS_Tick_GetIRQn (void) {
+  return (SysTick_IRQn);
+}
+
+// Get OS Tick clock.
+__WEAK uint32_t OS_Tick_GetClock (void) {
+  return (SystemCoreClock);
+}
+
+// Get OS Tick interval.
+__WEAK uint32_t OS_Tick_GetInterval (void) {
+  return (SysTick->LOAD + 1U);
+}
+
+// Get OS Tick count value.
+__WEAK uint32_t OS_Tick_GetCount (void) {
+  uint32_t load = SysTick->LOAD;
+  return  (load - SysTick->VAL);
+}
+
+// Get OS Tick overflow status.
+__WEAK uint32_t OS_Tick_GetOverflow (void) {
+  return ((SysTick->CTRL >> 16) & 1U);
+}
+
+#endif  // SysTick