1 /*********************************************************************
2 * SEGGER Microcontroller GmbH & Co. KG *
3 * The Embedded Experts *
4 **********************************************************************
5 * *
6 * (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
7 * *
8 * www.segger.com Support: support@segger.com *
9 * *
10 **********************************************************************
11 * *
12 * SEGGER SystemView * Real-time application analysis *
13 * *
14 **********************************************************************
15 * *
16 * All rights reserved. *
17 * *
18 * SEGGER strongly recommends to not make any changes *
19 * to or modify the source code of this software in order to stay *
20 * compatible with the RTT protocol and J-Link. *
21 * *
22 * Redistribution and use in source and binary forms, with or *
23 * without modification, are permitted provided that the following *
24 * conditions are met: *
25 * *
26 * o Redistributions of source code must retain the above copyright *
27 * notice, this list of conditions and the following disclaimer. *
28 * *
29 * o Redistributions in binary form must reproduce the above *
30 * copyright notice, this list of conditions and the following *
31 * disclaimer in the documentation and/or other materials provided *
32 * with the distribution. *
33 * *
34 * o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
35 * nor the names of its contributors may be used to endorse or *
36 * promote products derived from this software without specific *
37 * prior written permission. *
38 * *
39 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
40 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
41 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
42 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
43 * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
44 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
45 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
46 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
47 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
48 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
49 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
50 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
51 * DAMAGE. *
52 * *
53 **********************************************************************
54 * *
55 * SystemView version: V2.42 *
56 * *
57 **********************************************************************
58 -------------------------- END-OF-HEADER -----------------------------
59
60 File : SEGGER_SYSVIEW_Config_FreeRTOS.c
61 Purpose : Sample setup configuration of SystemView with FreeRTOS.
62 Revision: $Rev: 3734 $
63 */
64 #include "sdkconfig.h"
65 #include "freertos/FreeRTOS.h"
66 #include "SEGGER_SYSVIEW.h"
67 #include "esp_app_trace.h"
68 #include "esp_app_trace_util.h"
69 #include "esp_intr_alloc.h"
70 #include "soc/soc.h"
71 #include "soc/interrupts.h"
72 #if CONFIG_IDF_TARGET_ESP32
73 #include "esp32/clk.h"
74 #elif CONFIG_IDF_TARGET_ESP32S2
75 #include "esp32s2/clk.h"
76 #endif
77
78
79 extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
80
81 /*********************************************************************
82 *
83 * Defines, configurable
84 *
85 **********************************************************************
86 */
87 // The application name to be displayed in SystemViewer
88 #define SYSVIEW_APP_NAME "FreeRTOS Application"
89
90 // The target device name
91 #define SYSVIEW_DEVICE_NAME CONFIG_IDF_TARGET
92
93 // Determine which timer to use as timestamp source
94 #if CONFIG_SYSVIEW_TS_SOURCE_CCOUNT
95 #define TS_USE_CCOUNT 1
96 #elif CONFIG_SYSVIEW_TS_SOURCE_ESP_TIMER
97 #define TS_USE_ESP_TIMER 1
98 #else
99 #define TS_USE_TIMERGROUP 1
100 #endif
101
102 #if TS_USE_TIMERGROUP
103 #include "driver/timer.h"
104
105 // Timer group timer divisor
106 #define SYSVIEW_TIMER_DIV 2
107
108 // Frequency of the timestamp.
109 #define SYSVIEW_TIMESTAMP_FREQ (esp_clk_apb_freq() / SYSVIEW_TIMER_DIV)
110
111 // Timer ID and group ID
112 #if defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_00) || defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_01)
113 #define TS_TIMER_ID 0
114 #else
115 #define TS_TIMER_ID 1
116 #endif // TIMER_00 || TIMER_01
117
118 #if defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_00) || defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_10)
119 #define TS_TIMER_GROUP 0
120 #else
121 #define TS_TIMER_GROUP 1
122 #endif // TIMER_00 || TIMER_10
123
124 #endif // TS_USE_TIMERGROUP
125
126 #if TS_USE_ESP_TIMER
127 // esp_timer provides 1us resolution
128 #define SYSVIEW_TIMESTAMP_FREQ (1000000)
129 #endif // TS_USE_ESP_TIMER
130
131 #if TS_USE_CCOUNT
132 // CCOUNT is incremented at CPU frequency
133 #if CONFIG_IDF_TARGET_ESP32
134 #define SYSVIEW_TIMESTAMP_FREQ (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000)
135 #elif CONFIG_IDF_TARGET_ESP32S2
136 #define SYSVIEW_TIMESTAMP_FREQ (CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ * 1000000)
137 #endif
138 #endif // TS_USE_CCOUNT
139
140 // System Frequency.
141 #define SYSVIEW_CPU_FREQ (esp_clk_cpu_freq())
142
143 // The lowest RAM address used for IDs (pointers)
144 #define SYSVIEW_RAM_BASE (SOC_DROM_LOW)
145
146 #if CONFIG_FREERTOS_CORETIMER_0
147 #define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER0_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
148 #endif
149 #if CONFIG_FREERTOS_CORETIMER_1
150 #define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER1_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
151 #endif
152
153 // SystemView is single core specific: it implies that SEGGER_SYSVIEW_LOCK()
154 // disables IRQs (disables rescheduling globally). So we can not use finite timeouts for locks and return error
155 // in case of expiration, because error will not be handled and SEGGER's code will go further implying that
156 // everything is fine, so for multi-core env we have to wait on underlying lock forever
157 #define SEGGER_LOCK_WAIT_TMO ESP_APPTRACE_TMO_INFINITE
158
159 static esp_apptrace_lock_t s_sys_view_lock = {.mux = portMUX_INITIALIZER_UNLOCKED, .int_state = 0};
160
161 /*********************************************************************
162 *
163 * _cbSendSystemDesc()
164 *
165 * Function description
166 * Sends SystemView description strings.
167 */
_cbSendSystemDesc(void)168 static void _cbSendSystemDesc(void) {
169 char irq_str[32];
170 SEGGER_SYSVIEW_SendSysDesc("N="SYSVIEW_APP_NAME",D="SYSVIEW_DEVICE_NAME",C=Xtensa,O=FreeRTOS");
171 snprintf(irq_str, sizeof(irq_str), "I#%d=SysTick", SYSTICK_INTR_ID);
172 SEGGER_SYSVIEW_SendSysDesc(irq_str);
173 size_t isr_count = sizeof(esp_isr_names)/sizeof(esp_isr_names[0]);
174 for (size_t i = 0; i < isr_count; ++i) {
175 snprintf(irq_str, sizeof(irq_str), "I#%d=%s", ETS_INTERNAL_INTR_SOURCE_OFF + i, esp_isr_names[i]);
176 SEGGER_SYSVIEW_SendSysDesc(irq_str);
177 }
178 }
179
180 /*********************************************************************
181 *
182 * Global functions
183 *
184 **********************************************************************
185 */
SEGGER_SYSVIEW_TS_Init(void)186 static void SEGGER_SYSVIEW_TS_Init(void)
187 {
188 /* We only need to initialize something if we use Timer Group.
189 * esp_timer and ccount can be used as is.
190 */
191 #if TS_USE_TIMERGROUP
192 timer_config_t config = {
193 .alarm_en = 0,
194 .auto_reload = 0,
195 .counter_dir = TIMER_COUNT_UP,
196 .divider = SYSVIEW_TIMER_DIV,
197 .counter_en = 0
198 };
199 /* Configure timer */
200 timer_init(TS_TIMER_GROUP, TS_TIMER_ID, &config);
201 /* Load counter value */
202 timer_set_counter_value(TS_TIMER_GROUP, TS_TIMER_ID, 0x00000000ULL);
203 /* Start counting */
204 timer_start(TS_TIMER_GROUP, TS_TIMER_ID);
205 #endif // TS_USE_TIMERGROUP
206 }
207
SEGGER_SYSVIEW_Conf(void)208 void SEGGER_SYSVIEW_Conf(void) {
209 U32 disable_evts = 0;
210
211 SEGGER_SYSVIEW_TS_Init();
212 SEGGER_SYSVIEW_Init(SYSVIEW_TIMESTAMP_FREQ, SYSVIEW_CPU_FREQ,
213 &SYSVIEW_X_OS_TraceAPI, _cbSendSystemDesc);
214 SEGGER_SYSVIEW_SetRAMBase(SYSVIEW_RAM_BASE);
215
216 #if !CONFIG_SYSVIEW_EVT_OVERFLOW_ENABLE
217 disable_evts |= SYSVIEW_EVTMASK_OVERFLOW;
218 #endif
219 #if !CONFIG_SYSVIEW_EVT_ISR_ENTER_ENABLE
220 disable_evts |= SYSVIEW_EVTMASK_ISR_ENTER;
221 #endif
222 #if !CONFIG_SYSVIEW_EVT_ISR_EXIT_ENABLE
223 disable_evts |= SYSVIEW_EVTMASK_ISR_EXIT;
224 #endif
225 #if !CONFIG_SYSVIEW_EVT_TASK_START_EXEC_ENABLE
226 disable_evts |= SYSVIEW_EVTMASK_TASK_START_EXEC;
227 #endif
228 #if !CONFIG_SYSVIEW_EVT_TASK_STOP_EXEC_ENABLE
229 disable_evts |= SYSVIEW_EVTMASK_TASK_STOP_EXEC;
230 #endif
231 #if !CONFIG_SYSVIEW_EVT_TASK_START_READY_ENABLE
232 disable_evts |= SYSVIEW_EVTMASK_TASK_START_READY;
233 #endif
234 #if !CONFIG_SYSVIEW_EVT_TASK_STOP_READY_ENABLE
235 disable_evts |= SYSVIEW_EVTMASK_TASK_STOP_READY;
236 #endif
237 #if !CONFIG_SYSVIEW_EVT_TASK_CREATE_ENABLE
238 disable_evts |= SYSVIEW_EVTMASK_TASK_CREATE;
239 #endif
240 #if !CONFIG_SYSVIEW_EVT_TASK_TERMINATE_ENABLE
241 disable_evts |= SYSVIEW_EVTMASK_TASK_TERMINATE;
242 #endif
243 #if !CONFIG_SYSVIEW_EVT_IDLE_ENABLE
244 disable_evts |= SYSVIEW_EVTMASK_IDLE;
245 #endif
246 #if !CONFIG_SYSVIEW_EVT_ISR_TO_SCHEDULER_ENABLE
247 disable_evts |= SYSVIEW_EVTMASK_ISR_TO_SCHEDULER;
248 #endif
249 #if !CONFIG_SYSVIEW_EVT_TIMER_ENTER_ENABLE
250 disable_evts |= SYSVIEW_EVTMASK_TIMER_ENTER;
251 #endif
252 #if !CONFIG_SYSVIEW_EVT_TIMER_EXIT_ENABLE
253 disable_evts |= SYSVIEW_EVTMASK_TIMER_EXIT;
254 #endif
255 SEGGER_SYSVIEW_DisableEvents(disable_evts);
256 }
257
SEGGER_SYSVIEW_X_GetTimestamp(void)258 U32 SEGGER_SYSVIEW_X_GetTimestamp(void)
259 {
260 #if TS_USE_TIMERGROUP
261 uint64_t ts = 0;
262 timer_get_counter_value(TS_TIMER_GROUP, TS_TIMER_ID, &ts);
263 return (U32) ts; // return lower part of counter value
264 #elif TS_USE_CCOUNT
265 return portGET_RUN_TIME_COUNTER_VALUE();
266 #elif TS_USE_ESP_TIMER
267 return (U32) esp_timer_get_time(); // return lower part of counter value
268 #endif
269 }
270
SEGGER_SYSVIEW_X_RTT_Lock(void)271 void SEGGER_SYSVIEW_X_RTT_Lock(void)
272 {
273 }
274
SEGGER_SYSVIEW_X_RTT_Unlock(void)275 void SEGGER_SYSVIEW_X_RTT_Unlock(void)
276 {
277 }
278
SEGGER_SYSVIEW_X_SysView_Lock(void)279 unsigned SEGGER_SYSVIEW_X_SysView_Lock(void)
280 {
281 esp_apptrace_tmo_t tmo;
282 esp_apptrace_tmo_init(&tmo, SEGGER_LOCK_WAIT_TMO);
283 esp_apptrace_lock_take(&s_sys_view_lock, &tmo);
284 // to be recursive save IRQ status on the stack of the caller to keep it from overwriting
285 return s_sys_view_lock.int_state;
286 }
287
SEGGER_SYSVIEW_X_SysView_Unlock(unsigned int_state)288 void SEGGER_SYSVIEW_X_SysView_Unlock(unsigned int_state)
289 {
290 s_sys_view_lock.int_state = int_state;
291 esp_apptrace_lock_give(&s_sys_view_lock);
292 }
293
294 /*************************** End of file ****************************/
295