RTX5: added Object Memory usage counters
diff --git a/CMSIS/RTOS2/RTX/Config/RTX_Config.h b/CMSIS/RTOS2/RTX/Config/RTX_Config.h
index 82e4eb5..04ab7eb 100644
--- a/CMSIS/RTOS2/RTX/Config/RTX_Config.h
+++ b/CMSIS/RTOS2/RTX/Config/RTX_Config.h
@@ -17,7 +17,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * $Revision:   V5.2.0
+ * $Revision:   V5.3.0
  *
  * Project:     CMSIS-RTOS RTX
  * Title:       RTX Configuration definitions
@@ -69,7 +69,18 @@
  
 //   </e>
  
+//   <o>ISR FIFO Queue 
+//      <4=>  4 entries    <8=>   8 entries   <12=>  12 entries   <16=>  16 entries
+//     <24=> 24 entries   <32=>  32 entries   <48=>  48 entries   <64=>  64 entries
+//     <96=> 96 entries  <128=> 128 entries  <196=> 196 entries  <256=> 256 entries
+//   <i> RTOS Functions called from ISR store requests to this buffer.
+//   <i> Default: 16 entries
+#ifndef OS_ISR_FIFO_QUEUE
+#define OS_ISR_FIFO_QUEUE           16
+#endif
+ 
 //   <h>Event Recording
+//   <i> Configures events recording.
  
 //     <q>Memory Management
 //     <i> Enables Memory Management events recording.
@@ -127,14 +138,10 @@
  
 //   </h>
  
-//   <o>ISR FIFO Queue 
-//      <4=>  4 entries    <8=>   8 entries   <12=>  12 entries   <16=>  16 entries
-//     <24=> 24 entries   <32=>  32 entries   <48=>  48 entries   <64=>  64 entries
-//     <96=> 96 entries  <128=> 128 entries  <196=> 196 entries  <256=> 256 entries
-//   <i> RTOS Functions called from ISR store requests to this buffer.
-//   <i> Default: 16 entries
-#ifndef OS_ISR_FIFO_QUEUE
-#define OS_ISR_FIFO_QUEUE           16
+//   <q>Object Memory usage counters
+//   <i> Enables object memory usage counters.
+#ifndef OS_OBJ_MEM_USAGE
+#define OS_OBJ_MEM_USAGE            0
 #endif
  
 // </h>
diff --git a/CMSIS/RTOS2/RTX/Include/rtx_evr.h b/CMSIS/RTOS2/RTX/Include/rtx_evr.h
index 970255c..05e75ac 100644
--- a/CMSIS/RTOS2/RTX/Include/rtx_evr.h
+++ b/CMSIS/RTOS2/RTX/Include/rtx_evr.h
@@ -27,8 +27,8 @@
 #define RTX_EVR_H_
 
 #include "cmsis_os2.h"                  // CMSIS RTOS API
+#include "RTX_Config.h"                 // RTX Configuration
 #include "rtx_os.h"                     // RTX OS definitions
-#include "RTX_Config.h"
 
 
 /// Extended Status codes
diff --git a/CMSIS/RTOS2/RTX/Include/rtx_os.h b/CMSIS/RTOS2/RTX/Include/rtx_os.h
index a29caac..84744ae 100644
--- a/CMSIS/RTOS2/RTX/Include/rtx_os.h
+++ b/CMSIS/RTOS2/RTX/Include/rtx_os.h
@@ -343,6 +343,22 @@
  
 extern osRtxInfo_t osRtxInfo;           ///< OS Runtime Information
  
+/// OS Runtime Object Memory Usage structure
+typedef struct {
+  uint32_t cnt_alloc;                   ///< Counter for alloc
+  uint32_t cnt_free;                    ///< Counter for free
+  uint32_t max_used;                    ///< Maximum used
+} osRtxObjectMemUsage_t;
+ 
+/// OS Runtime Object Memory Usage variables
+extern osRtxObjectMemUsage_t osRtxThreadMemUsage;
+extern osRtxObjectMemUsage_t osRtxTimerMemUsage;
+extern osRtxObjectMemUsage_t osRtxEventFlagsMemUsage;
+extern osRtxObjectMemUsage_t osRtxMutexMemUsage;
+extern osRtxObjectMemUsage_t osRtxSemaphoreMemUsage;
+extern osRtxObjectMemUsage_t osRtxMemoryPoolMemUsage;
+extern osRtxObjectMemUsage_t osRtxMessageQueueMemUsage;
+ 
  
 //  ==== OS API definitions ====
  
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_evflags.c b/CMSIS/RTOS2/RTX/Source/rtx_evflags.c
index f30c16a..df990cd 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_evflags.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_evflags.c
@@ -26,6 +26,14 @@
 #include "rtx_lib.h"
 
 
