We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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) {