Hi,
as you now, the RTX5 has no support for old school event viewer. In 5.26 the system analyser has some support for OS2, but I realize a little buggy, and it needs DAP with eating memory.
So, I mine out a solution, and I hope this helps for many developers. I made a patch for 5.4.0 turns the event viewer for work again. You run the following batch from c:\Keil_v5\ARM\Pack\ARM\CMSIS:
attrib -R 5.4.0\CMSIS\RTOS2\RTX\Source\rtx_lib.c attrib -R 5.4.0\CMSIS\RTOS2\RTX\Source\rtx_thread.c attrib -R 5.4.0\CMSIS\RTOS2\RTX\Include\rtx_os.h cd 5.4.0 patch -p1 < ..\cmsis_5.4.0_legacy_trace.patch
The cmsis_5.4.0_legacy_trace.patch file content:
diff -urN 5.4.0.original\CMSIS\RTOS2\RTX\Include\rtx_os.h 5.4.0\CMSIS\RTOS2\RTX\Include\rtx_os.h --- 5.4.0.original\CMSIS\RTOS2\RTX\Include\rtx_os.h Wed Aug 01 16:34:14 2018 +++ 5.4.0\CMSIS\RTOS2\RTX\Include\rtx_os.h Fri Sep 21 08:07:37 2018 @@ -126,6 +126,7 @@ #ifdef RTX_TF_M_EXTENSION uint32_t tz_module; ///< TrustZone Module Identifier #endif + uint8_t trace_id; ///< Legacy id for old school trace } osRtxThread_t; diff -urN 5.4.0.original\CMSIS\RTOS2\RTX\Source\rtx_lib.c 5.4.0\CMSIS\RTOS2\RTX\Source\rtx_lib.c --- 5.4.0.original\CMSIS\RTOS2\RTX\Source\rtx_lib.c Wed Aug 01 16:34:14 2018 +++ 5.4.0\CMSIS\RTOS2\RTX\Source\rtx_lib.c Fri Sep 21 08:07:37 2018 @@ -118,7 +118,7 @@ // Idle Thread Control Block -static osRtxThread_t os_idle_thread_cb \ +osRtxThread_t os_idle_thread_cb \ __attribute__((section(".bss.os.thread.cb"))); // Idle Thread Stack diff -urN 5.4.0.original\CMSIS\RTOS2\RTX\Source\rtx_thread.c 5.4.0\CMSIS\RTOS2\RTX\Source\rtx_thread.c --- 5.4.0.original\CMSIS\RTOS2\RTX\Source\rtx_thread.c Wed Aug 01 16:34:14 2018 +++ 5.4.0\CMSIS\RTOS2\RTX\Source\rtx_thread.c Fri Sep 21 08:07:37 2018 @@ -26,6 +26,64 @@ #include "rtx_lib.h" +/* Definitions */ +#define INITIAL_xPSR 0x01000000U +#define DEMCR_TRCENA 0x01000000U +#define ITM_ITMENA 0x00000001U +#define MAGIC_WORD 0xE25A2EA5U +#define MAGIC_PATTERN 0xCCCCCCCCU + +/* Core Debug registers */ +#define DEMCR (*((volatile uint32_t *)0xE000EDFCU)) + +/* ITM registers */ +#define ITM_CONTROL (*((volatile uint32_t *)0xE0000E80U)) +#define ITM_ENABLE (*((volatile uint32_t *)0xE0000E00U)) +#define ITM_PORT30_U32 (*((volatile uint32_t *)0xE0000078U)) +#define ITM_PORT31_U32 (*((volatile uint32_t *)0xE000007CU)) +#define ITM_PORT31_U16 (*((volatile uint16_t *)0xE000007CU)) +#define ITM_PORT31_U8 (*((volatile uint8_t *)0xE000007CU)) + +char dbg_msg = 0; + +/*--------------------------- dbg_init --------------------------------------*/ + +void DBG_INIT (void) +{ + if (((DEMCR & DEMCR_TRCENA) != 0U) && + ((ITM_CONTROL & ITM_ITMENA) != 0U) && + ((ITM_ENABLE & (1UL << 31)) != 0U)) + { + dbg_msg = 1; + } +} + +/*--------------------------- dbg_task_notify -------------------------------*/ + +void DBG_TASK_NOTIFY (os_thread_t* thread, char create) +{ + if (!dbg_msg) return; + while (ITM_PORT31_U32 == 0U); + ITM_PORT31_U32 = (uint32_t)thread->thread_addr; + while (ITM_PORT31_U32 == 0U); + ITM_PORT31_U16 = (uint16_t)((create << 8) | (uint8_t)thread->trace_id); +} + +/*--------------------------- dbg_task_switch -------------------------------*/ + +void DBG_TASK_SWITCH (os_thread_t* thread) +{ + if (!dbg_msg) return; + //if (os_tsk.next == os_tsk.run) return; + while (ITM_PORT31_U32 == 0U); + ITM_PORT31_U8 = (uint8_t)thread->trace_id; +} + + + + + + // OS Runtime Object Memory Usage #if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))) osRtxObjectMemUsage_t osRtxThreadMemUsage \ @@ -434,6 +492,7 @@ osRtxInfo.thread.run.next = thread; osRtxThreadStackCheck(); EvrRtxThreadSwitched(thread); + DBG_TASK_SWITCH(osRtxInfo.thread.run.next); } /// Dispatch specified Thread or Ready Thread with Highest Priority. @@ -791,6 +850,13 @@ #endif #endif + static uint8_t trace_id = 0; + extern osRtxThread_t os_idle_thread_cb; + if (thread == &os_idle_thread_cb) + thread->trace_id = 255; + else + thread->trace_id = trace_id++; + // Initialize stack //lint --e{613} false detection: "Possible use of null pointer" ptr = (uint32_t *)stack_mem; @@ -817,6 +883,7 @@ osRtxInfo.post_process.thread = osRtxThreadPostProcess; EvrRtxThreadCreated(thread, thread->thread_addr, thread->name); + DBG_TASK_NOTIFY(thread, 1); } else { EvrRtxThreadError(NULL, (int32_t)osErrorNoMemory); } @@ -1257,6 +1324,7 @@ } EvrRtxThreadDestroyed(thread); + DBG_TASK_NOTIFY(thread, 0); } /// Terminate execution of a thread. @@ -1621,6 +1689,8 @@ /// \return true - success, false - failure. bool_t osRtxThreadStartup (void) { bool_t ret = TRUE; + + DBG_INIT(); // Create Idle Thread if (osRtxInfo.thread.idle == NULL) {