1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <SEGGER_SYSVIEW.h>
9 #include <ksched.h>
10
11 extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
12
13 #if CONFIG_THREAD_MAX_NAME_LEN
14 #define THREAD_NAME_LEN CONFIG_THREAD_MAX_NAME_LEN
15 #else
16 #define THREAD_NAME_LEN 20
17 #endif
18
19
set_thread_name(char * name,struct k_thread * thread)20 static void set_thread_name(char *name, struct k_thread *thread)
21 {
22 const char *tname = k_thread_name_get(thread);
23
24 if (tname != NULL && tname[0] != '\0') {
25 memcpy(name, tname, THREAD_NAME_LEN);
26 name[THREAD_NAME_LEN - 1] = '\0';
27 } else {
28 snprintk(name, THREAD_NAME_LEN, "T%pE%p",
29 thread, &thread->entry);
30 }
31 }
32
sys_trace_thread_info(struct k_thread * thread)33 void sys_trace_thread_info(struct k_thread *thread)
34 {
35 char name[THREAD_NAME_LEN];
36
37 set_thread_name(name, thread);
38
39 SEGGER_SYSVIEW_TASKINFO Info;
40
41 Info.TaskID = (uint32_t)(uintptr_t)thread;
42 Info.sName = name;
43 Info.Prio = thread->base.prio;
44 Info.StackBase = thread->stack_info.size;
45 Info.StackSize = thread->stack_info.start;
46 SEGGER_SYSVIEW_SendTaskInfo(&Info);
47 }
48
49
cbSendSystemDesc(void)50 static void cbSendSystemDesc(void)
51 {
52 SEGGER_SYSVIEW_SendSysDesc("N=" CONFIG_SEGGER_SYSVIEW_APP_NAME);
53 SEGGER_SYSVIEW_SendSysDesc("D=" CONFIG_BOARD " "
54 CONFIG_SOC_SERIES " " CONFIG_ARCH);
55 SEGGER_SYSVIEW_SendSysDesc("O=Zephyr");
56 }
57
send_task_list_cb(void)58 static void send_task_list_cb(void)
59 {
60 struct k_thread *thread;
61
62 for (thread = _kernel.threads; thread; thread = thread->next_thread) {
63 char name[THREAD_NAME_LEN];
64
65 if (z_is_idle_thread_object(thread)) {
66 continue;
67 }
68
69 set_thread_name(name, thread);
70
71 SEGGER_SYSVIEW_SendTaskInfo(&(SEGGER_SYSVIEW_TASKINFO) {
72 .TaskID = (uint32_t)(uintptr_t)thread,
73 .sName = name,
74 .StackSize = thread->stack_info.size,
75 .StackBase = thread->stack_info.start,
76 .Prio = thread->base.prio,
77 });
78 }
79 }
80
81
get_time_cb(void)82 static U64 get_time_cb(void)
83 {
84 return (U64)k_cycle_get_32();
85 }
86
87
88 const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI = {
89 get_time_cb,
90 send_task_list_cb,
91 };
92
93
94
SEGGER_SYSVIEW_Conf(void)95 void SEGGER_SYSVIEW_Conf(void)
96 {
97 SEGGER_SYSVIEW_Init(sys_clock_hw_cycles_per_sec(),
98 sys_clock_hw_cycles_per_sec(),
99 &SYSVIEW_X_OS_TraceAPI, cbSendSystemDesc);
100 #if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_sram), okay)
101 SEGGER_SYSVIEW_SetRAMBase(DT_REG_ADDR(DT_CHOSEN(zephyr_sram)));
102 #else
103 /* Setting RAMBase is just an optimization: this value is subtracted
104 * from all pointers in order to save bandwidth. It's not an error
105 * if a platform does not set this value.
106 */
107 #endif
108 }
109