This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Legacy thread trace (event viewer) support for RTX5/OS2

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) {