1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/logging/log.h>
9 
10 #ifdef CONFIG_LOG_FRONTEND_STMESP
11 #include <zephyr/logging/log_frontend_stmesp.h>
12 #endif
13 
14 LOG_MODULE_REGISTER(app);
15 
16 #define TEST_LOG(rpt, item)                                                                        \
17 	({                                                                                         \
18 		uint32_t key = irq_lock();                                                         \
19 		uint32_t t = k_cycle_get_32();                                                     \
20 		for (uint32_t i = 0; i < rpt; i++) {                                               \
21 			__DEBRACKET item;                                                          \
22 		}                                                                                  \
23 		t = k_cycle_get_32() - t;                                                          \
24 		irq_unlock(key);                                                                   \
25 		k_msleep(400);                                                                     \
26 		t;                                                                                 \
27 	})
28 
29 static char *core_name = "unknown";
30 
get_core_name(void)31 static void get_core_name(void)
32 {
33 	if (strstr(CONFIG_BOARD_TARGET, "cpuapp")) {
34 		core_name = "app";
35 	} else if (strstr(CONFIG_BOARD_TARGET, "cpurad")) {
36 		core_name = "rad";
37 	} else if (strstr(CONFIG_BOARD_TARGET, "cpuppr")) {
38 		core_name = "ppr";
39 	} else if (strstr(CONFIG_BOARD_TARGET, "cpuflpr")) {
40 		core_name = "flpr";
41 	}
42 }
43 
t_to_ns(uint32_t t,uint32_t rpt,uint32_t freq)44 static uint32_t t_to_ns(uint32_t t, uint32_t rpt, uint32_t freq)
45 {
46 	return (uint32_t)(((uint64_t)t * 1000000000) / (uint64_t)(rpt * freq));
47 }
48 
timing_report(uint32_t t,uint32_t rpt,const char * str)49 static void timing_report(uint32_t t, uint32_t rpt, const char *str)
50 {
51 	uint32_t ns = t_to_ns(t, rpt, CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
52 
53 	LOG_RAW("%s: Timing for %s: %d.%dus\n", core_name, str, ns / 1000, (ns % 1000) / 10);
54 }
55 
main(void)56 int main(void)
57 {
58 	uint32_t t;
59 	uint32_t delta;
60 	uint32_t rpt = 10;
61 	uint32_t t0, t1, t2, t3, t_s;
62 	char str[] = "test string";
63 
64 	get_core_name();
65 
66 	t = k_cycle_get_32();
67 	delta = k_cycle_get_32() - t;
68 
69 	t0 = TEST_LOG(rpt, (LOG_INF("test no arguments")));
70 	t0 -= delta;
71 
72 	t1 = TEST_LOG(rpt, (LOG_INF("test with one argument %d", 100)));
73 	t1 -= delta;
74 
75 	t2 = TEST_LOG(rpt, (LOG_INF("test with two arguments %d %d", 100, 10)));
76 	t2 -= delta;
77 
78 	t3 = TEST_LOG(rpt, (LOG_INF("test with three arguments %d %d %d", 100, 10, 1)));
79 	t3 -= delta;
80 
81 	t_s = TEST_LOG(rpt, (LOG_INF("test with string %s", str)));
82 	t_s -= delta;
83 
84 #ifdef CONFIG_LOG_FRONTEND_STMESP
85 	uint32_t rpt_tp = 20;
86 	uint32_t t_tp, t_tpd;
87 
88 	t_tp = TEST_LOG(rpt_tp, (log_frontend_stmesp_tp(5)));
89 	t_tp -= delta;
90 
91 	t_tpd = TEST_LOG(rpt_tp, (log_frontend_stmesp_tp_d32(6, 10)));
92 	t_tpd -= delta;
93 #endif
94 
95 	timing_report(t0, rpt, "log message with 0 arguments");
96 	timing_report(t1, rpt, "log message with 1 argument");
97 	timing_report(t2, rpt, "log message with 2 arguments");
98 	timing_report(t3, rpt, "log message with 3 arguments");
99 	timing_report(t_s, rpt, "log_message with string");
100 
101 #ifdef CONFIG_LOG_FRONTEND_STMESP
102 	timing_report(t_tp, rpt_tp, "tracepoint");
103 	timing_report(t_tpd, rpt_tp, "tracepoint_d32");
104 #endif
105 
106 	/* Needed in coverage run to separate STM logs from printk() */
107 	k_msleep(400);
108 	return 0;
109 }
110