+//  OS Runtime Object Memory Usage
+#if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)))
+osRtxObjectMemUsage_t osRtxEventFlagsMemUsage \
+__attribute__((section(".data.os.evflags.obj"))) =
+{ 0U, 0U, 0U };
+#endif
+
+
 //  ==== Helper functions ====
 
 /// Set Event Flags.
@@ -197,6 +205,16 @@
       //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);
     }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+    if (ef != NULL) {
+      uint32_t used;
+      osRtxEventFlagsMemUsage.cnt_alloc++;
+      used = osRtxEventFlagsMemUsage.cnt_alloc - osRtxEventFlagsMemUsage.cnt_free;
+      if (osRtxEventFlagsMemUsage.max_used < used) {
+        osRtxEventFlagsMemUsage.max_used = used;
+      }
+    }
+#endif
     flags = osRtxFlagSystemObject;
   } else {
     flags = 0U;
@@ -446,6 +464,9 @@
     } else {
       (void)osRtxMemoryFree(osRtxInfo.mem.common, ef);
     }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+    osRtxEventFlagsMemUsage.cnt_free++;
+#endif
   }
 
   EvrRtxEventFlagsDestroyed(ef);
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_evr.c b/CMSIS/RTOS2/RTX/Source/rtx_evr.c
index 7969f0c..1b03c5f 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_evr.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_evr.c
@@ -27,9 +27,11 @@
 #include "cmsis_compiler.h"
 #include "rtx_evr.h"                    // RTX Event Recorder definitions
 
+#ifndef RTE_COMPONENTS_H
 #include "RTE_Components.h"
+#endif
 
-#ifdef RTE_Compiler_EventRecorder
+#ifdef  RTE_Compiler_EventRecorder
 
 //lint -e923 -e9074 -e9078 -emacro((835,845),EventID) [MISRA Note 13]
 
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_lib.c b/CMSIS/RTOS2/RTX/Source/rtx_lib.c
index cb58a4c..d0c5ada 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_lib.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_lib.c
@@ -24,8 +24,8 @@
  */
 
 #include "cmsis_compiler.h"
-#include "rtx_os.h"
 #include "RTX_Config.h"
+#include "rtx_os.h"
 
 
 // System Configuration
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_lib.h b/CMSIS/RTOS2/RTX/Source/rtx_lib.h
index 4666b1e..58a2a5a 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_lib.h
+++ b/CMSIS/RTOS2/RTX/Source/rtx_lib.h
@@ -32,8 +32,9 @@
      (defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ != 0)))
 #include "tz_context.h"                 // TrustZone Context API
 #endif
-#include "os_tick.h"
+#include "os_tick.h"                    // CMSIS OS Tick API
 #include "cmsis_os2.h"                  // CMSIS RTOS API
+#include "RTX_Config.h"                 // RTX Configuration
 #include "rtx_os.h"                     // RTX OS definitions
 #include "rtx_evr.h"                    // RTX Event Recorder definitions
 
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_memory.c b/CMSIS/RTOS2/RTX/Source/rtx_memory.c
index e40ca7b..9ba5680 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_memory.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_memory.c
@@ -35,11 +35,12 @@
 //  Memory Block Header structure
 typedef struct mem_block_s {
   struct mem_block_s *next;     // Next Memory Block in list
-  uint32_t            info;     // Info: length = <31:2>:'00', type = <1:0>
+  uint32_t            info;     // Block Info or max used Memory (in last block)
 } mem_block_t;
 
