RTX5: Add support for Process Isolation (Functional Safety)

Based on CMSIS-RTOS2 API 2.2.0:
 - MPU Protected Zones
 - Safety Classes
 - Thread Watchdogs

Additional safety features:
 - Object Pointer checking
 - SVC Function Pointer checking
diff --git a/CMSIS/DoxyGen/RTOS2/src/cmsis_os2.txt b/CMSIS/DoxyGen/RTOS2/src/cmsis_os2.txt
index 7790bde..5f602c9 100644
--- a/CMSIS/DoxyGen/RTOS2/src/cmsis_os2.txt
+++ b/CMSIS/DoxyGen/RTOS2/src/cmsis_os2.txt
@@ -742,7 +742,7 @@
 
 The file "RTX_Config.h" defines the configuration parameters of CMSIS-RTOS RTX and must be part of every project that is
 using the CMSIS-RTOS RTX kernel. The configuration options are explained in detail in the following sections:
-- \ref systemConfig covers system-wide settings for the global memory pool, tick frequency, ISR event buffer and round-robin thread switching.
+- \ref systemConfig covers system-wide settings for the global memory pool, tick frequency, ISR event buffer and round-robin thread switching as well as process isolation-related features.
 - \ref threadConfig provides several parameters to configure the \ref CMSIS_RTOS_ThreadMgmt functions.
 - \ref timerConfig provides several parameters to configure the \ref CMSIS_RTOS_TimerMgmt functions.
 - \ref eventFlagsConfig provides several parameters to configure the \ref CMSIS_RTOS_EventFlags functions.
@@ -776,14 +776,20 @@
 <b>System Configuration Options</b>
 \image html config_wizard_system.png "RTX_Config.h: System Configuration"
 
-Name                                   | \#define                 | Description
----------------------------------------|--------------------------|----------------------------------------------------------------
-Global Dynamic Memory size [bytes]     | \c OS_DYNAMIC_MEM_SIZE   | Defines the combined global dynamic memory size for the \ref GlobalMemoryPool. Default value is \token{32768}. Value range is \token{[0-1073741824]} bytes, in multiples of \token{8} bytes.
-Kernel Tick Frequency (Hz)             | \c OS_TICK_FREQ          | Defines base time unit for delays and timeouts in Hz. Default: 1000Hz = 1ms period.
-Round-Robin Thread switching           | \c OS_ROBIN_ENABLE       | Enables Round-Robin Thread switching.
-Round-Robin Timeout                    | \c OS_ROBIN_TIMEOUT      | Defines how long a thread will execute before a thread switch. Default value is \token{5}. Value range is \token{[1-1000]}.
-ISR FIFO Queue                         | \c OS_ISR_FIFO_QUEUE     | RTOS Functions called from ISR store requests to this buffer. Default value is \token{16 entries}. Value range is \token{[4-256]} entries in multiples of \token{4}.
-Object Memory usage counters           | \c OS_OBJ_MEM_USAGE      | Enables object memory usage counters to evaluate the maximum memory pool requirements individually for each RTOS object type.
+Name                                        | \#define                 | Description
+--------------------------------------------|--------------------------|----------------------------------------------------------------
+\ref systemConfig_glob_mem                  | \c OS_DYNAMIC_MEM_SIZE   | Defines the combined global dynamic memory size for the \ref GlobalMemoryPool. Default value is \token{32768}. Value range is \token{[0-1073741824]} bytes, in multiples of \token{8} bytes.
+Kernel Tick Frequency (Hz)                  | \c OS_TICK_FREQ          | Defines base time unit for delays and timeouts in Hz. Default value is \token{1000} (1000 Hz = 1 ms period).
+\ref systemConfig_rr                        | \c OS_ROBIN_ENABLE       | Enables Round-Robin Thread switching. Default value is \token{1} (enabled).
+&nbsp;&nbsp;&nbsp;Round-Robin Timeout       | \c OS_ROBIN_TIMEOUT      | Defines how long a thread will execute before a thread switch. Default value is \token{5}. Value range is \token{[1-1000]}.
+\ref safetyConfig_safety                    | \c OS_SAFETY_FEATURES    | Enables safety-related features as configured in this group. Default value is \token{1} (enabled).
+&nbsp;&nbsp;&nbsp;Safety class              | \c OS_SAFETY_CLASS       | Enables \ref rtos_process_isolation_safety_class functionality. Default value is \token{1} (enabled).
+&nbsp;&nbsp;&nbsp;MPU Protected Zone        | \c OS_EXECUTION_ZONE     | Enables \ref rtos_process_isolation_mpu. Default value is \token{1} (enabled).
+&nbsp;&nbsp;&nbsp;Thread Watchdog           | \c OS_THREAD_WATCHDOG    | Enables \ref rtos_process_isolation_thread_wdt functionality. Default value is \token{1} (enabled).
+&nbsp;&nbsp;&nbsp;Object Pointer checking   | \c OS_OBJ_PTR_CHECK | Enables verification of object pointer alignment and memory region. Default value is \token{0} (disabled).
+&nbsp;&nbsp;&nbsp;SVC Function Pointer checking | \c OS_SVC_PTR_CHECK | Enables verification of SVC function pointer alignment and memory region. Default value is \token{0} (disabled).
+\ref systemConfig_isr_fifo                  | \c OS_ISR_FIFO_QUEUE     | RTOS Functions called from ISR store requests to this buffer. Default value is \token{16 entries}. Value range is \token{[4-256]} entries in multiples of \token{4}.
+\ref systemConfig_usage_counters            | \c OS_OBJ_MEM_USAGE      | Enables object memory usage counters to evaluate the maximum memory pool requirements individually for each RTOS object type. Default value is \token{0} (disabled).
 
 \subsection systemConfig_glob_mem Global Dynamic Memory size [bytes]
 Refer to \ref GlobalMemoryPool.
@@ -809,6 +815,52 @@
 Round-Robin multitasking is controlled with the <b>\#define OS_ROBIN_ENABLE</b>. The time slice period is configured (in RTX
 timer ticks) with the <b>\#define OS_ROBIN_TIMEOUT</b>.
 
+\subsection safetyConfig_safety Safety features (Source variant only)
+
+Safety features group in \ref systemConfig enables individual selection of safety-related functionalities.
+It requires that RTX is used in the source variant.
+
+It also includes:
+- Thread functions: \ref osThreadProtectPrivileged
+
+<b>MPU Protected Zone</b><br>
+Enables \ref rtos_process_isolation_mpu functionality in the system. This includes:
+- Thread attributes: \ref osThreadZone
+- Thread functions: \ref osThreadGetZone, \ref osThreadTerminateZone
+- Zone Management: \ref osZoneSetup_Callback
+
+When enabled, the MPU Protected Zone values also need to be specified for the threads created by the kernel:
+- For Idle thread in \ref threadConfig
+- For Timer thread in \ref timerConfig
+
+<b>Safety class</b><br>
+Enables \ref rtos_process_isolation_safety_class functionality in the system RTOS. This includes:
+- Object attributes: \ref osSafetyClass
+- Kernel functions: \ref osKernelProtect, \ref osKernelDestroyClass
+- Thread functions: \ref osThreadGetClass, \ref osThreadSuspendClass, \ref osThreadResumeClass
+
+When enabled, the safety class values need to be specified for threads created  by the kernel:
+- For Idle thread in \ref threadConfig
+- For Timer thread in \ref timerConfig
+
+<b>Thread Watchdog</b><br>
+Enables \ref rtos_process_isolation_thread_wdt functionality in the system RTOS. This includes:
+- Thread functions: \ref osThreadFeedWatchdog
+- Handler functions: \ref osWatchdogAlarm_Handler
+
+<b>Object Pointer checking</b><br>
+Enables verification of object pointer alignment and memory region.
+
+Before accessing RTX objects the RTX kernel verifies that obtained object pointer is valid (at least not \token{NULL}). When <i>Object Pointer checking</i> is enabled the kernel will additionally verify that
+the control block of the object is located in the memory section allocated for such object type, and that it is correctly aligned within that memory section.
+
+If static memory allocation is used, the user shall place the control blocks of the objects into the correct named memory sections as described in \ref StaticObjectMemory.
+For object-specific and dynamic memory allocations the kernel will place the objects correctly.
+
+<b>SVC Function Pointer checking</b><br>
+Enables verification of SVC function pointer alignment and memory region.
+
+Many kernel functions are executed in SVC context. Corresponding function pointers are placed by the kernel into a special named memory section. If <i>SVC Function Pointer checking</i> is enabled the kernel before calling an SVC function will additionally verify that its pointer is located in the expected memory section and is correctly aligned within that memory region.
 
 \subsection systemConfig_isr_fifo ISR FIFO Queue
 The RTX functions (\ref CMSIS_RTOS_ISR_Calls), when called from and interrupt handler, store the request type and optional
@@ -845,9 +897,11 @@
 Default Thread Stack size [bytes]                        | \c OS_STACK_SIZE    | Defines stack size for threads with zero stack size specified. Default value is \token{3072}. Value range is \token{[96-1073741824]} Bytes, in multiples of \token{8}. 
 Idle Thread Stack size [bytes]                           | \c OS_IDLE_THREAD_STACK_SIZE              | Defines stack size for Idle thread. Default value is \token{512}. Value range is \token{[72-1073741824]} bytes, in multiples of \token{8}. 
 Idle Thread TrustZone Module ID                          | \c OS_IDLE_THREAD_TZ_MOD_ID    | Defines the \ref osThreadAttr_t::tz_module "TrustZone Module ID" the Idle Thread shall use. This needs to be set to a non-zero value if the Idle Thread need to call secure functions. Default value is \token{0}.
+Idle Thread Safety Class                                 | \c OS_IDLE_THREAD_CLASS        | Defines the the \ref rtos_process_isolation_safety_class "Safety Class" for the Idle thread. Applied only if Safety Class functionality is enabled in \ref systemConfig. Default value is \token{0}.
+Idle Thread Zone                                         | \c OS_IDLE_THREAD_ZONE         | Defines the \ref rtos_process_isolation_mpu "MPU Protected Zone" for the Idle thread. Applied only if MPU protected Zone functionality is enabled in \ref systemConfig. Default value is \token{0}.
 Stack overrun checking                                   | \c OS_STACK_CHECK   | Enable stack overrun checks at thread switch. 
 Stack usage watermark                                    | \c OS_STACK_WATERMARK    | Initialize thread stack with watermark pattern for analyzing stack usage. Enabling this option increases significantly the execution time of thread creation.
-Processor mode for Thread execution                      | \c OS_PRIVILEGE_MODE     | Controls the processor mode. Default value is \token{Privileged} mode. Value range is \token{[0=Unprivileged; 1=Privileged]} mode.
+Processor mode for Thread execution                      | \c OS_PRIVILEGE_MODE     | Controls the default processor mode when not specified through thread attributes \ref osThreadUnprivileged or \ref osThreadPrivileged. Default value is \token{Unprivileged} mode. Value range is \token{[0=Unprivileged; 1=Privileged]} mode.
 
 \subsection threadConfig_countstack Configuration of Thread Count and Stack Space
 
@@ -889,8 +943,10 @@
 Enabling this option significantly increases the execution time of \ref osThreadNew (depends on thread stack size).
  
 \subsection threadConfig_procmode Processor Mode for Thread Execution
-RTX5 allows to execute threads in unprivileged or privileged processor mode. The processor mode is controlled with the
+RTX5 allows to execute threads in unprivileged or privileged processor mode. The processor mode is configured for all threads with the
 define \c OS_PRIVILEGE_MODE.
+
+It is also possible to specify the privilege level for individual threads. For that use \ref osThreadUnprivileged and \ref osThreadPrivileged defines in the \e attr_bits of \ref osThreadAttr_t argument when creating a thread with \ref osThreadNew.
  
 In \b unprivileged processor mode, the application software:
 - has limited access to the MSR and MRS instructions, and cannot use the CPS instruction.
@@ -914,6 +970,8 @@
 Timer Thread Priority                  | \c OS_TIMER_THREAD_PRIO        | Defines priority for timer thread. Default value is \token{40}. Value range is \token{[8-48]}, in multiples of \token{8}. The numbers have the following priority correlation: \token{8=Low}; \token{16=Below Normal}; \token{24=Normal}; \token{32=Above Normal}; \token{40=High}; \token{48=Realtime} 
 Timer Thread Stack size [bytes]        | \c OS_TIMER_THREAD_STACK_SIZE  | Defines stack size for Timer thread. May be set to 0 when timers are not used. Default value is \token{512}. Value range is \token{[0-1073741824]}, in multiples of \token{8}.
 Timer Thread TrustZone Module ID       | \c OS_TIMER_THREAD_TZ_MOD_ID   | Defines the \ref osThreadAttr_t::tz_module "TrustZone Module ID" the Timer Thread shall use. This needs to be set to a non-zero value if any Timer Callbacks need to call secure functions. Default value is \token{0}.
+Timer Thread Safety Class              | \c OS_TIMER_THREAD_CLASS        | Defines the the \ref rtos_process_isolation_safety_class "Safety Class" for the Timer thread. Applied only if Safety class functionality is enabled in \ref systemConfig. Default value is \token{0}.
+Timer Thread Zone                      | \c OS_TIMER_THREAD_ZONE         | Defines the \ref rtos_process_isolation_mpu "MPU Protected Zone" for the Timer thread. Applied only if MPU protected Zone functionality is enabled in \ref systemConfig. Default value is \token{0}.
 Timer Callback Queue entries           | \c OS_TIMER_CB_QUEUE           | Number of concurrent active timer callback functions. May be set to 0 when timers are not used. Default value is \token{4}. Value range is \token{[0-256]}.
 
 \subsection timerConfig_obj Object-specific memory allocation
@@ -1127,12 +1185,15 @@
 \c EVR_RTX_KERNEL_LOCKED_DISABLE, \c EVR_RTX_KERNEL_UNLOCK_DISABLE, \c EVR_RTX_KERNEL_UNLOCKED_DISABLE,
 \c EVR_RTX_KERNEL_RESTORE_LOCK_DISABLE, \c EVR_RTX_KERNEL_LOCK_RESTORED_DISABLE, \c EVR_RTX_KERNEL_SUSPEND_DISABLE,
 \c EVR_RTX_KERNEL_SUSPENDED_DISABLE, \c EVR_RTX_KERNEL_RESUME_DISABLE, \c EVR_RTX_KERNEL_RESUMED_DISABLE,
+\c EVR_RTX_KERNEL_PROTECT_DISABLE, \c EVR_RTX_KERNEL_PROTECTED_DISABLE,
 \c EVR_RTX_KERNEL_GET_TICK_COUNT_DISABLE, \c EVR_RTX_KERNEL_GET_TICK_FREQ_DISABLE,
-\c EVR_RTX_KERNEL_GET_SYS_TIMER_COUNT_DISABLE, \c EVR_RTX_KERNEL_GET_SYS_TIMER_FREQ_DISABLE
+\c EVR_RTX_KERNEL_GET_SYS_TIMER_COUNT_DISABLE, \c EVR_RTX_KERNEL_GET_SYS_TIMER_FREQ_DISABLE,
+\c EVR_RTX_KERNEL_DESTROY_CLASS_DISABLE, \c EVR_RTX_KERNEL_ERROR_NOTIFY_DISABLE
 
 \b Thread \b events \n
 \c EVR_RTX_THREAD_ERROR_DISABLE, \c EVR_RTX_THREAD_NEW_DISABLE, \c EVR_RTX_THREAD_CREATED_DISABLE,
 \c EVR_RTX_THREAD_GET_NAME_DISABLE, \c EVR_RTX_THREAD_GET_ID_DISABLE, \c EVR_RTX_THREAD_GET_STATE_DISABLE,
+\c EVR_RTX_THREAD_GET_CLASS_DISABLE, \c EVR_RTX_THREAD_GET_ZONE_DISABLE,
 \c EVR_RTX_THREAD_GET_STACK_SIZE_DISABLE, \c EVR_RTX_THREAD_GET_STACK_SPACE_DISABLE, \c EVR_RTX_THREAD_SET_PRIORITY_DISABLE,
 \c EVR_RTX_THREAD_PRIORITY_UPDATED_DISABLE, \c EVR_RTX_THREAD_GET_PRIORITY_DISABLE, \c EVR_RTX_THREAD_YIELD_DISABLE,
 \c EVR_RTX_THREAD_SUSPEND_DISABLE, \c EVR_RTX_THREAD_SUSPENDED_DISABLE, \c EVR_RTX_THREAD_RESUME_DISABLE,
@@ -1140,7 +1201,10 @@
 \c EVR_RTX_THREAD_JOIN_DISABLE, \c EVR_RTX_THREAD_JOIN_PENDING_DISABLE, \c EVR_RTX_THREAD_JOINED_DISABLE,
 \c EVR_RTX_THREAD_BLOCKED_DISABLE, \c EVR_RTX_THREAD_UNBLOCKED_DISABLE, \c EVR_RTX_THREAD_PREEMPTED_DISABLE,
 \c EVR_RTX_THREAD_SWITCHED_DISABLE, \c EVR_RTX_THREAD_EXIT_DISABLE, \c EVR_RTX_THREAD_TERMINATE_DISABLE,
-\c EVR_RTX_THREAD_DESTROYED_DISABLE, \c EVR_RTX_THREAD_GET_COUNT_DISABLE, \c EVR_RTX_THREAD_ENUMERATE_DISABLE
+\c EVR_RTX_THREAD_DESTROYED_DISABLE, \c EVR_RTX_THREAD_GET_COUNT_DISABLE, \c EVR_RTX_THREAD_ENUMERATE_DISABLE,
+\c EVR_RTX_THREAD_FEED_WATCHDOG_DISABLE, \c EVR_RTX_THREAD_FEED_WATCHDOG_DONE_DISABLE, \c EVR_RTX_THREAD_WATCHDOG_EXPIRED_DISABLE,
+\c EVR_RTX_THREAD_PROTECT_PRIVILEGED_DISABLE, \c EVR_RTX_THREAD_PRIVILEGED_PROTECTED_DISABLE,
+\c EVR_RTX_THREAD_SUSPEND_CLASS_DISABLE, \c EVR_RTX_THREAD_RESUME_CLASS_DISABLE, \c EVR_RTX_THREAD_TERMINATE_ZONE_DISABLE
 
 \b Generic \b wait \b events \n
 \c EVR_RTX_DELAY_ERROR_DISABLE, \c EVR_RTX_DELAY_DISABLE, \c EVR_RTX_DELAY_UNTIL_DISABLE,
@@ -1266,9 +1330,9 @@
 Interrupt Control          | The CMSIS-Core functions __disable_irq and __enable_irq to control the interrupt system via the CPSR core register.
 
 The RTX implements interfaces to the processor hardware in following files: 
- - <b>%irq_armv6m.s</b> defines exception handlers for Cortex-M0/M0+
+ - <b>%irq_armv6m.S</b> defines exception handlers for Cortex-M0/M0+
 \if ARMv8M
- - <b>%irq_armv8mbl.s</b> defines exception handlers for Cortex-M23
+ - <b>%irq_armv8mbl.S</b> defines exception handlers for Cortex-M23
 \endif 
  - <b>%rtx_core_cm.h</b> defines processor specific helper functions and the interfaces to Core Registers and Core Peripherals.
  - <b>%os_tick.h</b> is the \ref CMSIS_RTOS_TickAPI that defines the interface functions to the SysTick timer.
@@ -1294,9 +1358,9 @@
 LDREX, STREX instructions  | Exclusive access instructions \b LDREX and \b STREX are used to implement atomic execution without disabling interrupts.
 
 The interface files to the processor hardware are: 
- - <b>%irq_armv7m.s</b> defines exception handlers for Cortex-M3 and Cortex-M4/M7.
+ - <b>%irq_armv7m.S</b> defines exception handlers for Cortex-M3 and Cortex-M4/M7.
 \if ARMv8M 
- - <b>%irq_armv8mml.s</b> defines exception handlers for Cortex-M33/M35P
+ - <b>%irq_armv8mml.S</b> defines exception handlers for Cortex-M33/M35P
 \endif
  - <b>%rtx_core_cm.h</b> defines processor specific helper functions and the interfaces to Core Registers and Core Peripherals.
  - <b>%os_tick.h</b> is the \ref CMSIS_RTOS_TickAPI that defines the interface functions to the SysTick timer.
@@ -1316,7 +1380,7 @@
 Interrupt Controller       | An interrupt controller interface is required to setup and control Timer Peripheral interrupt. The interface for Arm GIC (Generic Interrupt Controller) is implemented in %irq_ctrl_gic.c using the <a class="el" href="../../Core_A/html/group__irq__ctrl__gr.html">IRQ Controller API</a>.
 
 The interface files to the processor hardware are: 
- - <b>%irq_armv7a.s</b> defines SVC, IRQ, Data Abort, Prefetch Abort and Undefined Instruction exception handlers.
+ - <b>%irq_armv7a.S</b> defines SVC, IRQ, Data Abort, Prefetch Abort and Undefined Instruction exception handlers.
  - <b>%rtx_core_ca.h</b> defines processor specific helper functions and the interfaces to Core Registers and Core Peripherals.
  - <b>%os_tick.h</b> is the \ref CMSIS_RTOS_TickAPI that defines the interface functions to the timer peripheral.
  - <b>%irq_ctrl.h</b> is the <a class="el" href="../../Core_A/html/group__irq__ctrl__gr.html">IRQ Controller API</a> that defines the interface functions to the interrupt controller.
@@ -1379,7 +1443,7 @@
 
 Category                      | Control Block Size Attribute      | Size       | \#define symbol
 :-----------------------------|:----------------------------------|:-----------|:--------------------
-\ref CMSIS_RTOS_ThreadMgmt    | \ref osThreadAttr_t::cb_mem       | 68 bytes   | \ref osRtxThreadCbSize
+\ref CMSIS_RTOS_ThreadMgmt    | \ref osThreadAttr_t::cb_mem       | 80 bytes   | \ref osRtxThreadCbSize
 \ref CMSIS_RTOS_TimerMgmt     | \ref osTimerAttr_t::cb_mem        | 32 bytes   | \ref osRtxTimerCbSize
 \ref CMSIS_RTOS_EventFlags    | \ref osEventFlagsAttr_t::cb_mem   | 16 bytes   | \ref osRtxEventFlagsCbSize
 \ref CMSIS_RTOS_MutexMgmt     | \ref osMutexAttr_t::cb_mem        | 28 bytes   | \ref osRtxMutexCbSize
@@ -1568,8 +1632,8 @@
 <ul>
  <li>Arm Compiler 5.06 Update 7</li>
  <li>Arm Compiler 6.6.4 (Long Term Maintenance)</li>
- <li>Arm Compiler 6.16</li>
- <li>RTOS-aware debugging with uVision 5.34</li>
+ <li>Arm Compiler 6.19</li>
+ <li>RTOS-aware debugging with uVision 5.38</li>
 </ul>
 
 
@@ -1622,7 +1686,7 @@
 \page misraCompliance5 MISRA C:2012 Compliance 
 The RTX5 C source files use <b><a class=el href="http://www.misra.org.uk/" target="_blank">MISRA C:2012</a></b> guidelines as underlying coding standard.
 
-For MISRA validation, <b><a class=el href="http://www.gimpel.com/" target="_blank">PC-lint</a></b> V9.00L is used with configuration for Arm Compiler V6.16.
+For MISRA validation, <b><a class=el href="http://www.gimpel.com/" target="_blank">PC-lint</a></b> V9.00L is used with configuration for Arm Compiler V6.19.
 The PC-Lint validation setup is part of the project file <b>.\\CMSIS\\RTOS2\\RTX\\Library\\ARM\\MDK\\RTX_CM.uvprojx</b> as shown below. 
 Refer to <b><a class=el href="https://www.keil.com/support/man/docs/uv4/uv4_ut_pclint_validation.htm" target="_blank">Setup for PC-Lint</a></b> for more information.
 
diff --git a/CMSIS/DoxyGen/RTOS2/src/history.txt b/CMSIS/DoxyGen/RTOS2/src/history.txt
index 5a903d4..1ee375e 100644
--- a/CMSIS/DoxyGen/RTOS2/src/history.txt
+++ b/CMSIS/DoxyGen/RTOS2/src/history.txt
@@ -117,6 +117,13 @@
       <th>Description</th>
     </tr>
     <tr>
+      <td>V5.7.0</td>
+      <td>
+       - Based on CMSIS-RTOS API V2.2.0.
+       - Added support for Process Isolation: MPU Protected Zones, Safety Classes, Thread Watchdogs.
+      </td>
+    </tr>
+    <tr>
       <td>V5.5.5</td>
       <td>
        - Added de-allocation of Arm C library thread data (libspace) when thread is terminated.
diff --git a/CMSIS/DoxyGen/RTOS2/src/images/config_wizard_evtrecRTOSEvtFilterSetup.png b/CMSIS/DoxyGen/RTOS2/src/images/config_wizard_evtrecRTOSEvtFilterSetup.png
index 007ad4c..611119a 100644
--- a/CMSIS/DoxyGen/RTOS2/src/images/config_wizard_evtrecRTOSEvtFilterSetup.png
+++ b/CMSIS/DoxyGen/RTOS2/src/images/config_wizard_evtrecRTOSEvtFilterSetup.png
Binary files differ
diff --git a/CMSIS/DoxyGen/RTOS2/src/images/config_wizard_system.png b/CMSIS/DoxyGen/RTOS2/src/images/config_wizard_system.png
index 6502d6e..c1544bf 100644
--- a/CMSIS/DoxyGen/RTOS2/src/images/config_wizard_system.png
+++ b/CMSIS/DoxyGen/RTOS2/src/images/config_wizard_system.png
Binary files differ
diff --git a/CMSIS/DoxyGen/RTOS2/src/images/config_wizard_threads.png b/CMSIS/DoxyGen/RTOS2/src/images/config_wizard_threads.png
index f7870fd..68cc44d 100644
--- a/CMSIS/DoxyGen/RTOS2/src/images/config_wizard_threads.png
+++ b/CMSIS/DoxyGen/RTOS2/src/images/config_wizard_threads.png
Binary files differ
diff --git a/CMSIS/DoxyGen/RTOS2/src/images/config_wizard_timer.png b/CMSIS/DoxyGen/RTOS2/src/images/config_wizard_timer.png
index 1722acb..3aa1790 100644
--- a/CMSIS/DoxyGen/RTOS2/src/images/config_wizard_timer.png
+++ b/CMSIS/DoxyGen/RTOS2/src/images/config_wizard_timer.png
Binary files differ
diff --git a/CMSIS/DoxyGen/RTOS2/src/rtx_evr.txt b/CMSIS/DoxyGen/RTOS2/src/rtx_evr.txt
index 262fb1e..b184a2e 100644
--- a/CMSIS/DoxyGen/RTOS2/src/rtx_evr.txt
+++ b/CMSIS/DoxyGen/RTOS2/src/rtx_evr.txt
@@ -105,24 +105,25 @@
 The status parameter indicates the execution status and can be one of the \ref osStatus_t "osStatus_t codes" or one
 of the extended execution status codes which are summarized in the table below.
 
-|      Extended Status Code     | Description |
-|:------------------------------|:------------|
-| osRtxErrorKernelNotReady      | Kernel scheduler is not in Ready state. |
-| osRtxErrorKernelNotRunning    | Kernel scheduler is not executing - there is no running thread. |
-| osRtxErrorInvalidControlBlock | Object control block with invalid alignment or size was specified. |
-| osRtxErrorInvalidDataMemory   | Object data memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidThreadStack  | Thread stack memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidPriority     | Invalid thread priority was specified. |
-| osRtxErrorThreadNotJoinable   | Specified thread is not joinable. |
-| osRtxErrorMutexNotOwned       | Specified mutex is not owned by the current running thread. |
-| osRtxErrorMutexNotLocked      | Specified mutex is not locked. |
-| osRtxErrorMutexLockLimit      | Maximum number of recursive mutex locks reached. |
-| osRtxErrorSemaphoreCountLimit | Semaphore count limit reached. |
-| osRtxErrorTZ_InitContext_S    | Secure context memory system initialization failed. |
-| osRtxErrorTZ_AllocContext_S   | Secure context memory allocation failed. |
-| osRtxErrorTZ_FreeContext_S    | Secure context memory deallocation failed. |
-| osRtxErrorTZ_LoadContext_S    | Secure context load failed. |
-| osRtxErrorTZ_SaveContext_S    | Secure context save failed. |
+|      Extended Status Code       | Description |
+|:--------------------------------|:------------|
+| osRtxErrorKernelNotReady        | Kernel scheduler is not in Ready state. |
+| osRtxErrorKernelNotRunning      | Kernel scheduler is not executing - there is no running thread. |
+| osRtxErrorInvalidControlBlock   | Object control block with invalid alignment or size was specified. |
+| osRtxErrorInvalidDataMemory     | Object data memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidThreadStack    | Thread stack memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidPriority       | Invalid thread priority was specified. |
+| osRtxErrorInvalidPrivilegedMode | Privileged thread cannot be created - kernel protect privileged is active. |
+| osRtxErrorThreadNotJoinable     | Specified thread is not joinable. |
+| osRtxErrorMutexNotOwned         | Specified mutex is not owned by the current running thread. |
+| osRtxErrorMutexNotLocked        | Specified mutex is not locked. |
+| osRtxErrorMutexLockLimit        | Maximum number of recursive mutex locks reached. |
+| osRtxErrorSemaphoreCountLimit   | Semaphore count limit reached. |
+| osRtxErrorTZ_InitContext_S      | Secure context memory system initialization failed. |
+| osRtxErrorTZ_AllocContext_S     | Secure context memory allocation failed. |
+| osRtxErrorTZ_FreeContext_S      | Secure context memory deallocation failed. |
+| osRtxErrorTZ_LoadContext_S      | Secure context load failed. |
+| osRtxErrorTZ_SaveContext_S      | Secure context save failed. |
 
 \b Value in the Event Recorder shows:
   - \b status : execution status code.
@@ -262,6 +263,21 @@
 */
 
 /**
+\fn void EvrRtxKernelProtect (uint32_t safety_class)
+\details
+The event \b KernelProtect is generated when the function \ref osKernelProtect is called.
+
+\b Value in the Event Recorder shows:
+  - \b safety_class : safety class value.
+*/
+
+/**
+\fn void EvrRtxKernelProtected (void)
+\details
+The event \b KernelProtected is generated when the function \ref osKernelProtect successfully applies kernel safety class protection.
+*/
+
+/**
 \fn void EvrRtxKernelGetTickCount (uint32_t count)
 \details
 The event \b KernelGetTickCount is generated when the function \ref osKernelGetTickCount is called.
@@ -306,6 +322,16 @@
   - \b code : error code. 
   - \b object_id : object that caused the error.
 */
+
+/**
+\fn void EvrRtxKernelDestroyClass (uint32_t safety_class, uint32_t mode)
+\details
+The event \b KernelDestroyClass is generated when the function \ref osKernelDestroyClass is called.
+
+\b Value in the Event Recorder shows:
+  - \b safety_class : safety class value. 
+  - \b mode : operation mode.
+*/
 */
 
 /**
@@ -327,24 +353,25 @@
 The status parameter indicates the execution status and can be one of the \ref osStatus_t "osStatus_t codes" or one
 of the extended execution status codes which are summarized in the table below.
 
-|      Extended Status Code     | Description |
-|:------------------------------|:------------|
-| osRtxErrorKernelNotReady      | Kernel scheduler is not in Ready state. |
-| osRtxErrorKernelNotRunning    | Kernel scheduler is not executing - there is no running thread. |
-| osRtxErrorInvalidControlBlock | Object control block with invalid alignment or size was specified. |
-| osRtxErrorInvalidDataMemory   | Object data memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidThreadStack  | Thread stack memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidPriority     | Invalid thread priority was specified. |
-| osRtxErrorThreadNotJoinable   | Specified thread is not joinable. |
-| osRtxErrorMutexNotOwned       | Specified mutex is not owned by the current running thread. |
-| osRtxErrorMutexNotLocked      | Specified mutex is not locked. |
-| osRtxErrorMutexLockLimit      | Maximum number of recursive mutex locks reached. |
-| osRtxErrorSemaphoreCountLimit | Semaphore count limit reached. |
-| osRtxErrorTZ_InitContext_S    | Secure context memory system initialization failed. |
-| osRtxErrorTZ_AllocContext_S   | Secure context memory allocation failed. |
-| osRtxErrorTZ_FreeContext_S    | Secure context memory deallocation failed. |
-| osRtxErrorTZ_LoadContext_S    | Secure context load failed. |
-| osRtxErrorTZ_SaveContext_S    | Secure context save failed. |
+|      Extended Status Code       | Description |
+|:--------------------------------|:------------|
+| osRtxErrorKernelNotReady        | Kernel scheduler is not in Ready state. |
+| osRtxErrorKernelNotRunning      | Kernel scheduler is not executing - there is no running thread. |
+| osRtxErrorInvalidControlBlock   | Object control block with invalid alignment or size was specified. |
+| osRtxErrorInvalidDataMemory     | Object data memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidThreadStack    | Thread stack memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidPriority       | Invalid thread priority was specified. |
+| osRtxErrorInvalidPrivilegedMode | Privileged thread cannot be created - kernel protect privileged is active. |
+| osRtxErrorThreadNotJoinable     | Specified thread is not joinable. |
+| osRtxErrorMutexNotOwned         | Specified mutex is not owned by the current running thread. |
+| osRtxErrorMutexNotLocked        | Specified mutex is not locked. |
+| osRtxErrorMutexLockLimit        | Maximum number of recursive mutex locks reached. |
+| osRtxErrorSemaphoreCountLimit   | Semaphore count limit reached. |
+| osRtxErrorTZ_InitContext_S      | Secure context memory system initialization failed. |
+| osRtxErrorTZ_AllocContext_S     | Secure context memory allocation failed. |
+| osRtxErrorTZ_FreeContext_S      | Secure context memory deallocation failed. |
+| osRtxErrorTZ_LoadContext_S      | Secure context load failed. |
+| osRtxErrorTZ_SaveContext_S      | Secure context save failed. |
 
 \b Value in the Event Recorder shows:
   - \b thread_id : thread ID.
@@ -382,6 +409,26 @@
 */
 
 /**
+\fn void EvrRtxThreadGetClass (osThreadId_t thread_id, uint32_t safety_class)
+\details
+The event \b ThreadGetClass is generated when the function \ref osThreadGetClass is called and its execution result is known.
+
+\b Value in the Event Recorder shows:
+  - \b thread_id : thread ID.
+  - \b safety_class : retrieved safety class value (osErrorId in case of a failure).
+*/
+
+/**
+\fn void EvrRtxThreadGetZone (osThreadId_t thread_id, uint32_t zone)
+\details
+The event \b ThreadGetZone is generated when the function \ref osThreadGetZone is called and its execution result is known.
+
+\b Value in the Event Recorder shows:
+  - \b thread_id : thread ID.
+  - \b zone : retrieved MPU Protected Zone value (osErrorId in case of a failure).
+*/
+
+/**
 \fn void EvrRtxThreadGetId (osThreadId_t thread_id)
 \details
 The event \b ThreadGetId is generated when the function \ref osThreadGetId is called and its execution result is known.
@@ -600,6 +647,34 @@
 */
 
 /**
+\fn void EvrRtxThreadFeedWatchdog (uint32_t ticks)
+\details
+
+The event \b ThreadFeedWatchdog is generated when the function \ref osThreadFeedWatchdog is called.
+
+\b Value in the Event Recorder shows:
+  - \b ticks : watchdog timeout in number of kernel ticks.
+*/
+
+/**
+\fn void EvrRtxThreadFeedWatchdogDone (void)
+\details
+The event \b ThreadFeedWatchdogDone is generated when the function \ref osThreadFeedWatchdog successfully feeds the watchdog timer.
+*/
+
+/**
+\fn void EvrRtxThreadProtectPrivileged (void)
+\details
+The event \b ThreadProtectPrivileged is generated when the function \ref osThreadProtectPrivileged is called.
+*/
+
+/**
+\fn void EvrRtxThreadPrivilegedProtected (void)
+\details
+The event \b ThreadPrivilegedProtected is generated when the function \ref osThreadProtectPrivileged successfully applies the new privileged thread creation protection.
+*/
+
+/**
 \fn void EvrRtxThreadGetCount (uint32_t count)
 \details
 The event \b ThreadGetCount is generated when the function \ref osThreadGetCount is called and its execution result is known.
@@ -620,6 +695,44 @@
 */
 
 /**
+\fn void EvrRtxThreadSuspendClass (uint32_t safety_class, uint32_t mode)
+\details
+The event \b ThreadSuspendClass is generated when the function \ref osThreadSuspendClass is called.
+
+\b Value in the Event Recorder shows:
+  - \b safety_class : safety class value.
+  - \b mode : operation mode.
+*/
+
+/**
+\fn void EvrRtxThreadResumeClass (uint32_t safety_class, uint32_t mode)
+\details
+The event \b ThreadResumeClass is generated when the function \ref osThreadResumeClass is called.
+
+\b Value in the Event Recorder shows:
+  - \b safety_class : safety class value.
+  - \b mode : operation mode.
+*/
+
+/**
+\fn void EvrRtxThreadTerminateZone (uint32_t zone)
+\details
+The event \b ThreadTerminateZone is generated when the function \ref osThreadTerminateZone is called.
+
+\b Value in the Event Recorder shows:
+  - \b zone : MPU Protected Zone value.
+*/
+
+/**
+\fn void EvrRtxThreadWatchdogExpired (osThreadId_t thread_id)
+\details
+The event \b ThreadWatchdogExpired is generated when the thread watchdog timer expires.
+
+\b Value in the Event Recorder shows:
+  - \b thread_id : thread ID.
+*/
+
+/**
 @}
 */
 
@@ -638,24 +751,25 @@
 The status parameter indicates the execution status and can be one of the \ref osStatus_t "osStatus_t codes" or one
 of the extended execution status codes which are summarized in the table below.
 
-|      Extended Status Code     | Description |
-|:------------------------------|:------------|
-| osRtxErrorKernelNotReady      | Kernel scheduler is not in Ready state. |
-| osRtxErrorKernelNotRunning    | Kernel scheduler is not executing - there is no running thread. |
-| osRtxErrorInvalidControlBlock | Object control block with invalid alignment or size was specified. |
-| osRtxErrorInvalidDataMemory   | Object data memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidThreadStack  | Thread stack memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidPriority     | Invalid thread priority was specified. |
-| osRtxErrorThreadNotJoinable   | Specified thread is not joinable. |
-| osRtxErrorMutexNotOwned       | Specified mutex is not owned by the current running thread. |
-| osRtxErrorMutexNotLocked      | Specified mutex is not locked. |
-| osRtxErrorMutexLockLimit      | Maximum number of recursive mutex locks reached. |
-| osRtxErrorSemaphoreCountLimit | Semaphore count limit reached. |
-| osRtxErrorTZ_InitContext_S    | Secure context memory system initialization failed. |
-| osRtxErrorTZ_AllocContext_S   | Secure context memory allocation failed. |
-| osRtxErrorTZ_FreeContext_S    | Secure context memory deallocation failed. |
-| osRtxErrorTZ_LoadContext_S    | Secure context load failed. |
-| osRtxErrorTZ_SaveContext_S    | Secure context save failed. |
+|      Extended Status Code       | Description |
+|:--------------------------------|:------------|
+| osRtxErrorKernelNotReady        | Kernel scheduler is not in Ready state. |
+| osRtxErrorKernelNotRunning      | Kernel scheduler is not executing - there is no running thread. |
+| osRtxErrorInvalidControlBlock   | Object control block with invalid alignment or size was specified. |
+| osRtxErrorInvalidDataMemory     | Object data memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidThreadStack    | Thread stack memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidPriority       | Invalid thread priority was specified. |
+| osRtxErrorInvalidPrivilegedMode | Privileged thread cannot be created - kernel protect privileged is active. |
+| osRtxErrorThreadNotJoinable     | Specified thread is not joinable. |
+| osRtxErrorMutexNotOwned         | Specified mutex is not owned by the current running thread. |
+| osRtxErrorMutexNotLocked        | Specified mutex is not locked. |
+| osRtxErrorMutexLockLimit        | Maximum number of recursive mutex locks reached. |
+| osRtxErrorSemaphoreCountLimit   | Semaphore count limit reached. |
+| osRtxErrorTZ_InitContext_S      | Secure context memory system initialization failed. |
+| osRtxErrorTZ_AllocContext_S     | Secure context memory allocation failed. |
+| osRtxErrorTZ_FreeContext_S      | Secure context memory deallocation failed. |
+| osRtxErrorTZ_LoadContext_S      | Secure context load failed. |
+| osRtxErrorTZ_SaveContext_S      | Secure context save failed. |
 
 \b Value in the Event Recorder shows:
   - \b status : execution status code.
@@ -725,24 +839,25 @@
 The status parameter indicates the execution status and can be one of the \ref osStatus_t "osStatus_t codes" or one
 of the extended execution status codes which are summarized in the table below.
 
-|      Extended Status Code     | Description |
-|:------------------------------|:------------|
-| osRtxErrorKernelNotReady      | Kernel scheduler is not in Ready state. |
-| osRtxErrorKernelNotRunning    | Kernel scheduler is not executing - there is no running thread. |
-| osRtxErrorInvalidControlBlock | Object control block with invalid alignment or size was specified. |
-| osRtxErrorInvalidDataMemory   | Object data memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidThreadStack  | Thread stack memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidPriority     | Invalid thread priority was specified. |
-| osRtxErrorThreadNotJoinable   | Specified thread is not joinable. |
-| osRtxErrorMutexNotOwned       | Specified mutex is not owned by the current running thread. |
-| osRtxErrorMutexNotLocked      | Specified mutex is not locked. |
-| osRtxErrorMutexLockLimit      | Maximum number of recursive mutex locks reached. |
-| osRtxErrorSemaphoreCountLimit | Semaphore count limit reached. |
-| osRtxErrorTZ_InitContext_S    | Secure context memory system initialization failed. |
-| osRtxErrorTZ_AllocContext_S   | Secure context memory allocation failed. |
-| osRtxErrorTZ_FreeContext_S    | Secure context memory deallocation failed. |
-| osRtxErrorTZ_LoadContext_S    | Secure context load failed. |
-| osRtxErrorTZ_SaveContext_S    | Secure context save failed. |
+|      Extended Status Code       | Description |
+|:--------------------------------|:------------|
+| osRtxErrorKernelNotReady        | Kernel scheduler is not in Ready state. |
+| osRtxErrorKernelNotRunning      | Kernel scheduler is not executing - there is no running thread. |
+| osRtxErrorInvalidControlBlock   | Object control block with invalid alignment or size was specified. |
+| osRtxErrorInvalidDataMemory     | Object data memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidThreadStack    | Thread stack memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidPriority       | Invalid thread priority was specified. |
+| osRtxErrorInvalidPrivilegedMode | Privileged thread cannot be created - kernel protect privileged is active. |
+| osRtxErrorThreadNotJoinable     | Specified thread is not joinable. |
+| osRtxErrorMutexNotOwned         | Specified mutex is not owned by the current running thread. |
+| osRtxErrorMutexNotLocked        | Specified mutex is not locked. |
+| osRtxErrorMutexLockLimit        | Maximum number of recursive mutex locks reached. |
+| osRtxErrorSemaphoreCountLimit   | Semaphore count limit reached. |
+| osRtxErrorTZ_InitContext_S      | Secure context memory system initialization failed. |
+| osRtxErrorTZ_AllocContext_S     | Secure context memory allocation failed. |
+| osRtxErrorTZ_FreeContext_S      | Secure context memory deallocation failed. |
+| osRtxErrorTZ_LoadContext_S      | Secure context load failed. |
+| osRtxErrorTZ_SaveContext_S      | Secure context save failed. |
 
 \b Value in the Event Recorder shows:
   - \b thread_id : thread ID.
@@ -868,24 +983,25 @@
 The status parameter indicates the execution status and can be one of the \ref osStatus_t "osStatus_t codes" or one
 of the extended execution status codes which are summarized in the table below.
 
-|      Extended Status Code     | Description |
-|:------------------------------|:------------|
-| osRtxErrorKernelNotReady      | Kernel scheduler is not in Ready state. |
-| osRtxErrorKernelNotRunning    | Kernel scheduler is not executing - there is no running thread. |
-| osRtxErrorInvalidControlBlock | Object control block with invalid alignment or size was specified. |
-| osRtxErrorInvalidDataMemory   | Object data memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidThreadStack  | Thread stack memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidPriority     | Invalid thread priority was specified. |
-| osRtxErrorThreadNotJoinable   | Specified thread is not joinable. |
-| osRtxErrorMutexNotOwned       | Specified mutex is not owned by the current running thread. |
-| osRtxErrorMutexNotLocked      | Specified mutex is not locked. |
-| osRtxErrorMutexLockLimit      | Maximum number of recursive mutex locks reached. |
-| osRtxErrorSemaphoreCountLimit | Semaphore count limit reached. |
-| osRtxErrorTZ_InitContext_S    | Secure context memory system initialization failed. |
-| osRtxErrorTZ_AllocContext_S   | Secure context memory allocation failed. |
-| osRtxErrorTZ_FreeContext_S    | Secure context memory deallocation failed. |
-| osRtxErrorTZ_LoadContext_S    | Secure context load failed. |
-| osRtxErrorTZ_SaveContext_S    | Secure context save failed. |
+|      Extended Status Code       | Description |
+|:--------------------------------|:------------|
+| osRtxErrorKernelNotReady        | Kernel scheduler is not in Ready state. |
+| osRtxErrorKernelNotRunning      | Kernel scheduler is not executing - there is no running thread. |
+| osRtxErrorInvalidControlBlock   | Object control block with invalid alignment or size was specified. |
+| osRtxErrorInvalidDataMemory     | Object data memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidThreadStack    | Thread stack memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidPriority       | Invalid thread priority was specified. |
+| osRtxErrorInvalidPrivilegedMode | Privileged thread cannot be created - kernel protect privileged is active. |
+| osRtxErrorThreadNotJoinable     | Specified thread is not joinable. |
+| osRtxErrorMutexNotOwned         | Specified mutex is not owned by the current running thread. |
+| osRtxErrorMutexNotLocked        | Specified mutex is not locked. |
+| osRtxErrorMutexLockLimit        | Maximum number of recursive mutex locks reached. |
+| osRtxErrorSemaphoreCountLimit   | Semaphore count limit reached. |
+| osRtxErrorTZ_InitContext_S      | Secure context memory system initialization failed. |
+| osRtxErrorTZ_AllocContext_S     | Secure context memory allocation failed. |
+| osRtxErrorTZ_FreeContext_S      | Secure context memory deallocation failed. |
+| osRtxErrorTZ_LoadContext_S      | Secure context load failed. |
+| osRtxErrorTZ_SaveContext_S      | Secure context save failed. |
 
 \b Value in the Event Recorder shows:
   - \b ef_id : event flags ID.
@@ -1063,24 +1179,25 @@
 The status parameter indicates the execution status and can be one of the \ref osStatus_t "osStatus_t codes" or one
 of the extended execution status codes which are summarized in the table below.
 
-|      Extended Status Code     | Description |
-|:------------------------------|:------------|
-| osRtxErrorKernelNotReady      | Kernel scheduler is not in Ready state. |
-| osRtxErrorKernelNotRunning    | Kernel scheduler is not executing - there is no running thread. |
-| osRtxErrorInvalidControlBlock | Object control block with invalid alignment or size was specified. |
-| osRtxErrorInvalidDataMemory   | Object data memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidThreadStack  | Thread stack memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidPriority     | Invalid thread priority was specified. |
-| osRtxErrorThreadNotJoinable   | Specified thread is not joinable. |
-| osRtxErrorMutexNotOwned       | Specified mutex is not owned by the current running thread. |
-| osRtxErrorMutexNotLocked      | Specified mutex is not locked. |
-| osRtxErrorMutexLockLimit      | Maximum number of recursive mutex locks reached. |
-| osRtxErrorSemaphoreCountLimit | Semaphore count limit reached. |
-| osRtxErrorTZ_InitContext_S    | Secure context memory system initialization failed. |
-| osRtxErrorTZ_AllocContext_S   | Secure context memory allocation failed. |
-| osRtxErrorTZ_FreeContext_S    | Secure context memory deallocation failed. |
-| osRtxErrorTZ_LoadContext_S    | Secure context load failed. |
-| osRtxErrorTZ_SaveContext_S    | Secure context save failed. |
+|      Extended Status Code       | Description |
+|:--------------------------------|:------------|
+| osRtxErrorKernelNotReady        | Kernel scheduler is not in Ready state. |
+| osRtxErrorKernelNotRunning      | Kernel scheduler is not executing - there is no running thread. |
+| osRtxErrorInvalidControlBlock   | Object control block with invalid alignment or size was specified. |
+| osRtxErrorInvalidDataMemory     | Object data memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidThreadStack    | Thread stack memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidPriority       | Invalid thread priority was specified. |
+| osRtxErrorInvalidPrivilegedMode | Privileged thread cannot be created - kernel protect privileged is active. |
+| osRtxErrorThreadNotJoinable     | Specified thread is not joinable. |
+| osRtxErrorMutexNotOwned         | Specified mutex is not owned by the current running thread. |
+| osRtxErrorMutexNotLocked        | Specified mutex is not locked. |
+| osRtxErrorMutexLockLimit        | Maximum number of recursive mutex locks reached. |
+| osRtxErrorSemaphoreCountLimit   | Semaphore count limit reached. |
+| osRtxErrorTZ_InitContext_S      | Secure context memory system initialization failed. |
+| osRtxErrorTZ_AllocContext_S     | Secure context memory allocation failed. |
+| osRtxErrorTZ_FreeContext_S      | Secure context memory deallocation failed. |
+| osRtxErrorTZ_LoadContext_S      | Secure context load failed. |
+| osRtxErrorTZ_SaveContext_S      | Secure context save failed. |
 
 \b Value in the Event Recorder shows:
   - \b timer_id : timer ID.
@@ -1212,24 +1329,25 @@
 The status parameter indicates the execution status and can be one of the \ref osStatus_t "osStatus_t codes" or one
 of the extended execution status codes which are summarized in the table below.
 
-|      Extended Status Code     | Description |
-|:------------------------------|:------------|
-| osRtxErrorKernelNotReady      | Kernel scheduler is not in Ready state. |
-| osRtxErrorKernelNotRunning    | Kernel scheduler is not executing - there is no running thread. |
-| osRtxErrorInvalidControlBlock | Object control block with invalid alignment or size was specified. |
-| osRtxErrorInvalidDataMemory   | Object data memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidThreadStack  | Thread stack memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidPriority     | Invalid thread priority was specified. |
-| osRtxErrorThreadNotJoinable   | Specified thread is not joinable. |
-| osRtxErrorMutexNotOwned       | Specified mutex is not owned by the current running thread. |
-| osRtxErrorMutexNotLocked      | Specified mutex is not locked. |
-| osRtxErrorMutexLockLimit      | Maximum number of recursive mutex locks reached. |
-| osRtxErrorSemaphoreCountLimit | Semaphore count limit reached. |
-| osRtxErrorTZ_InitContext_S    | Secure context memory system initialization failed. |
-| osRtxErrorTZ_AllocContext_S   | Secure context memory allocation failed. |
-| osRtxErrorTZ_FreeContext_S    | Secure context memory deallocation failed. |
-| osRtxErrorTZ_LoadContext_S    | Secure context load failed. |
-| osRtxErrorTZ_SaveContext_S    | Secure context save failed. |
+|      Extended Status Code       | Description |
+|:--------------------------------|:------------|
+| osRtxErrorKernelNotReady        | Kernel scheduler is not in Ready state. |
+| osRtxErrorKernelNotRunning      | Kernel scheduler is not executing - there is no running thread. |
+| osRtxErrorInvalidControlBlock   | Object control block with invalid alignment or size was specified. |
+| osRtxErrorInvalidDataMemory     | Object data memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidThreadStack    | Thread stack memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidPriority       | Invalid thread priority was specified. |
+| osRtxErrorInvalidPrivilegedMode | Privileged thread cannot be created - kernel protect privileged is active. |
+| osRtxErrorThreadNotJoinable     | Specified thread is not joinable. |
+| osRtxErrorMutexNotOwned         | Specified mutex is not owned by the current running thread. |
+| osRtxErrorMutexNotLocked        | Specified mutex is not locked. |
+| osRtxErrorMutexLockLimit        | Maximum number of recursive mutex locks reached. |
+| osRtxErrorSemaphoreCountLimit   | Semaphore count limit reached. |
+| osRtxErrorTZ_InitContext_S      | Secure context memory system initialization failed. |
+| osRtxErrorTZ_AllocContext_S     | Secure context memory allocation failed. |
+| osRtxErrorTZ_FreeContext_S      | Secure context memory deallocation failed. |
+| osRtxErrorTZ_LoadContext_S      | Secure context load failed. |
+| osRtxErrorTZ_SaveContext_S      | Secure context save failed. |
 
 \b Value in the Event Recorder shows:
   - \b mutex_id : mutex ID.
@@ -1378,24 +1496,25 @@
 The status parameter indicates the execution status and can be one of the \ref osStatus_t "osStatus_t codes" or one
 of the extended execution status codes which are summarized in the table below.
 
-|      Extended Status Code     | Description |
-|:------------------------------|:------------|
-| osRtxErrorKernelNotReady      | Kernel scheduler is not in Ready state. |
-| osRtxErrorKernelNotRunning    | Kernel scheduler is not executing - there is no running thread. |
-| osRtxErrorInvalidControlBlock | Object control block with invalid alignment or size was specified. |
-| osRtxErrorInvalidDataMemory   | Object data memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidThreadStack  | Thread stack memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidPriority     | Invalid thread priority was specified. |
-| osRtxErrorThreadNotJoinable   | Specified thread is not joinable. |
-| osRtxErrorMutexNotOwned       | Specified mutex is not owned by the current running thread. |
-| osRtxErrorMutexNotLocked      | Specified mutex is not locked. |
-| osRtxErrorMutexLockLimit      | Maximum number of recursive mutex locks reached. |
-| osRtxErrorSemaphoreCountLimit | Semaphore count limit reached. |
-| osRtxErrorTZ_InitContext_S    | Secure context memory system initialization failed. |
-| osRtxErrorTZ_AllocContext_S   | Secure context memory allocation failed. |
-| osRtxErrorTZ_FreeContext_S    | Secure context memory deallocation failed. |
-| osRtxErrorTZ_LoadContext_S    | Secure context load failed. |
-| osRtxErrorTZ_SaveContext_S    | Secure context save failed. |
+|      Extended Status Code       | Description |
+|:--------------------------------|:------------|
+| osRtxErrorKernelNotReady        | Kernel scheduler is not in Ready state. |
+| osRtxErrorKernelNotRunning      | Kernel scheduler is not executing - there is no running thread. |
+| osRtxErrorInvalidControlBlock   | Object control block with invalid alignment or size was specified. |
+| osRtxErrorInvalidDataMemory     | Object data memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidThreadStack    | Thread stack memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidPriority       | Invalid thread priority was specified. |
+| osRtxErrorInvalidPrivilegedMode | Privileged thread cannot be created - kernel protect privileged is active. |
+| osRtxErrorThreadNotJoinable     | Specified thread is not joinable. |
+| osRtxErrorMutexNotOwned         | Specified mutex is not owned by the current running thread. |
+| osRtxErrorMutexNotLocked        | Specified mutex is not locked. |
+| osRtxErrorMutexLockLimit        | Maximum number of recursive mutex locks reached. |
+| osRtxErrorSemaphoreCountLimit   | Semaphore count limit reached. |
+| osRtxErrorTZ_InitContext_S      | Secure context memory system initialization failed. |
+| osRtxErrorTZ_AllocContext_S     | Secure context memory allocation failed. |
+| osRtxErrorTZ_FreeContext_S      | Secure context memory deallocation failed. |
+| osRtxErrorTZ_LoadContext_S      | Secure context load failed. |
+| osRtxErrorTZ_SaveContext_S      | Secure context save failed. |
 
 \b Value in the Event Recorder shows:
   - \b semaphore_id : semaphore ID.
@@ -1546,24 +1665,25 @@
 The status parameter indicates the execution status and can be one of the \ref osStatus_t "osStatus_t codes" or one
 of the extended execution status codes which are summarized in the table below.
 
-|      Extended Status Code     | Description |
-|:------------------------------|:------------|
-| osRtxErrorKernelNotReady      | Kernel scheduler is not in Ready state. |
-| osRtxErrorKernelNotRunning    | Kernel scheduler is not executing - there is no running thread. |
-| osRtxErrorInvalidControlBlock | Object control block with invalid alignment or size was specified. |
-| osRtxErrorInvalidDataMemory   | Object data memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidThreadStack  | Thread stack memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidPriority     | Invalid thread priority was specified. |
-| osRtxErrorThreadNotJoinable   | Specified thread is not joinable. |
-| osRtxErrorMutexNotOwned       | Specified mutex is not owned by the current running thread. |
-| osRtxErrorMutexNotLocked      | Specified mutex is not locked. |
-| osRtxErrorMutexLockLimit      | Maximum number of recursive mutex locks reached. |
-| osRtxErrorSemaphoreCountLimit | Semaphore count limit reached. |
-| osRtxErrorTZ_InitContext_S    | Secure context memory system initialization failed. |
-| osRtxErrorTZ_AllocContext_S   | Secure context memory allocation failed. |
-| osRtxErrorTZ_FreeContext_S    | Secure context memory deallocation failed. |
-| osRtxErrorTZ_LoadContext_S    | Secure context load failed. |
-| osRtxErrorTZ_SaveContext_S    | Secure context save failed. |
+|      Extended Status Code       | Description |
+|:--------------------------------|:------------|
+| osRtxErrorKernelNotReady        | Kernel scheduler is not in Ready state. |
+| osRtxErrorKernelNotRunning      | Kernel scheduler is not executing - there is no running thread. |
+| osRtxErrorInvalidControlBlock   | Object control block with invalid alignment or size was specified. |
+| osRtxErrorInvalidDataMemory     | Object data memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidThreadStack    | Thread stack memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidPriority       | Invalid thread priority was specified. |
+| osRtxErrorInvalidPrivilegedMode | Privileged thread cannot be created - kernel protect privileged is active. |
+| osRtxErrorThreadNotJoinable     | Specified thread is not joinable. |
+| osRtxErrorMutexNotOwned         | Specified mutex is not owned by the current running thread. |
+| osRtxErrorMutexNotLocked        | Specified mutex is not locked. |
+| osRtxErrorMutexLockLimit        | Maximum number of recursive mutex locks reached. |
+| osRtxErrorSemaphoreCountLimit   | Semaphore count limit reached. |
+| osRtxErrorTZ_InitContext_S      | Secure context memory system initialization failed. |
+| osRtxErrorTZ_AllocContext_S     | Secure context memory allocation failed. |
+| osRtxErrorTZ_FreeContext_S      | Secure context memory deallocation failed. |
+| osRtxErrorTZ_LoadContext_S      | Secure context load failed. |
+| osRtxErrorTZ_SaveContext_S      | Secure context save failed. |
 
 \b Value in the Event Recorder shows:
   - \b mp_id : memory pool ID.
@@ -1755,24 +1875,25 @@
 The status parameter indicates the execution status and can be one of the \ref osStatus_t "osStatus_t codes" or one
 of the extended execution status codes which are summarized in the table below.
 
-|      Extended Status Code     | Description |
-|:------------------------------|:------------|
-| osRtxErrorKernelNotReady      | Kernel scheduler is not in Ready state. |
-| osRtxErrorKernelNotRunning    | Kernel scheduler is not executing - there is no running thread. |
-| osRtxErrorInvalidControlBlock | Object control block with invalid alignment or size was specified. |
-| osRtxErrorInvalidDataMemory   | Object data memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidThreadStack  | Thread stack memory with invalid alignment or size was specified. |
-| osRtxErrorInvalidPriority     | Invalid thread priority was specified. |
-| osRtxErrorThreadNotJoinable   | Specified thread is not joinable. |
-| osRtxErrorMutexNotOwned       | Specified mutex is not owned by the current running thread. |
-| osRtxErrorMutexNotLocked      | Specified mutex is not locked. |
-| osRtxErrorMutexLockLimit      | Maximum number of recursive mutex locks reached. |
-| osRtxErrorSemaphoreCountLimit | Semaphore count limit reached. |
-| osRtxErrorTZ_InitContext_S    | Secure context memory system initialization failed. |
-| osRtxErrorTZ_AllocContext_S   | Secure context memory allocation failed. |
-| osRtxErrorTZ_FreeContext_S    | Secure context memory deallocation failed. |
-| osRtxErrorTZ_LoadContext_S    | Secure context load failed. |
-| osRtxErrorTZ_SaveContext_S    | Secure context save failed. |
+|      Extended Status Code       | Description |
+|:--------------------------------|:------------|
+| osRtxErrorKernelNotReady        | Kernel scheduler is not in Ready state. |
+| osRtxErrorKernelNotRunning      | Kernel scheduler is not executing - there is no running thread. |
+| osRtxErrorInvalidControlBlock   | Object control block with invalid alignment or size was specified. |
+| osRtxErrorInvalidDataMemory     | Object data memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidThreadStack    | Thread stack memory with invalid alignment or size was specified. |
+| osRtxErrorInvalidPriority       | Invalid thread priority was specified. |
+| osRtxErrorInvalidPrivilegedMode | Privileged thread cannot be created - kernel protect privileged is active. |
+| osRtxErrorThreadNotJoinable     | Specified thread is not joinable. |
+| osRtxErrorMutexNotOwned         | Specified mutex is not owned by the current running thread. |
+| osRtxErrorMutexNotLocked        | Specified mutex is not locked. |
+| osRtxErrorMutexLockLimit        | Maximum number of recursive mutex locks reached. |
+| osRtxErrorSemaphoreCountLimit   | Semaphore count limit reached. |
+| osRtxErrorTZ_InitContext_S      | Secure context memory system initialization failed. |
+| osRtxErrorTZ_AllocContext_S     | Secure context memory allocation failed. |
+| osRtxErrorTZ_FreeContext_S      | Secure context memory deallocation failed. |
+| osRtxErrorTZ_LoadContext_S      | Secure context load failed. |
+| osRtxErrorTZ_SaveContext_S      | Secure context save failed. |
 
 \b Value in the Event Recorder shows:
   - \b mq_id : message queue ID.
@@ -2007,4 +2128,4 @@
 /**
 @} 
 */
-// end group Event Recorder
\ No newline at end of file
+// end group Event Recorder
diff --git a/CMSIS/DoxyGen/RTOS2/src/rtx_os.txt b/CMSIS/DoxyGen/RTOS2/src/rtx_os.txt
index cde714d..c2dc3c6 100644
--- a/CMSIS/DoxyGen/RTOS2/src/rtx_os.txt
+++ b/CMSIS/DoxyGen/RTOS2/src/rtx_os.txt
@@ -239,6 +239,15 @@
 to lock global C/C++ library resources.
 */
 
+/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
+/**
+\def osRtxErrorSVC
+\brief Invalid SVC function called.
+\details
+This error identifier is used with \ref osRtxErrorNotify when RTX5 detects SVC function pointer that is not properly aligned
+or is located outside of the RTX5 SVC function table.
+*/
+
 /**
 @}
 */
@@ -267,6 +276,7 @@
 | \ref osRtxErrorTimerQueueOverflow | User Timer Callback Queue overflow detected for timer (timer_id=object_id)        |
 | \ref osRtxErrorClibSpace          | Standard C/C++ library libspace not available: increase \c OS_THREAD_LIBSPACE_NUM |
 | \ref osRtxErrorClibMutex          | Standard C/C++ library mutex initialization failed                                |
+| \ref osRtxErrorSVC                | Invalid SVC function called (function=object_id)                                  |
 
 The function \b osRtxErrorNotify must contain an infinite loop to prevent further program execution. You can use an emulator
 to step over the infinite loop and trace into the code introducing a runtime error. For the overflow errors this means you
@@ -295,6 +305,9 @@
     case osRtxErrorClibMutex:
       // Standard C/C++ library mutex initialization failed
       break;
+    case osRtxErrorSVC:
+      // Invalid SVC function called (function=object_id)
+      break;
     default:
       break;
   }
diff --git a/CMSIS/RTOS2/RTX/Config/RTX_Config.c b/CMSIS/RTOS2/RTX/Config/RTX_Config.c
index 737078a..d21fa0a 100644
--- a/CMSIS/RTOS2/RTX/Config/RTX_Config.c
+++ b/CMSIS/RTOS2/RTX/Config/RTX_Config.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -17,7 +17,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * $Revision:   V5.1.1
+ * $Revision:   V5.2.0
  *
  * Project:     CMSIS-RTOS RTX
  * Title:       RTX Configuration
@@ -55,6 +55,9 @@
     case osRtxErrorClibMutex:
       // Standard C/C++ library mutex initialization failed
       break;
+    case osRtxErrorSVC:
+      // Invalid SVC function called (function=object_id)
+      break;
     default:
       // Reserved
       break;
diff --git a/CMSIS/RTOS2/RTX/Config/RTX_Config.h b/CMSIS/RTOS2/RTX/Config/RTX_Config.h
index 4d2f501..fe0c57b 100644
--- a/CMSIS/RTOS2/RTX/Config/RTX_Config.h
+++ b/CMSIS/RTOS2/RTX/Config/RTX_Config.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -17,7 +17,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * $Revision:   V5.5.2
+ * $Revision:   V5.6.0
  *
  * Project:     CMSIS-RTOS RTX
  * Title:       RTX Configuration definitions
@@ -69,6 +69,61 @@
  
 //   </e>
  
+//   <e>Safety features (Source variant only)
+//   <i> Enables FuSa related features.
+//   <i> Requires RTX Source variant.
+//   <i> Enables:
+//   <i>  - selected features from this group
+//   <i>  - Thread functions: osThreadProtectPrivileged
+#ifndef OS_SAFETY_FEATURES
+#define OS_SAFETY_FEATURES          0
+#endif
+ 
+//     <q>Safety Class
+//     <i> Threads assigned to lower classes cannot modify higher class threads.
+//     <i> Enables:
+//     <i>  - Object attributes: osSafetyClass
+//     <i>  - Kernel functions: osKernelProtect, osKernelDestroyClass
+//     <i>  - Thread functions: osThreadGetClass, osThreadSuspendClass, osThreadResumeClass
+#ifndef OS_SAFETY_CLASS
+#define OS_SAFETY_CLASS             1
+#endif
+ 
+//     <q>MPU Protected Zone
+//     <i> Access protection via MPU (Spatial isolation).
+//     <i> Enables:
+//     <i>  - Thread attributes: osThreadZone
+//     <i>  - Thread functions: osThreadGetZone, osThreadTerminateZone
+//     <i>  - Zone Management: osZoneSetup_Callback
+#ifndef OS_EXECUTION_ZONE
+#define OS_EXECUTION_ZONE           1
+#endif
+ 
+//     <q>Thread Watchdog
+//     <i> Watchdog alerts ensure timing for critical threads (Temporal isolation).
+//     <i> Enables:
+//     <i>  - Thread functions: osThreadFeedWatchdog
+//     <i>  - Handler functions: osWatchdogAlarm_Handler
+#ifndef OS_THREAD_WATCHDOG
+#define OS_THREAD_WATCHDOG          1
+#endif
+ 
+//     <q>Object Pointer checking
+//     <i> Check object pointer alignment and memory region.
+#ifndef OS_OBJ_PTR_CHECK
+#define OS_OBJ_PTR_CHECK            0
+#endif
+ 
+//     <q>SVC Function Pointer checking
+//     <i> Check SVC function pointer alignment and memory region.
+//     <i> User needs to define a linker execution region RTX_SVC_VENEERS
+//     <i> containing input sections: rtx_*.o (.text.os.svc.veneer.*)
+#ifndef OS_SVC_PTR_CHECK
+#define OS_SVC_PTR_CHECK            0
+#endif
+ 
+//   </e>
+ 
 //   <o>ISR FIFO Queue
 //      <4=>  4 entries    <8=>   8 entries   <12=>  12 entries   <16=>  16 entries
 //     <24=> 24 entries   <32=>  32 entries   <48=>  48 entries   <64=>  64 entries
@@ -142,11 +197,25 @@
 #define OS_IDLE_THREAD_TZ_MOD_ID    0
 #endif
  
+//   <o>Idle Thread Safety Class <0-15>
+//   <i> Defines the Safety Class number.
+//   <i> Default: 0
+#ifndef OS_IDLE_THREAD_CLASS
+#define OS_IDLE_THREAD_CLASS        0
+#endif
+ 
+//   <o>Idle Thread Zone <0-127>
+//   <i> Defines Thread Zone.
+//   <i> Default: 0
+#ifndef OS_IDLE_THREAD_ZONE
+#define OS_IDLE_THREAD_ZONE         0
+#endif
+ 
 //   <q>Stack overrun checking
 //   <i> Enables stack overrun check at thread switch (requires RTX source variant).
 //   <i> Enabling this option increases slightly the execution time of a thread switch.
 #ifndef OS_STACK_CHECK
-#define OS_STACK_CHECK              0
+#define OS_STACK_CHECK              1
 #endif
  
 //   <q>Stack usage watermark
@@ -156,12 +225,12 @@
 #define OS_STACK_WATERMARK          0
 #endif
  
-//   <o>Processor mode for Thread execution
+//   <o>Default Processor mode for Thread execution
 //     <0=> Unprivileged mode
 //     <1=> Privileged mode
-//   <i> Default: Privileged mode
+//   <i> Default: Unprivileged mode
 #ifndef OS_PRIVILEGE_MODE
-#define OS_PRIVILEGE_MODE           1
+#define OS_PRIVILEGE_MODE           0
 #endif
  
 // </h>
@@ -211,6 +280,20 @@
 #define OS_TIMER_THREAD_TZ_MOD_ID   0
 #endif
  
+//   <o>Timer Thread Safety Class <0-15>
+//   <i> Defines the Safety Class number.
+//   <i> Default: 0
+#ifndef OS_TIMER_THREAD_CLASS
+#define OS_TIMER_THREAD_CLASS       0
+#endif
+ 
+//   <o>Timer Thread Zone <0-127>
+//   <i> Defines Thread Zone.
+//   <i> Default: 0
+#ifndef OS_TIMER_THREAD_ZONE
+#define OS_TIMER_THREAD_ZONE        0
+#endif
+ 
 //   <o>Timer Callback Queue entries <0-256>
 //   <i> Number of concurrent active timer callback functions.
 //   <i> May be set to 0 when timers are not used.
diff --git a/CMSIS/RTOS2/RTX/Include/rtx_def.h b/CMSIS/RTOS2/RTX/Include/rtx_def.h
index 26230e7..370af6c 100644
--- a/CMSIS/RTOS2/RTX/Include/rtx_def.h
+++ b/CMSIS/RTOS2/RTX/Include/rtx_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -31,12 +31,31 @@
 #endif
 #include "RTX_Config.h"
 
+#if (defined(OS_SAFETY_FEATURES) && (OS_SAFETY_FEATURES != 0))
+ #define RTX_SAFETY_FEATURES
+ #if (defined(OS_SAFETY_CLASS) && (OS_SAFETY_CLASS != 0))
+  #define RTX_SAFETY_CLASS
+ #endif
+ #if (defined(OS_EXECUTION_ZONE) && (OS_EXECUTION_ZONE != 0))
+  #define RTX_EXECUTION_ZONE
+ #endif
+ #if (defined(OS_THREAD_WATCHDOG) && (OS_THREAD_WATCHDOG != 0))
+  #define RTX_THREAD_WATCHDOG
+ #endif
+ #if (defined(OS_OBJ_PTR_CHECK) && (OS_OBJ_PTR_CHECK != 0))
+  #define RTX_OBJ_PTR_CHECK
+ #endif
+ #if (defined(OS_SVC_PTR_CHECK) && (OS_SVC_PTR_CHECK != 0))
+  #define RTX_SVC_PTR_CHECK
+ #endif
+#endif
+
 #if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
-  #define RTX_OBJ_MEM_USAGE
+ #define RTX_OBJ_MEM_USAGE
 #endif
 
 #if (defined(OS_STACK_CHECK) && (OS_STACK_CHECK != 0))
-  #define RTX_STACK_CHECK
+ #define RTX_STACK_CHECK
 #endif
 
 #ifdef  RTE_CMSIS_RTOS2_RTX5_ARMV8M_NS
diff --git a/CMSIS/RTOS2/RTX/Include/rtx_evr.h b/CMSIS/RTOS2/RTX/Include/rtx_evr.h
index 2a6899e..67e9ae0 100644
--- a/CMSIS/RTOS2/RTX/Include/rtx_evr.h
+++ b/CMSIS/RTOS2/RTX/Include/rtx_evr.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -79,22 +79,23 @@
 
 
 /// Extended Status codes
-#define osRtxErrorKernelNotReady        (-7)
-#define osRtxErrorKernelNotRunning      (-8)
-#define osRtxErrorInvalidControlBlock   (-9)
-#define osRtxErrorInvalidDataMemory     (-10)
-#define osRtxErrorInvalidThreadStack    (-11)
-#define osRtxErrorInvalidPriority       (-12)
-#define osRtxErrorThreadNotJoinable     (-13)
-#define osRtxErrorMutexNotOwned         (-14)
-#define osRtxErrorMutexNotLocked        (-15)
-#define osRtxErrorMutexLockLimit        (-16)
-#define osRtxErrorSemaphoreCountLimit   (-17)
-#define osRtxErrorTZ_InitContext_S      (-18)
-#define osRtxErrorTZ_AllocContext_S     (-19)
-#define osRtxErrorTZ_FreeContext_S      (-20)
-#define osRtxErrorTZ_LoadContext_S      (-21)
-#define osRtxErrorTZ_SaveContext_S      (-22)
+#define osRtxErrorKernelNotReady        (-8)
+#define osRtxErrorKernelNotRunning      (-9)
+#define osRtxErrorInvalidControlBlock   (-10)
+#define osRtxErrorInvalidDataMemory     (-11)
+#define osRtxErrorInvalidThreadStack    (-12)
+#define osRtxErrorInvalidPriority       (-13)
+#define osRtxErrorInvalidPrivilegedMode (-14)
+#define osRtxErrorThreadNotJoinable     (-15)
+#define osRtxErrorMutexNotOwned         (-16)
+#define osRtxErrorMutexNotLocked        (-17)
+#define osRtxErrorMutexLockLimit        (-18)
+#define osRtxErrorSemaphoreCountLimit   (-19)
+#define osRtxErrorTZ_InitContext_S      (-20)
+#define osRtxErrorTZ_AllocContext_S     (-21)
+#define osRtxErrorTZ_FreeContext_S      (-22)
+#define osRtxErrorTZ_LoadContext_S      (-23)
+#define osRtxErrorTZ_SaveContext_S      (-24)
 
 
 //  ==== Memory Events ====
@@ -352,6 +353,25 @@
 #endif
 
 /**
+  \brief  Event on protect the RTOS Kernel scheduler access (API)
+  \param[in]  safety_class  safety class.
+*/
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_PROTECT_DISABLE))
+extern void EvrRtxKernelProtect (uint32_t safety_class);
+#else
+#define EvrRtxKernelProtect(safety_class)
+#endif
+
+/**
+  \brief  Event on successful RTOS Kernel scheduler protect (API)
+*/
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_PROTECTED_DISABLE))
+extern void EvrRtxKernelProtected (void);
+#else
+#define EvrRtxKernelProtected()
+#endif
+
+/**
   \brief  Event on RTOS kernel tick count retrieve (API)
   \param[in]  count         RTOS kernel current tick count.
 */
@@ -402,6 +422,17 @@
 #define EvrRtxKernelErrorNotify(code, object_id)
 #endif
 
+/**
+  \brief  Event on destroy safety class objects (API)
+  \param[in]  safety_class  safety class.
+  \param[in]  mode          safety mode.
+*/
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_DESTROY_CLASS_DISABLE))
+extern void EvrRtxKernelDestroyClass (uint32_t safety_class, uint32_t mode);
+#else
+#define EvrRtxKernelDestroyClass(safety_class, mode)
+#endif
+
 
 //  ==== Thread Events ====
 
@@ -452,6 +483,28 @@
 #endif
 
 /**
+  \brief  Event on thread safety class retrieve (API)
+  \param[in]  thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
+  \param[in]  safety_class  thread safety class.
+*/
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_CLASS_DISABLE))
+extern void EvrRtxThreadGetClass (osThreadId_t thread_id, uint32_t safety_class);
+#else
+#define EvrRtxThreadGetClass(thread_id, safety_class)
+#endif
+
+/**
+  \brief  Event on thread zone retrieve (API)
+  \param[in]  thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
+  \param[in]  zone          thread zone.
+*/
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_ZONE_DISABLE))
+extern void EvrRtxThreadGetZone (osThreadId_t thread_id, uint32_t zone);
+#else
+#define EvrRtxThreadGetZone(thread_id, zone)
+#endif
+
+/**
   \brief  Event on current running thread ID retrieve (API)
   \param[in]  thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
 */
@@ -698,6 +751,43 @@
 #endif
 
 /**
+  \brief  Event on thread feed watchdog (API)
+  \param[in]  ticks         timeout in number of ticks.
+*/
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FEED_WATCHDOG_DISABLE))
+extern void EvrRtxThreadFeedWatchdog (uint32_t ticks);
+#else
+#define EvrRtxThreadFeedWatchdog(ticks)
+#endif
+
+/**
+  \brief  Event on thread feed watchdog done (Op)
+*/
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FEED_WATCHDOG_DONE_DISABLE))
+extern void EvrRtxThreadFeedWatchdogDone (void);
+#else
+#define EvrRtxThreadFeedWatchdogDone()
+#endif
+
+/**
+  \brief  Event on protect the creation of privileged threads (API)
+*/
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_PROTECT_PRIVILEGED_DISABLE))
+extern void EvrRtxThreadProtectPrivileged (void);
+#else
+#define EvrRtxThreadProtectPrivileged()
+#endif
+
+/**
+  \brief  Event on successful protect the creation of privileged threads (Op)
+*/
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_PRIVILEGED_PROTECTED_DISABLE))
+extern void EvrRtxThreadPrivilegedProtected (void);
+#else
+#define EvrRtxThreadPrivilegedProtected()
+#endif
+
+/**
   \brief  Event on active thread count retrieve (API)
   \param[in]  count         number of active threads.
 */
@@ -719,6 +809,48 @@
 #define EvrRtxThreadEnumerate(thread_array, array_items, count)
 #endif
 
+/**
+  \brief  Event on thread safety class suspend (API)
+  \param[in]  safety_class  safety class.
+  \param[in]  mode          safety mode.
+*/
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SUSPEND_CLASS_DISABLE))
+extern void EvrRtxThreadSuspendClass (uint32_t safety_class, uint32_t mode);
+#else
+#define EvrRtxThreadSuspendClass(safety_class, mode)
+#endif
+
+/**
+  \brief  Event on thread safety class resume (API)
+  \param[in]  safety_class  safety class.
+  \param[in]  mode          safety mode.
+*/
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_RESUME_CLASS_DISABLE))
+extern void EvrRtxThreadResumeClass (uint32_t safety_class, uint32_t mode);
+#else
+#define EvrRtxThreadResumeClass(safety_class, mode)
+#endif
+
+/**
+  \brief  Event on thread zone terminate (API)
+  \param[in]  zone          thread zone.
+*/
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_TERMINATE_ZONE_DISABLE))
+extern void EvrRtxThreadTerminateZone (uint32_t zone);
+#else
+#define EvrRtxThreadTerminateZone(zone)
+#endif
+
+/**
+  \brief  Event on thread watchdog expired (Error)
+  \param[in]  thread_id     thread ID obtained by \ref osThreadNew.
+*/
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_WATCHDOG_EXPIRED_DISABLE))
+extern void EvrRtxThreadWatchdogExpired (osThreadId_t thread_id);
+#else
+#define EvrRtxThreadWatchdogExpired(thread_id)
+#endif
+
 
 //  ==== Thread Flags Events ====
 
diff --git a/CMSIS/RTOS2/RTX/Include/rtx_os.h b/CMSIS/RTOS2/RTX/Include/rtx_os.h
index 66e4843..80f14a9 100644
--- a/CMSIS/RTOS2/RTX/Include/rtx_os.h
+++ b/CMSIS/RTOS2/RTX/Include/rtx_os.h
@@ -38,9 +38,9 @@
  
  
 /// Kernel Information
-#define osRtxVersionAPI      20010003   ///< API version (2.1.3)
-#define osRtxVersionKernel   50050005   ///< Kernel version (5.5.5)
-#define osRtxKernelId     "RTX V5.5.5"  ///< Kernel identification string
+#define osRtxVersionAPI      20020000   ///< API version (2.2.0)
+#define osRtxVersionKernel   50070000   ///< Kernel version (5.7.0)
+#define osRtxKernelId     "RTX V5.7.0"  ///< Kernel identification string
  
  
 //  ==== Common definitions ====
@@ -60,6 +60,10 @@
 #define osRtxFlagSystemObject   0x01U
 #define osRtxFlagSystemMemory   0x02U
  
+/// Object Attribute Class definitions
+#define osRtxAttrClass_Pos      4U
+#define osRtxAttrClass_Msk      0xF0U
+ 
  
 //  ==== Kernel definitions ====
  
@@ -70,6 +74,11 @@
 #define osRtxKernelLocked               ((uint8_t)osKernelLocked)
 #define osRtxKernelSuspended            ((uint8_t)osKernelSuspended)
  
+/// Kernel Protect definitions
+#define osRtxKernelProtectPrivileged    0x01U
+#define osRtxKernelProtectClass_Pos     4U
+#define osRtxKernelProtectClass_Msk     0xF0U
+ 
  
 //  ==== Thread definitions ====
  
@@ -124,9 +133,10 @@
   uint32_t                         sp;  ///< Current Stack Pointer
   uint32_t                thread_addr;  ///< Thread entry address
   uint32_t                  tz_memory;  ///< TrustZone Memory Identifier
-#ifdef RTX_TF_M_EXTENSION
-  uint32_t                  tz_module;  ///< TrustZone Module Identifier
-#endif
+  uint8_t                        zone;  ///< Thread Zone
+  uint8_t                 reserved[3];
+  struct osRtxThread_s     *wdog_next;  ///< Link pointer to next Thread in Watchdog list
+  uint32_t                  wdog_tick;  ///< Watchdog tick counter
 } osRtxThread_t;
  
  
@@ -137,8 +147,8 @@
 #define osRtxTimerStopped       0x01U   ///< Timer Stopped
 #define osRtxTimerRunning       0x02U   ///< Timer Running
  
-/// Timer Type definitions
-#define osRtxTimerPeriodic      ((uint8_t)osTimerPeriodic)
+/// Timer attribute definitions
+#define osRtxTimerPeriodic      0x01U   ///< Timer Periodic mode
  
 /// Timer Function Information
 typedef struct {
@@ -151,7 +161,7 @@
   uint8_t                          id;  ///< Object Identifier
   uint8_t                       state;  ///< Object State
   uint8_t                       flags;  ///< Object Flags
-  uint8_t                        type;  ///< Timer Type (Periodic/One-shot)
+  uint8_t                        attr;  ///< Object Attributes
   const char                    *name;  ///< Object Name
   struct osRtxTimer_s           *prev;  ///< Pointer to previous active Timer
   struct osRtxTimer_s           *next;  ///< Pointer to next active Timer
@@ -168,7 +178,7 @@
   uint8_t                          id;  ///< Object Identifier
   uint8_t              reserved_state;  ///< Object State (not used)
   uint8_t                       flags;  ///< Object Flags
-  uint8_t                    reserved;
+  uint8_t                        attr;  ///< Object Attributes
   const char                    *name;  ///< Object Name
   osRtxThread_t          *thread_list;  ///< Waiting Threads List
   uint32_t                event_flags;  ///< Event Flags
@@ -200,7 +210,7 @@
   uint8_t                          id;  ///< Object Identifier
   uint8_t              reserved_state;  ///< Object State (not used)
   uint8_t                       flags;  ///< Object Flags
-  uint8_t                    reserved;
+  uint8_t                        attr;  ///< Object Attributes
   const char                    *name;  ///< Object Name
   osRtxThread_t          *thread_list;  ///< Waiting Threads List
   uint16_t                     tokens;  ///< Current number of tokens
@@ -225,7 +235,7 @@
   uint8_t                          id;  ///< Object Identifier
   uint8_t              reserved_state;  ///< Object State (not used)
   uint8_t                       flags;  ///< Object Flags
-  uint8_t                    reserved;
+  uint8_t                        attr;  ///< Object Attributes
   const char                    *name;  ///< Object Name
   osRtxThread_t          *thread_list;  ///< Waiting Threads List
   osRtxMpInfo_t               mp_info;  ///< Memory Pool Info
@@ -249,7 +259,7 @@
   uint8_t                          id;  ///< Object Identifier
   uint8_t              reserved_state;  ///< Object State (not used)
   uint8_t                       flags;  ///< Object Flags
-  uint8_t                    reserved;
+  uint8_t                        attr;  ///< Object Attributes
   const char                    *name;  ///< Object Name
   osRtxThread_t          *thread_list;  ///< Waiting Threads List
   osRtxMpInfo_t               mp_info;  ///< Memory Pool Info
@@ -267,7 +277,7 @@
   uint8_t                          id;  ///< Object Identifier
   uint8_t                       state;  ///< Object State
   uint8_t                       flags;  ///< Object Flags
-  uint8_t                    reserved;
+  uint8_t                        attr;  ///< Object Attributes
   const char                    *name;  ///< Object Name
   osRtxThread_t          *thread_list;  ///< Threads List
 } osRtxObject_t;
@@ -283,7 +293,7 @@
     uint8_t                     state;  ///< State
     volatile uint8_t          blocked;  ///< Blocked
     uint8_t                    pendSV;  ///< Pending SV
-    uint8_t                  reserved;
+    uint8_t                   protect;  ///< Protect options
     uint32_t                     tick;  ///< Tick counter
   } kernel;
   int32_t                   tick_irqn;  ///< Tick Timer IRQ Number
@@ -297,7 +307,7 @@
     osRtxThread_t         *delay_list;  ///< Delay List
     osRtxThread_t          *wait_list;  ///< Wait List (no Timeout)
     osRtxThread_t     *terminate_list;  ///< Terminate Thread List
-    uint32_t                 reserved;
+    osRtxThread_t          *wdog_list;  ///< Watchdog List
     struct {                            ///< Thread Round Robin Info
       osRtxThread_t           *thread;  ///< Round Robin Thread
       uint32_t                timeout;  ///< Round Robin Timeout
@@ -399,6 +409,7 @@
 #define osRtxErrorTimerQueueOverflow    3U  ///< User Timer Callback Queue overflow detected for timer.
 #define osRtxErrorClibSpace             4U  ///< Standard C/C++ library libspace not available: increase \c OS_THREAD_LIBSPACE_NUM.
 #define osRtxErrorClibMutex             5U  ///< Standard C/C++ library mutex initialization failed.
+#define osRtxErrorSVC                   6U  ///< Invalid SVC function called.
  
 /// OS Error Callback function
 extern uint32_t osRtxErrorNotify (uint32_t code, void *object_id);
@@ -412,11 +423,6 @@
 extern void PendSV_Handler  (void);
 extern void SysTick_Handler (void);
  
-/// OS Trusted Firmware M Extension
-#ifdef RTX_TF_M_EXTENSION
-extern uint32_t osRtxTzGetModuleId (void);
-#endif
- 
  
 //  ==== OS External Configuration ====
  
@@ -424,6 +430,12 @@
 #define osRtxConfigPrivilegedMode   (1UL<<0)    ///< Threads in Privileged mode
 #define osRtxConfigStackCheck       (1UL<<1)    ///< Stack overrun checking
 #define osRtxConfigStackWatermark   (1UL<<2)    ///< Stack usage Watermark
+#define osRtxConfigSafetyFeatures   (1UL<<3)    ///< Safety features enabled
+#define osRtxConfigSafetyClass      (1UL<<4)    ///< Safety Class feature enabled
+#define osRtxConfigExecutionZone    (1UL<<5)    ///< Execution Zone enabled
+#define osRtxConfigThreadWatchdog   (1UL<<6)    ///< Thread Watchdog enabled
+#define osRtxConfigObjPtrCheck      (1UL<<7)    ///< Object Pointer Checking enabled
+#define osRtxConfigSVCPtrCheck      (1UL<<8)    ///< SVC Pointer Checking enabled
  
 /// OS Configuration structure
 typedef struct {
diff --git a/CMSIS/RTOS2/RTX/Library/ARM/MDK/RTX_CM.uvprojx b/CMSIS/RTOS2/RTX/Library/ARM/MDK/RTX_CM.uvprojx
index 9a5fcd3..1d92738 100644
--- a/CMSIS/RTOS2/RTX/Library/ARM/MDK/RTX_CM.uvprojx
+++ b/CMSIS/RTOS2/RTX/Library/ARM/MDK/RTX_CM.uvprojx
@@ -10,7 +10,7 @@
       <TargetName>CM0_LE</TargetName>
       <ToolsetNumber>0x4</ToolsetNumber>
       <ToolsetName>ARM-ADS</ToolsetName>
-      <pCCUsed>6160000::V6.16::ARMCLANG</pCCUsed>
+      <pCCUsed>6190000::V6.19::ARMCLANG</pCCUsed>
       <uAC6>1</uAC6>
       <TargetOption>
         <TargetCommonOption>
@@ -186,6 +186,7 @@
             <RvdsVP>0</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <StupSel>8</StupSel>
@@ -608,7 +609,7 @@
       <TargetName>CM3_LE</TargetName>
       <ToolsetNumber>0x4</ToolsetNumber>
       <ToolsetName>ARM-ADS</ToolsetName>
-      <pCCUsed>6160000::V6.16::ARMCLANG</pCCUsed>
+      <pCCUsed>6190000::V6.19::ARMCLANG</pCCUsed>
       <uAC6>1</uAC6>
       <TargetOption>
         <TargetCommonOption>
@@ -784,6 +785,7 @@
             <RvdsVP>0</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <StupSel>8</StupSel>
@@ -1206,7 +1208,7 @@
       <TargetName>CM4F_LE</TargetName>
       <ToolsetNumber>0x4</ToolsetNumber>
       <ToolsetName>ARM-ADS</ToolsetName>
-      <pCCUsed>6160000::V6.16::ARMCLANG</pCCUsed>
+      <pCCUsed>6190000::V6.19::ARMCLANG</pCCUsed>
       <uAC6>1</uAC6>
       <TargetOption>
         <TargetCommonOption>
@@ -1382,6 +1384,7 @@
             <RvdsVP>2</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <StupSel>8</StupSel>
@@ -1804,7 +1807,7 @@
       <TargetName>ARMv8MBL_LE</TargetName>
       <ToolsetNumber>0x4</ToolsetNumber>
       <ToolsetName>ARM-ADS</ToolsetName>
-      <pCCUsed>6160000::V6.16::ARMCLANG</pCCUsed>
+      <pCCUsed>6190000::V6.19::ARMCLANG</pCCUsed>
       <uAC6>1</uAC6>
       <TargetOption>
         <TargetCommonOption>
@@ -1980,6 +1983,7 @@
             <RvdsVP>0</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <StupSel>8</StupSel>
@@ -2402,7 +2406,7 @@
       <TargetName>ARMv8MBL_NS_LE</TargetName>
       <ToolsetNumber>0x4</ToolsetNumber>
       <ToolsetName>ARM-ADS</ToolsetName>
-      <pCCUsed>6160000::V6.16::ARMCLANG</pCCUsed>
+      <pCCUsed>6190000::V6.19::ARMCLANG</pCCUsed>
       <uAC6>1</uAC6>
       <TargetOption>
         <TargetCommonOption>
@@ -2578,6 +2582,7 @@
             <RvdsVP>0</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <StupSel>8</StupSel>
@@ -3000,7 +3005,7 @@
       <TargetName>ARMv8MML_LE</TargetName>
       <ToolsetNumber>0x4</ToolsetNumber>
       <ToolsetName>ARM-ADS</ToolsetName>
-      <pCCUsed>6160000::V6.16::ARMCLANG</pCCUsed>
+      <pCCUsed>6190000::V6.19::ARMCLANG</pCCUsed>
       <uAC6>1</uAC6>
       <TargetOption>
         <TargetCommonOption>
@@ -3176,6 +3181,7 @@
             <RvdsVP>0</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <StupSel>8</StupSel>
@@ -3598,7 +3604,7 @@
       <TargetName>ARMv8MML_NS_LE</TargetName>
       <ToolsetNumber>0x4</ToolsetNumber>
       <ToolsetName>ARM-ADS</ToolsetName>
-      <pCCUsed>6160000::V6.16::ARMCLANG</pCCUsed>
+      <pCCUsed>6190000::V6.19::ARMCLANG</pCCUsed>
       <uAC6>1</uAC6>
       <TargetOption>
         <TargetCommonOption>
@@ -3774,6 +3780,7 @@
             <RvdsVP>0</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <StupSel>8</StupSel>
@@ -4196,7 +4203,7 @@
       <TargetName>ARMv8MML_SP_LE</TargetName>
       <ToolsetNumber>0x4</ToolsetNumber>
       <ToolsetName>ARM-ADS</ToolsetName>
-      <pCCUsed>6160000::V6.16::ARMCLANG</pCCUsed>
+      <pCCUsed>6190000::V6.19::ARMCLANG</pCCUsed>
       <uAC6>1</uAC6>
       <TargetOption>
         <TargetCommonOption>
@@ -4372,6 +4379,7 @@
             <RvdsVP>2</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <StupSel>8</StupSel>
@@ -4794,7 +4802,7 @@
       <TargetName>ARMv8MML_SP_NS_LE</TargetName>
       <ToolsetNumber>0x4</ToolsetNumber>
       <ToolsetName>ARM-ADS</ToolsetName>
-      <pCCUsed>6160000::V6.16::ARMCLANG</pCCUsed>
+      <pCCUsed>6190000::V6.19::ARMCLANG</pCCUsed>
       <uAC6>1</uAC6>
       <TargetOption>
         <TargetCommonOption>
@@ -4970,6 +4978,7 @@
             <RvdsVP>2</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <StupSel>8</StupSel>
diff --git a/CMSIS/RTOS2/RTX/Library/GCC/MDK/RTX_CM.uvprojx b/CMSIS/RTOS2/RTX/Library/GCC/MDK/RTX_CM.uvprojx
index 2b32337..0cd60c4 100644
--- a/CMSIS/RTOS2/RTX/Library/GCC/MDK/RTX_CM.uvprojx
+++ b/CMSIS/RTOS2/RTX/Library/GCC/MDK/RTX_CM.uvprojx
@@ -171,6 +171,7 @@
             <RvdsVP>0</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <OnChipMemories>
@@ -661,6 +662,7 @@
             <RvdsVP>0</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <OnChipMemories>
@@ -1198,6 +1200,7 @@
             <RvdsVP>2</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <OnChipMemories>
@@ -1688,6 +1691,7 @@
             <RvdsVP>0</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <OnChipMemories>
@@ -2225,6 +2229,7 @@
             <RvdsVP>0</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <OnChipMemories>
@@ -2762,6 +2767,7 @@
             <RvdsVP>0</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <OnChipMemories>
@@ -3299,6 +3305,7 @@
             <RvdsVP>0</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <OnChipMemories>
@@ -3836,6 +3843,7 @@
             <RvdsVP>2</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <OnChipMemories>
@@ -4373,6 +4381,7 @@
             <RvdsVP>2</RvdsVP>
             <RvdsMve>0</RvdsMve>
             <RvdsCdeCp>0</RvdsCdeCp>
+            <nBranchProt>0</nBranchProt>
             <hadIRAM2>0</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <OnChipMemories>
diff --git a/CMSIS/RTOS2/RTX/RTX5.scvd b/CMSIS/RTOS2/RTX/RTX5.scvd
index 5b5d126..2585bae 100644
--- a/CMSIS/RTOS2/RTX/RTX5.scvd
+++ b/CMSIS/RTOS2/RTX/RTX5.scvd
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <component_viewer schemaVersion="1.2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="Component_Viewer.xsd">
-  <component name="CMSIS:RTOS2:Keil RTX5" shortname="RTX5" version="5.5.3"/>    <!-- name and version of the component -->
+  <component name="CMSIS:RTOS2:Keil RTX5" shortname="RTX5" version="5.7.0"/>    <!-- name and version of the component -->
 
   <typedefs>
     <!-- Attributes structure for thread -->
@@ -69,7 +69,7 @@
     </typedef>
 
     <!-- Thread Control Block -->
-    <typedef name="osRtxThread_t" info="" size="68">
+    <typedef name="osRtxThread_t" info="" size="80">
       <member name="id"            type="uint8_t"        offset="0" info="Object Identifier"/>
       <member name="state"         type="uint8_t"        offset="1" info="Object State">
         <enum name="osThreadInactive"    value="0"  info=""/>
@@ -91,8 +91,10 @@
       </member>
       <member name="flags"         type="uint8_t"        offset="2" info="Object Flags"/>
       <member name="attr"          type="uint8_t"        offset="3" info="Object Attributes">
-        <enum name="osThreadDetached" value="0x00" info="Thread created in detached mode"/>
-        <enum name="osThreadJoinable" value="0x01" info="Thread created in joinable mode"/>
+        <enum name="osThreadDetached"     value="0x00" info="Thread created in detached mode"/>
+        <enum name="osThreadJoinable"     value="0x01" info="Thread created in joinable mode"/>
+        <enum name="osThreadUnprivileged" value="0x02" info="Thread created in unprivileged mode"/>
+        <enum name="osThreadPrivileged"   value="0x04" info="Thread created in privileged mode"/>
       </member>
       <member name="name"          type="uint32_t"       offset="4"  info="Object name (type is *uint8_t)"/>
       <member name="thread_next"   type="*osRtxThread_t" offset="8"  info="Link pointer to next Thread in Object list"/>
@@ -170,12 +172,18 @@
       <member name="sp"            type="uint32_t"       offset="56" info="Current stack pointer"/>
       <member name="thread_addr"   type="uint32_t"       offset="60" info="Thread entry address"/>
       <member name="tz_memory"     type="uint32_t"       offset="64" info="TrustZone Memory Identifier"/>
+      <member name="zone"          type="uint8_t"        offset="68" info="Thread Zone"/>
+      <member name="reserved"      type="uint8_t"        offset="69" info="Reserved bytes"/>
+      <member name="wdog_next"     type="*osRtxThread_t" offset="72" info="Link pointer to next Thread in Watchdog list"/>
+      <member name="wdog_tick"     type="uint32_t"       offset="76" info="Watchdog tick counter"/>
 
       <var name="cb_valid"   type="uint32_t" info="Control block validation status (valid=1, invalid=0)"/>
       <var name="sp_valid"   type="uint32_t" info="Stack pointer validation status (valid=1, invalid=0)"/>
       <var name="out_type"   type="uint8_t"  info="Output display type ID"/>
 
       <var name="ex_delay"   type="uint32_t" info="Calculated execution delay"/>
+      <var name="wd_tick"    type="uint32_t" info="Calculated absolute watchdog tick time"/>
+      <var name="wd_state"   type="uint32_t" info="Watchdog state (0=not running, 1=running)"/>
 
       <var name="stack_val"  type="uint32_t" info="Stack usage: analysis result"/>
       <var name="stack_cur"  type="uint32_t" info="Stack usage: current (address)"/>
@@ -195,7 +203,7 @@
         <enum name="Running"  value="2" info="Timer is running"/>
       </member>
       <member name="flags"       type="uint8_t"       offset="2" info="Object Flags"/>
-      <member name="type"        type="uint8_t"       offset="3" info="Timer Type">
+      <member name="attr"        type="uint8_t"       offset="3" info="Object Attributes">
         <enum name="osTimerOnce"     value="0" info="One-shot timer"/>
         <enum name="osTimerPeriodic" value="1" info="Periodic timer"/>
       </member>
@@ -217,7 +225,7 @@
       <member name="id"          type="uint8_t"        offset="0"  info="Object Identifier"/>
       <member name="state"       type="uint8_t"        offset="1"  info="Object State"/>
       <member name="flags"       type="uint8_t"        offset="2"  info="Object Flags"/>
-      <member name="reserved"    type="uint8_t"        offset="3"  info=""/>
+      <member name="attr"        type="uint8_t"        offset="3"  info="Object Attributes"/>
       <member name="name"        type="uint32_t"       offset="4"  info="Object name (type is *uint8_t)"/>
       <member name="thread_list" type="*osRtxThread_t" offset="8"  info="Waiting threads list"/>
       <member name="event_flags" type="int32_t"        offset="12" info="Event flags"/>
@@ -254,7 +262,7 @@
       <member name="id"          type="uint8_t"        offset="0"  info="Object Identifier"/>
       <member name="state"       type="uint8_t"        offset="1"  info="Object State"/>
       <member name="flags"       type="uint8_t"        offset="2"  info="Object Flags"/>
-      <member name="reserved"    type="uint8_t"        offset="3"  info=""/>
+      <member name="attr"        type="uint8_t"        offset="3"  info="Object Attributes"/>
       <member name="name"        type="uint32_t"       offset="4"  info="Object name (type is *uint8_t)"/>
       <member name="thread_list" type="*osRtxThread_t" offset="8"  info="Waiting threads list"/>
       <member name="tokens"      type="uint16_t"       offset="12" info="Current number of tokens"/>
@@ -280,7 +288,7 @@
       <member name="id"          type="uint8_t"        offset="0" info="Object Identifier"/>
       <member name="state"       type="uint8_t"        offset="1" info="Object State"/>
       <member name="flags"       type="uint8_t"        offset="2" info="Object Flags"/>
-      <member name="reserved"    type="uint8_t"        offset="3" info=""/>
+      <member name="attr"        type="uint8_t"        offset="3" info="Object Attributes"/>
       <member name="name"        type="uint32_t"       offset="4" info="Object name (type is *uint8_t)"/>
       <member name="thread_list" type="*osRtxThread_t" offset="8" info="Waiting threads list"/>
 
@@ -314,7 +322,7 @@
       <member name="id"          type="uint8_t"         offset="0" info="Object Identifier"/>
       <member name="state"       type="uint8_t"         offset="1" info="Object State"/>
       <member name="flags"       type="uint8_t"         offset="2" info="Object Flags"/>
-      <member name="reserved"    type="uint8_t"         offset="3" info=""/>
+      <member name="attr"        type="uint8_t"         offset="3" info="Object Attributes"/>
       <member name="name"        type="uint32_t"        offset="4" info="Object name (type is *uint8_t)"/>
       <member name="thread_list" type="*osRtxThread_t"  offset="8" info="Waiting threads list"/>
 
@@ -352,6 +360,7 @@
       </member>
       <member name="kernel_blocked"             type="uint8_t"              offset="9"  info="Kernel blocked"/>
       <member name="kernel_pendSV"              type="uint8_t"              offset="10" info="Kernel pending SV"/>
+      <member name="kernel_protect"             type="uint8_t"              offset="11" info="Protect options"/>
       <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"/>
@@ -361,7 +370,7 @@
       <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_attr"          type="uint8_t"              offset="28+3" info="Object Attributes"/>
       <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" />
 
@@ -369,6 +378,7 @@
       <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_wdog_list"           type="*osRtxThread_t"       offset="56"  info="Watchdog list"/>
 
       <member name="thread_robin_thread"        type="*osRtxThread_t"       offset="60"  info="Round Robin thread"/>
       <member name="thread_timeout"             type="uint32_t"             offset="64"  info="Round Robin timeout"/>
@@ -452,6 +462,12 @@
 
       <var name="stack_check"  type="uint8_t" info="Stack checking (0:disabled, 1:enabled)"/>
       <var name="stack_wmark"  type="uint8_t" info="Stack watermark (0:disabled, 1:enabled)"/>
+      <var name="safety_feat"  type="uint8_t" info="Safety features (0:disabled, 1:enabled)"/>
+      <var name="safety_class" type="uint8_t" info="Thread safety class (0:disabled, 1:enabled)"/>
+      <var name="exec_zone"    type="uint8_t" info="Execution zone (0:disabled, 1:enabled)"/>
+      <var name="watchdog"     type="uint8_t" info="Thread watchdog (0:disabled, 1:enabled)"/>
+      <var name="obj_check"    type="uint8_t" info="Object pointer checking (0:disabled, 1:enabled)"/>
+      <var name="svc_check"    type="uint8_t" info="SVC function pointer checking (0:disabled, 1:enabled)"/>
     </typedef>
 
     <!-- Memory Pool Header -->
@@ -489,29 +505,31 @@
 
     <typedef name="rtx_t" info="Various RTX Definitions" size="8">
       <member name="status" type="int32_t" offset="0" info="RTX5 operations status">
-        <enum name="osOK"                          value="0"   info="Operation completed successfully"/>
-        <enum name="osError"                       value="-1"  info="Unspecified RTOS error: run-time error but no other error message fits."/>
-        <enum name="osErrorTimeout"                value="-2"  info="Operation not completed within the timeout period."/>
-        <enum name="osErrorResource"               value="-3"  info="Resource not available"/>
-        <enum name="osErrorParameter"              value="-4"  info="Parameter error"/>
-        <enum name="osErrorNoMemory"               value="-5"  info="System is out of memory: it was impossible to allocate or reserve memory for the operation"/>
-        <enum name="osErrorISR"                    value="-6"  info="Not allowed in ISR context: the function cannot be called from interrupt service routines"/>
-        <enum name="osRtxErrorKernelNotReady"      value="-7"  info="RTOS Kernel scheduler is not ready"/>
-        <enum name="osRtxErrorKernelNotRunning"    value="-8"  info="RTOS Kernel scheduler is not running"/>
-        <enum name="osRtxErrorInvalidControlBlock" value="-9"  info="Object control block is not properly aligned or has an invalid size"/>
-        <enum name="osRtxErrorInvalidDataMemory"   value="-10" info="Data memory is not is not properly aligned or has an invalid size"/>
-        <enum name="osRtxErrorInvalidThreadStack"  value="-11" info="Thread stack is invalid"/>
-        <enum name="osRtxErrorInvalidPriority"     value="-12" info="Thread priority is invalid"/>
-        <enum name="osRtxErrorThreadNotJoinable"   value="-13" info="Thread is not joinable"/>
-        <enum name="osRtxErrorMutexNotOwned"       value="-14" info="Mutex is not owned by the current running thread"/>
-        <enum name="osRtxErrorMutexNotLocked"      value="-15" info="Mutex is not locked"/>
-        <enum name="osRtxErrorMutexLockLimit"      value="-16" info="Maximum number of recursive mutex locks reached"/>
-        <enum name="osRtxErrorSemaphoreCountLimit" value="-17" info="Semaphore count limit reached"/>
-        <enum name="osRtxErrorTZ_InitContext_S"    value="-18" info=""/>
-        <enum name="osRtxErrorTZ_AllocContext_S"   value="-19" info=""/>
-        <enum name="osRtxErrorTZ_FreeContext_S"    value="-20" info=""/>
-        <enum name="osRtxErrorTZ_LoadContext_S"    value="-21" info=""/>
-        <enum name="osRtxErrorTZ_SaveContext_S"    value="-22" info=""/>
+        <enum name="osOK"                            value="0"   info="Operation completed successfully"/>
+        <enum name="osError"                         value="-1"  info="Unspecified RTOS error: run-time error but no other error message fits."/>
+        <enum name="osErrorTimeout"                  value="-2"  info="Operation not completed within the timeout period."/>
+        <enum name="osErrorResource"                 value="-3"  info="Resource not available"/>
+        <enum name="osErrorParameter"                value="-4"  info="Parameter error"/>
+        <enum name="osErrorNoMemory"                 value="-5"  info="System is out of memory: it was impossible to allocate or reserve memory for the operation"/>
+        <enum name="osErrorISR"                      value="-6"  info="Not allowed in ISR context: the function cannot be called from interrupt service routines"/>
+        <enum name="osErrorSafetyClass"              value="-7"  info="Operation denied because of safety class violation"/>
+        <enum name="osRtxErrorKernelNotReady"        value="-8"  info="RTOS Kernel scheduler is not ready"/>
+        <enum name="osRtxErrorKernelNotRunning"      value="-9"  info="RTOS Kernel scheduler is not running"/>
+        <enum name="osRtxErrorInvalidControlBlock"   value="-10" info="Object control block is not properly aligned or has an invalid size"/>
+        <enum name="osRtxErrorInvalidDataMemory"     value="-11" info="Data memory is not is not properly aligned or has an invalid size"/>
+        <enum name="osRtxErrorInvalidThreadStack"    value="-12" info="Thread stack is invalid"/>
+        <enum name="osRtxErrorInvalidPriority"       value="-13" info="Thread priority is invalid"/>
+        <enum name="osRtxErrorInvalidPrivilegedMode" value="-14" info="Privileged thread cannot be created, kernel protect is active"/>
+        <enum name="osRtxErrorThreadNotJoinable"     value="-15" info="Thread is not joinable"/>
+        <enum name="osRtxErrorMutexNotOwned"         value="-16" info="Mutex is not owned by the current running thread"/>
+        <enum name="osRtxErrorMutexNotLocked"        value="-17" info="Mutex is not locked"/>
+        <enum name="osRtxErrorMutexLockLimit"        value="-18" info="Maximum number of recursive mutex locks reached"/>
+        <enum name="osRtxErrorSemaphoreCountLimit"   value="-19" info="Semaphore count limit reached"/>
+        <enum name="osRtxErrorTZ_InitContext_S"      value="-20" info=""/>
+        <enum name="osRtxErrorTZ_AllocContext_S"     value="-21" info=""/>
+        <enum name="osRtxErrorTZ_FreeContext_S"      value="-22" info=""/>
+        <enum name="osRtxErrorTZ_LoadContext_S"      value="-23" info=""/>
+        <enum name="osRtxErrorTZ_SaveContext_S"      value="-24" info=""/>
       </member>
     </typedef>
 
@@ -616,6 +634,7 @@
         <enum name="osRtxErrorTimerQueueOverflow" value="3" info="User Timer Callback Queue overflow"/>
         <enum name="osRtxErrorClibSpace"          value="4" info="Standard C/C++ library libspace not available"/>
         <enum name="osRtxErrorClibMutex"          value="5" info="Standard C/C++ library mutex initialization failed"/>
+        <enum name="osRtxErrorSVC"                value="6" info="Invalid SVC function called"/>
       </member>
     </typedef>
 
@@ -677,6 +696,12 @@
       <calc>
         os_Config.stack_check  = (os_Config.flags >> 1) &amp; 1;
         os_Config.stack_wmark  = (os_Config.flags >> 2) &amp; 1;
+        os_Config.safety_feat  = (os_Config.flags >> 3) &amp; 1;
+        os_Config.safety_class = (os_Config.flags >> 4) &amp; 1;
+        os_Config.exec_zone    = (os_Config.flags >> 5) &amp; 1;
+        os_Config.watchdog     = (os_Config.flags >> 6) &amp; 1;
+        os_Config.obj_check    = (os_Config.flags >> 7) &amp; 1;
+        os_Config.svc_check    = (os_Config.flags >> 8) &amp; 1;
       </calc>
 
       <calc cond="((os_Info.version / 10000000) == 5) &amp;&amp; (os_Info.kernel_state &gt; 0) &amp;&amp; (os_Info.kernel_state &lt; 5)">
@@ -711,7 +736,7 @@
       </calc>
 
       <!-- Determine number of control blocks to read -->
-      <calc cond="TCB_Rd"> TCB_Rd /= 68; </calc>
+      <calc cond="TCB_Rd"> TCB_Rd /= 80; </calc>
       <calc cond="CCB_Rd"> CCB_Rd /= 32; </calc>
       <calc cond="ECB_Rd"> ECB_Rd /= 16; </calc>
       <calc cond="MCB_Rd"> MCB_Rd /= 28; </calc>
@@ -823,6 +848,9 @@
         <readlist cond="(mem_list_com[i].len &amp; 1) &amp;&amp; (mem_list_com[i].id == 0xFA)" name="QCB" type="osRtxMessageQueue_t" offset="addr" count="1" />
       </list>
 
+      <!-- Read thread watchdog list -->
+      <readlist name="WDL" cond="RTX_En &amp;&amp; os_Config.watchdog &amp;&amp; os_Info.thread_wdog_list" type="osRtxThread_t" offset="os_Info.thread_wdog_list" next="wdog_next" init="1"/>
+
       <!-- Validate and process Thread control blocks -->
       <list name="i" start="0" limit="TCB._count">
         <calc>
@@ -908,6 +936,26 @@
             TCB[i].ex_delay += TDL[j].delay;
           </calc>
         </list>
+
+        <!-- Determine thread absolute watchdog tick value -->
+        <calc cond="os_Config.watchdog">
+          k = 0;
+        </calc>
+
+        <list cond="os_Config.watchdog" name="j" start="0" limit="WDL._count">
+          <calc cond="k == 0">
+            TCB[i].wd_tick += WDL[j].wdog_tick;
+          </calc>
+
+          <calc cond="TCB[i]._addr == WDL[j]._addr">
+            k = 1;
+          </calc>
+        </list>
+
+        <!-- Watchdog is running for a thread that was found in the watchdog list -->
+        <calc cond="os_Config.safety_feat">
+            TCB[i].wd_state = k;
+        </calc>
       </list>
 
       <!-- Validate and process Timer control blocks -->
@@ -1100,6 +1148,10 @@
           <item property="Kernel ID"    value="RTX V%d[V_Major].%d[V_Minor].%d[V_Patch]" cond="RTX_En != 0"/>
           <item property="Kernel State" value="osKernelInactive"         cond="RTX_En == 0"/>
           <item property="Kernel State" value="%E[os_Info.kernel_state]" cond="RTX_En != 0"/>
+          <item>
+            <print property="Kernel Protect" value="osThreadPrivileged: %t[(os_Info.kernel_protect &amp; 1) ? &quot;Disabled&quot; : &quot;Enabled&quot;]"                                               cond="(os_Config.safety_feat == 1) &amp;&amp; (os_Config.safety_class == 0) &amp;&amp; (RTX_En != 0)" />
+            <print property="Kernel Protect" value="osThreadPrivileged: %t[(os_Info.kernel_protect &amp; 1) ? &quot;Disabled&quot; : &quot;Enabled&quot;], osSafetyClass(%d[os_Info.kernel_protect/16])" cond="(os_Config.safety_feat == 1) &amp;&amp; (os_Config.safety_class == 1) &amp;&amp; (RTX_En != 0)" />
+          </item>
           <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="Round Robin"            value="Disabled"                    cond="(os_Config.robin_timeout == 0) &amp;&amp; (RTX_En != 0)" />
@@ -1172,7 +1224,12 @@
 
               <item property="State"        value="%E[TCB[i].state &amp; 0x07]"/>
               <item property="Priority"     value="%E[TCB[i].priority]"/>
-              <item property="Attributes"   value="%E[TCB[i].attr &amp; 0x01]"/>
+              <item>
+                <print cond="(os_Config.exec_zone == 0) &amp;&amp; (os_Config.safety_class == 0)" property="Attributes" value="%E[TCB[i].attr &amp; 0x01], %E[TCB[i].attr &amp; 0x06]"/>
+                <print cond="(os_Config.exec_zone == 0) &amp;&amp; (os_Config.safety_class == 1)" property="Attributes" value="%E[TCB[i].attr &amp; 0x01], %E[TCB[i].attr &amp; 0x06], osSafetyClass(%d[TCB[i].attr/16])"/>
+                <print cond="(os_Config.exec_zone == 1) &amp;&amp; (os_Config.safety_class == 0)" property="Attributes" value="%E[TCB[i].attr &amp; 0x01], %E[TCB[i].attr &amp; 0x06], osThreadZone(%d[TCB[i].zone])"/>
+                <print cond="(os_Config.exec_zone == 1) &amp;&amp; (os_Config.safety_class == 1)" property="Attributes" value="%E[TCB[i].attr &amp; 0x01], %E[TCB[i].attr &amp; 0x06], osSafetyClass(%d[TCB[i].attr/16]), osThreadZone(%d[TCB[i].zone])"/>
+              </item>
 
               <item>
                 <print property="Waiting" value="%E[TCB[i].state], Timeout: %d[TCB[i].ex_delay]" cond="((TCB[i].state &amp; 0x07) == 3) &amp;&amp; (TCB[i].ex_delay != -1)"/>
@@ -1231,6 +1288,10 @@
 
               <item property="Stack Overrun" value="Overrun detected" cond="TCB[i].stack_over != 0"/>
               <item property="Flags" value="%x[TCB[i].thread_flags]"/>
+              <item>
+                <print cond="(os_Config.watchdog != 0) &amp;&amp; (TCB[i].wd_state == 0)" property="Watchdog" value="Inactive"/>
+                <print cond="(os_Config.watchdog != 0) &amp;&amp; (TCB[i].wd_state == 1)" property="Watchdog" value="Running, Timeout: %d[TCB[i].wd_tick]"/>
+              </item>
               <item property="Wait Flags" value="%x[TCB[i].wait_flags], %E[TCB[i].flags_options &amp; 1]"                 cond="(TCB[i].wait_flags != 0) &amp;&amp; ((TCB[i].flags_options &amp; 2) == 0)"/>
               <item property="Wait Flags" value="%x[TCB[i].wait_flags], %E[TCB[i].flags_options &amp; 1], osFlagsNoClear" cond="(TCB[i].wait_flags != 0) &amp;&amp; ((TCB[i].flags_options &amp; 2) != 0)"/>
               <item property="TrustZone ID" value="%d[TCB[i].tz_memory]" cond="TCB[i].tz_memory"/>
@@ -1242,11 +1303,12 @@
         <item cond="CCB_En" property="Timers" value="">
           <list name="i" start="0" limit="CCB._count">
             <item cond="CCB[i].cb_valid" property="id: %x[CCB[i]._addr] %N[CCB[i].name]" value="%E[CCB[i].state], Tick: %d[CCB[i].ex_tick]">
-              <item property="State"    value="%E[CCB[i].state]" />
-              <item property="Type"     value="%E[CCB[i].type]" />
-              <item property="Tick"     value="%d[CCB[i].ex_tick]" />
-              <item property="Load"     value="%d[CCB[i].load]" />
-              <item property="Callback" value="Func: %S[CCB[i].finfo_fp], Arg: %x[CCB[i].finfo_arg]" />
+              <item property="State"      value="%E[CCB[i].state]" />
+              <item property="Type"       value="%E[CCB[i].attr &amp; 0x01]" />
+              <item property="Attributes" value="osSafetyClass(%d[CCB[i].attr/16])" cond="os_Config.safety_class == 1"/>
+              <item property="Tick"       value="%d[CCB[i].ex_tick]" />
+              <item property="Load"       value="%d[CCB[i].load]" />
+              <item property="Callback"   value="Func: %S[CCB[i].finfo_fp], Arg: %x[CCB[i].finfo_arg]" />
             </item>
           </list>
         </item>
@@ -1255,6 +1317,7 @@
         <item cond="SCB_En" property="Semaphores" value="">
           <list name="i" start="0" limit="SCB._count">
             <item cond="SCB[i].cb_valid" property="id: %x[SCB[i]._addr] %N[SCB[i].name]" value="Tokens: %d[SCB[i].tokens], Max: %d[SCB[i].max_tokens]">
+            <item property="Attributes" value="osSafetyClass(%d[SCB[i].attr/16])" cond="os_Config.safety_class == 1"/>
             <item property="Tokens"     value="%d[SCB[i].tokens]" />
             <item property="Max Tokens" value="%d[SCB[i].max_tokens]" />
 
@@ -1278,7 +1341,7 @@
           <list name="i" start="0" limit="MCB._count">
             <item cond="MCB[i].cb_valid" property="id: %x[MCB[i]._addr] %N[MCB[i].name]" value="Lock counter: %d[MCB[i].lock]">
               <item property="Lock counter" value="%x[MCB[i].lock]"/>
-              <item property="Attributes" value="%x[MCB[i].attr]">
+              <item property="Attributes" value="osSafetyClass(%d[MCB[i].attr/16])" cond="os_Config.safety_class == 1">
                 <item property="osMutexRecursive"   value="%t[(MCB[i].attr &amp; 0x01) ?  &quot;True&quot; : &quot;False&quot;]" />
                 <item property="osMutexPrioInherit" value="%t[(MCB[i].attr &amp; 0x02) ?  &quot;True&quot; : &quot;False&quot;]" />
                 <item property="osMutexRobust"      value="%t[(MCB[i].attr &amp; 0x08) ?  &quot;True&quot; : &quot;False&quot;]" />
@@ -1307,6 +1370,7 @@
         <item cond="ECB_En" property="Event Flags" value="">
           <list name="i" start="0" limit="ECB._count">
             <item cond="ECB[i].cb_valid" property="id: %x[ECB[i]._addr] %N[ECB[i].name]" value="Flags: %x[ECB[i].event_flags]">
+              <item property="Attributes" value="osSafetyClass(%d[ECB[i].attr/16])" cond="os_Config.safety_class == 1"/>
 
               <!-- Waiting thread list -->
               <item cond="ECB[i].wl_cnt" property="Threads waiting (%d[ECB[i].wl_cnt])" value="">
@@ -1328,6 +1392,7 @@
           <list name="i" start="0" limit="PCB._count">
             <item cond="PCB[i].cb_valid" property="id: %x[PCB[i]._addr] %N[PCB[i].name]" value="Used: %d[PCB[i].used_blocks], Max: %d[PCB[i].max_blocks]">
 
+              <item property="Attributes"  value="osSafetyClass(%d[PCB[i].attr/16])" cond="os_Config.safety_class == 1"/>
               <item property="Used blocks" value="%d[PCB[i].used_blocks]"/>
               <item property="Max blocks"  value="%d[PCB[i].max_blocks]"/>
               <item property="Block size"  value="%d[PCB[i].block_size]"/>
@@ -1354,6 +1419,7 @@
           <list name="i" start="0" limit="QCB._count">
             <item cond="QCB[i].cb_valid" property="id: %x[QCB[i]._addr] %N[QCB[i].name]" value="Messages: %d[QCB[i].msg_count], Max: %d[QCB[i].max_blocks]">
 
+              <item property="Attributes"   value="osSafetyClass(%d[QCB[i].attr/16])" cond="os_Config.safety_class == 1"/>
               <item property="Messages"     value="%d[QCB[i].ml_cnt]"/>
               <item property="Max Messages" value="%d[QCB[i].max_blocks]"/>
               <item property="Message size" value="%d[QCB[i].msg_size]"/>
@@ -1439,17 +1505,22 @@
     <event id="0xF100 + 0x10" level="Op"     property="KernelSuspended"                     value="sleep_ticks=%d[val1]" info="Kernel execution was suspended."/>
     <event id="0xF100 + 0x11" level="API"    property="KernelResume"                        value="sleep_ticks=%d[val1]" info="osKernelResume function was called."/>
     <event id="0xF100 + 0x12" level="Op"     property="KernelResumed"                       value="" info="Kernel execution was resumed."/>
+    <event id="0xF100 + 0x17" level="API"    property="KernelProtect"                       value="safety_class=%d[val1]" info="osKernelProtect function was called."/>
+    <event id="0xF100 + 0x18" level="Op"     property="KernelProtected"                     value="" info="Kernel safety class protection was activated."/>
     <event id="0xF100 + 0x13" level="API"    property="KernelGetTickCount"                  value="count=%d[val1]" info="osKernelGetTickCount function was called."/>
     <event id="0xF100 + 0x14" level="API"    property="KernelGetTickFreq"                   value="freq=%d[val1]" info="osKernelGetTickFreq function was called."/>
     <event id="0xF100 + 0x15" level="API"    property="KernelGetSysTimerCount"              value="count=%d[val1]" info="osKernelGetSysTimerCount function was called."/>
     <event id="0xF100 + 0x16" level="API"    property="KernelGetSysTimerFreq"               value="freq=%d[val1]" info="osKernelGetSysTimerFreq function was called."/>
     <event id="0xF100 + 0x19" level="Error"  property="KernelErrorNotify"                   value="code=%E[val1, rtx_error:id], object_id=%x[val2]" info="osKernelErrorNotify function was called."/>
+    <event id="0xF100 + 0x1A" level="API"    property="KernelDestroyClass"                  value="safety_class=%d[val1], mode=%x[val2]" info="osKernelDestroyClass function was called."/>
 
     <event id="0xF200 + 0x00" level="Error"  property="ThreadError"                                                                       value="thread_id=%x[val1], status=%E[val2, rtx_t:status]" info="Thread error occurred."/>
     <event id="0xF200 + 0x01" level="API"    property="ThreadNew"                                                                         value="func=%S[val1], argument=%x[val2], attr=%x[val3]" info="osThreadNew function was called."/>
     <event id="0xF200 + 0x03" level="Op"     property="ThreadCreated"    tracking="Start" state="Ready"    handle="val1" hname="%S[val2]" value="thread_id=%x[val1]" info="Thread object was created."/>
     <event id="0xF200 + 0x2C" level="Op"     property="ThreadCreated"    tracking="Start" state="Ready"    handle="val1" hname="%N[val2]" value="thread_id=%x[val1]" info="Thread object was created."/>
     <event id="0xF200 + 0x04" level="API"    property="ThreadGetName"                                                                     value="thread_id=%x[val1], name=%N[val2]" info="osThreadGetName function was called and object name was retrieved."/>
+    <event id="0xF200 + 0x30" level="API"    property="ThreadGetClass"                                                                    value="thread_id=%x[val1], safety_class=%d[val2]" info="osThreadGetClass function was called and thread safety class was retrieved."/>
+    <event id="0xF200 + 0x31" level="API"    property="ThreadGetZone"                                                                     value="thread_id=%x[val1], zone=%d[val2]" info="osThreadGetZone function was called and thread execution zone was retrieved."/>
     <event id="0xF200 + 0x06" level="API"    property="ThreadGetId"                                                                       value="thread_id=%x[val1]" info="osThreadGetId function was called and current running thread id was retrieved."/>
     <event id="0xF200 + 0x07" level="API"    property="ThreadGetState"                                                                    value="thread_id=%x[val1], state=%E[val2, rtx_th_state:id]" info="osThreadGetState function was called and thread state was retrieved."/>
     <event id="0xF200 + 0x08" level="API"    property="ThreadGetStackSize"                                                                value="thread_id=%x[val1], stack_size=%d[val2]" info="osThreadGetStackSize function was called and thread stack size was retrieved."/>
@@ -1474,8 +1545,16 @@
     <event id="0xF200 + 0x1A" level="API"    property="ThreadExit"                                                                        value="" info="osThreadExit function was called."/>
     <event id="0xF200 + 0x1B" level="API"    property="ThreadTerminate"                                                                   value="thread_id=%x[val1]" info="osThreadTerminate function was called."/>
     <event id="0xF200 + 0x1C" level="Op"     property="ThreadDestroyed"  tracking="Stop"  state="Inactive" handle="val1"                  value="thread_id=%x[val1]" info="Thread execution was terminated."/>
+    <event id="0xF200 + 0x2E" level="API"    property="ThreadFeedWatchdog"                                                                value="ticks=%d[val1]" info="osThreadFeedWatchdog function was called."/>
+    <event id="0xF200 + 0x2F" level="Op"     property="ThreadFeedWatchdogDone"                                                            value="" info="Thread watchdog timer was feed."/>
+    <event id="0xF200 + 0x32" level="API"    property="ThreadProtectPrivileged"                                                           value="" info="osThreadProtectPrivileged function was called."/>
+    <event id="0xF200 + 0x33" level="Op"     property="ThreadPrivilegedProtected"                                                         value="" info="Creation of privileged threads was protected."/>
     <event id="0xF200 + 0x1D" level="API"    property="ThreadGetCount"                                                                    value="count=%d[val1]" info="osThreadGetCount function was called and number of active threads was retrieved."/>
     <event id="0xF200 + 0x1E" level="API"    property="ThreadEnumerate"                                                                   value="thread_array=%x[val1], array_items=%d[val2], count=%d[val3]" info="osThreadEnumerate function was called and active threads were enumerated."/>
+    <event id="0xF200 + 0x34" level="API"    property="ThreadSuspendClass"                                                                value="safety_class=%d[val1], mode=%x[val2]" info="osThreadSuspendClass function was called."/>
+    <event id="0xF200 + 0x35" level="API"    property="ThreadResumeClass"                                                                 value="safety_class=%d[val1], mode=%x[val2]" info="osThreadResumeClass function was called."/>
+    <event id="0xF200 + 0x36" level="API"    property="ThreadTerminateZone"                                                               value="zone=%d[val1]" info="osThreadTerminateZone function was called."/>
+    <event id="0xF200 + 0x37" level="Error"  property="ThreadWatchdogExpired"                                                             value="thread_id=%x[val1]" info="Thread watchdog timer has expired."/>
 
     <event id="0xF400 + 0x00" level="Error"  property="ThreadFlagsError"            value="thread_id=%x[val1], status=%E[val2, rtx_t:status]" info="Thread flags error occurred."/>
     <event id="0xF400 + 0x01" level="API"    property="ThreadFlagsSet"              value="thread_id=%x[val1], flags=%x[val2]" info="osThreadFlagsSet function was called."/>
diff --git a/CMSIS/RTOS2/RTX/Source/ARM/irq_armv6m.s b/CMSIS/RTOS2/RTX/Source/ARM/irq_armv6m.s
index 7900d8d..6ad99aa 100644
--- a/CMSIS/RTOS2/RTX/Source/ARM/irq_armv6m.s
+++ b/CMSIS/RTOS2/RTX/Source/ARM/irq_armv6m.s
@@ -1,5 +1,5 @@
 ;/*
-; * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+; * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
 ; *
 ; * SPDX-License-Identifier: Apache-2.0
 ; *
@@ -24,15 +24,13 @@
 ; */
 
 
-                IF       :LNOT::DEF:RTX_STACK_CHECK
-RTX_STACK_CHECK EQU      0
-                ENDIF
-
 I_T_RUN_OFS     EQU      20                     ; osRtxInfo.thread.run offset
 TCB_SP_OFS      EQU      56                     ; TCB.SP offset
+TCB_ZONE_OFS    EQU      68                     ; TCB.zone offset
 
 osRtxErrorStackOverflow\
                 EQU      1                      ; Stack overflow
+osRtxErrorSVC   EQU      6                      ; Invalid SVC function called
 
 
                 PRESERVE8
@@ -51,10 +49,18 @@
                 EXPORT   SVC_Handler
                 IMPORT   osRtxUserSVC
                 IMPORT   osRtxInfo
-            IF RTX_STACK_CHECK != 0
+            IF :DEF:RTX_STACK_CHECK
                 IMPORT   osRtxThreadStackCheck
                 IMPORT   osRtxKernelErrorNotify
             ENDIF
+            IF :DEF:RTX_SVC_PTR_CHECK
+                IMPORT   |Image$$RTX_SVC_VENEERS$$Base|
+                IMPORT   |Image$$RTX_SVC_VENEERS$$Length|
+                IMPORT   osRtxKernelErrorNotify
+            ENDIF
+            IF :DEF:RTX_EXECUTION_ZONE
+                IMPORT   osZoneSetup_Callback
+            ENDIF
 
                 MOV      R0,LR
                 LSRS     R0,R0,#3               ; Determine return stack from EXC_RETURN bit 2
@@ -68,6 +74,30 @@
                 CMP      R1,#0                  ; Check SVC number
                 BNE      SVC_User               ; Branch if not SVC 0
 
+            IF :DEF:RTX_SVC_PTR_CHECK
+
+                SUBS     R1,R7,#0x01            ; Clear T-bit of function address
+                LSLS     R2,R1,#29              ; Check if 8-byte aligned
+                BEQ      SVC_PtrBoundsCheck     ; Branch if address is aligned
+
+SVC_PtrInvalid
+                PUSH     {R0,LR}                ; Save SP and EXC_RETURN
+                MOVS     R0,#osRtxErrorSVC      ; Parameter: code
+                MOV      R1,R7                  ; Parameter: object_id
+                BL       osRtxKernelErrorNotify ; Call osRtxKernelErrorNotify
+                POP      {R2,R3}                ; Restore SP and EXC_RETURN
+                MOV      LR,R3                  ; Set EXC_RETURN
+                B        SVC_Context            ; Branch to context handling
+
+SVC_PtrBoundsCheck
+                LDR      R2,=|Image$$RTX_SVC_VENEERS$$Base|
+                LDR      R3,=|Image$$RTX_SVC_VENEERS$$Length|
+                SUBS     R2,R1,R2               ; Subtract SVC table base address
+                CMP      R2,R3                  ; Compare with SVC table boundaries
+                BHS      SVC_PtrInvalid         ; Branch if address is out of bounds
+
+            ENDIF
+
                 PUSH     {R0,LR}                ; Save SP and EXC_RETURN
                 LDMIA    R0,{R0-R3}             ; Load function parameters from stack
                 BLX      R7                     ; Call service function
@@ -91,7 +121,7 @@
                 SUBS     R0,R0,#32              ; Calculate SP: space for R4..R11
                 STR      R0,[R1,#TCB_SP_OFS]    ; Store SP
 
-            IF RTX_STACK_CHECK != 0
+            IF :DEF:RTX_STACK_CHECK
 
                 PUSH     {R1,R2}                ; Save osRtxInfo.thread.run: curr & next
                 MOV      R0,R1                  ; Parameter: osRtxInfo.thread.run.curr
@@ -105,6 +135,7 @@
                 LDR      R3,=osRtxInfo+I_T_RUN_OFS   ; Load address of osRtxInfo.thread.run
                 LDR      R2,[R3,#4]             ; Load osRtxInfo.thread.run: next
                 STR      R2,[R3]                ; osRtxInfo.thread.run: curr = next
+                MOVS     R1,#0                  ; Simulate deleted running thread
                 B        SVC_ContextRestore     ; Branch to context restore handling
 
 SVC_ContextSaveRegs
@@ -120,7 +151,22 @@
                 STMIA    R0!,{R4-R7}            ; Save R8..R11
 
 SVC_ContextRestore
-                LDR      R0,[R2,#TCB_SP_OFS]    ; Load SP
+                 MOVS     R4,R2                 ; Assign osRtxInfo.thread.run.next to R4
+            IF :DEF:RTX_EXECUTION_ZONE
+                 MOVS     R3,#TCB_ZONE_OFS      ; Get TCB.zone offset
+                 LDRB     R0,[R2,R3]            ; Load osRtxInfo.thread.run.next: zone
+                 CMP      R1,#0
+                 BEQ      SVC_ZoneSetup         ; Branch if running thread is deleted
+                 LDRB     R1,[R1,R3]            ; Load osRtxInfo.thread.run.curr: zone
+                 CMP      R0,R1                 ; Check if next:zone == curr:zone
+                 BEQ      SVC_ContextRestore_N  ; Branch if zone has not changed
+
+SVC_ZoneSetup
+                 BL     osZoneSetup_Callback    ;  Setup zone for next thread
+            ENDIF
+
+SVC_ContextRestore_N
+                LDR      R0,[R4,#TCB_SP_OFS]    ; Load SP
                 ADDS     R0,R0,#16              ; Adjust address
                 LDMIA    R0!,{R4-R7}            ; Restore R8..R11
                 MOV      R8,R4
@@ -192,4 +238,17 @@
                 ENDP
 
 
+            IF :DEF:RTX_SAFETY_FEATURES
+
+osFaultResume   PROC
+                EXPORT   osFaultResume
+
+                B        SVC_Context            ; Branch to context handling
+
+                ALIGN
+                ENDP
+
+            ENDIF
+
+
                 END
diff --git a/CMSIS/RTOS2/RTX/Source/ARM/irq_armv7m.s b/CMSIS/RTOS2/RTX/Source/ARM/irq_armv7m.s
index c47e2d5..f484efd 100644
--- a/CMSIS/RTOS2/RTX/Source/ARM/irq_armv7m.s
+++ b/CMSIS/RTOS2/RTX/Source/ARM/irq_armv7m.s
@@ -1,5 +1,5 @@
 ;/*
-; * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+; * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
 ; *
 ; * SPDX-License-Identifier: Apache-2.0
 ; *
@@ -24,10 +24,6 @@
 ; */
 
 
-                IF       :LNOT::DEF:RTX_STACK_CHECK
-RTX_STACK_CHECK EQU      0
-                ENDIF
-
                 IF       ({FPU}="FPv4-SP") || ({FPU}="VFPv4_D16") || ({FPU}="VFPv4_SP_D16") || ({FPU}="FPv5-SP") || ({FPU}="FPv5_D16")
 FPU_USED        EQU      1
                 ELSE
@@ -37,11 +33,13 @@
 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
+TCB_ZONE_OFS    EQU      68                     ; TCB.zone offset
 
 FPCCR           EQU      0xE000EF34             ; FPCCR Address
 
 osRtxErrorStackOverflow\
                 EQU      1                      ; Stack overflow
+osRtxErrorSVC   EQU      6                      ; Invalid SVC function called
 
 
                 PRESERVE8
@@ -60,10 +58,18 @@
                 EXPORT   SVC_Handler
                 IMPORT   osRtxUserSVC
                 IMPORT   osRtxInfo
-            IF RTX_STACK_CHECK != 0
+            IF :DEF:RTX_STACK_CHECK
                 IMPORT   osRtxThreadStackCheck
                 IMPORT   osRtxKernelErrorNotify
             ENDIF
+            IF :DEF:RTX_SVC_PTR_CHECK
+                IMPORT   |Image$$RTX_SVC_VENEERS$$Base|
+                IMPORT   |Image$$RTX_SVC_VENEERS$$Length|
+                IMPORT   osRtxKernelErrorNotify
+            ENDIF
+            IF :DEF:RTX_EXECUTION_ZONE
+                IMPORT   osZoneSetup_Callback
+            ENDIF
 
                 TST      LR,#0x04               ; Determine return stack from EXC_RETURN bit 2
                 ITE      EQ
@@ -75,6 +81,30 @@
                 CMP      R1,#0                  ; Check SVC number
                 BNE      SVC_User               ; Branch if not SVC 0
 
+            IF :DEF:RTX_SVC_PTR_CHECK
+
+                LDR      R12,[R0,#16]           ; Load function address from stack
+                SUB      R1,R12,#1              ; Clear T-bit of function address
+                LSLS     R2,R1,#30              ; Check if 4-byte aligned
+                BEQ      SVC_PtrBoundsCheck     ; Branch if address is aligned
+
+SVC_PtrInvalid
+                PUSH     {R0,LR}                ; Save SP and EXC_RETURN
+                MOV      R0,#osRtxErrorSVC      ; Parameter: code
+                MOV      R1,R12                 ; Parameter: object_id
+                BL       osRtxKernelErrorNotify ; Call osRtxKernelErrorNotify
+                POP      {R12,LR}               ; Restore SP and EXC_RETURN
+                B        SVC_Context            ; Branch to context handling
+
+SVC_PtrBoundsCheck
+                LDR      R2,=|Image$$RTX_SVC_VENEERS$$Base|
+                LDR      R3,=|Image$$RTX_SVC_VENEERS$$Length|
+                SUB      R2,R1,R2               ; Subtract SVC table base address
+                CMP      R2,R3                  ; Compare with SVC table boundaries
+                BHS      SVC_PtrInvalid         ; Branch if address is out of bounds
+
+            ENDIF
+
                 PUSH     {R0,LR}                ; Save SP and EXC_RETURN
                 LDM      R0,{R0-R3,R12}         ; Load function parameters and address from stack
                 BLX      R12                    ; Call service function
@@ -105,7 +135,7 @@
               ENDIF
 
 SVC_ContextSave
-            IF RTX_STACK_CHECK != 0
+            IF :DEF:RTX_STACK_CHECK
                 SUB      R12,R12,#32            ; Calculate SP: space for R4..R11
               IF FPU_USED != 0
                 TST      LR,#0x10               ; Determine stack frame from EXC_RETURN bit 4
@@ -122,13 +152,14 @@
                 CBNZ     R0,SVC_ContextSaveRegs ; Branch when stack check is ok
 
               IF FPU_USED != 0
-                MOV      R4,R1                  ; Save osRtxInfo.thread.run.curr
+                MOV      R4,R1                  ; Assign osRtxInfo.thread.run.curr to R4
               ENDIF
                 MOV      R0,#osRtxErrorStackOverflow ; Parameter: r0=code, r1=object_id
                 BL       osRtxKernelErrorNotify      ; Call osRtxKernelErrorNotify
                 LDR      R3,=osRtxInfo+I_T_RUN_OFS   ; Load address of osRtxInfo.thread.run
                 LDR      R2,[R3,#4]             ; Load osRtxInfo.thread.run: next
                 STR      R2,[R3]                ; osRtxInfo.thread.run: curr = next
+                MOVS     R1,#0                  ; Simulate deleted running thread
               IF FPU_USED != 0
                 LDRB     LR,[R4,#TCB_SF_OFS]    ; Load stack frame information
                 B        SVC_FP_LazyState       ; Branch to FP lazy state handling
@@ -157,9 +188,21 @@
             ENDIF
 
 SVC_ContextRestore
-                LDR      R0,[R2,#TCB_SP_OFS]    ; Load SP
+                 MOVS     R4,R2                 ; Assign osRtxInfo.thread.run.next to R4, clear Z flag
+            IF :DEF:RTX_EXECUTION_ZONE
+                 LDRB     R0,[R2,#TCB_ZONE_OFS] ; Load osRtxInfo.thread.run.next: zone
+                 CBZ      R1,SVC_ZoneSetup      ; Branch if running thread is deleted (Z flag unchanged)
+                 LDRB     R1,[R1,#TCB_ZONE_OFS] ; Load osRtxInfo.thread.run.curr: zone
+                 CMP      R0,R1                 ; Check if next:zone == curr:zone
+
+SVC_ZoneSetup
+                 IT       NE                    ; If zone has changed or running thread is deleted
+                 BLNE     osZoneSetup_Callback  ;  Setup zone for next thread
+            ENDIF
+
+                LDR      R0,[R4,#TCB_SP_OFS]    ; Load SP
               IF FPU_USED != 0
-                LDRB     R1,[R2,#TCB_SF_OFS]    ; Load stack frame information
+                LDRB     R1,[R4,#TCB_SF_OFS]    ; Load stack frame information
                 ORN      LR,R1,#0xFF            ; Set EXC_RETURN
                 TST      LR,#0x10               ; Determine stack frame from EXC_RETURN bit 4
                 IT       EQ                     ; If extended stack frame
@@ -220,4 +263,18 @@
                 ENDP
 
 
+            IF :DEF:RTX_SAFETY_FEATURES
+
+osFaultResume   PROC
+                EXPORT   osFaultResume
+
+                MRS      R12,PSP                ; Save PSP to R12
+                B        SVC_Context            ; Branch to context handling
+
+                ALIGN
+                ENDP
+
+            ENDIF
+
+
                 END
diff --git a/CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mbl.s b/CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mbl.s
index 55d29d3..132ea37 100644
--- a/CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mbl.s
+++ b/CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mbl.s
@@ -1,5 +1,5 @@
 ;/*
-; * Copyright (c) 2016-2021 Arm Limited. All rights reserved.
+; * Copyright (c) 2016-2023 Arm Limited. All rights reserved.
 ; *
 ; * SPDX-License-Identifier: Apache-2.0
 ; *
@@ -24,10 +24,6 @@
 ; */
 
 
-                IF       :LNOT::DEF:RTX_STACK_CHECK
-RTX_STACK_CHECK EQU      0
-                ENDIF
-
                 IF       :LNOT::DEF:DOMAIN_NS
 DOMAIN_NS       EQU      0
                 ENDIF
@@ -37,9 +33,11 @@
 TCB_SP_OFS      EQU      56                     ; TCB.SP offset
 TCB_SF_OFS      EQU      34                     ; TCB.stack_frame offset
 TCB_TZM_OFS     EQU      64                     ; TCB.tz_memory offset
+TCB_ZONE_OFS    EQU      68                     ; TCB.zone offset
 
 osRtxErrorStackOverflow\
                 EQU      1                      ; Stack overflow
+osRtxErrorSVC   EQU      6                      ; Invalid SVC function called
 
 
                 PRESERVE8
@@ -58,10 +56,18 @@
                 EXPORT   SVC_Handler
                 IMPORT   osRtxUserSVC
                 IMPORT   osRtxInfo
-            IF RTX_STACK_CHECK != 0
+            IF :DEF:RTX_STACK_CHECK
                 IMPORT   osRtxThreadStackCheck
                 IMPORT   osRtxKernelErrorNotify
             ENDIF
+            IF :DEF:RTX_SVC_PTR_CHECK
+                IMPORT   |Image$$RTX_SVC_VENEERS$$Base|
+                IMPORT   |Image$$RTX_SVC_VENEERS$$Length|
+                IMPORT   osRtxKernelErrorNotify
+            ENDIF
+            IF :DEF:RTX_EXECUTION_ZONE
+                IMPORT   osZoneSetup_Callback
+            ENDIF
             IF DOMAIN_NS != 0
                 IMPORT   TZ_LoadContext_S
                 IMPORT   TZ_StoreContext_S
@@ -79,6 +85,30 @@
                 CMP      R1,#0                  ; Check SVC number
                 BNE      SVC_User               ; Branch if not SVC 0
 
+            IF :DEF:RTX_SVC_PTR_CHECK
+
+                SUBS     R1,R7,#0x01            ; Clear T-bit of function address
+                LSLS     R2,R1,#29              ; Check if 8-byte aligned
+                BEQ      SVC_PtrBoundsCheck     ; Branch if address is aligned
+
+SVC_PtrInvalid
+                PUSH     {R0,LR}                ; Save SP and EXC_RETURN
+                MOVS     R0,#osRtxErrorSVC      ; Parameter: code
+                MOV      R1,R7                  ; Parameter: object_id
+                BL       osRtxKernelErrorNotify ; Call osRtxKernelErrorNotify
+                POP      {R2,R3}                ; Restore SP and EXC_RETURN
+                MOV      LR,R3                  ; Set EXC_RETURN
+                B        SVC_Context            ; Branch to context handling
+
+SVC_PtrBoundsCheck
+                LDR      R2,=|Image$$RTX_SVC_VENEERS$$Base|
+                LDR      R3,=|Image$$RTX_SVC_VENEERS$$Length|
+                SUBS     R2,R1,R2               ; Subtract SVC table base address
+                CMP      R2,R3                  ; Compare with SVC table boundaries
+                BHS      SVC_PtrInvalid         ; Branch if address is out of bounds
+
+            ENDIF
+
                 PUSH     {R0,LR}                ; Save SP and EXC_RETURN
                 LDMIA    R0,{R0-R3}             ; Load function parameters from stack
                 BLX      R7                     ; Call service function
@@ -115,7 +145,7 @@
                 BMI      SVC_ContextSaveSP      ; Branch if secure
             ENDIF
 
-            IF RTX_STACK_CHECK != 0
+            IF :DEF:RTX_STACK_CHECK
                 SUBS     R0,R0,#32              ; Calculate SP: space for R4..R11
 
 SVC_ContextSaveSP
@@ -137,6 +167,7 @@
                 LDR      R3,=osRtxInfo+I_T_RUN_OFS   ; Load address of osRtxInfo.thread.run
                 LDR      R2,[R3,#4]             ; Load osRtxInfo.thread.run: next
                 STR      R2,[R3]                ; osRtxInfo.thread.run: curr = next
+                MOVS     R1,#0                  ; Simulate deleted running thread
                 B        SVC_ContextRestore     ; Branch to context restore handling
 
 SVC_ContextSaveRegs
@@ -171,25 +202,37 @@
             ENDIF
 
 SVC_ContextRestore
+                 MOVS     R4,R2                 ; Assign osRtxInfo.thread.run.next to R4
+            IF :DEF:RTX_EXECUTION_ZONE
+                 MOVS     R3,#TCB_ZONE_OFS      ; Get TCB.zone offset
+                 LDRB     R0,[R2,R3]            ; Load osRtxInfo.thread.run.next: zone
+                 CBZ      R1,SVC_ZoneSetup      ; Branch if running thread is deleted
+                 LDRB     R1,[R1,R3]            ; Load osRtxInfo.thread.run.curr: zone
+                 CMP      R0,R1                 ; Check if next:zone == curr:zone
+                 BEQ      SVC_ContextRestore_S  ; Branch if zone has not changed
+
+SVC_ZoneSetup
+                 BL     osZoneSetup_Callback    ;  Setup zone for next thread
+            ENDIF
+
+SVC_ContextRestore_S
             IF DOMAIN_NS != 0
-                LDR      R0,[R2,#TCB_TZM_OFS]   ; Load TrustZone memory identifier
+                LDR      R0,[R4,#TCB_TZM_OFS]   ; Load TrustZone memory identifier
                 CBZ      R0,SVC_ContextRestore_NS ; Branch if there is no secure context
-                PUSH     {R2,R3}                ; Save registers
                 BL       TZ_LoadContext_S       ; Load secure context
-                POP      {R2,R3}                ; Restore registers
             ENDIF
 
 SVC_ContextRestore_NS
-                LDR      R0,[R2,#TCB_SM_OFS]    ; Load stack memory base
+                LDR      R0,[R4,#TCB_SM_OFS]    ; Load stack memory base
                 MSR      PSPLIM,R0              ; Set PSPLIM
-                MOV      R0,R2                  ; osRtxInfo.thread.run.next
+                MOV      R0,R4                  ; osRtxInfo.thread.run.next
                 ADDS     R0,R0,#TCB_SF_OFS      ; Adjust address
                 LDRB     R3,[R0]                ; Load stack frame information
                 MOVS     R0,#0xFF
                 MVNS     R0,R0                  ; R0=0xFFFFFF00
                 ORRS     R3,R3,R0
                 MOV      LR,R3                  ; Set EXC_RETURN
-                LDR      R0,[R2,#TCB_SP_OFS]    ; Load SP
+                LDR      R0,[R4,#TCB_SP_OFS]    ; Load SP
             IF DOMAIN_NS != 0
                 LSLS     R3,R3,#25              ; Check domain of interrupted thread
                 BMI      SVC_ContextRestoreSP   ; Branch if secure
@@ -265,4 +308,17 @@
                 ENDP
 
 
+            IF :DEF:RTX_SAFETY_FEATURES
+
+osFaultResume   PROC
+                EXPORT   osFaultResume
+
+                B        SVC_Context            ; Branch to context handling
+
+                ALIGN
+                ENDP
+
+            ENDIF
+
+
                 END
diff --git a/CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mml.s b/CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mml.s
index 318fa4a..e3c9807 100644
--- a/CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mml.s
+++ b/CMSIS/RTOS2/RTX/Source/ARM/irq_armv8mml.s
@@ -1,5 +1,5 @@
 ;/*
-; * Copyright (c) 2016-2021 Arm Limited. All rights reserved.
+; * Copyright (c) 2016-2023 Arm Limited. All rights reserved.
 ; *
 ; * SPDX-License-Identifier: Apache-2.0
 ; *
@@ -24,15 +24,11 @@
 ; */
 
 
-                IF       :LNOT::DEF:RTX_STACK_CHECK
-RTX_STACK_CHECK EQU      0
-                ENDIF
-
                 IF       :LNOT::DEF:DOMAIN_NS
 DOMAIN_NS       EQU      0
                 ENDIF
 
-                IF       ({FPU}="FPv5-SP") || ({FPU}="FPv5_D16")
+                IF       ({FPU}="FPv4-SP") || ({FPU}="VFPv4_D16") || ({FPU}="VFPv4_SP_D16") || ({FPU}="FPv5-SP") || ({FPU}="FPv5_D16")
 FPU_USED        EQU      1
                 ELSE
 FPU_USED        EQU      0
@@ -43,11 +39,13 @@
 TCB_SP_OFS      EQU      56                     ; TCB.SP offset
 TCB_SF_OFS      EQU      34                     ; TCB.stack_frame offset
 TCB_TZM_OFS     EQU      64                     ; TCB.tz_memory offset
+TCB_ZONE_OFS    EQU      68                     ; TCB.zone offset
 
 FPCCR           EQU      0xE000EF34             ; FPCCR Address
 
 osRtxErrorStackOverflow\
                 EQU      1                      ; Stack overflow
+osRtxErrorSVC   EQU      6                      ; Invalid SVC function called
 
 
                 PRESERVE8
@@ -66,10 +64,18 @@
                 EXPORT   SVC_Handler
                 IMPORT   osRtxUserSVC
                 IMPORT   osRtxInfo
-            IF RTX_STACK_CHECK != 0
+            IF :DEF:RTX_STACK_CHECK
                 IMPORT   osRtxThreadStackCheck
                 IMPORT   osRtxKernelErrorNotify
             ENDIF
+            IF :DEF:RTX_SVC_PTR_CHECK
+                IMPORT   |Image$$RTX_SVC_VENEERS$$Base|
+                IMPORT   |Image$$RTX_SVC_VENEERS$$Length|
+                IMPORT   osRtxKernelErrorNotify
+            ENDIF
+            IF :DEF:RTX_EXECUTION_ZONE
+                IMPORT   osZoneSetup_Callback
+            ENDIF
             IF DOMAIN_NS != 0
                 IMPORT   TZ_LoadContext_S
                 IMPORT   TZ_StoreContext_S
@@ -85,6 +91,30 @@
                 CMP      R1,#0                  ; Check SVC number
                 BNE      SVC_User               ; Branch if not SVC 0
 
+            IF :DEF:RTX_SVC_PTR_CHECK
+
+                LDR      R12,[R0,#16]           ; Load function address from stack
+                SUB      R1,R12,#1              ; Clear T-bit of function address
+                LSLS     R2,R1,#30              ; Check if 4-byte aligned
+                BEQ      SVC_PtrBoundsCheck     ; Branch if address is aligned
+
+SVC_PtrInvalid
+                PUSH     {R0,LR}                ; Save SP and EXC_RETURN
+                MOV      R0,#osRtxErrorSVC      ; Parameter: code
+                MOV      R1,R12                 ; Parameter: object_id
+                BL       osRtxKernelErrorNotify ; Call osRtxKernelErrorNotify
+                POP      {R12,LR}               ; Restore SP and EXC_RETURN
+                B        SVC_Context            ; Branch to context handling
+
+SVC_PtrBoundsCheck
+                LDR      R2,=|Image$$RTX_SVC_VENEERS$$Base|
+                LDR      R3,=|Image$$RTX_SVC_VENEERS$$Length|
+                SUB      R2,R1,R2               ; Subtract SVC table base address
+                CMP      R2,R3                  ; Compare with SVC table boundaries
+                BHS      SVC_PtrInvalid         ; Branch if address is out of bounds
+
+            ENDIF
+
                 PUSH     {R0,LR}                ; Save SP and EXC_RETURN
                 LDM      R0,{R0-R3,R12}         ; Load function parameters and address from stack
                 BLX      R12                    ; Call service function
@@ -129,7 +159,7 @@
                 BNE      SVC_ContextSaveSP      ; Branch if secure
             ENDIF
 
-            IF RTX_STACK_CHECK != 0
+            IF :DEF:RTX_STACK_CHECK
                 SUB      R12,R12,#32            ; Calculate SP: space for R4..R11
               IF FPU_USED != 0
                 TST      LR,#0x10               ; Determine stack frame from EXC_RETURN bit 4
@@ -148,13 +178,14 @@
                 CBNZ     R0,SVC_ContextSaveRegs ; Branch when stack check is ok
 
               IF FPU_USED != 0
-                MOV      R4,R1                  ; Save osRtxInfo.thread.run.curr
+                MOV      R4,R1                  ; Assign osRtxInfo.thread.run.curr to R4
               ENDIF
                 MOV      R0,#osRtxErrorStackOverflow ; Parameter: r0=code, r1=object_id
                 BL       osRtxKernelErrorNotify      ; Call osRtxKernelErrorNotify
                 LDR      R3,=osRtxInfo+I_T_RUN_OFS   ; Load address of osRtxInfo.thread.run
                 LDR      R2,[R3,#4]             ; Load osRtxInfo.thread.run: next
                 STR      R2,[R3]                ; osRtxInfo.thread.run: curr = next
+                MOVS     R1,#0                  ; Simulate deleted running thread
               IF FPU_USED != 0
                 LDRB     LR,[R4,#TCB_SF_OFS]    ; Load stack frame information
                 B        SVC_FP_LazyState       ; Branch to FP lazy state handling
@@ -188,19 +219,29 @@
             ENDIF
 
 SVC_ContextRestore
+                 MOVS     R4,R2                 ; Assign osRtxInfo.thread.run.next to R4, clear Z flag
+            IF :DEF:RTX_EXECUTION_ZONE
+                 LDRB     R0,[R2,#TCB_ZONE_OFS] ; Load osRtxInfo.thread.run.next: zone
+                 CBZ      R1,SVC_ZoneSetup      ; Branch if running thread is deleted (Z flag unchanged)
+                 LDRB     R1,[R1,#TCB_ZONE_OFS] ; Load osRtxInfo.thread.run.curr: zone
+                 CMP      R0,R1                 ; Check if next:zone == curr:zone
+
+SVC_ZoneSetup
+                 IT       NE                    ; If zone has changed or running thread is deleted
+                 BLNE     osZoneSetup_Callback  ;  Setup zone for next thread
+            ENDIF
+
             IF DOMAIN_NS != 0
-                LDR      R0,[R2,#TCB_TZM_OFS]   ; Load TrustZone memory identifier
-                CBZ      R0,SVC_ContextRestore_NS; Branch if there is no secure context
-                PUSH     {R2,R3}                ; Save registers
+                LDR      R0,[R4,#TCB_TZM_OFS]   ; Load TrustZone memory identifier
+                CBZ      R0,SVC_ContextRestore_NS ; Branch if there is no secure context
                 BL       TZ_LoadContext_S       ; Load secure context
-                POP      {R2,R3}                ; Restore registers
             ENDIF
 
 SVC_ContextRestore_NS
-                LDR      R0,[R2,#TCB_SP_OFS]    ; Load SP
-                LDR      R1,[R2,#TCB_SM_OFS]    ; Load stack memory base
+                LDR      R0,[R4,#TCB_SP_OFS]    ; Load SP
+                LDR      R1,[R4,#TCB_SM_OFS]    ; Load stack memory base
                 MSR      PSPLIM,R1              ; Set PSPLIM
-                LDRB     R1,[R2,#TCB_SF_OFS]    ; Load stack frame information
+                LDRB     R1,[R4,#TCB_SF_OFS]    ; Load stack frame information
                 ORN      LR,R1,#0xFF            ; Set EXC_RETURN
 
             IF DOMAIN_NS != 0
@@ -268,4 +309,18 @@
                 ENDP
 
 
+            IF :DEF:RTX_SAFETY_FEATURES
+
+osFaultResume   PROC
+                EXPORT   osFaultResume
+
+                MRS      R12,PSP                ; Save PSP to R12
+                B        SVC_Context            ; Branch to context handling
+
+                ALIGN
+                ENDP
+
+            ENDIF
+
+
                 END
diff --git a/CMSIS/RTOS2/RTX/Source/GCC/irq_armv6m.S b/CMSIS/RTOS2/RTX/Source/GCC/irq_armv6m.S
index ef4fa75..413a9ce 100644
--- a/CMSIS/RTOS2/RTX/Source/GCC/irq_armv6m.S
+++ b/CMSIS/RTOS2/RTX/Source/GCC/irq_armv6m.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -28,10 +28,12 @@
 
         #include "rtx_def.h"
 
-        .equ     I_T_RUN_OFS, 20        // osRtxInfo.thread.run offset
-        .equ     TCB_SP_OFS,  56        // TCB.SP offset
+        .equ     I_T_RUN_OFS,       20  // osRtxInfo.thread.run offset
+        .equ     TCB_SP_OFS,        56  // TCB.SP offset
+        .equ     TCB_ZONE_OFS,      68  // TCB.zone offset
 
         .equ     osRtxErrorStackOverflow, 1 // Stack overflow
+        .equ     osRtxErrorSVC,           6 // Invalid SVC function called
 
         .section ".rodata"
         .global  irqRtxLib              // Non weak library reference
@@ -64,6 +66,30 @@
         cmp      r1,#0                  // Check SVC number
         bne      SVC_User               // Branch if not SVC 0
 
+    #ifdef RTX_SVC_PTR_CHECK
+
+        subs     r1,r7,#0x01            // Clear T-bit of function address
+        lsls     r2,r1,#29              // Check if 8-byte aligned
+        beq      SVC_PtrBoundsCheck     // Branch if address is aligned
+
+SVC_PtrInvalid:
+        push     {r0,lr}                // Save SP and EXC_RETURN
+        movs     r0,#osRtxErrorSVC      // Parameter: code
+        mov      r1,r7                  // Parameter: object_id
+        bl       osRtxKernelErrorNotify // Call osRtxKernelErrorNotify
+        pop      {r2,r3}                // Restore SP and EXC_RETURN
+        mov      lr,r3                  // Set EXC_RETURN
+        b        SVC_Context            // Branch to context handling
+
+SVC_PtrBoundsCheck:
+        ldr      r2,=Image$$RTX_SVC_VENEERS$$Base
+        ldr      r3,=Image$$RTX_SVC_VENEERS$$Length
+        subs     r2,r1,r2               // Subtract SVC table base address
+        cmp      r2,r3                  // Compare with SVC table boundaries
+        bhs      SVC_PtrInvalid         // Branch if address is out of bounds
+
+    #endif // RTX_SVC_PTR_CHECK
+
         push     {r0,lr}                // Save SP and EXC_RETURN
         ldmia    r0,{r0-r3}             // Load function parameters from stack
         blx      r7                     // Call service function
@@ -101,6 +127,7 @@
         ldr      r3,=osRtxInfo+I_T_RUN_OFS   // Load address of osRtxInfo.thread.run
         ldr      r2,[r3,#4]             // Load osRtxInfo.thread.run: next
         str      r2,[r3]                // osRtxInfo.thread.run: curr = next
+        movs     r1,#0                  // Simulate deleted running thread
         b        SVC_ContextRestore     // Branch to context restore handling
 
 SVC_ContextSaveRegs:
@@ -116,7 +143,22 @@
         stmia    r0!,{r4-r7}            // Save R8..R11
 
 SVC_ContextRestore:
-        ldr      r0,[r2,#TCB_SP_OFS]    // Load SP
+        movs     r4,r2                  // Assign osRtxInfo.thread.run.next to R4
+    #ifdef RTX_EXECUTION_ZONE
+        movs     r3,#TCB_ZONE_OFS       // Get TCB.zone offset
+        ldrb     r0,[r2,r3]             // Load osRtxInfo.thread.run.next: zone
+        cmp      r1,#0
+        beq      SVC_ZoneSetup          // Branch if running thread is deleted
+        ldrb     r1,[r1,r3]             // Load osRtxInfo.thread.run.curr: zone
+        cmp      r0,r1                  // Check if next:zone == curr:zone
+        beq      SVC_ContextRestore_N   // Branch if zone has not changed
+
+SVC_ZoneSetup:
+        bl       osZoneSetup_Callback   // Setup zone for next thread
+    #endif // RTX_EXECUTION_ZONE
+
+SVC_ContextRestore_N:
+        ldr      r0,[r4,#TCB_SP_OFS]    // Load SP
         adds     r0,r0,#16              // Adjust address
         ldmia    r0!,{r4-r7}            // Restore R8..R11
         mov      r8,r4
@@ -194,4 +236,21 @@
         .size    SysTick_Handler, .-SysTick_Handler
 
 
+    #ifdef RTX_SAFETY_FEATURES
+
+        .thumb_func
+        .type    osFaultResume, %function
+        .global  osFaultResume
+        .fnstart
+        .cantunwind
+osFaultResume:
+
+        b        SVC_Context            // Branch to context handling
+
+        .fnend
+        .size   osFaultResume, .-osFaultResume
+
+    #endif // RTX_SAFETY_FEATURES
+
+
         .end
diff --git a/CMSIS/RTOS2/RTX/Source/GCC/irq_armv7m.S b/CMSIS/RTOS2/RTX/Source/GCC/irq_armv7m.S
index daf9871..49298cc 100644
--- a/CMSIS/RTOS2/RTX/Source/GCC/irq_armv7m.S
+++ b/CMSIS/RTOS2/RTX/Source/GCC/irq_armv7m.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -34,13 +34,15 @@
         .equ     FPU_USED, 0
         #endif
 
-        .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
+        .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
+        .equ     TCB_ZONE_OFS,      68  // TCB.zone offset
 
         .equ     FPCCR,     0xE000EF34  // FPCCR Address
 
         .equ     osRtxErrorStackOverflow, 1 // Stack overflow
+        .equ     osRtxErrorSVC,           6 // Invalid SVC function called
 
         .section ".rodata"
         .global  irqRtxLib              // Non weak library reference
@@ -71,6 +73,30 @@
         cmp      r1,#0                  // Check SVC number
         bne      SVC_User               // Branch if not SVC 0
 
+    #ifdef RTX_SVC_PTR_CHECK
+
+        ldr      r12,[r0,#16]           // Load function address from stack
+        sub      r1,r12,#1              // Clear T-bit of function address
+        lsls     r2,r1,#30              // Check if 4-byte aligned
+        beq      SVC_PtrBoundsCheck     // Branch if address is aligned
+
+SVC_PtrInvalid:
+        push     {r0,lr}                // Save SP and EXC_RETURN
+        mov      r0,#osRtxErrorSVC      // Parameter: code
+        mov      r1,r12                 // Parameter: object_id
+        bl       osRtxKernelErrorNotify // Call osRtxKernelErrorNotify
+        pop      {r12,lr}               // Restore SP and EXC_RETURN
+        b        SVC_Context            // Branch to context handling
+
+SVC_PtrBoundsCheck:
+        ldr      r2,=Image$$RTX_SVC_VENEERS$$Base
+        ldr      r3,=Image$$RTX_SVC_VENEERS$$Length
+        sub      r2,r1,r2               // Subtract SVC table base address
+        cmp      r2,r3                  // Compare with SVC table boundaries
+        bhs      SVC_PtrInvalid         // Branch if address is out of bounds
+
+    #endif // RTX_SVC_PTR_CHECK
+
         push     {r0,lr}                // Save SP and EXC_RETURN
         ldm      r0,{r0-r3,r12}         // Load function parameters and address from stack
         blx      r12                    // Call service function
@@ -118,13 +144,14 @@
         cbnz     r0,SVC_ContextSaveRegs // Branch when stack check is ok
 
       .if (FPU_USED != 0)
-        mov      r4,r1                  // Save osRtxInfo.thread.run.curr
+        mov      r4,r1                  // Assign osRtxInfo.thread.run.curr to R4
       .endif
         mov      r0,#osRtxErrorStackOverflow // Parameter: r0=code, r1=object_id
         bl       osRtxKernelErrorNotify      // Call osRtxKernelErrorNotify
         ldr      r3,=osRtxInfo+I_T_RUN_OFS   // Load address of osRtxInfo.thread.run
         ldr      r2,[r3,#4]             // Load osRtxInfo.thread.run: next
         str      r2,[r3]                // osRtxInfo.thread.run: curr = next
+        movs     r1,#0                  // Simulate deleted running thread
       .if (FPU_USED != 0)
         ldrb     lr,[r4,#TCB_SF_OFS]    // Load stack frame information
         b        SVC_FP_LazyState       // Branch to FP lazy state handling
@@ -153,9 +180,21 @@
     #endif // RTX_STACK_CHECK
 
 SVC_ContextRestore:
-        ldr      r0,[r2,#TCB_SP_OFS]    // Load SP
+        movs     r4,r2                  // Assign osRtxInfo.thread.run.next to R4, clear Z flag
+    #ifdef RTX_EXECUTION_ZONE
+        ldrb     r0,[r2,#TCB_ZONE_OFS]  // Load osRtxInfo.thread.run.next: zone
+        cbz      r1,SVC_ZoneSetup       // Branch if running thread is deleted (Z flag unchanged)
+        ldrb     r1,[r1,#TCB_ZONE_OFS]  // Load osRtxInfo.thread.run.curr: zone
+        cmp      r0,r1                  // Check if next:zone == curr:zone
+
+SVC_ZoneSetup:
+        it       ne                     // If zone has changed or running thread is deleted
+        blne     osZoneSetup_Callback   //  Setup zone for next thread
+    #endif // RTX_EXECUTION_ZONE
+
+        ldr      r0,[r4,#TCB_SP_OFS]    // Load SP
       .if (FPU_USED != 0)
-        ldrb     r1,[r2,#TCB_SF_OFS]    // Load stack frame information
+        ldrb     r1,[r4,#TCB_SF_OFS]    // Load stack frame information
         orn      lr,r1,#0xFF            // Set EXC_RETURN
         tst      lr,#0x10               // Determine stack frame from EXC_RETURN bit 4
         it       eq                     // If extended stack frame
@@ -222,4 +261,22 @@
         .size    SysTick_Handler, .-SysTick_Handler
 
 
+    #ifdef RTX_SAFETY_FEATURES
+
+        .thumb_func
+        .type    osFaultResume, %function
+        .global  osFaultResume
+        .fnstart
+        .cantunwind
+osFaultResume:
+
+        mrs      r12,psp                // Save PSP to R12
+        b        SVC_Context            // Branch to context handling
+
+        .fnend
+        .size   osFaultResume, .-osFaultResume
+
+    #endif // RTX_SAFETY_FEATURES
+
+
         .end
diff --git a/CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mbl.S b/CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mbl.S
index 74591a6..c10846f 100644
--- a/CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mbl.S
+++ b/CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mbl.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2016-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -37,8 +37,10 @@
         .equ     TCB_SP_OFS,  56        // TCB.SP offset
         .equ     TCB_SF_OFS,  34        // TCB.stack_frame offset
         .equ     TCB_TZM_OFS, 64        // TCB.tz_memory offset
+        .equ     TCB_ZONE_OFS,68        // TCB.zone offset
 
         .equ     osRtxErrorStackOverflow, 1 // Stack overflow
+        .equ     osRtxErrorSVC,           6 // Invalid SVC function called
 
         .section ".rodata"
         .global  irqRtxLib              // Non weak library reference
@@ -71,6 +73,30 @@
         cmp      r1,#0                  // Check SVC number
         bne      SVC_User               // Branch if not SVC 0
 
+    #ifdef RTX_SVC_PTR_CHECK
+
+        subs     r1,r7,#0x01            // Clear T-bit of function address
+        lsls     r2,r1,#29              // Check if 8-byte aligned
+        beq      SVC_PtrBoundsCheck     // Branch if address is aligned
+
+SVC_PtrInvalid:
+        push     {r0,lr}                // Save SP and EXC_RETURN
+        movs     r0,#osRtxErrorSVC      // Parameter: code
+        mov      r1,r7                  // Parameter: object_id
+        bl       osRtxKernelErrorNotify // Call osRtxKernelErrorNotify
+        pop      {r2,r3}                // Restore SP and EXC_RETURN
+        mov      lr,r3                  // Set EXC_RETURN
+        b        SVC_Context            // Branch to context handling
+
+SVC_PtrBoundsCheck:
+        ldr      r2,=Image$$RTX_SVC_VENEERS$$Base
+        ldr      r3,=Image$$RTX_SVC_VENEERS$$Length
+        subs     r2,r1,r2               // Subtract SVC table base address
+        cmp      r2,r3                  // Compare with SVC table boundaries
+        bhs      SVC_PtrInvalid         // Branch if address is out of bounds
+
+    #endif // RTX_SVC_PTR_CHECK
+
         push     {r0,lr}                // Save SP and EXC_RETURN
         ldmia    r0,{r0-r3}             // Load function parameters from stack
         blx      r7                     // Call service function
@@ -129,6 +155,7 @@
         ldr      r3,=osRtxInfo+I_T_RUN_OFS   // Load address of osRtxInfo.thread.run
         ldr      r2,[r3,#4]             // Load osRtxInfo.thread.run: next
         str      r2,[r3]                // osRtxInfo.thread.run: curr = next
+        movs     r1,#0                  // Simulate deleted running thread
         b        SVC_ContextRestore     // Branch to context restore handling
 
 SVC_ContextSaveRegs:
@@ -163,25 +190,37 @@
     #endif // RTX_STACK_CHECK
 
 SVC_ContextRestore:
+        movs     r4,r2                  // Assign osRtxInfo.thread.run.next to R4
+    #ifdef RTX_EXECUTION_ZONE
+        movs     r3,#TCB_ZONE_OFS       // Get TCB.zone offset
+        ldrb     r0,[r2,r3]             // Load osRtxInfo.thread.run.next: zone
+        cbz      r1,SVC_ZoneSetup       // Branch if running thread is deleted
+        ldrb     r1,[r1,r3]             // Load osRtxInfo.thread.run.curr: zone
+        cmp      r0,r1                  // Check if next:zone == curr:zone
+        beq      SVC_ContextRestore_S   // Branch if zone has not changed
+
+SVC_ZoneSetup:
+        bl       osZoneSetup_Callback   // Setup zone for next thread
+    #endif // RTX_EXECUTION_ZONE
+
+SVC_ContextRestore_S:
     #if (DOMAIN_NS != 0)
-        ldr      r0,[r2,#TCB_TZM_OFS]   // Load TrustZone memory identifier
+        ldr      r0,[r4,#TCB_TZM_OFS]   // Load TrustZone memory identifier
         cbz      r0,SVC_ContextRestore_NS // Branch if there is no secure context
-        push     {r2,r3}                // Save registers
         bl       TZ_LoadContext_S       // Load secure context
-        pop      {r2,r3}                // Restore registers
     #endif
 
 SVC_ContextRestore_NS:
-        ldr      r0,[r2,#TCB_SM_OFS]    // Load stack memory base
+        ldr      r0,[r4,#TCB_SM_OFS]    // Load stack memory base
         msr      psplim,r0              // Set PSPLIM
-        mov      r0,r2                  // osRtxInfo.thread.run.next
+        mov      r0,r4                  // osRtxInfo.thread.run.next
         adds     r0,r0,#TCB_SF_OFS      // Adjust address
         ldrb     r3,[r0]                // Load stack frame information
         movs     r0,#0xFF
         mvns     r0,r0                  // R0=0xFFFFFF00
         orrs     r3,r3,r0
         mov      lr,r3                  // Set EXC_RETURN
-        ldr      r0,[r2,#TCB_SP_OFS]    // Load SP
+        ldr      r0,[r4,#TCB_SP_OFS]    // Load SP
     #if (DOMAIN_NS != 0)
         lsls     r3,r3,#25              // Check domain of interrupted thread
         bmi      SVC_ContextRestoreSP   // Branch if secure
@@ -263,4 +302,21 @@
         .size    SysTick_Handler, .-SysTick_Handler
 
 
+    #ifdef RTX_SAFETY_FEATURES
+
+        .thumb_func
+        .type    osFaultResume, %function
+        .global  osFaultResume
+        .fnstart
+        .cantunwind
+osFaultResume:
+
+        b        SVC_Context            // Branch to context handling
+
+        .fnend
+        .size   osFaultResume, .-osFaultResume
+
+    #endif // RTX_SAFETY_FEATURES
+
+
         .end
diff --git a/CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mml.S b/CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mml.S
index f2d6fea..4e3e6dd 100644
--- a/CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mml.S
+++ b/CMSIS/RTOS2/RTX/Source/GCC/irq_armv8mml.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2016-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -49,10 +49,12 @@
         .equ     TCB_SP_OFS,  56        // TCB.SP offset
         .equ     TCB_SF_OFS,  34        // TCB.stack_frame offset
         .equ     TCB_TZM_OFS, 64        // TCB.tz_memory offset
+        .equ     TCB_ZONE_OFS,68        // TCB.zone offset
 
         .equ     FPCCR,     0xE000EF34  // FPCCR Address
 
         .equ     osRtxErrorStackOverflow, 1 // Stack overflow
+        .equ     osRtxErrorSVC,           6 // Invalid SVC function called
 
         .section ".rodata"
         .global  irqRtxLib              // Non weak library reference
@@ -83,6 +85,30 @@
         cmp      r1,#0                  // Check SVC number
         bne      SVC_User               // Branch if not SVC 0
 
+    #ifdef RTX_SVC_PTR_CHECK
+
+        ldr      r12,[r0,#16]           // Load function address from stack
+        sub      r1,r12,#1              // Clear T-bit of function address
+        lsls     r2,r1,#30              // Check if 4-byte aligned
+        beq      SVC_PtrBoundsCheck     // Branch if address is aligned
+
+SVC_PtrInvalid:
+        push     {r0,lr}                // Save SP and EXC_RETURN
+        mov      r0,#osRtxErrorSVC      // Parameter: code
+        mov      r1,r12                 // Parameter: object_id
+        bl       osRtxKernelErrorNotify // Call osRtxKernelErrorNotify
+        pop      {r12,lr}               // Restore SP and EXC_RETURN
+        b        SVC_Context            // Branch to context handling
+
+SVC_PtrBoundsCheck:
+        ldr      r2,=Image$$RTX_SVC_VENEERS$$Base
+        ldr      r3,=Image$$RTX_SVC_VENEERS$$Length
+        sub      r2,r1,r2               // Subtract SVC table base address
+        cmp      r2,r3                  // Compare with SVC table boundaries
+        bhs      SVC_PtrInvalid         // Branch if address is out of bounds
+
+    #endif // RTX_SVC_PTR_CHECK
+
         push     {r0,lr}                // Save SP and EXC_RETURN
         ldm      r0,{r0-r3,r12}         // Load function parameters and address from stack
         blx      r12                    // Call service function
@@ -146,13 +172,14 @@
         cbnz     r0,SVC_ContextSaveRegs // Branch when stack check is ok
 
       .if (FPU_USED != 0) || (MVE_USED != 0)
-        mov      r4,r1                  // Save osRtxInfo.thread.run.curr
+        mov      r4,r1                  // Assign osRtxInfo.thread.run.curr to R4
       .endif
         mov      r0,#osRtxErrorStackOverflow // Parameter: r0=code, r1=object_id
         bl       osRtxKernelErrorNotify      // Call osRtxKernelErrorNotify
         ldr      r3,=osRtxInfo+I_T_RUN_OFS   // Load address of osRtxInfo.thread.run
         ldr      r2,[r3,#4]             // Load osRtxInfo.thread.run: next
         str      r2,[r3]                // osRtxInfo.thread.run: curr = next
+        movs     r1,#0                  // Simulate deleted running thread
       .if (FPU_USED != 0) || (MVE_USED != 0)
         ldrb     lr,[r4,#TCB_SF_OFS]    // Load stack frame information
         b        SVC_FP_LazyState       // Branch to FP lazy state handling
@@ -186,19 +213,29 @@
     #endif // RTX_STACK_CHECK
 
 SVC_ContextRestore:
+        movs     r4,r2                  // Assign osRtxInfo.thread.run.next to R4, clear Z flag
+    #ifdef RTX_EXECUTION_ZONE
+        ldrb     r0,[r2,#TCB_ZONE_OFS]  // Load osRtxInfo.thread.run.next: zone
+        cbz      r1,SVC_ZoneSetup       // Branch if running thread is deleted (Z flag unchanged)
+        ldrb     r1,[r1,#TCB_ZONE_OFS]  // Load osRtxInfo.thread.run.curr: zone
+        cmp      r0,r1                  // Check if next:zone == curr:zone
+
+SVC_ZoneSetup:
+        it       ne                     // If zone has changed or running thread is deleted
+        blne     osZoneSetup_Callback   //  Setup zone for next thread
+    #endif // RTX_EXECUTION_ZONE
+
     #if (DOMAIN_NS != 0)
-        ldr      r0,[r2,#TCB_TZM_OFS]   // Load TrustZone memory identifier
+        ldr      r0,[r4,#TCB_TZM_OFS]   // Load TrustZone memory identifier
         cbz      r0,SVC_ContextRestore_NS // Branch if there is no secure context
-        push     {r2,r3}                // Save registers
         bl       TZ_LoadContext_S       // Load secure context
-        pop      {r2,r3}                // Restore registers
     #endif
 
 SVC_ContextRestore_NS:
-        ldr      r0,[r2,#TCB_SP_OFS]    // Load SP
-        ldr      r1,[r2,#TCB_SM_OFS]    // Load stack memory base
+        ldr      r0,[r4,#TCB_SP_OFS]    // Load SP
+        ldr      r1,[r4,#TCB_SM_OFS]    // Load stack memory base
         msr      psplim,r1              // Set PSPLIM
-        ldrb     r1,[r2,#TCB_SF_OFS]    // Load stack frame information
+        ldrb     r1,[r4,#TCB_SF_OFS]    // Load stack frame information
         orn      lr,r1,#0xFF            // Set EXC_RETURN
     #if (DOMAIN_NS != 0)
         tst      lr,#0x40               // Check domain of interrupted thread
@@ -271,4 +308,22 @@
         .size    SysTick_Handler, .-SysTick_Handler
 
 
+    #ifdef RTX_SAFETY_FEATURES
+
+        .thumb_func
+        .type    osFaultResume, %function
+        .global  osFaultResume
+        .fnstart
+        .cantunwind
+osFaultResume:
+
+        mrs      r12,psp                // Save PSP to R12
+        b        SVC_Context            // Branch to context handling
+
+        .fnend
+        .size   osFaultResume, .-osFaultResume
+
+    #endif // RTX_SAFETY_FEATURES
+
+
         .end
diff --git a/CMSIS/RTOS2/RTX/Source/IAR/irq_armv6m.s b/CMSIS/RTOS2/RTX/Source/IAR/irq_armv6m.s
index a85322d..fa65825 100644
--- a/CMSIS/RTOS2/RTX/Source/IAR/irq_armv6m.s
+++ b/CMSIS/RTOS2/RTX/Source/IAR/irq_armv6m.s
@@ -1,5 +1,5 @@
 ;/*
-; * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+; * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
 ; *
 ; * SPDX-License-Identifier: Apache-2.0
 ; *
@@ -31,9 +31,11 @@
 
 I_T_RUN_OFS     EQU      20                     ; osRtxInfo.thread.run offset
 TCB_SP_OFS      EQU      56                     ; TCB.SP offset
+TCB_ZONE_OFS    EQU      68                     ; TCB.zone offset
 
 osRtxErrorStackOverflow\
                 EQU      1                      ; Stack overflow
+osRtxErrorSVC   EQU      6                      ; Invalid SVC function called
 
 
                 PRESERVE8
@@ -56,6 +58,14 @@
                 IMPORT   osRtxThreadStackCheck
                 IMPORT   osRtxKernelErrorNotify
             #endif
+            #ifdef RTX_SVC_PTR_CHECK
+                IMPORT   |Image$$RTX_SVC_VENEERS$$Base|
+                IMPORT   |Image$$RTX_SVC_VENEERS$$Length|
+                IMPORT   osRtxKernelErrorNotify
+            #endif
+            #ifdef RTX_EXECUTION_ZONE
+                IMPORT   osZoneSetup_Callback
+            #endif
 
                 MOV      R0,LR
                 LSRS     R0,R0,#3               ; Determine return stack from EXC_RETURN bit 2
@@ -69,6 +79,30 @@
                 CMP      R1,#0                  ; Check SVC number
                 BNE      SVC_User               ; Branch if not SVC 0
 
+            #ifdef RTX_SVC_PTR_CHECK
+
+                SUBS     R1,R7,#0x01            ; Clear T-bit of function address
+                LSLS     R2,R1,#29              ; Check if 8-byte aligned
+                BEQ      SVC_PtrBoundsCheck     ; Branch if address is aligned
+
+SVC_PtrInvalid
+                PUSH     {R0,LR}                ; Save SP and EXC_RETURN
+                MOVS     R0,#osRtxErrorSVC      ; Parameter: code
+                MOV      R1,R7                  ; Parameter: object_id
+                BL       osRtxKernelErrorNotify ; Call osRtxKernelErrorNotify
+                POP      {R2,R3}                ; Restore SP and EXC_RETURN
+                MOV      LR,R3                  ; Set EXC_RETURN
+                B        SVC_Context            ; Branch to context handling
+
+SVC_PtrBoundsCheck
+                LDR      R2,=|Image$$RTX_SVC_VENEERS$$Base|
+                LDR      R3,=|Image$$RTX_SVC_VENEERS$$Length|
+                SUBS     R2,R1,R2               ; Subtract SVC table base address
+                CMP      R2,R3                  ; Compare with SVC table boundaries
+                BHS      SVC_PtrInvalid         ; Branch if address is out of bounds
+
+              #endif
+
                 PUSH     {R0,LR}                ; Save SP and EXC_RETURN
                 LDMIA    R0,{R0-R3}             ; Load function parameters from stack
                 BLX      R7                     ; Call service function
@@ -106,6 +140,7 @@
                 LDR      R3,=osRtxInfo+I_T_RUN_OFS   ; Load address of osRtxInfo.thread.run
                 LDR      R2,[R3,#4]             ; Load osRtxInfo.thread.run: next
                 STR      R2,[R3]                ; osRtxInfo.thread.run: curr = next
+                MOVS     R1,#0                  ; Simulate deleted running thread
                 B        SVC_ContextRestore     ; Branch to context restore handling
 
 SVC_ContextSaveRegs
@@ -121,7 +156,22 @@
                 STMIA    R0!,{R4-R7}            ; Save R8..R11
 
 SVC_ContextRestore
-                LDR      R0,[R2,#TCB_SP_OFS]    ; Load SP
+                 MOVS     R4,R2                 ; Assign osRtxInfo.thread.run.next to R4
+            #ifdef RTX_EXECUTION_ZONE
+                 MOVS     R3,#TCB_ZONE_OFS      ; Get TCB.zone offset
+                 LDRB     R0,[R2,R3]            ; Load osRtxInfo.thread.run.next: zone
+                 CMP      R1,#0
+                 BEQ      SVC_ZoneSetup         ; Branch if running thread is deleted
+                 LDRB     R1,[R1,R3]            ; Load osRtxInfo.thread.run.curr: zone
+                 CMP      R0,R1                 ; Check if next:zone == curr:zone
+                 BEQ      SVC_ContextRestore_N  ; Branch if zone has not changed
+
+SVC_ZoneSetup
+                 BL     osZoneSetup_Callback    ;  Setup zone for next thread
+            #endif
+
+SVC_ContextRestore_N
+                LDR      R0,[R4,#TCB_SP_OFS]    ; Load SP
                 ADDS     R0,R0,#16              ; Adjust address
                 LDMIA    R0!,{R4-R7}            ; Restore R8..R11
                 MOV      R8,R4
@@ -184,4 +234,17 @@
                 B        SVC_Context            ; Branch to context handling
 
 
+            #ifdef RTX_SAFETY_FEATURES
+
+osFaultResume   PROC
+                EXPORT   osFaultResume
+
+                B        SVC_Context            ; Branch to context handling
+
+                ALIGN
+                ENDP
+
+            #endif
+
+
                 END
diff --git a/CMSIS/RTOS2/RTX/Source/IAR/irq_armv7m.s b/CMSIS/RTOS2/RTX/Source/IAR/irq_armv7m.s
index 7903d10..89a6a12 100644
--- a/CMSIS/RTOS2/RTX/Source/IAR/irq_armv7m.s
+++ b/CMSIS/RTOS2/RTX/Source/IAR/irq_armv7m.s
@@ -1,5 +1,5 @@
 ;/*
-; * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+; * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
 ; *
 ; * SPDX-License-Identifier: Apache-2.0
 ; *
@@ -38,11 +38,13 @@
 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
+TCB_ZONE_OFS    EQU      68                     ; TCB.zone offset
 
 FPCCR           EQU      0xE000EF34             ; FPCCR Address
 
 osRtxErrorStackOverflow\
                 EQU      1                      ; Stack overflow
+osRtxErrorSVC   EQU      6                      ; Invalid SVC function called
 
 
                 PRESERVE8
@@ -65,6 +67,14 @@
                 IMPORT   osRtxThreadStackCheck
                 IMPORT   osRtxKernelErrorNotify
             #endif
+            #ifdef RTX_SVC_PTR_CHECK
+                IMPORT   |Image$$RTX_SVC_VENEERS$$Base|
+                IMPORT   |Image$$RTX_SVC_VENEERS$$Length|
+                IMPORT   osRtxKernelErrorNotify
+            #endif
+            #ifdef RTX_EXECUTION_ZONE
+                IMPORT   osZoneSetup_Callback
+            #endif
 
                 TST      LR,#0x04               ; Determine return stack from EXC_RETURN bit 2
                 ITE      EQ
@@ -76,6 +86,30 @@
                 CMP      R1,#0                  ; Check SVC number
                 BNE      SVC_User               ; Branch if not SVC 0
 
+            #ifdef RTX_SVC_PTR_CHECK
+
+                LDR      R12,[R0,#16]           ; Load function address from stack
+                SUB      R1,R12,#1              ; Clear T-bit of function address
+                LSLS     R2,R1,#30              ; Check if 4-byte aligned
+                BEQ      SVC_PtrBoundsCheck     ; Branch if address is aligned
+
+SVC_PtrInvalid
+                PUSH     {R0,LR}                ; Save SP and EXC_RETURN
+                MOV      R0,#osRtxErrorSVC      ; Parameter: code
+                MOV      R1,R12                 ; Parameter: object_id
+                BL       osRtxKernelErrorNotify ; Call osRtxKernelErrorNotify
+                POP      {R12,LR}               ; Restore SP and EXC_RETURN
+                B        SVC_Context            ; Branch to context handling
+
+SVC_PtrBoundsCheck
+                LDR      R2,=|Image$$RTX_SVC_VENEERS$$Base|
+                LDR      R3,=|Image$$RTX_SVC_VENEERS$$Length|
+                SUB      R2,R1,R2               ; Subtract SVC table base address
+                CMP      R2,R3                  ; Compare with SVC table boundaries
+                BHS      SVC_PtrInvalid         ; Branch if address is out of bounds
+
+              #endif
+
                 PUSH     {R0,LR}                ; Save SP and EXC_RETURN
                 LDM      R0,{R0-R3,R12}         ; Load function parameters and address from stack
                 BLX      R12                    ; Call service function
@@ -123,13 +157,14 @@
                 CBNZ     R0,SVC_ContextSaveRegs ; Branch when stack check is ok
 
               #if (FPU_USED != 0)
-                MOV      R4,R1                  ; Save osRtxInfo.thread.run.curr
+                MOV      R4,R1                  ; Assign osRtxInfo.thread.run.curr to R4
               #endif
                 MOV      R0,#osRtxErrorStackOverflow ; Parameter: r0=code, r1=object_id
                 BL       osRtxKernelErrorNotify      ; Call osRtxKernelErrorNotify
                 LDR      R3,=osRtxInfo+I_T_RUN_OFS   ; Load address of osRtxInfo.thread.run
                 LDR      R2,[R3,#4]             ; Load osRtxInfo.thread.run: next
                 STR      R2,[R3]                ; osRtxInfo.thread.run: curr = next
+                MOVS     R1,#0                  ; Simulate deleted running thread
               #if (FPU_USED != 0)
                 LDRB     LR,[R4,#TCB_SF_OFS]    ; Load stack frame information
                 B        SVC_FP_LazyState       ; Branch to FP lazy state handling
@@ -158,9 +193,21 @@
             #endif
 
 SVC_ContextRestore
-                LDR      R0,[R2,#TCB_SP_OFS]    ; Load SP
+                 MOVS     R4,R2                 ; Assign osRtxInfo.thread.run.next to R4, clear Z flag
+            #ifdef RTX_EXECUTION_ZONE
+                 LDRB     R0,[R2,#TCB_ZONE_OFS] ; Load osRtxInfo.thread.run.next: zone
+                 CBZ      R1,SVC_ZoneSetup      ; Branch if running thread is deleted (Z flag unchanged)
+                 LDRB     R1,[R1,#TCB_ZONE_OFS] ; Load osRtxInfo.thread.run.curr: zone
+                 CMP      R0,R1                 ; Check if next:zone == curr:zone
+
+SVC_ZoneSetup
+                 IT       NE                    ; If zone has changed or running thread is deleted
+                 BLNE     osZoneSetup_Callback  ;  Setup zone for next thread
+            #endif
+
+                LDR      R0,[R4,#TCB_SP_OFS]    ; Load SP
               #if (FPU_USED != 0)
-                LDRB     R1,[R2,#TCB_SF_OFS]    ; Load stack frame information
+                LDRB     R1,[R4,#TCB_SF_OFS]    ; Load stack frame information
                 ORN      LR,R1,#0xFF            ; Set EXC_RETURN
                 TST      LR,#0x10               ; Determine stack frame from EXC_RETURN bit 4
                 IT       EQ                     ; If extended stack frame
@@ -212,4 +259,18 @@
                 B        SVC_Context            ; Branch to context handling
 
 
+            #ifdef RTX_SAFETY_FEATURES
+
+osFaultResume   PROC
+                EXPORT   osFaultResume
+
+                MRS      R12,PSP                ; Save PSP to R12
+                B        SVC_Context            ; Branch to context handling
+
+                ALIGN
+                ENDP
+
+            #endif
+
+
                 END
diff --git a/CMSIS/RTOS2/RTX/Source/IAR/irq_armv8mbl.s b/CMSIS/RTOS2/RTX/Source/IAR/irq_armv8mbl.s
index 5ee2e8b..362fad1 100644
--- a/CMSIS/RTOS2/RTX/Source/IAR/irq_armv8mbl.s
+++ b/CMSIS/RTOS2/RTX/Source/IAR/irq_armv8mbl.s
@@ -1,5 +1,5 @@
 ;/*
-; * Copyright (c) 2016-2021 Arm Limited. All rights reserved.
+; * Copyright (c) 2016-2023 Arm Limited. All rights reserved.
 ; *
 ; * SPDX-License-Identifier: Apache-2.0
 ; *
@@ -38,9 +38,11 @@
 TCB_SP_OFS      EQU      56                     ; TCB.SP offset
 TCB_SF_OFS      EQU      34                     ; TCB.stack_frame offset
 TCB_TZM_OFS     EQU      64                     ; TCB.tz_memory offset
+TCB_ZONE_OFS    EQU      68                     ; TCB.zone offset
 
 osRtxErrorStackOverflow\
                 EQU      1                      ; Stack overflow
+osRtxErrorSVC   EQU      6                      ; Invalid SVC function called
 
 
                 PRESERVE8
@@ -63,6 +65,14 @@
                 IMPORT   osRtxThreadStackCheck
                 IMPORT   osRtxKernelErrorNotify
             #endif
+            #ifdef RTX_SVC_PTR_CHECK
+                IMPORT   |Image$$RTX_SVC_VENEERS$$Base|
+                IMPORT   |Image$$RTX_SVC_VENEERS$$Length|
+                IMPORT   osRtxKernelErrorNotify
+            #endif
+            #ifdef RTX_EXECUTION_ZONE
+                IMPORT   osZoneSetup_Callback
+            #endif
             #if (DOMAIN_NS != 0)
                 IMPORT   TZ_LoadContext_S
                 IMPORT   TZ_StoreContext_S
@@ -80,6 +90,30 @@
                 CMP      R1,#0                  ; Check SVC number
                 BNE      SVC_User               ; Branch if not SVC 0
 
+            #ifdef RTX_SVC_PTR_CHECK
+
+                SUBS     R1,R7,#0x01            ; Clear T-bit of function address
+                LSLS     R2,R1,#29              ; Check if 8-byte aligned
+                BEQ      SVC_PtrBoundsCheck     ; Branch if address is aligned
+
+SVC_PtrInvalid
+                PUSH     {R0,LR}                ; Save SP and EXC_RETURN
+                MOVS     R0,#osRtxErrorSVC      ; Parameter: code
+                MOV      R1,R7                  ; Parameter: object_id
+                BL       osRtxKernelErrorNotify ; Call osRtxKernelErrorNotify
+                POP      {R2,R3}                ; Restore SP and EXC_RETURN
+                MOV      LR,R3                  ; Set EXC_RETURN
+                B        SVC_Context            ; Branch to context handling
+
+SVC_PtrBoundsCheck
+                LDR      R2,=|Image$$RTX_SVC_VENEERS$$Base|
+                LDR      R3,=|Image$$RTX_SVC_VENEERS$$Length|
+                SUBS     R2,R1,R2               ; Subtract SVC table base address
+                CMP      R2,R3                  ; Compare with SVC table boundaries
+                BHS      SVC_PtrInvalid         ; Branch if address is out of bounds
+
+              #endif
+
                 PUSH     {R0,LR}                ; Save SP and EXC_RETURN
                 LDMIA    R0,{R0-R3}             ; Load function parameters from stack
                 BLX      R7                     ; Call service function
@@ -138,6 +172,7 @@
                 LDR      R3,=osRtxInfo+I_T_RUN_OFS   ; Load address of osRtxInfo.thread.run
                 LDR      R2,[R3,#4]             ; Load osRtxInfo.thread.run: next
                 STR      R2,[R3]                ; osRtxInfo.thread.run: curr = next
+                MOVS     R1,#0                  ; Simulate deleted running thread
                 B        SVC_ContextRestore     ; Branch to context restore handling
 
 SVC_ContextSaveRegs
@@ -172,25 +207,37 @@
             #endif
 
 SVC_ContextRestore
+                 MOVS     R4,R2                 ; Assign osRtxInfo.thread.run.next to R4
+            #ifdef RTX_EXECUTION_ZONE
+                 MOVS     R3,#TCB_ZONE_OFS      ; Get TCB.zone offset
+                 LDRB     R0,[R2,R3]            ; Load osRtxInfo.thread.run.next: zone
+                 CBZ      R1,SVC_ZoneSetup      ; Branch if running thread is deleted
+                 LDRB     R1,[R1,R3]            ; Load osRtxInfo.thread.run.curr: zone
+                 CMP      R0,R1                 ; Check if next:zone == curr:zone
+                 BEQ      SVC_ContextRestore_S  ; Branch if zone has not changed
+
+SVC_ZoneSetup
+                 BL     osZoneSetup_Callback    ;  Setup zone for next thread
+            #endif
+
+SVC_ContextRestore_S
             #if (DOMAIN_NS != 0)
-                LDR      R0,[R2,#TCB_TZM_OFS]   ; Load TrustZone memory identifier
+                LDR      R0,[R4,#TCB_TZM_OFS]   ; Load TrustZone memory identifier
                 CBZ      R0,SVC_ContextRestore_NS ; Branch if there is no secure context
-                PUSH     {R2,R3}                ; Save registers
                 BL       TZ_LoadContext_S       ; Load secure context
-                POP      {R2,R3}                ; Restore registers
             #endif
 
 SVC_ContextRestore_NS
-                LDR      R0,[R2,#TCB_SM_OFS]    ; Load stack memory base
+                LDR      R0,[R4,#TCB_SM_OFS]    ; Load stack memory base
                 MSR      PSPLIM,R0              ; Set PSPLIM
-                MOV      R0,R2                  ; osRtxInfo.thread.run.next
+                MOV      R0,R4                  ; osRtxInfo.thread.run.next
                 ADDS     R0,R0,#TCB_SF_OFS      ; Adjust address
                 LDRB     R3,[R0]                ; Load stack frame information
                 MOVS     R0,#0xFF
                 MVNS     R0,R0                  ; R0=0xFFFFFF00
                 ORRS     R3,R3,R0
                 MOV      LR,R3                  ; Set EXC_RETURN
-                LDR      R0,[R2,#TCB_SP_OFS]    ; Load SP
+                LDR      R0,[R4,#TCB_SP_OFS]    ; Load SP
             #if (DOMAIN_NS != 0)
                 LSLS     R3,R3,#25              ; Check domain of interrupted thread
                 BMI      SVC_ContextRestoreSP   ; Branch if secure
@@ -256,4 +303,17 @@
                 B        SVC_Context            ; Branch to context handling
 
 
+            #ifdef RTX_SAFETY_FEATURES
+
+osFaultResume   PROC
+                EXPORT   osFaultResume
+
+                B        SVC_Context            ; Branch to context handling
+
+                ALIGN
+                ENDP
+
+            #endif
+
+
                 END
diff --git a/CMSIS/RTOS2/RTX/Source/IAR/irq_armv8mml.s b/CMSIS/RTOS2/RTX/Source/IAR/irq_armv8mml.s
index 57733f3..35e8df9 100644
--- a/CMSIS/RTOS2/RTX/Source/IAR/irq_armv8mml.s
+++ b/CMSIS/RTOS2/RTX/Source/IAR/irq_armv8mml.s
@@ -1,5 +1,5 @@
 ;/*
-; * Copyright (c) 2016-2021 Arm Limited. All rights reserved.
+; * Copyright (c) 2016-2023 Arm Limited. All rights reserved.
 ; *
 ; * SPDX-License-Identifier: Apache-2.0
 ; *
@@ -50,11 +50,13 @@
 TCB_SP_OFS      EQU      56                     ; TCB.SP offset
 TCB_SF_OFS      EQU      34                     ; TCB.stack_frame offset
 TCB_TZM_OFS     EQU      64                     ; TCB.tz_memory offset
+TCB_ZONE_OFS    EQU      68                     ; TCB.zone offset
 
 FPCCR           EQU      0xE000EF34             ; FPCCR Address
 
 osRtxErrorStackOverflow\
                 EQU      1                      ; Stack overflow
+osRtxErrorSVC   EQU      6                      ; Invalid SVC function called
 
 
                 PRESERVE8
@@ -77,6 +79,14 @@
                 IMPORT   osRtxThreadStackCheck
                 IMPORT   osRtxKernelErrorNotify
             #endif
+            #ifdef RTX_SVC_PTR_CHECK
+                IMPORT   |Image$$RTX_SVC_VENEERS$$Base|
+                IMPORT   |Image$$RTX_SVC_VENEERS$$Length|
+                IMPORT   osRtxKernelErrorNotify
+            #endif
+            #ifdef RTX_EXECUTION_ZONE
+                IMPORT   osZoneSetup_Callback
+            #endif
             #if (DOMAIN_NS != 0)
                 IMPORT   TZ_LoadContext_S
                 IMPORT   TZ_StoreContext_S
@@ -92,6 +102,30 @@
                 CMP      R1,#0                  ; Check SVC number
                 BNE      SVC_User               ; Branch if not SVC 0
 
+            #ifdef RTX_SVC_PTR_CHECK
+
+                LDR      R12,[R0,#16]           ; Load function address from stack
+                SUB      R1,R12,#1              ; Clear T-bit of function address
+                LSLS     R2,R1,#30              ; Check if 4-byte aligned
+                BEQ      SVC_PtrBoundsCheck     ; Branch if address is aligned
+
+SVC_PtrInvalid
+                PUSH     {R0,LR}                ; Save SP and EXC_RETURN
+                MOV      R0,#osRtxErrorSVC      ; Parameter: code
+                MOV      R1,R12                 ; Parameter: object_id
+                BL       osRtxKernelErrorNotify ; Call osRtxKernelErrorNotify
+                POP      {R12,LR}               ; Restore SP and EXC_RETURN
+                B        SVC_Context            ; Branch to context handling
+
+SVC_PtrBoundsCheck
+                LDR      R2,=|Image$$RTX_SVC_VENEERS$$Base|
+                LDR      R3,=|Image$$RTX_SVC_VENEERS$$Length|
+                SUB      R2,R1,R2               ; Subtract SVC table base address
+                CMP      R2,R3                  ; Compare with SVC table boundaries
+                BHS      SVC_PtrInvalid         ; Branch if address is out of bounds
+
+              #endif
+
                 PUSH     {R0,LR}                ; Save SP and EXC_RETURN
                 LDM      R0,{R0-R3,R12}         ; Load function parameters and address from stack
                 BLX      R12                    ; Call service function
@@ -155,13 +189,14 @@
                 CBNZ     R0,SVC_ContextSaveRegs ; Branch when stack check is ok
 
               #if ((FPU_USED != 0) || (MVE_USED != 0))
-                MOV      R4,R1                  ; Save osRtxInfo.thread.run.curr
+                MOV      R4,R1                  ; Assign osRtxInfo.thread.run.curr to R4
               #endif
                 MOV      R0,#osRtxErrorStackOverflow ; Parameter: r0=code, r1=object_id
                 BL       osRtxKernelErrorNotify      ; Call osRtxKernelErrorNotify
                 LDR      R3,=osRtxInfo+I_T_RUN_OFS   ; Load address of osRtxInfo.thread.run
                 LDR      R2,[R3,#4]             ; Load osRtxInfo.thread.run: next
                 STR      R2,[R3]                ; osRtxInfo.thread.run: curr = next
+                MOVS     R1,#0                  ; Simulate deleted running thread
               #if ((FPU_USED != 0) || (MVE_USED != 0))
                 LDRB     LR,[R4,#TCB_SF_OFS]    ; Load stack frame information
                 B        SVC_FP_LazyState       ; Branch to FP lazy state handling
@@ -196,19 +231,28 @@
             #endif
 
 SVC_ContextRestore
+                 MOVS     R4,R2                 ; Assign osRtxInfo.thread.run.next to R4, clear Z flag
+            #ifdef RTX_EXECUTION_ZONE
+                 LDRB     R0,[R2,#TCB_ZONE_OFS] ; Load osRtxInfo.thread.run.next: zone
+                 CBZ      R1,SVC_ZoneSetup      ; Branch if running thread is deleted (Z flag unchanged)
+                 LDRB     R1,[R1,#TCB_ZONE_OFS] ; Load osRtxInfo.thread.run.curr: zone
+                 CMP      R0,R1                 ; Check if next:zone == curr:zone
+
+SVC_ZoneSetup
+                 IT       NE                    ; If zone has changed or running thread is deleted
+                 BLNE     osZoneSetup_Callback  ;  Setup zone for next thread
+            #endif
             #if (DOMAIN_NS != 0)
-                LDR      R0,[R2,#TCB_TZM_OFS]   ; Load TrustZone memory identifier
-                CBZ      R0,SVC_ContextRestore_NS; Branch if there is no secure context
-                PUSH     {R2,R3}                ; Save registers
+                LDR      R0,[R4,#TCB_TZM_OFS]   ; Load TrustZone memory identifier
+                CBZ      R0,SVC_ContextRestore_NS ; Branch if there is no secure context
                 BL       TZ_LoadContext_S       ; Load secure context
-                POP      {R2,R3}                ; Restore registers
             #endif
 
 SVC_ContextRestore_NS
-                LDR      R0,[R2,#TCB_SP_OFS]    ; Load SP
-                LDR      R1,[R2,#TCB_SM_OFS]    ; Load stack memory base
+                LDR      R0,[R4,#TCB_SP_OFS]    ; Load SP
+                LDR      R1,[R4,#TCB_SM_OFS]    ; Load stack memory base
                 MSR      PSPLIM,R1              ; Set PSPLIM
-                LDRB     R1,[R2,#TCB_SF_OFS]    ; Load stack frame information
+                LDRB     R1,[R4,#TCB_SF_OFS]    ; Load stack frame information
                 ORN      LR,R1,#0xFF            ; Set EXC_RETURN
 
             #if (DOMAIN_NS != 0)
@@ -267,4 +311,18 @@
                 B        SVC_Context            ; Branch to context handling
 
 
+            #ifdef RTX_SAFETY_FEATURES
+
+osFaultResume   PROC
+                EXPORT   osFaultResume
+
+                MRS      R12,PSP                ; Save PSP to R12
+                B        SVC_Context            ; Branch to context handling
+
+                ALIGN
+                ENDP
+
+            #endif
+
+
                 END
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_core_cm.h b/CMSIS/RTOS2/RTX/Source/rtx_core_cm.h
index b1c0156..20a0d8b 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_core_cm.h
+++ b/CMSIS/RTOS2/RTX/Source/rtx_core_cm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -118,6 +118,18 @@
   return ((__get_CONTROL() & 1U) == 0U);
 }
 
+/// Set thread Privileged mode
+/// \param[in]  privileged      true=privileged, false=unprivileged
+__STATIC_INLINE void SetPrivileged (bool_t privileged) {
+  if (privileged) {
+    // Privileged Thread mode & PSP
+    __set_CONTROL(0x02U);
+  } else {
+    // Unprivileged Thread mode & PSP
+    __set_CONTROL(0x03U);
+  }
+}
+
 /// Check if in Exception
 /// \return     true=exception, false=thread
 __STATIC_INLINE bool_t IsException (void) {
@@ -361,8 +373,13 @@
 #define SVC_ArgR(n,a) \
 register uint32_t __r##n __ASM("r"#n) = (uint32_t)a
 
+#if    (defined(RTX_SVC_PTR_CHECK) && !defined(_lint))
 #define SVC_ArgF(f) \
-register uint32_t __rf   __ASM(SVC_RegF) = (uint32_t)f
+register uint32_t __rf   __ASM(SVC_RegF) = (uint32_t)jmpRtx##f
+#else
+#define SVC_ArgF(f) \
+register uint32_t __rf   __ASM(SVC_RegF) = (uint32_t)svcRtx##f
+#endif
 
 #define SVC_In0 "r"(__rf)
 #define SVC_In1 "r"(__rf),"r"(__r0)
@@ -379,71 +396,117 @@
 #define SVC_Call0(in, out, cl)                                                 \
   __ASM volatile ("svc 0" : out : in : cl)
 
+#if    (defined(RTX_SVC_PTR_CHECK) && !defined(_lint))
+#if   ((defined(__ARM_ARCH_7M__)        && (__ARM_ARCH_7M__        != 0)) ||   \
+       (defined(__ARM_ARCH_7EM__)       && (__ARM_ARCH_7EM__       != 0)) ||   \
+       (defined(__ARM_ARCH_8M_MAIN__)   && (__ARM_ARCH_8M_MAIN__   != 0)) ||   \
+       (defined(__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ != 0)))
+#define SVC_Jump(f)                                                            \
+  __ASM volatile (                                                             \
+    ".align 2\n\t"                                                             \
+    "b.w %[adr]" : : [adr] "X" (f)                                             \
+  )
+#elif ((defined(__ARM_ARCH_6M__)        && (__ARM_ARCH_6M__        != 0)) ||   \
+       (defined(__ARM_ARCH_8M_BASE__)   && (__ARM_ARCH_8M_BASE__   != 0)))
+#define SVC_Jump(f)                                                            \
+  __ASM volatile (                                                             \
+    ".align 3\n\t"                                                             \
+    "ldr r7,1f\n\t"                                                            \
+    "bx  r7\n"                                                                 \
+    "1: .word %[adr]" : : [adr] "X" (f)                                        \
+  )
+#endif
+#define SVC_Veneer_Prototye(f)                                                 \
+__STATIC_INLINE void jmpRtx##f (void);
+#define SVC_Veneer_Function(f)                                                 \
+__attribute__((naked,section(".text.os.svc.veneer."#f)))                       \
+__STATIC_INLINE void jmpRtx##f (void) {                                        \
+  SVC_Jump(svcRtx##f);                                                         \
+}
+#else
+#define SVC_Veneer_Prototye(f)
+#define SVC_Veneer_Function(f)
+#endif
+
 #define SVC0_0N(f,t)                                                           \
+SVC_Veneer_Prototye(f)                                                         \
 __attribute__((always_inline))                                                 \
 __STATIC_INLINE t __svc##f (void) {                                            \
-  SVC_ArgF(svcRtx##f);                                                         \
+  SVC_ArgF(f);                                                                 \
   SVC_Call0(SVC_In0, SVC_Out0, SVC_CL1);                                       \
-}
+}                                                                              \
+SVC_Veneer_Function(f)
 
 #define SVC0_0(f,t)                                                            \
+SVC_Veneer_Prototye(f)                                                         \
 __attribute__((always_inline))                                                 \
 __STATIC_INLINE t __svc##f (void) {                                            \
   SVC_ArgN(0);                                                                 \
-  SVC_ArgF(svcRtx##f);                                                         \
+  SVC_ArgF(f);                                                                 \
   SVC_Call0(SVC_In0, SVC_Out1, SVC_CL0);                                       \
   return (t) __r0;                                                             \
-}
+}                                                                              \
+SVC_Veneer_Function(f)
 
 #define SVC0_1N(f,t,t1)                                                        \
+SVC_Veneer_Prototye(f)                                                         \
 __attribute__((always_inline))                                                 \
 __STATIC_INLINE t __svc##f (t1 a1) {                                           \
   SVC_ArgR(0,a1);                                                              \
-  SVC_ArgF(svcRtx##f);                                                         \
+  SVC_ArgF(f);                                                                 \
   SVC_Call0(SVC_In1, SVC_Out1, SVC_CL0);                                       \
-}
+}                                                                              \
+SVC_Veneer_Function(f)
 
 #define SVC0_1(f,t,t1)                                                         \
+SVC_Veneer_Prototye(f)                                                         \
 __attribute__((always_inline))                                                 \
 __STATIC_INLINE t __svc##f (t1 a1) {                                           \
   SVC_ArgR(0,a1);                                                              \
-  SVC_ArgF(svcRtx##f);                                                         \
+  SVC_ArgF(f);                                                                 \
   SVC_Call0(SVC_In1, SVC_Out1, SVC_CL0);                                       \
   return (t) __r0;                                                             \
-}
+}                                                                              \
+SVC_Veneer_Function(f)
 
 #define SVC0_2(f,t,t1,t2)                                                      \
+SVC_Veneer_Prototye(f)                                                         \
 __attribute__((always_inline))                                                 \
 __STATIC_INLINE t __svc##f (t1 a1, t2 a2) {                                    \
   SVC_ArgR(0,a1);                                                              \
   SVC_ArgR(1,a2);                                                              \
-  SVC_ArgF(svcRtx##f);                                                         \
+  SVC_ArgF(f);                                                                 \
   SVC_Call0(SVC_In2, SVC_Out1, SVC_CL0);                                       \
   return (t) __r0;                                                             \
-}
+}                                                                              \
+SVC_Veneer_Function(f)
 
 #define SVC0_3(f,t,t1,t2,t3)                                                   \
+SVC_Veneer_Prototye(f)                                                         \
 __attribute__((always_inline))                                                 \
 __STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) {                             \
   SVC_ArgR(0,a1);                                                              \
   SVC_ArgR(1,a2);                                                              \
   SVC_ArgR(2,a3);                                                              \
-  SVC_ArgF(svcRtx##f);                                                         \
+  SVC_ArgF(f);                                                                 \
   SVC_Call0(SVC_In3, SVC_Out1, SVC_CL0);                                       \
   return (t) __r0;                                                             \
-}
+}                                                                              \
+SVC_Veneer_Function(f)
 
 #define SVC0_4(f,t,t1,t2,t3,t4)                                                \
+SVC_Veneer_Prototye(f)                                                         \
 __attribute__((always_inline))                                                 \
 __STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) {                      \
   SVC_ArgR(0,a1);                                                              \
   SVC_ArgR(1,a2);                                                              \
   SVC_ArgR(2,a3);                                                              \
   SVC_ArgR(3,a4);                                                              \
-  SVC_ArgF(svcRtx##f);                                                         \
+  SVC_ArgF(f);                                                                 \
   SVC_Call0(SVC_In4, SVC_Out1, SVC_CL0);                                       \
   return (t) __r0;                                                             \
-}
+}                                                                              \
+SVC_Veneer_Function(f)
 
 #endif
 
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_evflags.c b/CMSIS/RTOS2/RTX/Source/rtx_evflags.c
index f2300e9..bc47fa1 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_evflags.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_evflags.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -133,6 +133,94 @@
   return event_flags;
 }
 
+/// Verify that Event Flags object pointer is valid.
+/// \param[in]  ef              event flags object.
+/// \return true - valid, false - invalid.
+static bool_t IsEventFlagsPtrValid (const os_event_flags_t *ef) {
+#ifdef RTX_OBJ_PTR_CHECK
+  //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
+  uint32_t cb_start  = (uint32_t)&__os_evflags_cb_start__;
+  uint32_t cb_length = (uint32_t)&__os_evflags_cb_length__;
+
+  // Check the section boundaries
+  if (((uint32_t)ef - cb_start) >= cb_length) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+  // Check the object alignment
+  if ((((uint32_t)ef - cb_start) % sizeof(os_event_flags_t)) != 0U) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+#else
+  // Check NULL pointer
+  if (ef == NULL) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+#endif
+  return TRUE;
+}
+
+
+//  ==== Library functions ====
+
+/// Destroy an Event Flags object.
+/// \param[in]  ef              event flags object.
+static void osRtxEventFlagsDestroy (os_event_flags_t *ef) {
+
+  // Mark object as invalid
+  ef->id = osRtxIdInvalid;
+
+  // Free object memory
+  if ((ef->flags & osRtxFlagSystemObject) != 0U) {
+#ifdef RTX_OBJ_PTR_CHECK
+    (void)osRtxMemoryPoolFree(osRtxInfo.mpi.event_flags, ef);
+#else
+    if (osRtxInfo.mpi.event_flags != NULL) {
+      (void)osRtxMemoryPoolFree(osRtxInfo.mpi.event_flags, ef);
+    } else {
+      (void)osRtxMemoryFree(osRtxInfo.mem.common, ef);
+    }
+#endif
+#ifdef RTX_OBJ_MEM_USAGE
+    osRtxEventFlagsMemUsage.cnt_free++;
+#endif
+  }
+
+  EvrRtxEventFlagsDestroyed(ef);
+}
+
+#ifdef RTX_SAFETY_CLASS
+/// Delete an Event Flags safety class.
+/// \param[in]  safety_class    safety class.
+/// \param[in]  mode            safety mode.
+void osRtxEventFlagsDeleteClass (uint32_t safety_class, uint32_t mode) {
+  os_event_flags_t *ef;
+  os_thread_t      *thread;
+  uint32_t          length;
+
+  //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
+  ef     = (os_event_flags_t *)(uint32_t)&__os_evflags_cb_start__;
+  length =                     (uint32_t)&__os_evflags_cb_length__;
+  while (length >= sizeof(os_event_flags_t)) {
+    if (   (ef->id == osRtxIdEventFlags) &&
+        ((((mode & osSafetyWithSameClass)  != 0U) &&
+          ((ef->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
+         (((mode & osSafetyWithLowerClass) != 0U) &&
+          ((ef->attr >> osRtxAttrClass_Pos) <  (uint8_t)safety_class)))) {
+      while (ef->thread_list != NULL) {
+        thread = osRtxThreadListGet(osRtxObject(ef));
+        osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE);
+      }
+      osRtxEventFlagsDestroy(ef);
+    }
+    length -= sizeof(os_event_flags_t);
+    ef++;
+  }
+}
+#endif
+
 
 //  ==== Post ISR processing ====
 
@@ -163,18 +251,35 @@
 /// Create and Initialize an Event Flags object.
 /// \note API identical to osEventFlagsNew
 static osEventFlagsId_t svcRtxEventFlagsNew (const osEventFlagsAttr_t *attr) {
-  os_event_flags_t *ef;
-  uint8_t           flags;
-  const char       *name;
+  os_event_flags_t  *ef;
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread = osRtxThreadGetRunning();
+  uint32_t           attr_bits;
+#endif
+  uint8_t            flags;
+  const char        *name;
 
   // Process attributes
   if (attr != NULL) {
-    name = attr->name;
+    name      = attr->name;
+#ifdef RTX_SAFETY_CLASS
+    attr_bits = attr->attr_bits;
+#endif
     //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
-    ef   = attr->cb_mem;
+    ef        = attr->cb_mem;
+#ifdef RTX_SAFETY_CLASS
+    if ((attr_bits & osSafetyClass_Valid) != 0U) {
+      if ((thread != NULL) &&
+          ((thread->attr >> osRtxAttrClass_Pos) <
+          (uint8_t)((attr_bits & osSafetyClass_Msk) >> osSafetyClass_Pos))) {
+        EvrRtxEventFlagsError(NULL, (int32_t)osErrorSafetyClass);
+        //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+        return NULL;
+      }
+    }
+#endif
     if (ef != NULL) {
-      //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7]
-      if ((((uint32_t)ef & 3U) != 0U) || (attr->cb_size < sizeof(os_event_flags_t))) {
+      if (!IsEventFlagsPtrValid(ef) || (attr->cb_size != sizeof(os_event_flags_t))) {
         EvrRtxEventFlagsError(NULL, osRtxErrorInvalidControlBlock);
         //lint -e{904} "Return statement before end of function" [MISRA Note 1]
         return NULL;
@@ -187,8 +292,11 @@
       }
     }
   } else {
-    name = NULL;
-    ef   = NULL;
+    name      = NULL;
+#ifdef RTX_SAFETY_CLASS
+    attr_bits = 0U;
+#endif
+    ef        = NULL;
   }
 
   // Allocate object memory if not provided
@@ -196,9 +304,11 @@
     if (osRtxInfo.mpi.event_flags != NULL) {
       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
       ef = osRtxMemoryPoolAlloc(osRtxInfo.mpi.event_flags);
+#ifndef RTX_OBJ_PTR_CHECK
     } else {
       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
       ef = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_event_flags_t), 1U);
+#endif
     }
 #ifdef RTX_OBJ_MEM_USAGE
     if (ef != NULL) {
@@ -219,9 +329,21 @@
     // Initialize control block
     ef->id          = osRtxIdEventFlags;
     ef->flags       = flags;
+    ef->attr        = 0U;
     ef->name        = name;
     ef->thread_list = NULL;
     ef->event_flags = 0U;
+#ifdef RTX_SAFETY_CLASS
+    if ((attr_bits & osSafetyClass_Valid) != 0U) {
+      ef->attr     |= (uint8_t)((attr_bits & osSafetyClass_Msk) >>
+                                (osSafetyClass_Pos - osRtxAttrClass_Pos));
+    } else {
+      // Inherit safety class from the running thread
+      if (thread != NULL) {
+        ef->attr   |= (uint8_t)(thread->attr & osRtxAttrClass_Msk);
+      }
+    }
+#endif
 
     // Register post ISR processing function
     osRtxInfo.post_process.event_flags = osRtxEventFlagsPostProcess;
@@ -240,7 +362,7 @@
   os_event_flags_t *ef = osRtxEventFlagsId(ef_id);
 
   // Check parameters
-  if ((ef == NULL) || (ef->id != osRtxIdEventFlags)) {
+  if (!IsEventFlagsPtrValid(ef) || (ef->id != osRtxIdEventFlags)) {
     EvrRtxEventFlagsGetName(ef, NULL);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return NULL;
@@ -261,13 +383,24 @@
   uint32_t          event_flags0;
 
   // Check parameters
-  if ((ef == NULL) || (ef->id != osRtxIdEventFlags) ||
+  if (!IsEventFlagsPtrValid(ef) || (ef->id != osRtxIdEventFlags) ||
       ((flags & ~(((uint32_t)1U << osRtxEventFlagsLimit) - 1U)) != 0U)) {
     EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return ((uint32_t)osErrorParameter);
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (ef->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxEventFlagsError(ef, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return ((uint32_t)osErrorSafetyClass);
+  }
+#endif
+
   // Set Event Flags
   event_flags = EventFlagsSet(ef, flags);
 
@@ -298,17 +431,31 @@
 /// Clear the specified Event Flags.
 /// \note API identical to osEventFlagsClear
 static uint32_t svcRtxEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) {
-  os_event_flags_t *ef = osRtxEventFlagsId(ef_id);
-  uint32_t          event_flags;
+  os_event_flags_t  *ef = osRtxEventFlagsId(ef_id);
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread;
+#endif
+  uint32_t           event_flags;
 
   // Check parameters
-  if ((ef == NULL) || (ef->id != osRtxIdEventFlags) ||
+  if (!IsEventFlagsPtrValid(ef) || (ef->id != osRtxIdEventFlags) ||
       ((flags & ~(((uint32_t)1U << osRtxEventFlagsLimit) - 1U)) != 0U)) {
     EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return ((uint32_t)osErrorParameter);
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (ef->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxEventFlagsError(ef, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return ((uint32_t)osErrorSafetyClass);
+  }
+#endif
+
   // Clear Event Flags
   event_flags = EventFlagsClear(ef, flags);
 
@@ -323,7 +470,7 @@
   os_event_flags_t *ef = osRtxEventFlagsId(ef_id);
 
   // Check parameters
-  if ((ef == NULL) || (ef->id != osRtxIdEventFlags)) {
+  if (!IsEventFlagsPtrValid(ef) || (ef->id != osRtxIdEventFlags)) {
     EvrRtxEventFlagsGet(ef, 0U);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return 0U;
@@ -342,13 +489,24 @@
   uint32_t          event_flags;
 
   // Check parameters
-  if ((ef == NULL) || (ef->id != osRtxIdEventFlags) ||
+  if (!IsEventFlagsPtrValid(ef) || (ef->id != osRtxIdEventFlags) ||
       ((flags & ~(((uint32_t)1U << osRtxEventFlagsLimit) - 1U)) != 0U)) {
     EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return ((uint32_t)osErrorParameter);
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (ef->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxEventFlagsError(ef, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return ((uint32_t)osErrorSafetyClass);
+  }
+#endif
+
   // Check Event Flags
   event_flags = EventFlagsCheck(ef, flags, options);
   if (event_flags != 0U) {
@@ -384,12 +542,23 @@
   os_thread_t      *thread;
 
   // Check parameters
-  if ((ef == NULL) || (ef->id != osRtxIdEventFlags)) {
+  if (!IsEventFlagsPtrValid(ef) || (ef->id != osRtxIdEventFlags)) {
     EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (ef->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxEventFlagsError(ef, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Unblock waiting threads
   if (ef->thread_list != NULL) {
     do {
@@ -399,22 +568,7 @@
     osRtxThreadDispatch(NULL);
   }
 
-  // Mark object as invalid
-  ef->id = osRtxIdInvalid;
-
-  // Free object memory
-  if ((ef->flags & osRtxFlagSystemObject) != 0U) {
-    if (osRtxInfo.mpi.event_flags != NULL) {
-      (void)osRtxMemoryPoolFree(osRtxInfo.mpi.event_flags, ef);
-    } else {
-      (void)osRtxMemoryFree(osRtxInfo.mem.common, ef);
-    }
-#ifdef RTX_OBJ_MEM_USAGE
-    osRtxEventFlagsMemUsage.cnt_free++;
-#endif
-  }
-
-  EvrRtxEventFlagsDestroyed(ef);
+  osRtxEventFlagsDestroy(ef);
 
   return osOK;
 }
@@ -441,7 +595,7 @@
   uint32_t          event_flags;
 
   // Check parameters
-  if ((ef == NULL) || (ef->id != osRtxIdEventFlags) ||
+  if (!IsEventFlagsPtrValid(ef) || (ef->id != osRtxIdEventFlags) ||
       ((flags & ~(((uint32_t)1U << osRtxEventFlagsLimit) - 1U)) != 0U)) {
     EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
@@ -467,7 +621,7 @@
   uint32_t          event_flags;
 
   // Check parameters
-  if ((ef == NULL) || (ef->id != osRtxIdEventFlags) || (timeout != 0U) ||
+  if (!IsEventFlagsPtrValid(ef) || (ef->id != osRtxIdEventFlags) || (timeout != 0U) ||
       ((flags & ~(((uint32_t)1U << osRtxEventFlagsLimit) - 1U)) != 0U)) {
     EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
@@ -508,10 +662,9 @@
   const char *name;
 
   if (IsException() || IsIrqMasked()) {
-    EvrRtxEventFlagsGetName(ef_id, NULL);
-    name = NULL;
+    name = svcRtxEventFlagsGetName(ef_id);
   } else {
-    name = __svcEventFlagsGetName(ef_id);
+    name =  __svcEventFlagsGetName(ef_id);
   }
   return name;
 }
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_evr.c b/CMSIS/RTOS2/RTX/Source/rtx_evr.c
index 55b55a7..ec0671f 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_evr.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_evr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -59,11 +59,14 @@
 #define EvtRtxKernelSuspended               EventID(EventLevelOp,     EvtRtxKernelNo, 0x10U)
 #define EvtRtxKernelResume                  EventID(EventLevelAPI,    EvtRtxKernelNo, 0x11U)
 #define EvtRtxKernelResumed                 EventID(EventLevelOp,     EvtRtxKernelNo, 0x12U)
+#define EvtRtxKernelProtect                 EventID(EventLevelAPI,    EvtRtxKernelNo, 0x17U)
+#define EvtRtxKernelProtected               EventID(EventLevelOp,     EvtRtxKernelNo, 0x18U)
 #define EvtRtxKernelGetTickCount            EventID(EventLevelAPI,    EvtRtxKernelNo, 0x13U)
 #define EvtRtxKernelGetTickFreq             EventID(EventLevelAPI,    EvtRtxKernelNo, 0x14U)
 #define EvtRtxKernelGetSysTimerCount        EventID(EventLevelAPI,    EvtRtxKernelNo, 0x15U)
 #define EvtRtxKernelGetSysTimerFreq         EventID(EventLevelAPI,    EvtRtxKernelNo, 0x16U)
 #define EvtRtxKernelErrorNotify             EventID(EventLevelError,  EvtRtxKernelNo, 0x19U)
+#define EvtRtxKernelDestroyClass            EventID(EventLevelAPI,    EvtRtxKernelNo, 0x1AU)
 
 /// Event IDs for "RTX Thread"
 #define EvtRtxThreadError                   EventID(EventLevelError,  EvtRtxThreadNo, 0x00U)
@@ -71,6 +74,8 @@
 #define EvtRtxThreadCreated_Addr            EventID(EventLevelOp,     EvtRtxThreadNo, 0x03U)
 #define EvtRtxThreadCreated_Name            EventID(EventLevelOp,     EvtRtxThreadNo, 0x2CU)
 #define EvtRtxThreadGetName                 EventID(EventLevelAPI,    EvtRtxThreadNo, 0x04U)
+#define EvtRtxThreadGetClass                EventID(EventLevelAPI,    EvtRtxThreadNo, 0x30U)
+#define EvtRtxThreadGetZone                 EventID(EventLevelAPI,    EvtRtxThreadNo, 0x31U)
 #define EvtRtxThreadGetId                   EventID(EventLevelAPI,    EvtRtxThreadNo, 0x06U)
 #define EvtRtxThreadGetState                EventID(EventLevelAPI,    EvtRtxThreadNo, 0x07U)
 #define EvtRtxThreadGetStackSize            EventID(EventLevelAPI,    EvtRtxThreadNo, 0x08U)
@@ -95,8 +100,16 @@
 #define EvtRtxThreadExit                    EventID(EventLevelAPI,    EvtRtxThreadNo, 0x1AU)
 #define EvtRtxThreadTerminate               EventID(EventLevelAPI,    EvtRtxThreadNo, 0x1BU)
 #define EvtRtxThreadDestroyed               EventID(EventLevelOp,     EvtRtxThreadNo, 0x1CU)
+#define EvtRtxThreadFeedWatchdog            EventID(EventLevelAPI,    EvtRtxThreadNo, 0x2EU)
+#define EvtRtxThreadFeedWatchdogDone        EventID(EventLevelOp,     EvtRtxThreadNo, 0x2FU)
+#define EvtRtxThreadProtectPrivileged       EventID(EventLevelAPI,    EvtRtxThreadNo, 0x32U)
+#define EvtRtxThreadPrivilegedProtected     EventID(EventLevelOp,     EvtRtxThreadNo, 0x33U)
 #define EvtRtxThreadGetCount                EventID(EventLevelAPI,    EvtRtxThreadNo, 0x1DU)
 #define EvtRtxThreadEnumerate               EventID(EventLevelAPI,    EvtRtxThreadNo, 0x1EU)
+#define EvtRtxThreadSuspendClass            EventID(EventLevelAPI,    EvtRtxThreadNo, 0x34U)
+#define EvtRtxThreadResumeClass             EventID(EventLevelAPI,    EvtRtxThreadNo, 0x35U)
+#define EvtRtxThreadTerminateZone           EventID(EventLevelAPI,    EvtRtxThreadNo, 0x36U)
+#define EvtRtxThreadWatchdogExpired         EventID(EventLevelError,  EvtRtxThreadNo, 0x37U)
 
 /// Event IDs for "RTX Thread Flags"
 #define EvtRtxThreadFlagsError              EventID(EventLevelError,  EvtRtxThreadFlagsNo, 0x00U)
@@ -492,6 +505,24 @@
 }
 #endif
 
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_PROTECT_DISABLE))
+__WEAK void EvrRtxKernelProtect (uint32_t safety_class) {
+#if defined(RTE_Compiler_EventRecorder)
+  (void)EventRecord2(EvtRtxKernelProtect, safety_class, 0U);
+#else
+  (void)safety_class;
+#endif
+}
+#endif
+
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_PROTECTED_DISABLE))
+__WEAK void EvrRtxKernelProtected (void) {
+#if defined(RTE_Compiler_EventRecorder)
+  (void)EventRecord2(EvtRtxKernelProtected, 0U, 0U);
+#endif
+}
+#endif
+
 #if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_TICK_COUNT_DISABLE))
 __WEAK void EvrRtxKernelGetTickCount (uint32_t count) {
 #if defined(RTE_Compiler_EventRecorder)
@@ -543,6 +574,17 @@
 }
 #endif
 
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_DESTROY_CLASS_DISABLE))
+__WEAK void EvrRtxKernelDestroyClass (uint32_t safety_class, uint32_t mode) {
+#if defined(RTE_Compiler_EventRecorder)
+  (void)EventRecord2(EvtRtxKernelDestroyClass, safety_class, mode);
+#else
+  (void)safety_class;
+  (void)mode;
+#endif
+}
+#endif
+
 
 //  ==== Thread Events ====
 
@@ -596,6 +638,28 @@
 }
 #endif
 
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_CLASS_DISABLE))
+__WEAK void EvrRtxThreadGetClass (osThreadId_t thread_id, uint32_t safety_class) {
+#if defined(RTE_Compiler_EventRecorder)
+  (void)EventRecord2(EvtRtxThreadGetClass, (uint32_t)thread_id, safety_class);
+#else
+  (void)thread_id;
+  (void)safety_class;
+#endif
+}
+#endif
+
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_ZONE_DISABLE))
+__WEAK void EvrRtxThreadGetZone (osThreadId_t thread_id, uint32_t zone) {
+#if defined(RTE_Compiler_EventRecorder)
+  (void)EventRecord2(EvtRtxThreadGetZone, (uint32_t)thread_id, zone);
+#else
+  (void)thread_id;
+  (void)zone;
+#endif
+}
+#endif
+
 #if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_ID_DISABLE))
 __WEAK void EvrRtxThreadGetId (osThreadId_t thread_id) {
 #if defined(RTE_Compiler_EventRecorder)
@@ -842,6 +906,40 @@
 }
 #endif
 
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FEED_WATCHDOG_DISABLE))
+__WEAK void EvrRtxThreadFeedWatchdog (uint32_t ticks) {
+#if defined(RTE_Compiler_EventRecorder)
+  (void)EventRecord2(EvtRtxThreadFeedWatchdog, ticks, 0U);
+#else
+  (void)ticks;
+#endif
+}
+#endif
+
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FEED_WATCHDOG_DONE_DISABLE))
+__WEAK void EvrRtxThreadFeedWatchdogDone (void) {
+#if defined(RTE_Compiler_EventRecorder)
+  (void)EventRecord2(EvtRtxThreadFeedWatchdogDone, 0U, 0U);
+#endif
+}
+#endif
+
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_PROTECT_PRIVILEGED_DISABLE))
+__WEAK void EvrRtxThreadProtectPrivileged (void) {
+#if defined(RTE_Compiler_EventRecorder)
+  (void)EventRecord2(EvtRtxThreadProtectPrivileged, 0U, 0U);
+#endif
+}
+#endif
+
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_PRIVILEGED_PROTECTED_DISABLE))
+__WEAK void EvrRtxThreadPrivilegedProtected (void) {
+#if defined(RTE_Compiler_EventRecorder)
+  (void)EventRecord2(EvtRtxThreadPrivilegedProtected, 0U, 0U);
+#endif
+}
+#endif
+
 #if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_COUNT_DISABLE))
 __WEAK void EvrRtxThreadGetCount (uint32_t count) {
 #if defined(RTE_Compiler_EventRecorder)
@@ -864,6 +962,48 @@
 }
 #endif
 
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SUSPEND_CLASS_DISABLE))
+__WEAK void EvrRtxThreadSuspendClass (uint32_t safety_class, uint32_t mode) {
+#if defined(RTE_Compiler_EventRecorder)
+  (void)EventRecord2(EvtRtxThreadSuspendClass, safety_class, (uint32_t)mode);
+#else
+  (void)safety_class;
+  (void)mode;
+#endif
+}
+#endif
+
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_RESUME_CLASS_DISABLE))
+__WEAK void EvrRtxThreadResumeClass (uint32_t safety_class, uint32_t mode) {
+#if defined(RTE_Compiler_EventRecorder)
+  (void)EventRecord2(EvtRtxThreadResumeClass, safety_class, (uint32_t)mode);
+#else
+  (void)safety_class;
+  (void)mode;
+#endif
+}
+#endif
+
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_TERMINATE_ZONE_DISABLE))
+__WEAK void EvrRtxThreadTerminateZone (uint32_t zone) {
+#if defined(RTE_Compiler_EventRecorder)
+  (void)EventRecord2(EvtRtxThreadTerminateZone, zone, 0U);
+#else
+  (void)zone;
+#endif
+}
+#endif
+
+#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_WATCHDOG_EXPIRED_DISABLE))
+__WEAK void EvrRtxThreadWatchdogExpired (osThreadId_t thread_id) {
+#if defined(RTE_Compiler_EventRecorder)
+  (void)EventRecord2(EvtRtxThreadWatchdogExpired, (uint32_t)thread_id, 0U);
+#else
+  (void)thread_id;
+#endif
+}
+#endif
+
 
 //  ==== Thread Flags Events ====
 
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_kernel.c b/CMSIS/RTOS2/RTX/Source/rtx_kernel.c
index f7b24f9..50f3610 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_kernel.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_kernel.c
@@ -76,6 +76,16 @@
     delay = thread->delay;
   }
 
+#ifdef RTX_THREAD_WATCHDOG
+  // Check Thread Watchdog list
+  thread = osRtxInfo.thread.wdog_list;
+  if (thread != NULL) {
+    if (thread->wdog_tick < delay) {
+      delay = thread->wdog_tick;
+    }
+  }
+#endif
+
   // Check Active Timer list
   timer = osRtxInfo.timer.list;
   if (timer != NULL) {
@@ -115,6 +125,7 @@
 #endif
 
   // Initialize osRtxInfo
+  (void)memset(&osRtxInfo.kernel, 0, sizeof(osRtxInfo) - offsetof(osRtxInfo_t, kernel));
 
   osRtxInfo.isr_queue.data = osRtxConfig.isr_queue.data;
   osRtxInfo.isr_queue.max  = osRtxConfig.isr_queue.max;
@@ -274,14 +285,6 @@
   thread = osRtxThreadListGet(&osRtxInfo.thread.ready);
   osRtxThreadSwitch(thread);
 
-  if ((osRtxConfig.flags & osRtxConfigPrivilegedMode) != 0U) {
-    // Privileged Thread mode & PSP
-    __set_CONTROL(0x02U);
-  } else {
-    // Unprivileged Thread mode & PSP
-    __set_CONTROL(0x03U);
-  }
-
   osRtxInfo.kernel.state = osRtxKernelRunning;
 
   EvrRtxKernelStarted();
@@ -296,6 +299,15 @@
 
   switch (osRtxInfo.kernel.state) {
     case osRtxKernelRunning:
+#ifdef RTX_SAFETY_CLASS
+      // Check the safety class
+      if ((osRtxThreadGetRunning()->attr >> osRtxAttrClass_Pos) <
+          (osRtxInfo.kernel.protect >> osRtxKernelProtectClass_Pos)) {
+        EvrRtxKernelError((int32_t)osErrorSafetyClass);
+        lock = (int32_t)osErrorSafetyClass;
+        break;
+      }
+#endif
       osRtxInfo.kernel.state = osRtxKernelLocked;
       EvrRtxKernelLocked(0);
       lock = 0;
@@ -343,6 +355,15 @@
   switch (osRtxInfo.kernel.state) {
     case osRtxKernelRunning:
     case osRtxKernelLocked:
+#ifdef RTX_SAFETY_CLASS
+      // Check the safety class
+      if ((osRtxThreadGetRunning()->attr >> osRtxAttrClass_Pos) <
+          (osRtxInfo.kernel.protect >> osRtxKernelProtectClass_Pos)) {
+        EvrRtxKernelError((int32_t)osErrorSafetyClass);
+        lock_new = (int32_t)osErrorSafetyClass;
+        break;
+      }
+#endif
       switch (lock) {
         case 0:
           osRtxInfo.kernel.state = osRtxKernelRunning;
@@ -379,6 +400,16 @@
     return 0U;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check the safety class
+  if ((osRtxThreadGetRunning()->attr >> osRtxAttrClass_Pos) <
+      (osRtxInfo.kernel.protect >> osRtxKernelProtectClass_Pos)) {
+    EvrRtxKernelError((int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return 0U;
+  }
+#endif
+
   KernelBlock();
 
   osRtxInfo.kernel.state = osRtxKernelSuspended;
@@ -423,6 +454,14 @@
     timer->tick -= ticks;
   }
 
+#ifdef RTX_THREAD_WATCHDOG
+  // Update Thread Watchdog sleep ticks
+  thread = osRtxInfo.thread.wdog_list;
+  if (thread != NULL) {
+    thread->wdog_tick -= ticks;
+  }
+#endif
+
   kernel_tick = osRtxInfo.kernel.tick + sleep_ticks;
   osRtxInfo.kernel.tick += ticks;
 
@@ -436,6 +475,11 @@
     if (osRtxInfo.timer.tick != NULL) {
       osRtxInfo.timer.tick();
     }
+
+#ifdef RTX_THREAD_WATCHDOG
+    // Process Watchdog Timers
+    osRtxThreadWatchdogTick();
+#endif
   }
 
   osRtxInfo.kernel.state = osRtxKernelRunning;
@@ -447,6 +491,196 @@
   EvrRtxKernelResumed();
 }
 
+#ifdef RTX_SAFETY_CLASS
+
+/// Protect the RTOS Kernel scheduler access.
+/// \note API identical to osKernelProtect
+static osStatus_t svcRtxKernelProtect (uint32_t safety_class) {
+  uint32_t   thread_class;
+  osStatus_t status;
+
+  // Check parameters
+  if (safety_class > 0x0FU) {
+    EvrRtxKernelError((int32_t)osErrorParameter);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorParameter;
+  }
+
+  switch (osRtxInfo.kernel.state) {
+    case osRtxKernelInactive:
+      EvrRtxKernelError(osRtxErrorKernelNotReady);
+      status = osError;
+      break;
+    case osRtxKernelReady:
+      osRtxInfo.kernel.protect &= (uint8_t)~osRtxKernelProtectClass_Msk;
+      osRtxInfo.kernel.protect |= (uint8_t)(safety_class << osRtxKernelProtectClass_Pos);
+      EvrRtxKernelProtected();
+      status = osOK;
+      break;
+    case osRtxKernelRunning:
+      // Check the safety class
+      thread_class = (uint32_t)osRtxThreadGetRunning()->attr >> osRtxAttrClass_Pos;
+      if ((safety_class > thread_class) ||
+          (thread_class < ((uint32_t)osRtxInfo.kernel.protect >> osRtxKernelProtectClass_Pos))) {
+        EvrRtxKernelError((int32_t)osErrorSafetyClass);
+        status = osErrorSafetyClass;
+        break;
+      }
+      osRtxInfo.kernel.protect &= (uint8_t)~osRtxKernelProtectClass_Msk;
+      osRtxInfo.kernel.protect |= (uint8_t)(safety_class << osRtxKernelProtectClass_Pos);
+      EvrRtxKernelProtected();
+      status = osOK;
+      break;
+    case osRtxKernelLocked:
+    case osRtxKernelSuspended:
+      EvrRtxKernelError(osRtxErrorKernelNotRunning);
+      status = osError;
+      break;
+    default:
+      // Should never come here
+      status = osError;
+      break;
+  }
+
+  return status;
+}
+
+/// Destroy objects for specified safety classes.
+/// \note API identical to osKernelDestroyClass
+static osStatus_t svcRtxKernelDestroyClass (uint32_t safety_class, uint32_t mode) {
+  os_thread_t *thread;
+  os_thread_t *thread_next;
+
+  // Check parameters
+  if (safety_class > 0x0FU) {
+    EvrRtxKernelError((int32_t)osErrorParameter);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorParameter;
+  }
+
+  // Check running thread safety class (when called from thread)
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) && IsSVCallIrq()) {
+    if ((((mode & osSafetyWithSameClass)  != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) < (uint8_t)safety_class)) ||
+        (((mode & osSafetyWithLowerClass) != 0U) &&
+         (((thread->attr >> osRtxAttrClass_Pos) + 1U) < (uint8_t)safety_class))) {
+      EvrRtxKernelError((int32_t)osErrorSafetyClass);
+      //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+      return osErrorSafetyClass;
+    }
+  }
+
+  // Delete RTOS objects for safety class
+  osRtxMutexDeleteClass(safety_class, mode);
+  osRtxSemaphoreDeleteClass(safety_class, mode);
+  osRtxMemoryPoolDeleteClass(safety_class, mode);
+  osRtxMessageQueueDeleteClass(safety_class, mode);
+  osRtxEventFlagsDeleteClass(safety_class, mode);
+  osRtxTimerDeleteClass(safety_class, mode);
+
+  // Threads in Wait List
+  thread = osRtxInfo.thread.wait_list;
+  while (thread != NULL) {
+    thread_next = thread->delay_next;
+    if ((((mode & osSafetyWithSameClass)  != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
+        (((mode & osSafetyWithLowerClass) != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) <  (uint8_t)safety_class))) {
+      osRtxThreadListRemove(thread);
+      osRtxThreadDelayRemove(thread);
+#ifdef RTX_THREAD_WATCHDOG
+      osRtxThreadWatchdogRemove(thread);
+#endif
+      osRtxMutexOwnerRelease(thread->mutex_list);
+      osRtxThreadJoinWakeup(thread);
+      osRtxThreadDestroy(thread);
+    }
+    thread = thread_next;
+  }
+
+  // Threads in Delay List
+  thread = osRtxInfo.thread.delay_list;
+  while (thread != NULL) {
+    thread_next = thread->delay_next;
+    if ((((mode & osSafetyWithSameClass)  != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
+        (((mode & osSafetyWithLowerClass) != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) <  (uint8_t)safety_class))) {
+      osRtxThreadListRemove(thread);
+      osRtxThreadDelayRemove(thread);
+#ifdef RTX_THREAD_WATCHDOG
+      osRtxThreadWatchdogRemove(thread);
+#endif
+      osRtxMutexOwnerRelease(thread->mutex_list);
+      osRtxThreadJoinWakeup(thread);
+      osRtxThreadDestroy(thread);
+    }
+    thread = thread_next;
+  }
+
+  // Threads in Ready List
+  thread = osRtxInfo.thread.ready.thread_list;
+  while (thread != NULL) {
+    thread_next = thread->thread_next;
+    if ((((mode & osSafetyWithSameClass)  != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
+        (((mode & osSafetyWithLowerClass) != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) <  (uint8_t)safety_class))) {
+      osRtxThreadListRemove(thread);
+#ifdef RTX_THREAD_WATCHDOG
+      osRtxThreadWatchdogRemove(thread);
+#endif
+      osRtxMutexOwnerRelease(thread->mutex_list);
+      osRtxThreadJoinWakeup(thread);
+      osRtxThreadDestroy(thread);
+    }
+    thread = thread_next;
+  }
+
+  // Running Thread
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((((mode & osSafetyWithSameClass)  != 0U) &&
+        ((thread->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
+       (((mode & osSafetyWithLowerClass) != 0U) &&
+        ((thread->attr >> osRtxAttrClass_Pos) <  (uint8_t)safety_class)))) {
+    if ((osRtxKernelGetState() != osRtxKernelRunning) ||
+        (osRtxInfo.thread.ready.thread_list == NULL)) {
+      osRtxThreadDispatch(NULL);
+      EvrRtxKernelError((int32_t)osErrorResource);
+      //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+      return osErrorResource;
+    }
+#ifdef RTX_THREAD_WATCHDOG
+    osRtxThreadWatchdogRemove(thread);
+#endif
+    osRtxMutexOwnerRelease(thread->mutex_list);
+    osRtxThreadJoinWakeup(thread);
+    // Switch to next Ready Thread
+    osRtxThreadSwitch(osRtxThreadListGet(&osRtxInfo.thread.ready));
+    // Update Stack Pointer
+    thread->sp = __get_PSP();
+#ifdef RTX_STACK_CHECK
+    // Check Stack usage
+    if (!osRtxThreadStackCheck(thread)) {
+      osRtxThreadSetRunning(osRtxInfo.thread.run.next);
+      (void)osRtxKernelErrorNotify(osRtxErrorStackOverflow, thread);
+    }
+#endif
+    // Mark running thread as deleted
+    osRtxThreadSetRunning(NULL);
+    // Destroy Thread
+    osRtxThreadDestroy(thread);
+  } else {
+    osRtxThreadDispatch(NULL);
+  }
+
+  return osOK;
+}
+
+#endif
+
 /// Get the RTOS kernel tick count.
 /// \note API identical to osKernelGetTickCount
 static uint32_t svcRtxKernelGetTickCount (void) {
@@ -496,6 +730,10 @@
 SVC0_1 (KernelRestoreLock,      int32_t, int32_t)
 SVC0_0 (KernelSuspend,          uint32_t)
 SVC0_1N(KernelResume,           void, uint32_t)
+#ifdef RTX_SAFETY_CLASS
+SVC0_1 (KernelProtect,          osStatus_t, uint32_t)
+SVC0_2 (KernelDestroyClass,     osStatus_t, uint32_t, uint32_t)
+#endif
 SVC0_0 (KernelGetState,         osKernelState_t)
 SVC0_0 (KernelGetTickCount,     uint32_t)
 SVC0_0 (KernelGetTickFreq,      uint32_t)
@@ -644,6 +882,42 @@
   }
 }
 
+#ifdef RTX_SAFETY_CLASS
+
+/// Protect the RTOS Kernel scheduler access.
+osStatus_t osKernelProtect (uint32_t safety_class) {
+  osStatus_t status;
+
+  EvrRtxKernelProtect(safety_class);
+  if (IsException() || IsIrqMasked()) {
+    EvrRtxKernelError((int32_t)osErrorISR);
+    status = osErrorISR;
+  } else {
+    status = __svcKernelProtect(safety_class);
+  }
+  return status;
+}
+
+/// Destroy RTOS objects for specified safety classes.
+osStatus_t osKernelDestroyClass (uint32_t safety_class, uint32_t mode) {
+  osStatus_t status;
+
+  EvrRtxKernelDestroyClass(safety_class, mode);
+  if (IsException() || IsIrqMasked()) {
+    if (IsTickIrq(osRtxInfo.tick_irqn)) {
+      status = svcRtxKernelDestroyClass(safety_class, mode);
+    } else {
+      EvrRtxKernelError((int32_t)osErrorISR);
+      status = osErrorISR;
+    }
+  } else {
+    status   =  __svcKernelDestroyClass(safety_class, mode);
+  }
+  return status;
+}
+
+#endif
+
 /// Get the RTOS kernel tick count.
 uint32_t osKernelGetTickCount (void) {
   uint32_t count;
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_lib.c b/CMSIS/RTOS2/RTX/Source/rtx_lib.c
index 81ed07d..07a9f48 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_lib.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_lib.c
@@ -126,11 +126,18 @@
 
 // Idle Thread Attributes
 static const osThreadAttr_t os_idle_thread_attr = {
+  //lint -e{835} -e{845} "Zero argument to operator"
 #if defined(OS_IDLE_THREAD_NAME)
   OS_IDLE_THREAD_NAME,
 #else
   NULL,
 #endif
+#ifdef RTX_SAFETY_CLASS
+  osSafetyClass((uint32_t)OS_IDLE_THREAD_CLASS) |
+#endif
+#ifdef RTX_EXECUTION_ZONE
+  osThreadZone((uint32_t)OS_IDLE_THREAD_ZONE)   |
+#endif
   osThreadDetached,
   &os_idle_thread_cb,
   (uint32_t)sizeof(os_idle_thread_cb),
@@ -183,11 +190,18 @@
 
 // Timer Thread Attributes
 static const osThreadAttr_t os_timer_thread_attr = {
+  //lint -e{835} -e{845} "Zero argument to operator"
 #if defined(OS_TIMER_THREAD_NAME)
   OS_TIMER_THREAD_NAME,
 #else
   NULL,
 #endif
+#ifdef RTX_SAFETY_CLASS
+  osSafetyClass((uint32_t)OS_TIMER_THREAD_CLASS) |
+#endif
+#ifdef RTX_EXECUTION_ZONE
+  osThreadZone((uint32_t)OS_TIMER_THREAD_ZONE)   |
+#endif
   osThreadDetached,
   &os_timer_thread_cb,
   (uint32_t)sizeof(os_timer_thread_cb),
@@ -213,7 +227,11 @@
 
 // Timer Message Queue Attributes
 static const osMessageQueueAttr_t os_timer_mq_attr = {
+  //lint -e{835} -e{845} "Zero argument to operator"
   NULL,
+#ifdef RTX_SAFETY_CLASS
+  osSafetyClass((uint32_t)OS_TIMER_THREAD_CLASS) |
+#endif
   0U,
   &os_timer_mq_cb,
   (uint32_t)sizeof(os_timer_mq_cb),
@@ -435,6 +453,24 @@
 #if (OS_STACK_WATERMARK != 0)
   | osRtxConfigStackWatermark
 #endif
+#ifdef RTX_SAFETY_FEATURES
+  | osRtxConfigSafetyFeatures
+ #ifdef RTX_SAFETY_CLASS
+  | osRtxConfigSafetyClass
+ #endif
+ #ifdef RTX_EXECUTION_ZONE
+  | osRtxConfigExecutionZone
+ #endif
+ #ifdef RTX_THREAD_WATCHDOG
+  | osRtxConfigThreadWatchdog
+ #endif
+ #ifdef RTX_OBJ_PTR_CHECK
+  | osRtxConfigObjPtrCheck
+ #endif
+ #ifdef RTX_SVC_PTR_CHECK
+  | osRtxConfigSVCPtrCheck
+ #endif
+#endif
   ,
   (uint32_t)OS_TICK_FREQ,
 #if (OS_ROBIN_ENABLE != 0)
@@ -543,6 +579,31 @@
 extern void * const osRtxUserSVC[];
 __WEAK void * const osRtxUserSVC[1] = { (void *)0 };
 
+#if (defined(RTX_SAFETY_CLASS) && defined(RTX_OBJ_PTR_CHECK) && \
+    !((OS_TIMER_THREAD_STACK_SIZE != 0) && (OS_TIMER_CB_QUEUE != 0)))
+extern void osRtxTimerDeleteClass(uint32_t safety_class, uint32_t mode);
+// Default Timer Delete Class Function.
+__WEAK void osRtxTimerDeleteClass(uint32_t safety_class, uint32_t mode) {
+  (void)safety_class;
+  (void)mode;
+}
+#endif
+
+#ifdef RTX_THREAD_WATCHDOG
+// Default Watchdog Alarm Handler.
+__WEAK uint32_t osWatchdogAlarm_Handler (osThreadId_t thread_id) {
+  (void)thread_id;
+  return 0U;
+}
+#endif
+
+#ifdef RTX_EXECUTION_ZONE
+// Default Zone Setup Function.
+__WEAK void osZoneSetup_Callback (uint32_t zone) {
+  (void)zone;
+}
+#endif
+
 
 // OS Sections
 // ===========
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_lib.h b/CMSIS/RTOS2/RTX/Source/rtx_lib.h
index 54cfcf7..5af8221 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_lib.h
+++ b/CMSIS/RTOS2/RTX/Source/rtx_lib.h
@@ -54,6 +54,75 @@
 #define os_message_queue_t  osRtxMessageQueue_t
 #define os_object_t         osRtxObject_t
 
+
+//  ==== Library sections ====
+
+#if  defined(__CC_ARM) || \
+    (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
+// Referenced through linker
+//lint -esym(528,  __os_thread_cb_start__,    __os_thread_cb_length__)
+//lint -esym(528,  __os_timer_cb_start__,     __os_timer_cb_length__)
+//lint -esym(528,  __os_evflags_cb_start__,   __os_evflags_cb_length__)
+//lint -esym(528,  __os_mutex_cb_start__,     __os_mutex_cb_length__)
+//lint -esym(528,  __os_semaphore_cb_start__, __os_semaphore_cb_length__)
+//lint -esym(528,  __os_mempool_cb_start__,   __os_mempool_cb_length__)
+//lint -esym(528,  __os_msgqueue_cb_start__,  __os_msgqueue_cb_length__)
+// Accessed through linker
+//lint -esym(551,  __os_thread_cb_start__,    __os_thread_cb_length__)
+//lint -esym(551,  __os_timer_cb_start__,     __os_timer_cb_length__)
+//lint -esym(551,  __os_evflags_cb_start__,   __os_evflags_cb_length__)
+//lint -esym(551,  __os_mutex_cb_start__,     __os_mutex_cb_length__)
+//lint -esym(551,  __os_semaphore_cb_start__, __os_semaphore_cb_length__)
+//lint -esym(551,  __os_mempool_cb_start__,   __os_mempool_cb_length__)
+//lint -esym(551,  __os_msgqueue_cb_start__,  __os_msgqueue_cb_length__)
+// Initialized through linker
+//lint -esym(728,  __os_thread_cb_start__,    __os_thread_cb_length__)
+//lint -esym(728,  __os_timer_cb_start__,     __os_timer_cb_length__)
+//lint -esym(728,  __os_evflags_cb_start__,   __os_evflags_cb_length__)
+//lint -esym(728,  __os_mutex_cb_start__,     __os_mutex_cb_length__)
+//lint -esym(728,  __os_semaphore_cb_start__, __os_semaphore_cb_length__)
+//lint -esym(728,  __os_mempool_cb_start__,   __os_mempool_cb_length__)
+//lint -esym(728,  __os_msgqueue_cb_start__,  __os_msgqueue_cb_length__)
+// Global scope
+//lint -esym(9003, __os_thread_cb_start__,    __os_thread_cb_length__)
+//lint -esym(9003, __os_timer_cb_start__,     __os_timer_cb_length__)
+//lint -esym(9003, __os_evflags_cb_start__,   __os_evflags_cb_length__)
+//lint -esym(9003, __os_mutex_cb_start__,     __os_mutex_cb_length__)
+//lint -esym(9003, __os_semaphore_cb_start__, __os_semaphore_cb_length__)
+//lint -esym(9003, __os_mempool_cb_start__,   __os_mempool_cb_length__)
+//lint -esym(9003, __os_msgqueue_cb_start__,  __os_msgqueue_cb_length__)
+static const uint32_t __os_thread_cb_start__     __attribute__((weakref(".bss.os.thread.cb$$Base")));
+static const uint32_t __os_thread_cb_length__    __attribute__((weakref(".bss.os.thread.cb$$Length")));
+static const uint32_t __os_timer_cb_start__      __attribute__((weakref(".bss.os.timer.cb$$Base")));
+static const uint32_t __os_timer_cb_length__     __attribute__((weakref(".bss.os.timer.cb$$Length")));
+static const uint32_t __os_evflags_cb_start__    __attribute__((weakref(".bss.os.evflags.cb$$Base")));
+static const uint32_t __os_evflags_cb_length__   __attribute__((weakref(".bss.os.evflags.cb$$Length")));
+static const uint32_t __os_mutex_cb_start__      __attribute__((weakref(".bss.os.mutex.cb$$Base")));
+static const uint32_t __os_mutex_cb_length__     __attribute__((weakref(".bss.os.mutex.cb$$Length")));
+static const uint32_t __os_semaphore_cb_start__  __attribute__((weakref(".bss.os.semaphore.cb$$Base")));
+static const uint32_t __os_semaphore_cb_length__ __attribute__((weakref(".bss.os.semaphore.cb$$Length")));
+static const uint32_t __os_mempool_cb_start__    __attribute__((weakref(".bss.os.mempool.cb$$Base")));
+static const uint32_t __os_mempool_cb_length__   __attribute__((weakref(".bss.os.mempool.cb$$Length")));
+static const uint32_t __os_msgqueue_cb_start__   __attribute__((weakref(".bss.os.msgqueue.cb$$Base")));
+static const uint32_t __os_msgqueue_cb_length__  __attribute__((weakref(".bss.os.msgqueue.cb$$Length")));
+#else
+extern const uint32_t __os_thread_cb_start__     __attribute__((weak));
+extern const uint32_t __os_thread_cb_length__    __attribute__((weak));
+extern const uint32_t __os_timer_cb_start__      __attribute__((weak));
+extern const uint32_t __os_timer_cb_length__     __attribute__((weak));
+extern const uint32_t __os_evflags_cb_start__    __attribute__((weak));
+extern const uint32_t __os_evflags_cb_length__   __attribute__((weak));
+extern const uint32_t __os_mutex_cb_start__      __attribute__((weak));
+extern const uint32_t __os_mutex_cb_length__     __attribute__((weak));
+extern const uint32_t __os_semaphore_cb_start__  __attribute__((weak));
+extern const uint32_t __os_semaphore_cb_length__ __attribute__((weak));
+extern const uint32_t __os_mempool_cb_start__    __attribute__((weak));
+extern const uint32_t __os_mempool_cb_length__   __attribute__((weak));
+extern const uint32_t __os_msgqueue_cb_start__   __attribute__((weak));
+extern const uint32_t __os_msgqueue_cb_length__  __attribute__((weak));
+#endif
+
+
 //  ==== Inline functions ====
 
 // Thread ID
@@ -175,33 +244,64 @@
 //  ==== Library functions ====
 
 // Kernel Library functions
-extern void         osRtxKernelBeforeInit (void);
+extern void         osRtxKernelBeforeInit  (void);
 
 // Thread Library functions
-extern void         osRtxThreadListPut    (os_object_t *object, os_thread_t *thread);
-extern os_thread_t *osRtxThreadListGet    (os_object_t *object);
-extern void         osRtxThreadListSort   (os_thread_t *thread);
-extern void         osRtxThreadListRemove (os_thread_t *thread);
-extern void         osRtxThreadReadyPut   (os_thread_t *thread);
-extern void         osRtxThreadDelayTick  (void);
-extern uint32_t    *osRtxThreadRegPtr     (const os_thread_t *thread);
-extern void         osRtxThreadSwitch     (os_thread_t *thread);
-extern void         osRtxThreadDispatch   (os_thread_t *thread);
-extern void         osRtxThreadWaitExit   (os_thread_t *thread, uint32_t ret_val, bool_t dispatch);
-extern bool_t       osRtxThreadWaitEnter  (uint8_t state, uint32_t timeout);
+extern void         osRtxThreadListPut     (os_object_t *object, os_thread_t *thread);
+extern os_thread_t *osRtxThreadListGet     (os_object_t *object);
+extern void         osRtxThreadListSort    (os_thread_t *thread);
+extern void         osRtxThreadListRemove  (os_thread_t *thread);
+extern void         osRtxThreadReadyPut    (os_thread_t *thread);
+//lint -esym(759,osRtxThreadDelayRemove)    "Prototype in header"
+//lint -esym(765,osRtxThreadDelayRemove)    "Global scope"
+extern void         osRtxThreadDelayRemove (os_thread_t *thread);
+extern void         osRtxThreadDelayTick   (void);
+extern uint32_t    *osRtxThreadRegPtr      (const os_thread_t *thread);
+extern void         osRtxThreadSwitch      (os_thread_t *thread);
+extern void         osRtxThreadDispatch    (os_thread_t *thread);
+extern void         osRtxThreadWaitExit    (os_thread_t *thread, uint32_t ret_val, bool_t dispatch);
+extern bool_t       osRtxThreadWaitEnter   (uint8_t state, uint32_t timeout);
 #ifdef RTX_STACK_CHECK
-extern bool_t       osRtxThreadStackCheck (const os_thread_t *thread);
+extern bool_t       osRtxThreadStackCheck  (const os_thread_t *thread);
 #endif
-extern void         osRtxThreadBeforeFree (os_thread_t *thread);
-extern bool_t       osRtxThreadStartup    (void);
+#ifdef RTX_THREAD_WATCHDOG
+//lint -esym(759,osRtxThreadWatchdogRemove) "Prototype in header"
+//lint -esym(765,osRtxThreadWatchdogRemove) "Global scope"
+extern void         osRtxThreadWatchdogRemove(const os_thread_t *thread);
+extern void         osRtxThreadWatchdogTick  (void);
+#endif
+//lint -esym(759,osRtxThreadJoinWakeup)     "Prototype in header"
+//lint -esym(765,osRtxThreadJoinWakeup)     "Global scope"
+extern void         osRtxThreadJoinWakeup  (const os_thread_t *thread);
+//lint -esym(759,osRtxThreadDestroy)        "Prototype in header"
+//lint -esym(765,osRtxThreadDestroy)        "Global scope"
+extern void         osRtxThreadDestroy     (os_thread_t *thread);
+extern void         osRtxThreadBeforeFree  (os_thread_t *thread);
+extern bool_t       osRtxThreadStartup     (void);
 
 // Timer Library functions
-extern int32_t osRtxTimerSetup  (void);
-extern void    osRtxTimerThread (void *argument);
+extern int32_t osRtxTimerSetup       (void);
+extern void    osRtxTimerThread      (void *argument);
+#ifdef RTX_SAFETY_CLASS
+extern void    osRtxTimerDeleteClass (uint32_t safety_class, uint32_t mode);
+#endif
 
 // Mutex Library functions
 extern void osRtxMutexOwnerRelease (os_mutex_t *mutex_list);
 extern void osRtxMutexOwnerRestore (const os_mutex_t *mutex, const os_thread_t *thread_wakeup);
+#ifdef RTX_SAFETY_CLASS
+extern void osRtxMutexDeleteClass  (uint32_t safety_class, uint32_t mode);
+#endif
+
+// Semaphore Library functions
+#ifdef RTX_SAFETY_CLASS
+extern void osRtxSemaphoreDeleteClass (uint32_t safety_class, uint32_t mode);
+#endif
+
+// Event Flags Library functions
+#ifdef RTX_SAFETY_CLASS
+extern void osRtxEventFlagsDeleteClass(uint32_t safety_class, uint32_t mode);
+#endif
 
 // Memory Heap Library functions
 extern uint32_t osRtxMemoryInit (void *mem, uint32_t size);
@@ -209,12 +309,18 @@
 extern uint32_t osRtxMemoryFree (void *mem, void *block);
 
 // Memory Pool Library functions
-extern uint32_t   osRtxMemoryPoolInit  (os_mp_info_t *mp_info, uint32_t block_count, uint32_t block_size, void *block_mem);
-extern void      *osRtxMemoryPoolAlloc (os_mp_info_t *mp_info);
-extern osStatus_t osRtxMemoryPoolFree  (os_mp_info_t *mp_info, void *block);
+extern uint32_t   osRtxMemoryPoolInit       (os_mp_info_t *mp_info, uint32_t block_count, uint32_t block_size, void *block_mem);
+extern void      *osRtxMemoryPoolAlloc      (os_mp_info_t *mp_info);
+extern osStatus_t osRtxMemoryPoolFree       (os_mp_info_t *mp_info, void *block);
+#ifdef RTX_SAFETY_CLASS
+extern void       osRtxMemoryPoolDeleteClass(uint32_t safety_class, uint32_t mode);
+#endif
 
 // Message Queue Library functions
 extern int32_t osRtxMessageQueueTimerSetup (void);
+#ifdef RTX_SAFETY_CLASS
+extern void    osRtxMessageQueueDeleteClass(uint32_t safety_class, uint32_t mode);
+#endif
 
 // System Library functions
 extern void osRtxTick_Handler   (void);
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_mempool.c b/CMSIS/RTOS2/RTX/Source/rtx_mempool.c
index 30c9248..6df2f87 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_mempool.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_mempool.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -34,6 +34,38 @@
 #endif
 
 
+//  ==== Helper functions ====
+
+/// Verify that Memory Pool object pointer is valid.
+/// \param[in]  mp              memory pool object.
+/// \return true - valid, false - invalid.
+static bool_t IsMemoryPoolPtrValid (const os_memory_pool_t *mp) {
+#ifdef RTX_OBJ_PTR_CHECK
+  //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
+  uint32_t cb_start  = (uint32_t)&__os_mempool_cb_start__;
+  uint32_t cb_length = (uint32_t)&__os_mempool_cb_length__;
+
+  // Check the section boundaries
+  if (((uint32_t)mp - cb_start) >= cb_length) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+  // Check the object alignment
+  if ((((uint32_t)mp - cb_start) % sizeof(os_memory_pool_t)) != 0U) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+#else
+  // Check NULL pointer
+  if (mp == NULL) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+#endif
+  return TRUE;
+}
+
+
 //  ==== Library functions ====
 
 /// Initialize Memory Pool.
@@ -152,6 +184,67 @@
   return osOK;
 }
 
+/// Destroy a Memory Pool object.
+/// \param[in]  mp              memory pool object.
+static void osRtxMemoryPoolDestroy (os_memory_pool_t *mp) {
+
+  // Mark object as invalid
+  mp->id = osRtxIdInvalid;
+
+  // Free data memory
+  if ((mp->flags & osRtxFlagSystemMemory) != 0U) {
+    (void)osRtxMemoryFree(osRtxInfo.mem.mp_data, mp->mp_info.block_base);
+  }
+
+  // Free object memory
+  if ((mp->flags & osRtxFlagSystemObject) != 0U) {
+#ifdef RTX_OBJ_PTR_CHECK
+    (void)osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp);
+#else
+    if (osRtxInfo.mpi.memory_pool != NULL) {
+      (void)osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp);
+    } else {
+      (void)osRtxMemoryFree(osRtxInfo.mem.common, mp);
+    }
+#endif
+#ifdef RTX_OBJ_MEM_USAGE
+    osRtxMemoryPoolMemUsage.cnt_free++;
+#endif
+  }
+
+  EvrRtxMemoryPoolDestroyed(mp);
+}
+
+#ifdef RTX_SAFETY_CLASS
+/// Delete a Memory Pool safety class.
+/// \param[in]  safety_class    safety class.
+/// \param[in]  mode            safety mode.
+void osRtxMemoryPoolDeleteClass  (uint32_t safety_class, uint32_t mode) {
+  os_memory_pool_t *mp;
+  os_thread_t      *thread;
+  uint32_t          length;
+
+  //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
+  mp     = (os_memory_pool_t *)(uint32_t)&__os_mempool_cb_start__;
+  length =                     (uint32_t)&__os_mempool_cb_length__;
+  while (length >= sizeof(os_memory_pool_t)) {
+    if (   (mp->id == osRtxIdMemoryPool) &&
+        ((((mode & osSafetyWithSameClass)  != 0U) &&
+          ((mp->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
+         (((mode & osSafetyWithLowerClass) != 0U) &&
+          ((mp->attr >> osRtxAttrClass_Pos) <  (uint8_t)safety_class)))) {
+      while (mp->thread_list != NULL) {
+        thread = osRtxThreadListGet(osRtxObject(mp));
+        osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE);
+      }
+      osRtxMemoryPoolDestroy(mp);
+    }
+    length -= sizeof(os_memory_pool_t);
+    mp++;
+  }
+}
+#endif
+
 
 //  ==== Post ISR processing ====
 
@@ -181,14 +274,18 @@
 /// Create and Initialize a Memory Pool object.
 /// \note API identical to osMemoryPoolNew
 static osMemoryPoolId_t svcRtxMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) {
-  os_memory_pool_t *mp;
-  void             *mp_mem;
-  uint32_t          mp_size;
-  uint32_t          b_count;
-  uint32_t          b_size;
-  uint32_t          size;
-  uint8_t           flags;
-  const char       *name;
+  os_memory_pool_t  *mp;
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread = osRtxThreadGetRunning();
+  uint32_t           attr_bits;
+#endif
+  void              *mp_mem;
+  uint32_t           mp_size;
+  uint32_t           b_count;
+  uint32_t           b_size;
+  uint32_t           size;
+  uint8_t            flags;
+  const char        *name;
 
   // Check parameters
   if ((block_count == 0U) || (block_size == 0U) ||
@@ -204,15 +301,28 @@
 
   // Process attributes
   if (attr != NULL) {
-    name    = attr->name;
+    name      = attr->name;
+#ifdef RTX_SAFETY_CLASS
+    attr_bits = attr->attr_bits;
+#endif
     //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
-    mp      = attr->cb_mem;
+    mp        = attr->cb_mem;
     //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
-    mp_mem  = attr->mp_mem;
-    mp_size = attr->mp_size;
+    mp_mem    = attr->mp_mem;
+    mp_size   = attr->mp_size;
+#ifdef RTX_SAFETY_CLASS
+    if ((attr_bits & osSafetyClass_Valid) != 0U) {
+      if ((thread != NULL) &&
+          ((thread->attr >> osRtxAttrClass_Pos) <
+          (uint8_t)((attr_bits & osSafetyClass_Msk) >> osSafetyClass_Pos))) {
+        EvrRtxMemoryPoolError(NULL, (int32_t)osErrorSafetyClass);
+        //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+        return NULL;
+      }
+    }
+#endif
     if (mp != NULL) {
-      //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7]
-      if ((((uint32_t)mp & 3U) != 0U) || (attr->cb_size < sizeof(os_memory_pool_t))) {
+      if (!IsMemoryPoolPtrValid(mp) || (attr->cb_size != sizeof(os_memory_pool_t))) {
         EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidControlBlock);
         //lint -e{904} "Return statement before end of function" [MISRA Note 1]
         return NULL;
@@ -239,9 +349,12 @@
       }
     }
   } else {
-    name   = NULL;
-    mp     = NULL;
-    mp_mem = NULL;
+    name      = NULL;
+#ifdef RTX_SAFETY_CLASS
+    attr_bits = 0U;
+#endif
+    mp        = NULL;
+    mp_mem    = NULL;
   }
 
   // Allocate object memory if not provided
@@ -249,9 +362,11 @@
     if (osRtxInfo.mpi.memory_pool != NULL) {
       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
       mp = osRtxMemoryPoolAlloc(osRtxInfo.mpi.memory_pool);
+#ifndef RTX_OBJ_PTR_CHECK
     } else {
       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
       mp = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_memory_pool_t), 1U);
+#endif
     }
 #ifdef RTX_OBJ_MEM_USAGE
     if (mp != NULL) {
@@ -274,11 +389,15 @@
     mp_mem = osRtxMemoryAlloc(osRtxInfo.mem.mp_data, size, 0U);
     if (mp_mem == NULL) {
       if ((flags & osRtxFlagSystemObject) != 0U) {
+#ifdef RTX_OBJ_PTR_CHECK
+        (void)osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp);
+#else
         if (osRtxInfo.mpi.memory_pool != NULL) {
           (void)osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp);
         } else {
           (void)osRtxMemoryFree(osRtxInfo.mem.common, mp);
         }
+#endif
 #ifdef RTX_OBJ_MEM_USAGE
         osRtxMemoryPoolMemUsage.cnt_free++;
 #endif
@@ -294,8 +413,20 @@
     // Initialize control block
     mp->id          = osRtxIdMemoryPool;
     mp->flags       = flags;
+    mp->attr        = 0U;
     mp->name        = name;
     mp->thread_list = NULL;
+#ifdef RTX_SAFETY_CLASS
+    if ((attr_bits & osSafetyClass_Valid) != 0U) {
+      mp->attr     |= (uint8_t)((attr_bits & osSafetyClass_Msk) >>
+                                (osSafetyClass_Pos - osRtxAttrClass_Pos));
+    } else {
+      // Inherit safety class from the running thread
+      if (thread != NULL) {
+        mp->attr   |= (uint8_t)(thread->attr & osRtxAttrClass_Msk);
+      }
+    }
+#endif
     (void)osRtxMemoryPoolInit(&mp->mp_info, b_count, b_size, mp_mem);
 
     // Register post ISR processing function
@@ -315,7 +446,7 @@
   os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id);
 
   // Check parameters
-  if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
+  if (!IsMemoryPoolPtrValid(mp) || (mp->id != osRtxIdMemoryPool)) {
     EvrRtxMemoryPoolGetName(mp, NULL);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return NULL;
@@ -329,16 +460,30 @@
 /// Allocate a memory block from a Memory Pool.
 /// \note API identical to osMemoryPoolAlloc
 static void *svcRtxMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) {
-  os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id);
-  void             *block;
+  os_memory_pool_t  *mp = osRtxMemoryPoolId(mp_id);
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread;
+#endif
+  void              *block;
 
   // Check parameters
-  if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
+  if (!IsMemoryPoolPtrValid(mp) || (mp->id != osRtxIdMemoryPool)) {
     EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return NULL;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (mp->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxMemoryPoolError(mp, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return NULL;
+  }
+#endif
+
   // Allocate memory
   block = osRtxMemoryPoolAlloc(&mp->mp_info);
   if (block != NULL) {
@@ -370,12 +515,23 @@
   osStatus_t        status;
 
   // Check parameters
-  if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
+  if (!IsMemoryPoolPtrValid(mp) || (mp->id != osRtxIdMemoryPool)) {
     EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (mp->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxMemoryPoolError(mp, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Free memory
   status = osRtxMemoryPoolFree(&mp->mp_info, block);
   if (status == osOK) {
@@ -405,7 +561,7 @@
   os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id);
 
   // Check parameters
-  if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
+  if (!IsMemoryPoolPtrValid(mp) || (mp->id != osRtxIdMemoryPool)) {
     EvrRtxMemoryPoolGetCapacity(mp, 0U);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return 0U;
@@ -422,7 +578,7 @@
   os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id);
 
   // Check parameters
-  if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
+  if (!IsMemoryPoolPtrValid(mp) || (mp->id != osRtxIdMemoryPool)) {
     EvrRtxMemoryPoolGetBlockSize(mp, 0U);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return 0U;
@@ -439,7 +595,7 @@
   os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id);
 
   // Check parameters
-  if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
+  if (!IsMemoryPoolPtrValid(mp) || (mp->id != osRtxIdMemoryPool)) {
     EvrRtxMemoryPoolGetCount(mp, 0U);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return 0U;
@@ -456,7 +612,7 @@
   os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id);
 
   // Check parameters
-  if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
+  if (!IsMemoryPoolPtrValid(mp) || (mp->id != osRtxIdMemoryPool)) {
     EvrRtxMemoryPoolGetSpace(mp, 0U);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return 0U;
@@ -474,12 +630,23 @@
   os_thread_t      *thread;
 
   // Check parameters
-  if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
+  if (!IsMemoryPoolPtrValid(mp) || (mp->id != osRtxIdMemoryPool)) {
     EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (mp->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxMemoryPoolError(mp, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Unblock waiting threads
   if (mp->thread_list != NULL) {
     do {
@@ -489,27 +656,7 @@
     osRtxThreadDispatch(NULL);
   }
 
-  // Mark object as invalid
-  mp->id = osRtxIdInvalid;
-
-  // Free data memory
-  if ((mp->flags & osRtxFlagSystemMemory) != 0U) {
-    (void)osRtxMemoryFree(osRtxInfo.mem.mp_data, mp->mp_info.block_base);
-  }
-
-  // Free object memory
-  if ((mp->flags & osRtxFlagSystemObject) != 0U) {
-    if (osRtxInfo.mpi.memory_pool != NULL) {
-      (void)osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp);
-    } else {
-      (void)osRtxMemoryFree(osRtxInfo.mem.common, mp);
-    }
-#ifdef RTX_OBJ_MEM_USAGE
-    osRtxMemoryPoolMemUsage.cnt_free++;
-#endif
-  }
-
-  EvrRtxMemoryPoolDestroyed(mp);
+  osRtxMemoryPoolDestroy(mp);
 
   return osOK;
 }
@@ -538,7 +685,7 @@
   void             *block;
 
   // Check parameters
-  if ((mp == NULL) || (mp->id != osRtxIdMemoryPool) || (timeout != 0U)) {
+  if (!IsMemoryPoolPtrValid(mp) || (mp->id != osRtxIdMemoryPool) || (timeout != 0U)) {
     EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return NULL;
@@ -563,7 +710,7 @@
   osStatus_t        status;
 
   // Check parameters
-  if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
+  if (!IsMemoryPoolPtrValid(mp) || (mp->id != osRtxIdMemoryPool)) {
     EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
@@ -604,10 +751,9 @@
   const char *name;
 
   if (IsException() || IsIrqMasked()) {
-    EvrRtxMemoryPoolGetName(mp_id, NULL);
-    name = NULL;
+    name = svcRtxMemoryPoolGetName(mp_id);
   } else {
-    name = __svcMemoryPoolGetName(mp_id);
+    name =  __svcMemoryPoolGetName(mp_id);
   }
   return name;
 }
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_msgqueue.c b/CMSIS/RTOS2/RTX/Source/rtx_msgqueue.c
index e2a7910..11e96c2 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_msgqueue.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_msgqueue.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -155,6 +155,99 @@
   }
 }
 
+/// Verify that Message Queue object pointer is valid.
+/// \param[in]  mq              message queue object.
+/// \return true - valid, false - invalid.
+static bool_t IsMessageQueuePtrValid (const os_message_queue_t *mq) {
+#ifdef RTX_OBJ_PTR_CHECK
+  //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
+  uint32_t cb_start  = (uint32_t)&__os_msgqueue_cb_start__;
+  uint32_t cb_length = (uint32_t)&__os_msgqueue_cb_length__;
+
+  // Check the section boundaries
+  if (((uint32_t)mq - cb_start) >= cb_length) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+  // Check the object alignment
+  if ((((uint32_t)mq - cb_start) % sizeof(os_message_queue_t)) != 0U) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+#else
+  // Check NULL pointer
+  if (mq == NULL) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+#endif
+  return TRUE;
+}
+
+
+//  ==== Library functions ====
+
+/// Destroy a Message Queue object.
+/// \param[in]  mq              message queue object.
+static void osRtxMessageQueueDestroy (os_message_queue_t *mq) {
+
+  // Mark object as invalid
+  mq->id = osRtxIdInvalid;
+
+  // Free data memory
+  if ((mq->flags & osRtxFlagSystemMemory) != 0U) {
+    (void)osRtxMemoryFree(osRtxInfo.mem.mq_data, mq->mp_info.block_base);
+  }
+
+  // Free object memory
+  if ((mq->flags & osRtxFlagSystemObject) != 0U) {
+#ifdef RTX_OBJ_PTR_CHECK
+    (void)osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq);
+#else
+    if (osRtxInfo.mpi.message_queue != NULL) {
+      (void)osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq);
+    } else {
+      (void)osRtxMemoryFree(osRtxInfo.mem.common, mq);
+    }
+#endif
+#ifdef RTX_OBJ_MEM_USAGE
+    osRtxMessageQueueMemUsage.cnt_free++;
+#endif
+  }
+
+  EvrRtxMessageQueueDestroyed(mq);
+}
+
+#ifdef RTX_SAFETY_CLASS
+/// Delete a Message Queue safety class.
+/// \param[in]  safety_class    safety class.
+/// \param[in]  mode            safety mode.
+void osRtxMessageQueueDeleteClass (uint32_t safety_class, uint32_t mode) {
+  os_message_queue_t *mq;
+  os_thread_t        *thread;
+  uint32_t            length;
+
+  //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
+  mq     = (os_message_queue_t *)(uint32_t)&__os_msgqueue_cb_start__;
+  length =                       (uint32_t)&__os_msgqueue_cb_length__;
+  while (length >= sizeof(os_message_queue_t)) {
+    if (   (mq->id == osRtxIdMessageQueue) &&
+        ((((mode & osSafetyWithSameClass)  != 0U) &&
+          ((mq->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
+         (((mode & osSafetyWithLowerClass) != 0U) &&
+          ((mq->attr >> osRtxAttrClass_Pos) <  (uint8_t)safety_class)))) {
+      while (mq->thread_list != NULL) {
+        thread = osRtxThreadListGet(osRtxObject(mq));
+        osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE);
+      }
+      osRtxMessageQueueDestroy(mq);
+    }
+    length -= sizeof(os_message_queue_t);
+    mq++;
+  }
+}
+#endif
+
 
 //  ==== Post ISR processing ====
 
@@ -237,6 +330,10 @@
 /// \note API identical to osMessageQueueNew
 static osMessageQueueId_t svcRtxMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) {
   os_message_queue_t *mq;
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t  *thread = osRtxThreadGetRunning();
+  uint32_t            attr_bits;
+#endif
   void               *mq_mem;
   uint32_t            mq_size;
   uint32_t            block_size;
@@ -257,15 +354,28 @@
 
   // Process attributes
   if (attr != NULL) {
-    name    = attr->name;
+    name      = attr->name;
+#ifdef RTX_SAFETY_CLASS
+    attr_bits = attr->attr_bits;
+#endif
     //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
-    mq      = attr->cb_mem;
+    mq        = attr->cb_mem;
     //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
-    mq_mem  = attr->mq_mem;
-    mq_size = attr->mq_size;
+    mq_mem    = attr->mq_mem;
+    mq_size   = attr->mq_size;
+#ifdef RTX_SAFETY_CLASS
+    if ((attr_bits & osSafetyClass_Valid) != 0U) {
+      if ((thread != NULL) &&
+          ((thread->attr >> osRtxAttrClass_Pos) <
+          (uint8_t)((attr_bits & osSafetyClass_Msk) >> osSafetyClass_Pos))) {
+        EvrRtxMessageQueueError(NULL, (int32_t)osErrorSafetyClass);
+        //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+        return NULL;
+      }
+    }
+#endif
     if (mq != NULL) {
-      //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7]
-      if ((((uint32_t)mq & 3U) != 0U) || (attr->cb_size < sizeof(os_message_queue_t))) {
+      if (!IsMessageQueuePtrValid(mq) || (attr->cb_size != sizeof(os_message_queue_t))) {
         EvrRtxMessageQueueError(NULL, osRtxErrorInvalidControlBlock);
         //lint -e{904} "Return statement before end of function" [MISRA Note 1]
         return NULL;
@@ -292,9 +402,12 @@
       }
     }
   } else {
-    name   = NULL;
-    mq     = NULL;
-    mq_mem = NULL;
+    name      = NULL;
+#ifdef RTX_SAFETY_CLASS
+    attr_bits = 0U;
+#endif
+    mq        = NULL;
+    mq_mem    = NULL;
   }
 
   // Allocate object memory if not provided
@@ -302,9 +415,11 @@
     if (osRtxInfo.mpi.message_queue != NULL) {
       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
       mq = osRtxMemoryPoolAlloc(osRtxInfo.mpi.message_queue);
+#ifndef RTX_OBJ_PTR_CHECK
     } else {
       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
       mq = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_message_queue_t), 1U);
+#endif
     }
 #ifdef RTX_OBJ_MEM_USAGE
     if (mq != NULL) {
@@ -327,11 +442,15 @@
     mq_mem = osRtxMemoryAlloc(osRtxInfo.mem.mq_data, size, 0U);
     if (mq_mem == NULL) {
       if ((flags & osRtxFlagSystemObject) != 0U) {
+#ifdef RTX_OBJ_PTR_CHECK
+        (void)osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq);
+#else
         if (osRtxInfo.mpi.message_queue != NULL) {
           (void)osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq);
         } else {
           (void)osRtxMemoryFree(osRtxInfo.mem.common, mq);
         }
+#endif
 #ifdef RTX_OBJ_MEM_USAGE
         osRtxMessageQueueMemUsage.cnt_free++;
 #endif
@@ -347,12 +466,24 @@
     // Initialize control block
     mq->id          = osRtxIdMessageQueue;
     mq->flags       = flags;
+    mq->attr        = 0U;
     mq->name        = name;
     mq->thread_list = NULL;
     mq->msg_size    = msg_size;
     mq->msg_count   = 0U;
     mq->msg_first   = NULL;
     mq->msg_last    = NULL;
+#ifdef RTX_SAFETY_CLASS
+    if ((attr_bits & osSafetyClass_Valid) != 0U) {
+      mq->attr     |= (uint8_t)((attr_bits & osSafetyClass_Msk) >>
+                                (osSafetyClass_Pos - osRtxAttrClass_Pos));
+    } else {
+      // Inherit safety class from the running thread
+      if (thread != NULL) {
+        mq->attr   |= (uint8_t)(thread->attr & osRtxAttrClass_Msk);
+      }
+    }
+#endif
     (void)osRtxMemoryPoolInit(&mq->mp_info, msg_count, block_size, mq_mem);
 
     // Register post ISR processing function
@@ -372,7 +503,7 @@
   os_message_queue_t *mq = osRtxMessageQueueId(mq_id);
 
   // Check parameters
-  if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) {
+  if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue)) {
     EvrRtxMessageQueueGetName(mq, NULL);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return NULL;
@@ -394,12 +525,23 @@
   osStatus_t          status;
 
   // Check parameters
-  if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL)) {
+  if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL)) {
     EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (mq->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxMessageQueueError(mq, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Check if Thread is waiting to receive a Message
   if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessageGet)) {
     EvrRtxMessageQueueInserted(mq, msg_ptr);
@@ -463,12 +605,23 @@
   osStatus_t          status;
 
   // Check parameters
-  if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL)) {
+  if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL)) {
     EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (mq->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxMessageQueueError(mq, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Get Message from Queue
   msg = MessageQueueGet(mq);
   if (msg != NULL) {
@@ -531,7 +684,7 @@
   os_message_queue_t *mq = osRtxMessageQueueId(mq_id);
 
   // Check parameters
-  if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) {
+  if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue)) {
     EvrRtxMessageQueueGetCapacity(mq, 0U);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return 0U;
@@ -548,7 +701,7 @@
   os_message_queue_t *mq = osRtxMessageQueueId(mq_id);
 
   // Check parameters
-  if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) {
+  if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue)) {
     EvrRtxMessageQueueGetMsgSize(mq, 0U);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return 0U;
@@ -565,7 +718,7 @@
   os_message_queue_t *mq = osRtxMessageQueueId(mq_id);
 
   // Check parameters
-  if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) {
+  if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue)) {
     EvrRtxMessageQueueGetCount(mq, 0U);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return 0U;
@@ -582,7 +735,7 @@
   os_message_queue_t *mq = osRtxMessageQueueId(mq_id);
 
   // Check parameters
-  if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) {
+  if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue)) {
     EvrRtxMessageQueueGetSpace(mq, 0U);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return 0U;
@@ -603,12 +756,23 @@
   const void         *ptr;
 
   // Check parameters
-  if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) {
+  if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue)) {
     EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (mq->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxMessageQueueError(mq, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Remove Messages from Queue
   for (;;) {
     // Get Message from Queue
@@ -661,12 +825,23 @@
   os_thread_t        *thread;
 
   // Check parameters
-  if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) {
+  if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue)) {
     EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (mq->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxMessageQueueError(mq, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Unblock waiting threads
   if (mq->thread_list != NULL) {
     do {
@@ -676,27 +851,7 @@
     osRtxThreadDispatch(NULL);
   }
 
-  // Mark object as invalid
-  mq->id = osRtxIdInvalid;
-
-  // Free data memory
-  if ((mq->flags & osRtxFlagSystemMemory) != 0U) {
-    (void)osRtxMemoryFree(osRtxInfo.mem.mq_data, mq->mp_info.block_base);
-  }
-
-  // Free object memory
-  if ((mq->flags & osRtxFlagSystemObject) != 0U) {
-    if (osRtxInfo.mpi.message_queue != NULL) {
-      (void)osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq);
-    } else {
-      (void)osRtxMemoryFree(osRtxInfo.mem.common, mq);
-    }
-#ifdef RTX_OBJ_MEM_USAGE
-    osRtxMessageQueueMemUsage.cnt_free++;
-#endif
-  }
-
-  EvrRtxMessageQueueDestroyed(mq);
+  osRtxMessageQueueDestroy(mq);
 
   return osOK;
 }
@@ -727,7 +882,7 @@
   osStatus_t          status;
 
   // Check parameters
-  if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL) || (timeout != 0U)) {
+  if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL) || (timeout != 0U)) {
     EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
@@ -768,7 +923,7 @@
   osStatus_t          status;
 
   // Check parameters
-  if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL) || (timeout != 0U)) {
+  if (!IsMessageQueuePtrValid(mq) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL) || (timeout != 0U)) {
     EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
@@ -836,10 +991,9 @@
   const char *name;
 
   if (IsException() || IsIrqMasked()) {
-    EvrRtxMessageQueueGetName(mq_id, NULL);
-    name = NULL;
+    name = svcRtxMessageQueueGetName(mq_id);
   } else {
-    name = __svcMessageQueueGetName(mq_id);
+    name =  __svcMessageQueueGetName(mq_id);
   }
   return name;
 }
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_mutex.c b/CMSIS/RTOS2/RTX/Source/rtx_mutex.c
index fb889b4..6667188 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_mutex.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_mutex.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -34,6 +34,38 @@
 #endif
 
 
+//  ==== Helper functions ====
+
+/// Verify that Mutex object pointer is valid.
+/// \param[in]  mutex           mutex object.
+/// \return true - valid, false - invalid.
+static bool_t IsMutexPtrValid (const os_mutex_t *mutex) {
+#ifdef RTX_OBJ_PTR_CHECK
+  //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
+  uint32_t cb_start  = (uint32_t)&__os_mutex_cb_start__;
+  uint32_t cb_length = (uint32_t)&__os_mutex_cb_length__;
+
+  // Check the section boundaries
+  if (((uint32_t)mutex - cb_start) >= cb_length) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+  // Check the object alignment
+  if ((((uint32_t)mutex - cb_start) % sizeof(os_mutex_t)) != 0U) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+#else
+  // Check NULL pointer
+  if (mutex == NULL) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+#endif
+  return TRUE;
+}
+
+
 //  ==== Library functions ====
 
 /// Release Mutex list when owner Thread terminates.
@@ -109,16 +141,125 @@
   }
 }
 
+/// Unlock Mutex owner when mutex is deleted.
+/// \param[in]  mutex           mutex object.
+/// \return true - successful, false - not locked.
+static bool_t osRtxMutexOwnerUnlock (os_mutex_t *mutex) {
+  const os_mutex_t  *mutex0;
+        os_thread_t *thread;
+        int8_t       priority;
+
+  // Check if Mutex is locked
+  if (mutex->lock == 0U) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+
+  thread = mutex->owner_thread;
+
+  // Remove Mutex from Thread owner list
+  if (mutex->owner_next != NULL) {
+    mutex->owner_next->owner_prev = mutex->owner_prev;
+  }
+  if (mutex->owner_prev != NULL) {
+    mutex->owner_prev->owner_next = mutex->owner_next;
+  } else {
+    thread->mutex_list = mutex->owner_next;
+  }
+
+  // Restore owner Thread priority
+  priority = thread->priority_base;
+  mutex0   = thread->mutex_list;
+  // Check Mutexes owned by Thread
+  while (mutex0 != NULL) {
+    if ((mutex0->attr & osMutexPrioInherit) != 0U) {
+      if ((mutex0->thread_list != NULL) && (mutex0->thread_list->priority > priority)) {
+        // Higher priority Thread is waiting for Mutex
+        priority = mutex0->thread_list->priority;
+      }
+    }
+    mutex0 = mutex0->owner_next;
+  }
+  if (thread->priority != priority) {
+    thread->priority = priority;
+    osRtxThreadListSort(thread);
+  }
+
+  // Unblock waiting threads
+  while (mutex->thread_list != NULL) {
+    thread = osRtxThreadListGet(osRtxObject(mutex));
+    osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE);
+  }
+
+  mutex->lock = 0U;
+
+  return TRUE;
+}
+
+/// Destroy a Mutex object.
+/// \param[in]  mutex           mutex object.
+static void osRtxMutexDestroy (os_mutex_t *mutex) {
+
+  // Mark object as invalid
+  mutex->id = osRtxIdInvalid;
+
+  // Free object memory
+  if ((mutex->flags & osRtxFlagSystemObject) != 0U) {
+#ifdef RTX_OBJ_PTR_CHECK
+    (void)osRtxMemoryPoolFree(osRtxInfo.mpi.mutex, mutex);
+#else
+    if (osRtxInfo.mpi.mutex != NULL) {
+      (void)osRtxMemoryPoolFree(osRtxInfo.mpi.mutex, mutex);
+    } else {
+      (void)osRtxMemoryFree(osRtxInfo.mem.common, mutex);
+    }
+#endif
+#ifdef RTX_OBJ_MEM_USAGE
+    osRtxMutexMemUsage.cnt_free++;
+#endif
+  }
+  EvrRtxMutexDestroyed(mutex);
+}
+
+#ifdef RTX_SAFETY_CLASS
+/// Delete a Mutex safety class.
+/// \param[in]  safety_class    safety class.
+/// \param[in]  mode            safety mode.
+void osRtxMutexDeleteClass (uint32_t safety_class, uint32_t mode) {
+  os_mutex_t *mutex;
+  uint32_t    length;
+
+  //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
+  mutex  = (os_mutex_t *)(uint32_t)&__os_mutex_cb_start__;
+  length =               (uint32_t)&__os_mutex_cb_length__;
+  while (length >= sizeof(os_mutex_t)) {
+    if (   (mutex->id == osRtxIdMutex) &&
+        ((((mode & osSafetyWithSameClass)  != 0U) &&
+          ((mutex->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
+         (((mode & osSafetyWithLowerClass) != 0U) &&
+          ((mutex->attr >> osRtxAttrClass_Pos) <  (uint8_t)safety_class)))) {
+      (void)osRtxMutexOwnerUnlock(mutex);
+      osRtxMutexDestroy(mutex);
+    }
+    length -= sizeof(os_mutex_t);
+    mutex++;
+  }
+}
+#endif
+
 
 //  ==== Service Calls ====
 
 /// Create and Initialize a Mutex object.
 /// \note API identical to osMutexNew
 static osMutexId_t svcRtxMutexNew (const osMutexAttr_t *attr) {
-  os_mutex_t *mutex;
-  uint32_t    attr_bits;
-  uint8_t     flags;
-  const char *name;
+  os_mutex_t        *mutex;
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread = osRtxThreadGetRunning();
+#endif
+  uint32_t           attr_bits;
+  uint8_t            flags;
+  const char        *name;
 
   // Process attributes
   if (attr != NULL) {
@@ -126,9 +267,19 @@
     attr_bits = attr->attr_bits;
     //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
     mutex     = attr->cb_mem;
+#ifdef RTX_SAFETY_CLASS
+    if ((attr_bits & osSafetyClass_Valid) != 0U) {
+      if ((thread != NULL) &&
+          ((thread->attr >> osRtxAttrClass_Pos) <
+          (uint8_t)((attr_bits & osSafetyClass_Msk) >> osSafetyClass_Pos))) {
+        EvrRtxMutexError(NULL, (int32_t)osErrorSafetyClass);
+        //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+        return NULL;
+      }
+    }
+#endif
     if (mutex != NULL) {
-      //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7]
-      if ((((uint32_t)mutex & 3U) != 0U) || (attr->cb_size < sizeof(os_mutex_t))) {
+      if (!IsMutexPtrValid(mutex) || (attr->cb_size != sizeof(os_mutex_t))) {
         EvrRtxMutexError(NULL, osRtxErrorInvalidControlBlock);
         //lint -e{904} "Return statement before end of function" [MISRA Note 1]
         return NULL;
@@ -151,9 +302,11 @@
     if (osRtxInfo.mpi.mutex != NULL) {
       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
       mutex = osRtxMemoryPoolAlloc(osRtxInfo.mpi.mutex);
+#ifndef RTX_OBJ_PTR_CHECK
     } else {
       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
       mutex = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_mutex_t), 1U);
+#endif
     }
 #ifdef RTX_OBJ_MEM_USAGE
     if (mutex != NULL) {
@@ -174,14 +327,24 @@
     // Initialize control block
     mutex->id           = osRtxIdMutex;
     mutex->flags        = flags;
-    mutex->attr         = (uint8_t)attr_bits;
+    mutex->attr         = (uint8_t)(attr_bits & ~osRtxAttrClass_Msk);
     mutex->name         = name;
     mutex->thread_list  = NULL;
     mutex->owner_thread = NULL;
     mutex->owner_prev   = NULL;
     mutex->owner_next   = NULL;
     mutex->lock         = 0U;
-
+#ifdef RTX_SAFETY_CLASS
+    if ((attr_bits & osSafetyClass_Valid) != 0U) {
+      mutex->attr      |= (uint8_t)((attr_bits & osSafetyClass_Msk) >>
+                                    (osSafetyClass_Pos - osRtxAttrClass_Pos));
+    } else {
+      // Inherit safety class from the running thread
+      if (thread != NULL) {
+        mutex->attr    |= (uint8_t)(thread->attr & osRtxAttrClass_Msk);
+      }
+    }
+#endif
     EvrRtxMutexCreated(mutex, mutex->name);
   } else {
     EvrRtxMutexError(NULL, (int32_t)osErrorNoMemory);
@@ -196,7 +359,7 @@
   os_mutex_t *mutex = osRtxMutexId(mutex_id);
 
   // Check parameters
-  if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) {
+  if (!IsMutexPtrValid(mutex) || (mutex->id != osRtxIdMutex)) {
     EvrRtxMutexGetName(mutex, NULL);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return NULL;
@@ -223,12 +386,21 @@
   }
 
   // Check parameters
-  if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) {
+  if (!IsMutexPtrValid(mutex) || (mutex->id != osRtxIdMutex)) {
     EvrRtxMutexError(mutex, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  if ((thread->attr >> osRtxAttrClass_Pos) < (mutex->attr >> osRtxAttrClass_Pos)) {
+    EvrRtxMutexError(mutex, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Check if Mutex is not locked
   if (mutex->lock == 0U) {
     // Acquire Mutex
@@ -300,7 +472,7 @@
   }
 
   // Check parameters
-  if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) {
+  if (!IsMutexPtrValid(mutex) || (mutex->id != osRtxIdMutex)) {
     EvrRtxMutexError(mutex, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
@@ -381,7 +553,7 @@
   os_mutex_t *mutex = osRtxMutexId(mutex_id);
 
   // Check parameters
-  if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) {
+  if (!IsMutexPtrValid(mutex) || (mutex->id != osRtxIdMutex)) {
     EvrRtxMutexGetOwner(mutex, NULL);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return NULL;
@@ -403,75 +575,34 @@
 /// \note API identical to osMutexDelete
 static osStatus_t svcRtxMutexDelete (osMutexId_t mutex_id) {
         os_mutex_t  *mutex = osRtxMutexId(mutex_id);
-  const os_mutex_t  *mutex0;
-        os_thread_t *thread;
-        int8_t       priority;
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread;
+#endif
 
   // Check parameters
-  if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) {
+  if (!IsMutexPtrValid(mutex) || (mutex->id != osRtxIdMutex)) {
     EvrRtxMutexError(mutex, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
-  // Check if Mutex is locked
-  if (mutex->lock != 0U) {
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (mutex->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxMutexError(mutex, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
 
-    thread = mutex->owner_thread;
-
-    // Remove Mutex from Thread owner list
-    if (mutex->owner_next != NULL) {
-      mutex->owner_next->owner_prev = mutex->owner_prev;
-    }
-    if (mutex->owner_prev != NULL) {
-      mutex->owner_prev->owner_next = mutex->owner_next;
-    } else {
-      thread->mutex_list = mutex->owner_next;
-    }
-
-    // Restore owner Thread priority
-    priority = thread->priority_base;
-    mutex0   = thread->mutex_list;
-    // Check Mutexes owned by Thread
-    while (mutex0 != NULL) {
-      if ((mutex0->attr & osMutexPrioInherit) != 0U) {
-        if ((mutex0->thread_list != NULL) && (mutex0->thread_list->priority > priority)) {
-          // Higher priority Thread is waiting for Mutex
-          priority = mutex0->thread_list->priority;
-        }
-      }
-      mutex0 = mutex0->owner_next;
-    }
-    if (thread->priority != priority) {
-      thread->priority = priority;
-      osRtxThreadListSort(thread);
-    }
-
-    // Unblock waiting threads
-    while (mutex->thread_list != NULL) {
-      thread = osRtxThreadListGet(osRtxObject(mutex));
-      osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE);
-    }
-
+  // Unlock the mutex owner
+  if (osRtxMutexOwnerUnlock(mutex)) {
     osRtxThreadDispatch(NULL);
   }
 
-  // Mark object as invalid
-  mutex->id = osRtxIdInvalid;
-
-  // Free object memory
-  if ((mutex->flags & osRtxFlagSystemObject) != 0U) {
-    if (osRtxInfo.mpi.mutex != NULL) {
-      (void)osRtxMemoryPoolFree(osRtxInfo.mpi.mutex, mutex);
-    } else {
-      (void)osRtxMemoryFree(osRtxInfo.mem.common, mutex);
-    }
-#ifdef RTX_OBJ_MEM_USAGE
-    osRtxMutexMemUsage.cnt_free++;
-#endif
-  }
-
-  EvrRtxMutexDestroyed(mutex);
+  osRtxMutexDestroy(mutex);
 
   return osOK;
 }
@@ -508,10 +639,9 @@
   const char *name;
 
   if (IsException() || IsIrqMasked()) {
-    EvrRtxMutexGetName(mutex_id, NULL);
-    name = NULL;
+    name = svcRtxMutexGetName(mutex_id);
   } else {
-    name = __svcMutexGetName(mutex_id);
+    name =  __svcMutexGetName(mutex_id);
   }
   return name;
 }
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_semaphore.c b/CMSIS/RTOS2/RTX/Source/rtx_semaphore.c
index b96939a..1dbccf2 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_semaphore.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_semaphore.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -102,6 +102,93 @@
   return ret;
 }
 
+/// Verify that Semaphore object pointer is valid.
+/// \param[in]  semaphore       semaphore object.
+/// \return true - valid, false - invalid.
+static bool_t IsSemaphorePtrValid (const os_semaphore_t *semaphore) {
+#ifdef RTX_OBJ_PTR_CHECK
+  //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
+  uint32_t cb_start  = (uint32_t)&__os_semaphore_cb_start__;
+  uint32_t cb_length = (uint32_t)&__os_semaphore_cb_length__;
+
+  // Check the section boundaries
+  if (((uint32_t)semaphore - cb_start) >= cb_length) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+  // Check the object alignment
+  if ((((uint32_t)semaphore - cb_start) % sizeof(os_semaphore_t)) != 0U) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+#else
+  // Check NULL pointer
+  if (semaphore == NULL) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+#endif
+  return TRUE;
+}
+
+
+//  ==== Library functions ====
+
+/// Destroy a Semaphore object.
+/// \param[in]  semaphore       semaphore object.
+static void osRtxSemaphoreDestroy (os_semaphore_t *semaphore) {
+
+  // Mark object as invalid
+  semaphore->id = osRtxIdInvalid;
+
+  // Free object memory
+  if ((semaphore->flags & osRtxFlagSystemObject) != 0U) {
+#ifdef RTX_OBJ_PTR_CHECK
+    (void)osRtxMemoryPoolFree(osRtxInfo.mpi.semaphore, semaphore);
+#else
+    if (osRtxInfo.mpi.semaphore != NULL) {
+      (void)osRtxMemoryPoolFree(osRtxInfo.mpi.semaphore, semaphore);
+    } else {
+      (void)osRtxMemoryFree(osRtxInfo.mem.common, semaphore);
+    }
+#endif
+#ifdef RTX_OBJ_MEM_USAGE
+    osRtxSemaphoreMemUsage.cnt_free++;
+#endif
+  }
+  EvrRtxSemaphoreDestroyed(semaphore);
+}
+
+#ifdef RTX_SAFETY_CLASS
+/// Delete a Semaphore safety class.
+/// \param[in]  safety_class    safety class.
+/// \param[in]  mode            safety mode.
+void osRtxSemaphoreDeleteClass (uint32_t safety_class, uint32_t mode) {
+  os_semaphore_t *semaphore;
+  os_thread_t    *thread;
+  uint32_t        length;
+
+  //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
+  semaphore = (os_semaphore_t *)(uint32_t)&__os_semaphore_cb_start__;
+  length    =                   (uint32_t)&__os_semaphore_cb_length__;
+  while (length >= sizeof(os_semaphore_t)) {
+    if (   (semaphore->id == osRtxIdSemaphore) &&
+        ((((mode & osSafetyWithSameClass)  != 0U) &&
+          ((semaphore->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
+         (((mode & osSafetyWithLowerClass) != 0U) &&
+          ((semaphore->attr >> osRtxAttrClass_Pos) <  (uint8_t)safety_class)))) {
+      while (semaphore->thread_list != NULL) {
+        thread = osRtxThreadListGet(osRtxObject(semaphore));
+        osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE);
+      }
+      osRtxSemaphoreDestroy(semaphore);
+    }
+    length -= sizeof(os_semaphore_t);
+    semaphore++;
+  }
+}
+#endif
+
 
 //  ==== Post ISR processing ====
 
@@ -128,9 +215,13 @@
 /// Create and Initialize a Semaphore object.
 /// \note API identical to osSemaphoreNew
 static osSemaphoreId_t svcRtxSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) {
-  os_semaphore_t *semaphore;
-  uint8_t         flags;
-  const char     *name;
+  os_semaphore_t    *semaphore;
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread = osRtxThreadGetRunning();
+  uint32_t           attr_bits;
+#endif
+  uint8_t            flags;
+  const char        *name;
 
   // Check parameters
   if ((max_count == 0U) || (max_count > osRtxSemaphoreTokenLimit) || (initial_count > max_count)) {
@@ -142,11 +233,24 @@
   // Process attributes
   if (attr != NULL) {
     name      = attr->name;
+#ifdef RTX_SAFETY_CLASS
+    attr_bits = attr->attr_bits;
+#endif
     //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
     semaphore = attr->cb_mem;
+#ifdef RTX_SAFETY_CLASS
+    if ((attr_bits & osSafetyClass_Valid) != 0U) {
+      if ((thread != NULL) &&
+          ((thread->attr >> osRtxAttrClass_Pos) <
+          (uint8_t)((attr_bits & osSafetyClass_Msk) >> osSafetyClass_Pos))) {
+        EvrRtxSemaphoreError(NULL, (int32_t)osErrorSafetyClass);
+        //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+        return NULL;
+      }
+    }
+#endif
     if (semaphore != NULL) {
-      //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7]
-      if ((((uint32_t)semaphore & 3U) != 0U) || (attr->cb_size < sizeof(os_semaphore_t))) {
+      if (!IsSemaphorePtrValid(semaphore) || (attr->cb_size != sizeof(os_semaphore_t))) {
         EvrRtxSemaphoreError(NULL, osRtxErrorInvalidControlBlock);
         //lint -e{904} "Return statement before end of function" [MISRA Note 1]
         return NULL;
@@ -160,6 +264,9 @@
     }
   } else {
     name      = NULL;
+#ifdef RTX_SAFETY_CLASS
+    attr_bits = 0U;
+#endif
     semaphore = NULL;
   }
 
@@ -168,9 +275,11 @@
     if (osRtxInfo.mpi.semaphore != NULL) {
       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
       semaphore = osRtxMemoryPoolAlloc(osRtxInfo.mpi.semaphore);
+#ifndef RTX_OBJ_PTR_CHECK
     } else {
       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
       semaphore = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_semaphore_t), 1U);
+#endif
     }
 #ifdef RTX_OBJ_MEM_USAGE
     if (semaphore != NULL) {
@@ -191,10 +300,22 @@
     // Initialize control block
     semaphore->id          = osRtxIdSemaphore;
     semaphore->flags       = flags;
+    semaphore->attr        = 0U;
     semaphore->name        = name;
     semaphore->thread_list = NULL;
     semaphore->tokens      = (uint16_t)initial_count;
     semaphore->max_tokens  = (uint16_t)max_count;
+#ifdef RTX_SAFETY_CLASS
+    if ((attr_bits & osSafetyClass_Valid) != 0U) {
+      semaphore->attr     |= (uint8_t)((attr_bits & osSafetyClass_Msk) >>
+                                       (osSafetyClass_Pos - osRtxAttrClass_Pos));
+    } else {
+      // Inherit safety class from the running thread
+      if (thread != NULL) {
+        semaphore->attr   |= (uint8_t)(thread->attr & osRtxAttrClass_Msk);
+      }
+    }
+#endif
 
     // Register post ISR processing function
     osRtxInfo.post_process.semaphore = osRtxSemaphorePostProcess;
@@ -213,7 +334,7 @@
   os_semaphore_t *semaphore = osRtxSemaphoreId(semaphore_id);
 
   // Check parameters
-  if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) {
+  if (!IsSemaphorePtrValid(semaphore) || (semaphore->id != osRtxIdSemaphore)) {
     EvrRtxSemaphoreGetName(semaphore, NULL);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return NULL;
@@ -227,16 +348,30 @@
 /// Acquire a Semaphore token or timeout if no tokens are available.
 /// \note API identical to osSemaphoreAcquire
 static osStatus_t svcRtxSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) {
-  os_semaphore_t *semaphore = osRtxSemaphoreId(semaphore_id);
-  osStatus_t      status;
+  os_semaphore_t    *semaphore = osRtxSemaphoreId(semaphore_id);
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread;
+#endif
+  osStatus_t         status;
 
   // Check parameters
-  if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) {
+  if (!IsSemaphorePtrValid(semaphore) || (semaphore->id != osRtxIdSemaphore)) {
     EvrRtxSemaphoreError(semaphore, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (semaphore->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxSemaphoreError(semaphore, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Try to acquire token
   if (SemaphoreTokenDecrement(semaphore) != 0U) {
     EvrRtxSemaphoreAcquired(semaphore, semaphore->tokens);
@@ -269,12 +404,23 @@
   osStatus_t      status;
 
   // Check parameters
-  if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) {
+  if (!IsSemaphorePtrValid(semaphore) || (semaphore->id != osRtxIdSemaphore)) {
     EvrRtxSemaphoreError(semaphore, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (semaphore->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxSemaphoreError(semaphore, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Check if Thread is waiting for a token
   if (semaphore->thread_list != NULL) {
     EvrRtxSemaphoreReleased(semaphore, semaphore->tokens);
@@ -303,7 +449,7 @@
   os_semaphore_t *semaphore = osRtxSemaphoreId(semaphore_id);
 
   // Check parameters
-  if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) {
+  if (!IsSemaphorePtrValid(semaphore) || (semaphore->id != osRtxIdSemaphore)) {
     EvrRtxSemaphoreGetCount(semaphore, 0U);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return 0U;
@@ -321,12 +467,23 @@
   os_thread_t    *thread;
 
   // Check parameters
-  if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) {
+  if (!IsSemaphorePtrValid(semaphore) || (semaphore->id != osRtxIdSemaphore)) {
     EvrRtxSemaphoreError(semaphore, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (semaphore->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxSemaphoreError(semaphore, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Unblock waiting threads
   if (semaphore->thread_list != NULL) {
     do {
@@ -336,22 +493,7 @@
     osRtxThreadDispatch(NULL);
   }
 
-  // Mark object as invalid
-  semaphore->id = osRtxIdInvalid;
-
-  // Free object memory
-  if ((semaphore->flags & osRtxFlagSystemObject) != 0U) {
-    if (osRtxInfo.mpi.semaphore != NULL) {
-      (void)osRtxMemoryPoolFree(osRtxInfo.mpi.semaphore, semaphore);
-    } else {
-      (void)osRtxMemoryFree(osRtxInfo.mem.common, semaphore);
-    }
-#ifdef RTX_OBJ_MEM_USAGE
-    osRtxSemaphoreMemUsage.cnt_free++;
-#endif
-  }
-
-  EvrRtxSemaphoreDestroyed(semaphore);
+  osRtxSemaphoreDestroy(semaphore);
 
   return osOK;
 }
@@ -377,7 +519,7 @@
   osStatus_t      status;
 
   // Check parameters
-  if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore) || (timeout != 0U)) {
+  if (!IsSemaphorePtrValid(semaphore) || (semaphore->id != osRtxIdSemaphore) || (timeout != 0U)) {
     EvrRtxSemaphoreError(semaphore, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
@@ -404,7 +546,7 @@
   osStatus_t      status;
 
   // Check parameters
-  if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) {
+  if (!IsSemaphorePtrValid(semaphore) || (semaphore->id != osRtxIdSemaphore)) {
     EvrRtxSemaphoreError(semaphore, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
@@ -446,10 +588,9 @@
   const char *name;
 
   if (IsException() || IsIrqMasked()) {
-    EvrRtxSemaphoreGetName(semaphore_id, NULL);
-    name = NULL;
+    name = svcRtxSemaphoreGetName(semaphore_id);
   } else {
-    name = __svcSemaphoreGetName(semaphore_id);
+    name =  __svcSemaphoreGetName(semaphore_id);
   }
   return name;
 }
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_system.c b/CMSIS/RTOS2/RTX/Source/rtx_system.c
index bc969c8..2336039 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_system.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_system.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -132,6 +132,11 @@
     osRtxInfo.timer.tick();
   }
 
+#ifdef RTX_THREAD_WATCHDOG
+  // Process Watchdog Timers
+  osRtxThreadWatchdogTick();
+#endif
+
   // Check Round Robin timeout
   if (osRtxInfo.thread.robin.timeout != 0U) {
     thread = osRtxInfo.thread.run.next;
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_thread.c b/CMSIS/RTOS2/RTX/Source/rtx_thread.c
index 55f5d63..b8f9a8e 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_thread.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_thread.c
@@ -33,6 +33,16 @@
 { 0U, 0U, 0U };
 #endif
 
+//  Runtime Class/Zone assignment table
+#if defined(RTX_EXECUTION_ZONE) && defined(RTX_SAFETY_CLASS)
+static uint8_t ThreadClassTable[64] __attribute__((section(".data.os"))) = { 0U };
+#endif
+
+// Watchdog Alarm Flag
+#if defined(RTX_THREAD_WATCHDOG) && defined(RTX_EXECUTION_ZONE)
+static uint8_t WatchdogAlarmFlag __attribute__((section(".data.os"))) = 0U;
+#endif
+
 
 //  ==== Helper functions ====
 
@@ -133,6 +143,71 @@
   return thread_flags;
 }
 
+/// Verify that Thread object pointer is valid.
+/// \param[in]  thread          thread object.
+/// \return true - valid, false - invalid.
+static bool_t IsThreadPtrValid (const os_thread_t *thread) {
+#ifdef RTX_OBJ_PTR_CHECK
+  //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
+  uint32_t cb_start  = (uint32_t)&__os_thread_cb_start__;
+  uint32_t cb_length = (uint32_t)&__os_thread_cb_length__;
+
+  // Check the section boundaries
+  if (((uint32_t)thread - cb_start) >= cb_length) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+  // Check the object alignment
+  if ((((uint32_t)thread - cb_start) % sizeof(os_thread_t)) != 0U) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+#else
+  // Check NULL pointer
+  if (thread == NULL) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+#endif
+  return TRUE;
+}
+
+#if defined(RTX_EXECUTION_ZONE) && defined(RTX_SAFETY_CLASS)
+/// Check if Thread Zone to Safety Class mapping is valid.
+/// \param[in]  attr_bits       thread attributes.
+/// \param[in]  thread          running thread.
+/// \return true - valid, false - not valid.
+static bool_t IsClassMappingValid (uint32_t attr_bits, const os_thread_t *thread) {
+  uint32_t safety_class;
+  uint32_t zone;
+
+  if ((attr_bits & osThreadZone_Valid) != 0U) {
+    zone = (attr_bits & osThreadZone_Msk) >> osThreadZone_Pos;
+  } else if (thread != NULL) {
+    zone = thread->zone;
+  } else {
+    zone = 0U;
+  }
+
+  if ((attr_bits & osSafetyClass_Valid) != 0U) {
+    safety_class = (attr_bits & osSafetyClass_Msk) >> osSafetyClass_Pos;
+  } else if (thread != NULL) {
+    safety_class = (uint32_t)thread->attr >> osRtxAttrClass_Pos;
+  } else {
+    safety_class = 0U;
+  }
+
+  // Check if zone is free or assigned to class
+  if ((ThreadClassTable[zone] == 0U) ||
+      (ThreadClassTable[zone] == (0x80U | safety_class))) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return TRUE;
+  }
+  // Invalid class to zone mapping
+  return FALSE;
+}
+#endif
+
 
 //  ==== Library functions ====
 
@@ -289,7 +364,7 @@
 
 /// Remove a Thread from the Delay list.
 /// \param[in]  thread          thread object.
-static void osRtxThreadDelayRemove (os_thread_t *thread) {
+void osRtxThreadDelayRemove (os_thread_t *thread) {
 
   if (thread->delay == osWaitForever) {
     if (thread->delay_next != NULL) {
@@ -415,6 +490,7 @@
 void osRtxThreadSwitch (os_thread_t *thread) {
 
   thread->state = osRtxThreadRunning;
+  SetPrivileged((bool_t)((thread->attr & osThreadPrivileged) != 0U));
   osRtxInfo.thread.run.next = thread;
   EvrRtxThreadSwitched(thread);
 }
@@ -524,22 +600,109 @@
 }
 #endif
 
-#ifdef RTX_TF_M_EXTENSION
-/// Get TrustZone Module Identifier of running Thread.
-/// \return TrustZone Module Identifier.
-uint32_t osRtxTzGetModuleId (void) {
-  os_thread_t *thread;
-  uint32_t     tz_module;
+#ifdef RTX_THREAD_WATCHDOG
 
-  thread = osRtxThreadGetRunning();
-  if (thread != NULL) {
-    tz_module = thread->tz_module;
-  } else {
-    tz_module = 0U;
+/// Insert a Thread into the Watchdog list, sorted by tick (lowest at Head).
+/// \param[in]  thread          thread object.
+/// \param[in]  ticks           watchdog timeout.
+static void osRtxThreadWatchdogInsert (os_thread_t *thread, uint32_t ticks) {
+  os_thread_t *prev, *next;
+
+  if (ticks == 0U) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return;
   }
-
-  return tz_module;
+  prev = NULL;
+  next = osRtxInfo.thread.wdog_list;
+  while ((next != NULL) && ((next->wdog_tick <= ticks))) {
+    ticks -= next->wdog_tick;
+    prev   = next;
+    next   = next->wdog_next;
+  }
+  thread->wdog_tick = ticks;
+  thread->wdog_next = next;
+  if (next != NULL) {
+    next->wdog_tick -= ticks;
+  }
+  if (prev != NULL) {
+    prev->wdog_next = thread;
+  } else {
+    osRtxInfo.thread.wdog_list = thread;
+  }
 }
+
+/// Remove a Thread from the Watchdog list.
+/// \param[in]  thread          thread object.
+void osRtxThreadWatchdogRemove (const os_thread_t *thread) {
+  os_thread_t *prev, *next;
+
+  prev = NULL;
+  next = osRtxInfo.thread.wdog_list;
+  while ((next != NULL) && (next != thread)) {
+    prev = next;
+    next = next->wdog_next;
+  }
+  if (next == NULL) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return;
+  }
+  if (thread->wdog_next != NULL) {
+    thread->wdog_next->wdog_tick += thread->wdog_tick;
+  }
+  if (prev != NULL) {
+    prev->wdog_next = thread->wdog_next;
+  } else {
+    osRtxInfo.thread.wdog_list = thread->wdog_next;
+  }
+}
+
+/// Process Watchdog Tick (executed each System Tick).
+void osRtxThreadWatchdogTick (void) {
+  os_thread_t *thread_running;
+  os_thread_t *thread;
+#ifdef RTX_SAFETY_CLASS
+  os_thread_t *next;
+#endif
+  uint32_t ticks;
+
+  thread = osRtxInfo.thread.wdog_list;
+  if (thread == NULL) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return;
+  }
+  thread->wdog_tick--;
+
+  if (thread->wdog_tick == 0U) {
+    // Call watchdog handler for all expired threads
+    thread_running = osRtxThreadGetRunning();
+    do {
+      osRtxThreadSetRunning(osRtxInfo.thread.run.next);
+#ifdef RTX_SAFETY_CLASS
+      // First the highest safety thread (sorted by Safety Class)
+      next = thread->wdog_next;
+      while ((next != NULL) && (next->wdog_tick == 0U)) {
+        if ((next->attr & osRtxAttrClass_Msk) > (thread->attr & osRtxAttrClass_Msk)) {
+          thread = next;
+        }
+        next = next->wdog_next;
+      }
+#endif
+      osRtxThreadWatchdogRemove(thread);
+      EvrRtxThreadWatchdogExpired(thread);
+#ifdef RTX_EXECUTION_ZONE
+      WatchdogAlarmFlag = 1U;
+#endif
+      ticks = osWatchdogAlarm_Handler(thread);
+#ifdef RTX_EXECUTION_ZONE
+      WatchdogAlarmFlag = 0U;
+#endif
+      osRtxThreadWatchdogInsert(thread, ticks);
+      thread = osRtxInfo.thread.wdog_list;
+    } while ((thread != NULL) && (thread->wdog_tick == 0U));
+    osRtxThreadSetRunning(thread_running);
+  }
+}
+
 #endif
 
 static __NO_RETURN void osThreadEntry (void *argument, osThreadFunc_t func) {
@@ -571,18 +734,21 @@
 /// Create a thread and add it to Active Threads.
 /// \note API identical to osThreadNew
 static osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) {
-  os_thread_t  *thread;
-  uint32_t      attr_bits;
-  void         *stack_mem;
-  uint32_t      stack_size;
-  osPriority_t  priority;
-  uint8_t       flags;
-  const char   *name;
-  uint32_t     *ptr;
-  uint32_t      n;
+  os_thread_t       *thread;
+#if defined(RTX_SAFETY_CLASS) || defined(RTX_EXECUTION_ZONE)
+  const os_thread_t *thread_running = osRtxThreadGetRunning();
+#endif
+  uint32_t           attr_bits;
+  void              *stack_mem;
+  uint32_t           stack_size;
+  osPriority_t       priority;
+  uint8_t            flags;
+  const char        *name;
+  uint32_t          *ptr;
+  uint32_t           n;
 #if (DOMAIN_NS == 1)
-  TZ_ModuleId_t tz_module;
-  TZ_MemoryId_t tz_memory;
+  TZ_ModuleId_t      tz_module;
+  TZ_MemoryId_t      tz_memory;
 #endif
 
   // Check parameters
@@ -605,9 +771,24 @@
 #if (DOMAIN_NS == 1)
     tz_module  = attr->tz_module;
 #endif
+    if (((attr_bits & osThreadPrivileged) != 0U) && ((attr_bits & osThreadUnprivileged) != 0U)) {
+      EvrRtxThreadError(NULL, (int32_t)osErrorParameter);
+      //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+      return NULL;
+    }
+#ifdef RTX_SAFETY_CLASS
+    if ((attr_bits & osSafetyClass_Valid) != 0U) {
+      if ((thread_running != NULL) &&
+          ((thread_running->attr >> osRtxAttrClass_Pos) <
+          (uint8_t)((attr_bits & osSafetyClass_Msk) >> osSafetyClass_Pos))) {
+        EvrRtxThreadError(NULL, (int32_t)osErrorSafetyClass);
+        //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+        return NULL;
+      }
+    }
+#endif
     if (thread != NULL) {
-      //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7]
-      if ((((uint32_t)thread & 3U) != 0U) || (attr->cb_size < sizeof(os_thread_t))) {
+      if (!IsThreadPtrValid(thread) || (attr->cb_size != sizeof(os_thread_t))) {
         EvrRtxThreadError(NULL, osRtxErrorInvalidControlBlock);
         //lint -e{904} "Return statement before end of function" [MISRA Note 1]
         return NULL;
@@ -648,6 +829,35 @@
 #endif
   }
 
+  // Set default privilege if not specified
+  if ((attr_bits & (osThreadPrivileged | osThreadUnprivileged)) == 0U) {
+    if ((osRtxConfig.flags & osRtxConfigPrivilegedMode) != 0U) {
+      attr_bits |= osThreadPrivileged;
+    } else {
+      attr_bits |= osThreadUnprivileged;
+    }
+  }
+
+#ifdef RTX_SAFETY_FEATURES
+  // Check privilege protection
+  if ((attr_bits & osThreadPrivileged) != 0U) {
+    if ((osRtxInfo.kernel.protect & osRtxKernelProtectPrivileged) != 0U) {
+      EvrRtxThreadError(NULL, osRtxErrorInvalidPrivilegedMode);
+      //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+      return NULL;
+    }
+  }
+#endif
+
+#if defined(RTX_EXECUTION_ZONE) && defined(RTX_SAFETY_CLASS)
+  // Check class to zone mapping
+  if (!IsClassMappingValid(attr_bits, thread_running)) {
+    EvrRtxThreadError(NULL, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return NULL;
+  }
+#endif
+
   // Check stack size
   if (stack_size != 0U) {
     if (((stack_size & 7U) != 0U) || (stack_size < (64U + 8U)) || (stack_size > 0x7FFFFFFFU)) {
@@ -662,9 +872,11 @@
     if (osRtxInfo.mpi.thread != NULL) {
       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
       thread = osRtxMemoryPoolAlloc(osRtxInfo.mpi.thread);
+#ifndef RTX_OBJ_PTR_CHECK
     } else {
       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
       thread = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_thread_t), 1U);
+#endif
     }
 #ifdef RTX_OBJ_MEM_USAGE
     if (thread != NULL) {
@@ -701,11 +913,15 @@
     }
     if (stack_mem == NULL) {
       if ((flags & osRtxFlagSystemObject) != 0U) {
+#ifdef RTX_OBJ_PTR_CHECK
+        (void)osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread);
+#else
         if (osRtxInfo.mpi.thread != NULL) {
           (void)osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread);
         } else {
           (void)osRtxMemoryFree(osRtxInfo.mem.common, thread);
         }
+#endif
 #ifdef RTX_OBJ_MEM_USAGE
         osRtxThreadMemUsage.cnt_free++;
 #endif
@@ -729,11 +945,15 @@
         }
       }
       if ((flags & osRtxFlagSystemObject) != 0U) {
+#ifdef RTX_OBJ_PTR_CHECK
+        (void)osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread);
+#else
         if (osRtxInfo.mpi.thread != NULL) {
           (void)osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread);
         } else {
           (void)osRtxMemoryFree(osRtxInfo.mem.common, thread);
         }
+#endif
 #ifdef RTX_OBJ_MEM_USAGE
         osRtxThreadMemUsage.cnt_free++;
 #endif
@@ -753,7 +973,7 @@
     thread->id            = osRtxIdThread;
     thread->state         = osRtxThreadReady;
     thread->flags         = flags;
-    thread->attr          = (uint8_t)attr_bits;
+    thread->attr          = (uint8_t)(attr_bits & ~osRtxAttrClass_Msk);
     thread->name          = name;
     thread->thread_next   = NULL;
     thread->thread_prev   = NULL;
@@ -774,9 +994,39 @@
     thread->thread_addr   = (uint32_t)func;
   #if (DOMAIN_NS == 1)
     thread->tz_memory     = tz_memory;
-  #ifdef RTX_TF_M_EXTENSION
-    thread->tz_module     = tz_module;
   #endif
+  #ifdef RTX_SAFETY_CLASS
+    if ((attr_bits & osSafetyClass_Valid) != 0U) {
+      thread->attr       |= (uint8_t)((attr_bits & osSafetyClass_Msk) >>
+                                      (osSafetyClass_Pos - osRtxAttrClass_Pos));
+    } else {
+      // Inherit safety class from the running thread
+      if (thread_running != NULL) {
+        thread->attr     |= (uint8_t)(thread_running->attr & osRtxAttrClass_Msk);
+      }
+    }
+  #endif
+  #ifdef RTX_EXECUTION_ZONE
+    if ((attr_bits & osThreadZone_Valid) != 0U) {
+      thread->zone        = (uint8_t)((attr_bits & osThreadZone_Msk) >> osThreadZone_Pos);
+    } else {
+      // Inherit zone from the running thread
+      if (thread_running != NULL) {
+        thread->zone      = thread_running->zone;
+      } else {
+        thread->zone      = 0U;
+      }
+    }
+  #endif
+  #if defined(RTX_EXECUTION_ZONE) && defined(RTX_SAFETY_CLASS)
+    // Update class to zone assignment table
+    if (ThreadClassTable[thread->zone] == 0U) {
+      ThreadClassTable[thread->zone] = (uint8_t)(0x80U | (thread->attr >> osRtxAttrClass_Pos));
+    }
+  #endif
+  #ifdef RTX_THREAD_WATCHDOG
+    thread->wdog_next     = NULL;
+    thread->wdog_tick     = 0U;
   #endif
 
     // Initialize stack
@@ -795,7 +1045,7 @@
     }
     ptr[14] = (uint32_t)osThreadEntry;  // PC
     ptr[15] = xPSR_InitVal(
-                (bool_t)((osRtxConfig.flags & osRtxConfigPrivilegedMode) != 0U),
+                (bool_t)((attr_bits & osThreadPrivileged) != 0U),
                 (bool_t)(((uint32_t)func & 1U) != 0U)
               );                        // xPSR
     ptr[8]  = (uint32_t)argument;       // R0
@@ -822,7 +1072,7 @@
   os_thread_t *thread = osRtxThreadId(thread_id);
 
   // Check parameters
-  if ((thread == NULL) || (thread->id != osRtxIdThread)) {
+  if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
     EvrRtxThreadGetName(thread, NULL);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return NULL;
@@ -833,6 +1083,44 @@
   return thread->name;
 }
 
+#ifdef RTX_SAFETY_CLASS
+/// Get safety class of a thread.
+/// \note API identical to osThreadGetClass
+static uint32_t svcRtxThreadGetClass (osThreadId_t thread_id) {
+  os_thread_t *thread = osRtxThreadId(thread_id);
+
+  // Check parameters
+  if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
+    EvrRtxThreadGetClass(thread, osErrorId);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorId;
+  }
+
+  EvrRtxThreadGetClass(thread, (uint32_t)thread->attr >> osRtxAttrClass_Pos);
+
+  return ((uint32_t)thread->attr >> osRtxAttrClass_Pos);
+}
+#endif
+
+#ifdef RTX_EXECUTION_ZONE
+/// Get zone of a thread.
+/// \note API identical to osThreadGetZone
+static uint32_t svcRtxThreadGetZone (osThreadId_t thread_id) {
+  os_thread_t *thread = osRtxThreadId(thread_id);
+
+  // Check parameters
+  if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
+    EvrRtxThreadGetZone(thread, osErrorId);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorId;
+  }
+
+  EvrRtxThreadGetZone(thread, thread->zone);
+
+  return thread->zone;
+}
+#endif
+
 /// Return the thread ID of the current running thread.
 /// \note API identical to osThreadGetId
 static osThreadId_t svcRtxThreadGetId (void) {
@@ -850,7 +1138,7 @@
   osThreadState_t state;
 
   // Check parameters
-  if ((thread == NULL) || (thread->id != osRtxIdThread)) {
+  if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
     EvrRtxThreadGetState(thread, osThreadError);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osThreadError;
@@ -869,7 +1157,7 @@
   os_thread_t *thread = osRtxThreadId(thread_id);
 
   // Check parameters
-  if ((thread == NULL) || (thread->id != osRtxIdThread)) {
+  if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
     EvrRtxThreadGetStackSize(thread, 0U);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return 0U;
@@ -888,7 +1176,7 @@
         uint32_t  space;
 
   // Check parameters
-  if ((thread == NULL) || (thread->id != osRtxIdThread)) {
+  if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
     EvrRtxThreadGetStackSpace(thread, 0U);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return 0U;
@@ -921,16 +1209,30 @@
 /// Change priority of a thread.
 /// \note API identical to osThreadSetPriority
 static osStatus_t svcRtxThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) {
-  os_thread_t *thread = osRtxThreadId(thread_id);
+  os_thread_t       *thread = osRtxThreadId(thread_id);
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread_running;
+#endif
 
   // Check parameters
-  if ((thread == NULL) || (thread->id != osRtxIdThread) ||
+  if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread) ||
       (priority < osPriorityIdle) || (priority > osPriorityISR)) {
     EvrRtxThreadError(thread, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread_running = osRtxThreadGetRunning();
+  if ((thread_running != NULL) &&
+      ((thread_running->attr >> osRtxAttrClass_Pos) < (thread->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxThreadError(thread, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Check object state
   if (thread->state == osRtxThreadTerminated) {
     EvrRtxThreadError(thread, (int32_t)osErrorResource);
@@ -956,7 +1258,7 @@
   osPriority_t priority;
 
   // Check parameters
-  if ((thread == NULL) || (thread->id != osRtxIdThread)) {
+  if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
     EvrRtxThreadGetPriority(thread, osPriorityError);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osPriorityError;
@@ -1000,16 +1302,30 @@
 /// Suspend execution of a thread.
 /// \note API identical to osThreadSuspend
 static osStatus_t svcRtxThreadSuspend (osThreadId_t thread_id) {
-  os_thread_t *thread = osRtxThreadId(thread_id);
-  osStatus_t   status;
+  os_thread_t       *thread = osRtxThreadId(thread_id);
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread_running;
+#endif
+  osStatus_t         status;
 
   // Check parameters
-  if ((thread == NULL) || (thread->id != osRtxIdThread)) {
+  if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
     EvrRtxThreadError(thread, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread_running = osRtxThreadGetRunning();
+  if ((thread_running != NULL) &&
+      ((thread_running->attr >> osRtxAttrClass_Pos) < (thread->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxThreadError(thread, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Check object state
   switch (thread->state & osRtxThreadStateMask) {
     case osRtxThreadRunning:
@@ -1056,15 +1372,29 @@
 /// Resume execution of a thread.
 /// \note API identical to osThreadResume
 static osStatus_t svcRtxThreadResume (osThreadId_t thread_id) {
-  os_thread_t *thread = osRtxThreadId(thread_id);
+  os_thread_t       *thread = osRtxThreadId(thread_id);
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread_running;
+#endif
 
   // Check parameters
-  if ((thread == NULL) || (thread->id != osRtxIdThread)) {
+  if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
     EvrRtxThreadError(thread, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread_running = osRtxThreadGetRunning();
+  if ((thread_running != NULL) &&
+      ((thread_running->attr >> osRtxAttrClass_Pos) < (thread->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxThreadError(thread, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Check object state
   if ((thread->state & osRtxThreadStateMask) != osRtxThreadBlocked) {
     EvrRtxThreadError(thread, (int32_t)osErrorResource);
@@ -1084,7 +1414,7 @@
 
 /// Wakeup a thread waiting to join.
 /// \param[in]  thread          thread object.
-static void osRtxThreadJoinWakeup (os_thread_t *thread) {
+void osRtxThreadJoinWakeup (const os_thread_t *thread) {
 
   if (thread->thread_join != NULL) {
     osRtxThreadWaitExit(thread->thread_join, (uint32_t)osOK, FALSE);
@@ -1123,11 +1453,15 @@
 
   // Free object memory
   if ((thread->flags & osRtxFlagSystemObject) != 0U) {
+#ifdef RTX_OBJ_PTR_CHECK
+    (void)osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread);
+#else
     if (osRtxInfo.mpi.thread != NULL) {
       (void)osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread);
     } else {
       (void)osRtxMemoryFree(osRtxInfo.mem.common, thread);
     }
+#endif
 #ifdef RTX_OBJ_MEM_USAGE
     osRtxThreadMemUsage.cnt_free++;
 #endif
@@ -1136,7 +1470,7 @@
 
 /// Destroy a Thread.
 /// \param[in]  thread          thread object.
-static void osRtxThreadDestroy (os_thread_t *thread) {
+void osRtxThreadDestroy (os_thread_t *thread) {
 
   if ((thread->attr & osThreadJoinable) == 0U) {
     osRtxThreadFree(thread);
@@ -1156,15 +1490,29 @@
 /// Detach a thread (thread storage can be reclaimed when thread terminates).
 /// \note API identical to osThreadDetach
 static osStatus_t svcRtxThreadDetach (osThreadId_t thread_id) {
-  os_thread_t *thread = osRtxThreadId(thread_id);
+  os_thread_t       *thread = osRtxThreadId(thread_id);
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread_running;
+#endif
 
   // Check parameters
-  if ((thread == NULL) || (thread->id != osRtxIdThread)) {
+  if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
     EvrRtxThreadError(thread, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread_running = osRtxThreadGetRunning();
+  if ((thread_running != NULL) &&
+      ((thread_running->attr >> osRtxAttrClass_Pos) < (thread->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxThreadError(thread, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Check object attributes
   if ((thread->attr & osThreadJoinable) == 0U) {
     EvrRtxThreadError(thread, osRtxErrorThreadNotJoinable);
@@ -1192,12 +1540,23 @@
   osStatus_t   status;
 
   // Check parameters
-  if ((thread == NULL) || (thread->id != osRtxIdThread)) {
+  if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
     EvrRtxThreadError(thread, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread_running = osRtxThreadGetRunning();
+  if ((thread_running != NULL) &&
+      ((thread_running->attr >> osRtxAttrClass_Pos) < (thread->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxThreadError(thread, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Check object attributes
   if ((thread->attr & osThreadJoinable) == 0U) {
     EvrRtxThreadError(thread, osRtxErrorThreadNotJoinable);
@@ -1249,6 +1608,11 @@
   // Get running thread
   thread = osRtxThreadGetRunning();
 
+#ifdef RTX_THREAD_WATCHDOG
+  // Remove Thread from the Watchdog list
+  osRtxThreadWatchdogRemove(thread);
+#endif
+
   // Release owned Mutexes
   osRtxMutexOwnerRelease(thread->mutex_list);
 
@@ -1278,16 +1642,30 @@
 /// Terminate execution of a thread.
 /// \note API identical to osThreadTerminate
 static osStatus_t svcRtxThreadTerminate (osThreadId_t thread_id) {
-  os_thread_t *thread = osRtxThreadId(thread_id);
-  osStatus_t   status;
+  os_thread_t       *thread = osRtxThreadId(thread_id);
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread_running;
+#endif
+  osStatus_t         status;
 
   // Check parameters
-  if ((thread == NULL) || (thread->id != osRtxIdThread)) {
+  if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
     EvrRtxThreadError(thread, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread_running = osRtxThreadGetRunning();
+  if ((thread_running != NULL) &&
+      ((thread_running->attr >> osRtxAttrClass_Pos) < (thread->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxThreadError(thread, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Check object state
   switch (thread->state & osRtxThreadStateMask) {
     case osRtxThreadRunning:
@@ -1317,6 +1695,11 @@
   }
 
   if (status == osOK) {
+#ifdef RTX_THREAD_WATCHDOG
+    // Remove Thread from the Watchdog list
+    osRtxThreadWatchdogRemove(thread);
+#endif
+
     // Release owned Mutexes
     osRtxMutexOwnerRelease(thread->mutex_list);
 
@@ -1348,6 +1731,326 @@
   return status;
 }
 
+#ifdef RTX_THREAD_WATCHDOG
+/// Feed watchdog of the current running thread.
+/// \note API identical to osThreadFeedWatchdog
+static osStatus_t svcRtxThreadFeedWatchdog (uint32_t ticks) {
+  os_thread_t *thread;
+
+  // Check running thread
+  thread = osRtxThreadGetRunning();
+  if (thread == NULL) {
+    EvrRtxThreadError(NULL, osRtxErrorKernelNotRunning);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osError;
+  }
+
+  osRtxThreadWatchdogRemove(thread);
+  osRtxThreadWatchdogInsert(thread, ticks);
+
+  EvrRtxThreadFeedWatchdogDone();
+
+  return osOK;
+}
+#endif
+
+#ifdef RTX_SAFETY_FEATURES
+/// Protect the creation of privileged threads.
+/// \note API identical to osThreadProtectPrivileged
+static osStatus_t svcRtxThreadProtectPrivileged (void) {
+
+  // Check that Kernel is initialized
+  if (osRtxKernelGetState() == osRtxKernelInactive) {
+    EvrRtxThreadError(NULL, osRtxErrorKernelNotReady);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osError;
+  }
+
+  osRtxInfo.kernel.protect |= osRtxKernelProtectPrivileged;
+
+  EvrRtxThreadPrivilegedProtected();
+
+  return osOK;
+}
+#endif
+
+#ifdef RTX_SAFETY_CLASS
+
+/// Suspend execution of threads for specified safety classes.
+/// \note API identical to osThreadSuspendClass
+static osStatus_t svcRtxThreadSuspendClass (uint32_t safety_class, uint32_t mode) {
+  os_thread_t *thread;
+  os_thread_t *thread_next;
+
+  // Check parameters
+  if (safety_class > 0x0FU) {
+    EvrRtxThreadError(NULL, (int32_t)osErrorParameter);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorParameter;
+  }
+
+  // Check running thread safety class (when called from thread)
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) && IsSVCallIrq()) {
+    if ((((mode & osSafetyWithSameClass)  != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) < (uint8_t)safety_class)) ||
+        (((mode & osSafetyWithLowerClass) != 0U) &&
+         (((thread->attr >> osRtxAttrClass_Pos) + 1U) < (uint8_t)safety_class))) {
+      EvrRtxThreadError(NULL, (int32_t)osErrorSafetyClass);
+      //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+      return osErrorSafetyClass;
+    }
+  }
+
+  // Threads in Wait List
+  thread = osRtxInfo.thread.wait_list;
+  while (thread != NULL) {
+    thread_next = thread->delay_next;
+    if ((((mode & osSafetyWithSameClass)  != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
+        (((mode & osSafetyWithLowerClass) != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) <  (uint8_t)safety_class))) {
+      osRtxThreadListRemove(thread);
+      thread->state = osRtxThreadBlocked;
+      EvrRtxThreadSuspended(thread);
+    }
+    thread = thread_next;
+  }
+
+  // Threads in Delay List
+  thread = osRtxInfo.thread.delay_list;
+  while (thread != NULL) {
+    thread_next = thread->delay_next;
+    if ((((mode & osSafetyWithSameClass)  != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
+        (((mode & osSafetyWithLowerClass) != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) <  (uint8_t)safety_class))) {
+      osRtxThreadListRemove(thread);
+      osRtxThreadDelayRemove(thread);
+      thread->state = osRtxThreadBlocked;
+      osRtxThreadDelayInsert(thread, osWaitForever);
+      EvrRtxThreadSuspended(thread);
+    }
+    thread = thread_next;
+  }
+
+  // Threads in Ready List
+  thread = osRtxInfo.thread.ready.thread_list;
+  while (thread != NULL) {
+    thread_next = thread->thread_next;
+    if ((((mode & osSafetyWithSameClass)  != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
+        (((mode & osSafetyWithLowerClass) != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) <  (uint8_t)safety_class))) {
+      osRtxThreadListRemove(thread);
+      thread->state = osRtxThreadBlocked;
+      osRtxThreadDelayInsert(thread, osWaitForever);
+      EvrRtxThreadSuspended(thread);
+    }
+    thread = thread_next;
+  }
+
+  // Running Thread
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((((mode & osSafetyWithSameClass)  != 0U) &&
+        ((thread->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
+       (((mode & osSafetyWithLowerClass) != 0U) &&
+        ((thread->attr >> osRtxAttrClass_Pos) <  (uint8_t)safety_class)))) {
+    if ((osRtxKernelGetState() == osRtxKernelRunning) &&
+        (osRtxInfo.thread.ready.thread_list != NULL)) {
+      thread->state = osRtxThreadBlocked;
+      osRtxThreadDelayInsert(thread, osWaitForever);
+      EvrRtxThreadSuspended(thread);
+      osRtxThreadSwitch(osRtxThreadListGet(&osRtxInfo.thread.ready));
+    } else {
+      EvrRtxThreadError(thread, (int32_t)osErrorResource);
+      //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+      return osErrorResource;
+    }
+  }
+
+  return osOK;
+}
+
+/// Resume execution of threads for specified safety classes.
+/// \note API identical to osThreadResumeClass
+static osStatus_t svcRtxThreadResumeClass (uint32_t safety_class, uint32_t mode) {
+  os_thread_t *thread;
+  os_thread_t *thread_next;
+
+  // Check parameters
+  if (safety_class > 0x0FU) {
+    EvrRtxThreadError(NULL, (int32_t)osErrorParameter);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorParameter;
+  }
+
+  // Check running thread safety class (when called from thread)
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) && IsSVCallIrq()) {
+    if ((((mode & osSafetyWithSameClass)  != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) < (uint8_t)safety_class)) ||
+        (((mode & osSafetyWithLowerClass) != 0U) &&
+         (((thread->attr >> osRtxAttrClass_Pos) + 1U) < (uint8_t)safety_class))) {
+      EvrRtxThreadError(NULL, (int32_t)osErrorSafetyClass);
+      //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+      return osErrorSafetyClass;
+    }
+  }
+
+  // Threads in Wait List
+  thread = osRtxInfo.thread.wait_list;
+  while (thread != NULL) {
+    thread_next = thread->delay_next;
+    if ((((mode & osSafetyWithSameClass)  != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
+        (((mode & osSafetyWithLowerClass) != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) <  (uint8_t)safety_class))) {
+      // Wakeup Thread
+      osRtxThreadListRemove(thread);
+      osRtxThreadDelayRemove(thread);
+      osRtxThreadReadyPut(thread);
+      EvrRtxThreadResumed(thread);
+    }
+    thread = thread_next;
+  }
+
+  // Threads in Delay List
+  thread = osRtxInfo.thread.delay_list;
+  while (thread != NULL) {
+    thread_next = thread->delay_next;
+    if ((((mode & osSafetyWithSameClass)  != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
+        (((mode & osSafetyWithLowerClass) != 0U) &&
+         ((thread->attr >> osRtxAttrClass_Pos) <  (uint8_t)safety_class))) {
+      // Wakeup Thread
+      osRtxThreadListRemove(thread);
+      osRtxThreadDelayRemove(thread);
+      osRtxThreadReadyPut(thread);
+      EvrRtxThreadResumed(thread);
+    }
+    thread = thread_next;
+  }
+
+  osRtxThreadDispatch(NULL);
+
+  return osOK;
+}
+
+#endif
+
+#ifdef RTX_EXECUTION_ZONE
+/// Terminate execution of threads assigned to a specified MPU protected zone.
+/// \note API identical to osThreadTerminateZone
+static osStatus_t svcRtxThreadTerminateZone (uint32_t zone) {
+  os_thread_t *thread;
+  os_thread_t *thread_next;
+
+#ifdef RTX_THREAD_WATCHDOG
+  // Check Watchdog Alarm Flag
+  if (WatchdogAlarmFlag != 0U) {
+    EvrRtxThreadError(NULL, (int32_t)osErrorISR);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorISR;
+  }
+#endif
+
+  // Check parameters
+  if (zone > 0x3FU) {
+    EvrRtxThreadError(NULL, (int32_t)osErrorParameter);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorParameter;
+  }
+
+  // Threads in Wait List
+  thread = osRtxInfo.thread.wait_list;
+  while (thread != NULL) {
+    thread_next = thread->delay_next;
+    if (thread->zone == zone) {
+      osRtxThreadListRemove(thread);
+      osRtxThreadDelayRemove(thread);
+#ifdef RTX_THREAD_WATCHDOG
+      osRtxThreadWatchdogRemove(thread);
+#endif
+      osRtxMutexOwnerRelease(thread->mutex_list);
+      osRtxThreadJoinWakeup(thread);
+      osRtxThreadDestroy(thread);
+    }
+    thread = thread_next;
+  }
+
+  // Threads in Delay List
+  thread = osRtxInfo.thread.delay_list;
+  while (thread != NULL) {
+    thread_next = thread->delay_next;
+    if (thread->zone == zone) {
+      osRtxThreadListRemove(thread);
+      osRtxThreadDelayRemove(thread);
+#ifdef RTX_THREAD_WATCHDOG
+      osRtxThreadWatchdogRemove(thread);
+#endif
+      osRtxMutexOwnerRelease(thread->mutex_list);
+      osRtxThreadJoinWakeup(thread);
+      osRtxThreadDestroy(thread);
+    }
+    thread = thread_next;
+  }
+
+  // Threads in Ready List
+  thread = osRtxInfo.thread.ready.thread_list;
+  while (thread != NULL) {
+    thread_next = thread->thread_next;
+    if (thread->zone == zone) {
+      osRtxThreadListRemove(thread);
+#ifdef RTX_THREAD_WATCHDOG
+      osRtxThreadWatchdogRemove(thread);
+#endif
+      osRtxMutexOwnerRelease(thread->mutex_list);
+      osRtxThreadJoinWakeup(thread);
+      osRtxThreadDestroy(thread);
+    }
+    thread = thread_next;
+  }
+
+  // Running Thread
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) && (thread->zone == zone)) {
+    if ((osRtxKernelGetState() != osRtxKernelRunning) ||
+        (osRtxInfo.thread.ready.thread_list == NULL)) {
+      osRtxThreadDispatch(NULL);
+      EvrRtxThreadError(thread, (int32_t)osErrorResource);
+      //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+      return osErrorResource;
+    }
+#ifdef RTX_THREAD_WATCHDOG
+    osRtxThreadWatchdogRemove(thread);
+#endif
+    osRtxMutexOwnerRelease(thread->mutex_list);
+    osRtxThreadJoinWakeup(thread);
+    // Switch to next Ready Thread
+    osRtxThreadSwitch(osRtxThreadListGet(&osRtxInfo.thread.ready));
+    // Update Stack Pointer
+    thread->sp = __get_PSP();
+#ifdef RTX_STACK_CHECK
+    // Check Stack usage
+    if (!osRtxThreadStackCheck(thread)) {
+      osRtxThreadSetRunning(osRtxInfo.thread.run.next);
+      (void)osRtxKernelErrorNotify(osRtxErrorStackOverflow, thread);
+    }
+#endif
+    // Mark running thread as deleted
+    osRtxThreadSetRunning(NULL);
+    // Destroy Thread
+    osRtxThreadDestroy(thread);
+  } else {
+    osRtxThreadDispatch(NULL);
+  }
+
+  return osOK;
+}
+#endif
+
 /// Get number of active threads.
 /// \note API identical to osThreadGetCount
 static uint32_t svcRtxThreadGetCount (void) {
@@ -1430,12 +2133,15 @@
 /// Set the specified Thread Flags of a thread.
 /// \note API identical to osThreadFlagsSet
 static uint32_t svcRtxThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) {
-  os_thread_t *thread = osRtxThreadId(thread_id);
-  uint32_t     thread_flags;
-  uint32_t     thread_flags0;
+  os_thread_t       *thread = osRtxThreadId(thread_id);
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread_running;
+#endif
+  uint32_t           thread_flags;
+  uint32_t           thread_flags0;
 
   // Check parameters
-  if ((thread == NULL) || (thread->id != osRtxIdThread) ||
+  if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread) ||
       ((flags & ~(((uint32_t)1U << osRtxThreadFlagsLimit) - 1U)) != 0U)) {
     EvrRtxThreadFlagsError(thread, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
@@ -1449,6 +2155,17 @@
     return ((uint32_t)osErrorResource);
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread_running = osRtxThreadGetRunning();
+  if ((thread_running != NULL) &&
+      ((thread_running->attr >> osRtxAttrClass_Pos) < (thread->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxThreadFlagsError(thread, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return ((uint32_t)osErrorSafetyClass);
+  }
+#endif
+
   // Set Thread Flags
   thread_flags = ThreadFlagsSet(thread, flags);
 
@@ -1567,6 +2284,12 @@
 //lint ++flb "Library Begin" [MISRA Note 11]
 SVC0_3 (ThreadNew,           osThreadId_t,    osThreadFunc_t, void *, const osThreadAttr_t *)
 SVC0_1 (ThreadGetName,       const char *,    osThreadId_t)
+#ifdef RTX_SAFETY_CLASS
+SVC0_1 (ThreadGetClass,      uint32_t,        osThreadId_t)
+#endif
+#ifdef RTX_EXECUTION_ZONE
+SVC0_1 (ThreadGetZone,       uint32_t,        osThreadId_t)
+#endif
 SVC0_0 (ThreadGetId,         osThreadId_t)
 SVC0_1 (ThreadGetState,      osThreadState_t, osThreadId_t)
 SVC0_1 (ThreadGetStackSize,  uint32_t,        osThreadId_t)
@@ -1580,6 +2303,16 @@
 SVC0_1 (ThreadJoin,          osStatus_t,      osThreadId_t)
 SVC0_0N(ThreadExit,          void)
 SVC0_1 (ThreadTerminate,     osStatus_t,      osThreadId_t)
+#ifdef RTX_THREAD_WATCHDOG
+SVC0_1 (ThreadFeedWatchdog,      osStatus_t,  uint32_t)
+#endif
+#ifdef RTX_SAFETY_FEATURES
+SVC0_0 (ThreadProtectPrivileged, osStatus_t)
+#endif
+#ifdef RTX_SAFETY_CLASS
+SVC0_2 (ThreadSuspendClass,      osStatus_t,  uint32_t, uint32_t)
+SVC0_2 (ThreadResumeClass,       osStatus_t,  uint32_t, uint32_t)
+#endif
 SVC0_0 (ThreadGetCount,      uint32_t)
 SVC0_2 (ThreadEnumerate,     uint32_t,        osThreadId_t *, uint32_t)
 SVC0_2 (ThreadFlagsSet,      uint32_t,        osThreadId_t, uint32_t)
@@ -1599,7 +2332,7 @@
   uint32_t     thread_flags;
 
   // Check parameters
-  if ((thread == NULL) || (thread->id != osRtxIdThread) ||
+  if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread) ||
       ((flags & ~(((uint32_t)1U << osRtxThreadFlagsLimit) - 1U)) != 0U)) {
     EvrRtxThreadFlagsError(thread, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
@@ -1683,14 +2416,41 @@
   const char *name;
 
   if (IsException() || IsIrqMasked()) {
-    EvrRtxThreadGetName(thread_id, NULL);
-    name = NULL;
+    name = svcRtxThreadGetName(thread_id);
   } else {
-    name = __svcThreadGetName(thread_id);
+    name =  __svcThreadGetName(thread_id);
   }
   return name;
 }
 
+#ifdef RTX_SAFETY_CLASS
+/// Get safety class of a thread.
+uint32_t osThreadGetClass (osThreadId_t thread_id) {
+  uint32_t safety_class;
+
+  if (IsException() || IsIrqMasked()) {
+    safety_class = svcRtxThreadGetClass(thread_id);
+  } else {
+    safety_class =  __svcThreadGetClass(thread_id);
+  }
+  return safety_class;
+}
+#endif
+
+#ifdef RTX_EXECUTION_ZONE
+/// Get zone of a thread.
+uint32_t osThreadGetZone (osThreadId_t thread_id) {
+  uint32_t zone;
+
+  if (IsException() || IsIrqMasked()) {
+    zone = svcRtxThreadGetZone(thread_id);
+  } else {
+    zone =  __svcThreadGetZone(thread_id);
+  }
+  return zone;
+}
+#endif
+
 /// Return the thread ID of the current running thread.
 osThreadId_t osThreadGetId (void) {
   osThreadId_t thread_id;
@@ -1861,6 +2621,99 @@
   return status;
 }
 
+#ifdef RTX_THREAD_WATCHDOG
+/// Feed watchdog of the current running thread.
+osStatus_t osThreadFeedWatchdog (uint32_t ticks) {
+  osStatus_t status;
+
+  EvrRtxThreadFeedWatchdog(ticks);
+  if (IsException() || IsIrqMasked()) {
+    EvrRtxThreadError(NULL, (int32_t)osErrorISR);
+    status = osErrorISR;
+  } else {
+    status = __svcThreadFeedWatchdog(ticks);
+  }
+  return status;
+}
+#endif
+
+#ifdef RTX_SAFETY_FEATURES
+/// Protect the creation of privileged threads.
+osStatus_t osThreadProtectPrivileged (void) {
+  osStatus_t status;
+
+  EvrRtxThreadProtectPrivileged();
+  if (IsException() || IsIrqMasked()) {
+    EvrRtxThreadError(NULL, (int32_t)osErrorISR);
+    status = osErrorISR;
+  } else {
+    status = __svcThreadProtectPrivileged();
+  }
+  return status;
+}
+#endif
+
+#ifdef RTX_SAFETY_CLASS
+
+/// Suspend execution of threads for specified safety classes.
+osStatus_t osThreadSuspendClass (uint32_t safety_class, uint32_t mode) {
+  osStatus_t status;
+
+  EvrRtxThreadSuspendClass(safety_class, mode);
+  if (IsException() || IsIrqMasked()) {
+    if (IsTickIrq(osRtxInfo.tick_irqn)) {
+      status = svcRtxThreadSuspendClass(safety_class, mode);
+    } else {
+      EvrRtxThreadError(NULL, (int32_t)osErrorISR);
+      status = osErrorISR;
+    }
+  } else {
+    status   =  __svcThreadSuspendClass(safety_class, mode);
+  }
+  return status;
+}
+
+/// Resume execution of threads for specified safety classes.
+osStatus_t osThreadResumeClass (uint32_t safety_class, uint32_t mode) {
+  osStatus_t status;
+
+  EvrRtxThreadResumeClass(safety_class, mode);
+  if (IsException() || IsIrqMasked()) {
+    if (IsTickIrq(osRtxInfo.tick_irqn)) {
+      status = svcRtxThreadResumeClass(safety_class, mode);
+    } else {
+      EvrRtxThreadError(NULL, (int32_t)osErrorISR);
+      status = osErrorISR;
+    }
+  } else {
+    status   =  __svcThreadResumeClass(safety_class, mode);
+  }
+  return status;
+}
+
+#endif
+
+#ifdef RTX_EXECUTION_ZONE
+/// Terminate execution of threads assigned to a specified MPU protected zone.
+osStatus_t osThreadTerminateZone (uint32_t zone) {
+  osStatus_t status;
+
+  EvrRtxThreadTerminateZone(zone);
+  if (IsException() || IsIrqMasked()) {
+    if (IsFault() || IsSVCallIrq() || IsPendSvIrq() || IsTickIrq(osRtxInfo.tick_irqn)) {
+      status = svcRtxThreadTerminateZone(zone);
+    } else {
+      EvrRtxThreadError(NULL, (int32_t)osErrorISR);
+      status = osErrorISR;
+    }
+  } else {
+    EvrRtxThreadError(osRtxThreadGetRunning(), (int32_t)osError);
+    status   = osError;
+  }
+  return status;
+}
+#endif
+
 /// Get number of active threads.
 uint32_t osThreadGetCount (void) {
   uint32_t count;
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_timer.c b/CMSIS/RTOS2/RTX/Source/rtx_timer.c
index 8400687..11c16a1 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_timer.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_timer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -88,6 +88,35 @@
   osRtxInfo.timer.list = timer->next;
 }
 
+/// Verify that Timer object pointer is valid.
+/// \param[in]  timer           timer object.
+/// \return true - valid, false - invalid.
+static bool_t IsTimerPtrValid (const os_timer_t *timer) {
+#ifdef RTX_OBJ_PTR_CHECK
+  //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
+  uint32_t cb_start  = (uint32_t)&__os_timer_cb_start__;
+  uint32_t cb_length = (uint32_t)&__os_timer_cb_length__;
+
+  // Check the section boundaries
+  if (((uint32_t)timer - cb_start) >= cb_length) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+  // Check the object alignment
+  if ((((uint32_t)timer - cb_start) % sizeof(os_timer_t)) != 0U) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+#else
+  // Check NULL pointer
+  if (timer == NULL) {
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return FALSE;
+  }
+#endif
+  return TRUE;
+}
+
 
 //  ==== Library functions ====
 
@@ -119,7 +148,7 @@
         }
       }
     }
-    if (timer->type == osRtxTimerPeriodic) {
+    if ((timer->attr & osRtxTimerPeriodic) != 0U) {
       TimerInsert(timer, timer->load);
     } else {
       timer->state = osRtxTimerStopped;
@@ -164,14 +193,74 @@
   }
 }
 
+/// Destroy a Timer object.
+/// \param[in]  timer           timer object.
+static void osRtxTimerDestroy (os_timer_t *timer) {
+
+  // Mark object as inactive and invalid
+  timer->state = osRtxTimerInactive;
+  timer->id    = osRtxIdInvalid;
+
+  // Free object memory
+  if ((timer->flags & osRtxFlagSystemObject) != 0U) {
+#ifdef RTX_OBJ_PTR_CHECK
+    (void)osRtxMemoryPoolFree(osRtxInfo.mpi.timer, timer);
+#else
+    if (osRtxInfo.mpi.timer != NULL) {
+      (void)osRtxMemoryPoolFree(osRtxInfo.mpi.timer, timer);
+    } else {
+      (void)osRtxMemoryFree(osRtxInfo.mem.common, timer);
+    }
+#endif
+#ifdef RTX_OBJ_MEM_USAGE
+    osRtxTimerMemUsage.cnt_free++;
+#endif
+  }
+
+  EvrRtxTimerDestroyed(timer);
+}
+
+#ifdef RTX_SAFETY_CLASS
+/// Delete a Timer safety class.
+/// \param[in]  safety_class    safety class.
+/// \param[in]  mode            safety mode.
+void osRtxTimerDeleteClass (uint32_t safety_class, uint32_t mode) {
+  os_timer_t *timer;
+  uint32_t    length;
+
+  //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
+  timer = (os_timer_t *)(uint32_t)&__os_timer_cb_start__;
+  length    =           (uint32_t)&__os_timer_cb_length__;
+  while (length >= sizeof(os_timer_t)) {
+    if (   (timer->id == osRtxIdTimer) &&
+        ((((mode & osSafetyWithSameClass)  != 0U) &&
+          ((timer->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
+         (((mode & osSafetyWithLowerClass) != 0U) &&
+          ((timer->attr >> osRtxAttrClass_Pos) <  (uint8_t)safety_class)))) {
+      if (timer->state == osRtxTimerRunning) {
+        TimerRemove(timer);
+      }
+      osRtxTimerDestroy(timer);
+    }
+    length -= sizeof(os_timer_t);
+    timer++;
+  }
+}
+#endif
+
+
 //  ==== Service Calls ====
 
 /// Create and Initialize a timer.
 /// \note API identical to osTimerNew
 static osTimerId_t svcRtxTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) {
-  os_timer_t *timer;
-  uint8_t     flags;
-  const char *name;
+  os_timer_t        *timer;
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread = osRtxThreadGetRunning();
+  uint32_t           attr_bits;
+#endif
+  uint8_t            flags;
+  const char        *name;
 
   // Check parameters
   if ((func == NULL) || ((type != osTimerOnce) && (type != osTimerPeriodic))) {
@@ -182,12 +271,25 @@
 
   // Process attributes
   if (attr != NULL) {
-    name  = attr->name;
+    name      = attr->name;
+#ifdef RTX_SAFETY_CLASS
+    attr_bits = attr->attr_bits;
+#endif
     //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
-    timer = attr->cb_mem;
+    timer      = attr->cb_mem;
+#ifdef RTX_SAFETY_CLASS
+    if ((attr_bits & osSafetyClass_Valid) != 0U) {
+      if ((thread != NULL) &&
+          ((thread->attr >> osRtxAttrClass_Pos) <
+          (uint8_t)((attr_bits & osSafetyClass_Msk) >> osSafetyClass_Pos))) {
+        EvrRtxTimerError(NULL, (int32_t)osErrorSafetyClass);
+        //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+        return NULL;
+      }
+    }
+#endif
     if (timer != NULL) {
-      //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7]
-      if ((((uint32_t)timer & 3U) != 0U) || (attr->cb_size < sizeof(os_timer_t))) {
+      if (!IsTimerPtrValid(timer) || (attr->cb_size != sizeof(os_timer_t))) {
         EvrRtxTimerError(NULL, osRtxErrorInvalidControlBlock);
         //lint -e{904} "Return statement before end of function" [MISRA Note 1]
         return NULL;
@@ -200,8 +302,11 @@
       }
     }
   } else {
-    name  = NULL;
-    timer = NULL;
+    name      = NULL;
+#ifdef RTX_SAFETY_CLASS
+    attr_bits = 0U;
+#endif
+    timer     = NULL;
   }
 
   // Allocate object memory if not provided
@@ -209,9 +314,11 @@
     if (osRtxInfo.mpi.timer != NULL) {
       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
       timer = osRtxMemoryPoolAlloc(osRtxInfo.mpi.timer);
+#ifndef RTX_OBJ_PTR_CHECK
     } else {
       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
       timer = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_timer_t), 1U);
+#endif
     }
 #ifdef RTX_OBJ_MEM_USAGE
     if (timer != NULL) {
@@ -233,7 +340,11 @@
     timer->id         = osRtxIdTimer;
     timer->state      = osRtxTimerStopped;
     timer->flags      = flags;
-    timer->type       = (uint8_t)type;
+    if (type == osTimerPeriodic) {
+      timer->attr     = osRtxTimerPeriodic;
+    } else {
+      timer->attr     = 0U;
+    }
     timer->name       = name;
     timer->prev       = NULL;
     timer->next       = NULL;
@@ -241,7 +352,17 @@
     timer->load       = 0U;
     timer->finfo.func = func;
     timer->finfo.arg  = argument;
-
+#ifdef RTX_SAFETY_CLASS
+    if ((attr_bits & osSafetyClass_Valid) != 0U) {
+      timer->attr    |= (uint8_t)((attr_bits & osSafetyClass_Msk) >>
+                                  (osSafetyClass_Pos - osRtxAttrClass_Pos));
+    } else {
+      // Inherit safety class from the running thread
+      if (thread != NULL) {
+        timer->attr  |= (uint8_t)(thread->attr & osRtxAttrClass_Msk);
+      }
+    }
+#endif
     EvrRtxTimerCreated(timer, timer->name);
   } else {
     EvrRtxTimerError(NULL, (int32_t)osErrorNoMemory);
@@ -256,7 +377,7 @@
   os_timer_t *timer = osRtxTimerId(timer_id);
 
   // Check parameters
-  if ((timer == NULL) || (timer->id != osRtxIdTimer)) {
+  if (!IsTimerPtrValid(timer) || (timer->id != osRtxIdTimer)) {
     EvrRtxTimerGetName(timer, NULL);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return NULL;
@@ -270,15 +391,29 @@
 /// Start or restart a timer.
 /// \note API identical to osTimerStart
 static osStatus_t svcRtxTimerStart (osTimerId_t timer_id, uint32_t ticks) {
-  os_timer_t *timer = osRtxTimerId(timer_id);
+  os_timer_t        *timer = osRtxTimerId(timer_id);
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread;
+#endif
 
   // Check parameters
-  if ((timer == NULL) || (timer->id != osRtxIdTimer) || (ticks == 0U)) {
+  if (!IsTimerPtrValid(timer) || (timer->id != osRtxIdTimer) || (ticks == 0U)) {
     EvrRtxTimerError(timer, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (timer->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxTimerError(timer, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   if (timer->state == osRtxTimerRunning) {
     timer->load = ticks;
     TimerRemove(timer);
@@ -303,15 +438,29 @@
 /// Stop a timer.
 /// \note API identical to osTimerStop
 static osStatus_t svcRtxTimerStop (osTimerId_t timer_id) {
-  os_timer_t *timer = osRtxTimerId(timer_id);
+  os_timer_t        *timer = osRtxTimerId(timer_id);
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread;
+#endif
 
   // Check parameters
-  if ((timer == NULL) || (timer->id != osRtxIdTimer)) {
+  if (!IsTimerPtrValid(timer) || (timer->id != osRtxIdTimer)) {
     EvrRtxTimerError(timer, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (timer->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxTimerError(timer, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   // Check object state
   if (timer->state != osRtxTimerRunning) {
     EvrRtxTimerError(timer, (int32_t)osErrorResource);
@@ -335,7 +484,7 @@
   uint32_t    is_running;
 
   // Check parameters
-  if ((timer == NULL) || (timer->id != osRtxIdTimer)) {
+  if (!IsTimerPtrValid(timer) || (timer->id != osRtxIdTimer)) {
     EvrRtxTimerIsRunning(timer, 0U);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return 0U;
@@ -355,36 +504,34 @@
 /// Delete a timer.
 /// \note API identical to osTimerDelete
 static osStatus_t svcRtxTimerDelete (osTimerId_t timer_id) {
-  os_timer_t *timer = osRtxTimerId(timer_id);
+  os_timer_t        *timer = osRtxTimerId(timer_id);
+#ifdef RTX_SAFETY_CLASS
+  const os_thread_t *thread;
+#endif
 
   // Check parameters
-  if ((timer == NULL) || (timer->id != osRtxIdTimer)) {
+  if (!IsTimerPtrValid(timer) || (timer->id != osRtxIdTimer)) {
     EvrRtxTimerError(timer, (int32_t)osErrorParameter);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return osErrorParameter;
   }
 
+#ifdef RTX_SAFETY_CLASS
+  // Check running thread safety class
+  thread = osRtxThreadGetRunning();
+  if ((thread != NULL) &&
+      ((thread->attr >> osRtxAttrClass_Pos) < (timer->attr >> osRtxAttrClass_Pos))) {
+    EvrRtxTimerError(timer, (int32_t)osErrorSafetyClass);
+    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
+    return osErrorSafetyClass;
+  }
+#endif
+
   if (timer->state == osRtxTimerRunning) {
     TimerRemove(timer);
   }
 
-  // Mark object as inactive and invalid
-  timer->state = osRtxTimerInactive;
-  timer->id    = osRtxIdInvalid;
-
-  // Free object memory
-  if ((timer->flags & osRtxFlagSystemObject) != 0U) {
-    if (osRtxInfo.mpi.timer != NULL) {
-      (void)osRtxMemoryPoolFree(osRtxInfo.mpi.timer, timer);
-    } else {
-      (void)osRtxMemoryFree(osRtxInfo.mem.common, timer);
-    }
-#ifdef RTX_OBJ_MEM_USAGE
-    osRtxTimerMemUsage.cnt_free++;
-#endif
-  }
-
-  EvrRtxTimerDestroyed(timer);
+  osRtxTimerDestroy(timer);
 
   return osOK;
 }
@@ -421,10 +568,9 @@
   const char *name;
 
   if (IsException() || IsIrqMasked()) {
-    EvrRtxTimerGetName(timer_id, NULL);
-    name = NULL;
+    name = svcRtxTimerGetName(timer_id);
   } else {
-    name = __svcTimerGetName(timer_id);
+    name =  __svcTimerGetName(timer_id);
   }
   return name;
 }