-#define MB_INFO_LEN_MASK        0xFFFFFFFCU
-#define MB_INFO_TYPE_MASK       0x00000003U
+//  Memory Block Info: Length = <31:2>:'00', Type = <1:0>
+#define MB_INFO_LEN_MASK        0xFFFFFFFCU     // Length mask
+#define MB_INFO_TYPE_MASK       0x00000003U     // Type mask
 
 //  Memory Head Pointer
 __STATIC_INLINE mem_head_t *MemHeadPtr (void *mem) {
@@ -70,6 +71,7 @@
   mem_head_t  *head;
   mem_block_t *ptr;
 
+  // Check parameters
   //lint -e{923} "cast from pointer to unsigned int" [MISRA Note 7]
   if ((mem == NULL) || (((uint32_t)mem & 7U) != 0U) || ((size & 7U) != 0U) ||
       (size < (sizeof(mem_head_t) + (2U*sizeof(mem_block_t))))) {
@@ -78,13 +80,16 @@
     return 0U;
   }
 
+  // Initialize memory pool header
   head = MemHeadPtr(mem);
   head->size = size;
   head->used = sizeof(mem_head_t) + sizeof(mem_block_t);
 
+  // Initialize first and last block header
   ptr = MemBlockPtr(mem, sizeof(mem_head_t));
   ptr->next = MemBlockPtr(mem, size - sizeof(mem_block_t));
   ptr->next->next = NULL;
+  ptr->next->info = sizeof(mem_head_t) + sizeof(mem_block_t);
   ptr->info = 0U;
 
   EvrRtxMemoryInit(mem, size, 1U);
@@ -103,13 +108,14 @@
   uint32_t     block_size;
   uint32_t     hole_size;
 
+  // Check parameters
   if ((mem == NULL) || (size == 0U) || ((type & ~MB_INFO_TYPE_MASK) != 0U)) {
     EvrRtxMemoryAlloc(mem, size, type, NULL);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return NULL;
   }
 
-  // Add header to size
+  // Add block header to size
   block_size = size + sizeof(mem_block_t);
   // Make sure that block is 8-byte aligned
   block_size = (block_size + 7U) & ~((uint32_t)7U);
@@ -133,8 +139,16 @@
     }
   }
 
+  // Update used memory
   (MemHeadPtr(mem))->used += block_size;
 
+  // Update max used memory
+  p_new = MemBlockPtr(mem, (MemHeadPtr(mem))->size - sizeof(mem_block_t));
+  if (p_new->info < (MemHeadPtr(mem))->used) {
+    p_new->info = (MemHeadPtr(mem))->used;
+  }
+
+  // Allocate block
   if (p->info == 0U) {
     // No block allocated, set info of first element
     p->info = block_size | type;
@@ -161,16 +175,18 @@
   const mem_block_t *ptr;
         mem_block_t *p, *p_prev;
 
+  // Check parameters
   if ((mem == NULL) || (block == NULL)) {
     EvrRtxMemoryFree(mem, block, 0U);
     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
     return 0U;
   }
 
+  // Memory block header
   ptr = MemBlockPtr(block, 0U);
   ptr--;
 
-  // Search for header
+  // Search for block header
   p_prev = NULL;
   p = MemBlockPtr(mem, sizeof(mem_head_t));
   while (p != ptr) {
@@ -184,8 +200,10 @@
     }
   }
 
+  // Update used memory
   (MemHeadPtr(mem))->used -= p->info & MB_INFO_LEN_MASK;
 
+  // Free block
   if (p_prev == NULL) {
     // Release first block, only set info to 0
     p->info = 0U;
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_mempool.c b/CMSIS/RTOS2/RTX/Source/rtx_mempool.c
index 35dd470..f635908 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_mempool.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_mempool.c
@@ -26,6 +26,14 @@
 #include "rtx_lib.h"
 
 
+//  OS Runtime Object Memory Usage
+#if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)))
+osRtxObjectMemUsage_t osRtxMemoryPoolMemUsage \
+__attribute__((section(".data.os.mempool.obj"))) =
+{ 0U, 0U, 0U };
+#endif
+
+
 //  ==== Library functions ====
 
 /// Initialize Memory Pool.
@@ -270,6 +278,16 @@
       //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);
     }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+    if (mp != NULL) {
+      uint32_t used;
+      osRtxMemoryPoolMemUsage.cnt_alloc++;
+      used = osRtxMemoryPoolMemUsage.cnt_alloc - osRtxMemoryPoolMemUsage.cnt_free;
+      if (osRtxMemoryPoolMemUsage.max_used < used) {
+        osRtxMemoryPoolMemUsage.max_used = used;
+      }
+    }
+#endif
     flags = osRtxFlagSystemObject;
   } else {
     flags = 0U;
@@ -286,6 +304,9 @@
         } else {
           (void)osRtxMemoryFree(osRtxInfo.mem.common, mp);
         }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+        osRtxMemoryPoolMemUsage.cnt_free++;
+#endif
       }
       mp = NULL;
     } else {
@@ -565,6 +586,9 @@
     } else {
       (void)osRtxMemoryFree(osRtxInfo.mem.common, mp);
     }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+    osRtxMemoryPoolMemUsage.cnt_free++;
+#endif
   }
 
   EvrRtxMemoryPoolDestroyed(mp);
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_msgqueue.c b/CMSIS/RTOS2/RTX/Source/rtx_msgqueue.c
index 623f7a0..762c97d 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_msgqueue.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_msgqueue.c
@@ -26,6 +26,14 @@
 #include "rtx_lib.h"
 
 
+//  OS Runtime Object Memory Usage
+#if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)))
+osRtxObjectMemUsage_t osRtxMessageQueueMemUsage \
+__attribute__((section(".data.os.msgqueue.obj"))) =
+{ 0U, 0U, 0U };
+#endif
+
+
 //  ==== Helper functions ====
 
 /// Put a Message into Queue sorted by Priority (Highest at Head).
@@ -316,6 +324,16 @@
       //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);
     }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+    if (mq != NULL) {
+      uint32_t used;
+      osRtxMessageQueueMemUsage.cnt_alloc++;
+      used = osRtxMessageQueueMemUsage.cnt_alloc - osRtxMessageQueueMemUsage.cnt_free;
+      if (osRtxMessageQueueMemUsage.max_used < used) {
+        osRtxMessageQueueMemUsage.max_used = used;
+      }
+    }
+#endif
     flags = osRtxFlagSystemObject;
   } else {
     flags = 0U;
@@ -332,6 +350,9 @@
         } else {
           (void)osRtxMemoryFree(osRtxInfo.mem.common, mq);
         }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+        osRtxMessageQueueMemUsage.cnt_free++;
+#endif
       }
       mq = NULL;
     } else {
@@ -769,6 +790,9 @@
     } else {
       (void)osRtxMemoryFree(osRtxInfo.mem.common, mq);
     }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+    osRtxMessageQueueMemUsage.cnt_free++;
+#endif
   }
 
   EvrRtxMessageQueueDestroyed(mq);
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_mutex.c b/CMSIS/RTOS2/RTX/Source/rtx_mutex.c
index a61380e..ce19449 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_mutex.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_mutex.c
@@ -26,6 +26,14 @@
 #include "rtx_lib.h"
 
 
+//  OS Runtime Object Memory Usage
+#if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)))
+osRtxObjectMemUsage_t osRtxMutexMemUsage \
+__attribute__((section(".data.os.mutex.obj"))) =
+{ 0U, 0U, 0U };
+#endif
+
+
 //  ==== Library functions ====
 
 /// Release Mutex list when owner Thread terminates.
@@ -108,6 +116,16 @@
       //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);
     }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+    if (mutex != NULL) {
+      uint32_t used;
+      osRtxMutexMemUsage.cnt_alloc++;
+      used = osRtxMutexMemUsage.cnt_alloc - osRtxMutexMemUsage.cnt_free;
+      if (osRtxMutexMemUsage.max_used < used) {
+        osRtxMutexMemUsage.max_used = used;
+      }
+    }
+#endif
     flags = osRtxFlagSystemObject;
   } else {
     flags = 0U;
@@ -445,6 +463,9 @@
     } else {
       (void)osRtxMemoryFree(osRtxInfo.mem.common, mutex);
     }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+    osRtxMutexMemUsage.cnt_free++;
+#endif
   }
 
   EvrRtxMutexDestroyed(mutex);
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_semaphore.c b/CMSIS/RTOS2/RTX/Source/rtx_semaphore.c
index a51deeb..510f331 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_semaphore.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_semaphore.c
@@ -26,6 +26,14 @@
 #include "rtx_lib.h"
 
 
+//  OS Runtime Object Memory Usage
+#if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)))
+osRtxObjectMemUsage_t osRtxSemaphoreMemUsage \
+__attribute__((section(".data.os.semaphore.obj"))) =
+{ 0U, 0U, 0U };
+#endif
+
+
 //  ==== Helper functions ====
 
 /// Decrement Semaphore tokens.
@@ -169,6 +177,16 @@
       //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);
     }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+    if (semaphore != NULL) {
+      uint32_t used;
+      osRtxSemaphoreMemUsage.cnt_alloc++;
+      used = osRtxSemaphoreMemUsage.cnt_alloc - osRtxSemaphoreMemUsage.cnt_free;
+      if (osRtxSemaphoreMemUsage.max_used < used) {
+        osRtxSemaphoreMemUsage.max_used = used;
+      }
+    }
+#endif
     flags = osRtxFlagSystemObject;
   } else {
     flags = 0U;
@@ -369,6 +387,9 @@
     } else {
       (void)osRtxMemoryFree(osRtxInfo.mem.common, semaphore);
     }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+    osRtxSemaphoreMemUsage.cnt_free++;
+#endif
   }
 
   EvrRtxSemaphoreDestroyed(semaphore);
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_thread.c b/CMSIS/RTOS2/RTX/Source/rtx_thread.c
index fd53057..b811e5e 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_thread.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_thread.c
@@ -26,6 +26,14 @@
 #include "rtx_lib.h"
 
 
+//  OS Runtime Object Memory Usage
+#if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)))
+osRtxObjectMemUsage_t osRtxThreadMemUsage \
+__attribute__((section(".data.os.thread.obj"))) =
+{ 0U, 0U, 0U };
+#endif
+
+
 //  ==== Helper functions ====
 
 /// Set Thread Flags.
@@ -657,6 +665,16 @@
       //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);
     }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+    if (thread != NULL) {
+      uint32_t used;
+      osRtxThreadMemUsage.cnt_alloc++;
+      used = osRtxThreadMemUsage.cnt_alloc - osRtxThreadMemUsage.cnt_free;
+      if (osRtxThreadMemUsage.max_used < used) {
+        osRtxThreadMemUsage.max_used = used;
+      }
+    }
+#endif
     flags = osRtxFlagSystemObject;
   } else {
     flags = 0U;
@@ -687,6 +705,9 @@
         } else {
           (void)osRtxMemoryFree(osRtxInfo.mem.common, thread);
         }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+        osRtxThreadMemUsage.cnt_free++;
+#endif
       }
       thread = NULL;
     }
@@ -712,6 +733,9 @@
         } else {
           (void)osRtxMemoryFree(osRtxInfo.mem.common, thread);
         }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+        osRtxThreadMemUsage.cnt_free++;
+#endif
       }
       thread = NULL;
     }
@@ -1109,6 +1133,9 @@
     } else {
       (void)osRtxMemoryFree(osRtxInfo.mem.common, thread);
     }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+    osRtxThreadMemUsage.cnt_free++;
+#endif
   }
 }
 
diff --git a/CMSIS/RTOS2/RTX/Source/rtx_timer.c b/CMSIS/RTOS2/RTX/Source/rtx_timer.c
index f4ac620..2695194 100644
--- a/CMSIS/RTOS2/RTX/Source/rtx_timer.c
+++ b/CMSIS/RTOS2/RTX/Source/rtx_timer.c
@@ -26,6 +26,14 @@
 #include "rtx_lib.h"
 
 
+//  OS Runtime Object Memory Usage
+#if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)))
+osRtxObjectMemUsage_t osRtxTimerMemUsage \
+__attribute__((section(".data.os.timer.obj"))) =
+{ 0U, 0U, 0U };
+#endif
+
+
 //  ==== Helper functions ====
 
 /// Insert Timer into the Timer List sorted by Time.
@@ -183,6 +191,16 @@
       //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);
     }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+    if (timer != NULL) {
+      uint32_t used;
+      osRtxTimerMemUsage.cnt_alloc++;
+      used = osRtxTimerMemUsage.cnt_alloc - osRtxTimerMemUsage.cnt_free;
+      if (osRtxTimerMemUsage.max_used < used) {
+        osRtxTimerMemUsage.max_used = used;
+      }
+    }
+#endif
     flags = osRtxFlagSystemObject;
   } else {
     flags = 0U;
@@ -357,6 +375,9 @@
     } else {
       (void)osRtxMemoryFree(osRtxInfo.mem.common, timer);
     }
+#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
+    osRtxTimerMemUsage.cnt_free++;
+#endif
   }
 
   EvrRtxTimerDestroyed(timer);