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 #elif CONFIG_IDF_TARGET_ESP32S3
77 #include "esp32s3/clk.h"
78 #elif CONFIG_IDF_TARGET_ESP32C3
79 #include "esp32c3/clk.h"
80 #endif
81 
82 
83 extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
84 
85 /*********************************************************************
86 *
87 *       Defines, configurable
88 *
89 **********************************************************************
90 */
91 // The application name to be displayed in SystemViewer
92 #define SYSVIEW_APP_NAME        "FreeRTOS Application"
93 
94 // The target device name
95 #define SYSVIEW_DEVICE_NAME     CONFIG_IDF_TARGET
96 // The target core name
97 #if CONFIG_IDF_TARGET_ARCH_XTENSA
98 #define SYSVIEW_CORE_NAME       "xtensa"
99 #elif CONFIG_IDF_TARGET_ARCH_RISCV
100 #define SYSVIEW_CORE_NAME       "riscv"
101 #endif
102 
103 // Determine which timer to use as timestamp source
104 #if CONFIG_APPTRACE_SV_TS_SOURCE_CCOUNT
105 #define TS_USE_CCOUNT 1
106 #elif CONFIG_APPTRACE_SV_TS_SOURCE_ESP_TIMER
107 #define TS_USE_ESP_TIMER 1
108 #else
109 #define TS_USE_TIMERGROUP 1
110 #endif
111 
112 #if TS_USE_TIMERGROUP
113 #include "driver/timer.h"
114 
115 // Timer group timer divisor
116 #define SYSVIEW_TIMER_DIV       2
117 
118 // Frequency of the timestamp.
119 #define SYSVIEW_TIMESTAMP_FREQ  (esp_clk_apb_freq() / SYSVIEW_TIMER_DIV)
120 
121 // Timer ID and group ID
122 #if defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00) || defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_10)
123 #define TS_TIMER_ID 0
124 #else
125 #define TS_TIMER_ID 1
126 #endif // TIMER_00 || TIMER_01
127 
128 #if defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00) || defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_01)
129 #define TS_TIMER_GROUP 0
130 #else
131 #define TS_TIMER_GROUP 1
132 #endif // TIMER_00 || TIMER_10
133 
134 #endif // TS_USE_TIMERGROUP
135 
136 #if TS_USE_ESP_TIMER
137 // esp_timer provides 1us resolution
138 #define SYSVIEW_TIMESTAMP_FREQ  (1000000)
139 #endif // TS_USE_ESP_TIMER
140 
141 #if TS_USE_CCOUNT
142 // CCOUNT is incremented at CPU frequency
143 #if CONFIG_IDF_TARGET_ESP32
144 #define SYSVIEW_TIMESTAMP_FREQ  (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000)
145 #elif CONFIG_IDF_TARGET_ESP32S2
146 #define SYSVIEW_TIMESTAMP_FREQ  (CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ * 1000000)
147 #elif CONFIG_IDF_TARGET_ESP32S3
148 #define SYSVIEW_TIMESTAMP_FREQ  (CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ * 1000000)
149 #endif
150 #endif // TS_USE_CCOUNT
151 
152 // System Frequency.
153 #define SYSVIEW_CPU_FREQ        (esp_clk_cpu_freq())
154 
155 // The lowest RAM address used for IDs (pointers)
156 #define SYSVIEW_RAM_BASE        (SOC_DROM_LOW)
157 
158 #ifdef CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER
159 #if CONFIG_FREERTOS_CORETIMER_0
160     #define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER0_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
161 #endif
162 #if CONFIG_FREERTOS_CORETIMER_1
163     #define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER1_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
164 #endif
165 
166 #elif CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER
167     #define SYSTICK_INTR_ID (ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE)
168 #endif // CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER
169 
170 // SystemView is single core specific: it implies that SEGGER_SYSVIEW_LOCK()
171 // disables IRQs (disables rescheduling globally). So we can not use finite timeouts for locks and return error
172 // in case of expiration, because error will not be handled and SEGGER's code will go further implying that
173 // everything is fine, so for multi-core env we have to wait on underlying lock forever
174 #define SEGGER_LOCK_WAIT_TMO  ESP_APPTRACE_TMO_INFINITE
175 
176 static esp_apptrace_lock_t s_sys_view_lock = {.mux = portMUX_INITIALIZER_UNLOCKED, .int_state = 0};
177 
178 /*********************************************************************
179 *
180 *       _cbSendSystemDesc()
181 *
182 *  Function description
183 *    Sends SystemView description strings.
184 */
_cbSendSystemDesc(void)185 static void _cbSendSystemDesc(void) {
186     char irq_str[32];
187     SEGGER_SYSVIEW_SendSysDesc("N="SYSVIEW_APP_NAME",D="SYSVIEW_DEVICE_NAME",C="SYSVIEW_CORE_NAME",O=FreeRTOS");
188     snprintf(irq_str, sizeof(irq_str), "I#%d=SysTick", SYSTICK_INTR_ID);
189     SEGGER_SYSVIEW_SendSysDesc(irq_str);
190     size_t isr_count = sizeof(esp_isr_names)/sizeof(esp_isr_names[0]);
191     for (size_t i = 0; i < isr_count; ++i) {
192         if (esp_isr_names[i] == NULL || (ETS_INTERNAL_INTR_SOURCE_OFF + i) == SYSTICK_INTR_ID)
193             continue;
194         snprintf(irq_str, sizeof(irq_str), "I#%d=%s", ETS_INTERNAL_INTR_SOURCE_OFF + i, esp_isr_names[i]);
195         SEGGER_SYSVIEW_SendSysDesc(irq_str);
196     }
197 }
198 
199 /*********************************************************************
200 *
201 *       Global functions
202 *
203 **********************************************************************
204 */
SEGGER_SYSVIEW_TS_Init(void)205 static void SEGGER_SYSVIEW_TS_Init(void)
206 {
207     /* We only need to initialize something if we use Timer Group.
208      * esp_timer and ccount can be used as is.
209      */
210 #if TS_USE_TIMERGROUP
211     timer_config_t config = {
212         .alarm_en = 0,
213         .auto_reload = 0,
214         .counter_dir = TIMER_COUNT_UP,
215         .divider = SYSVIEW_TIMER_DIV,
216         .counter_en = 0
217     };
218     /* Configure timer */
219     timer_init(TS_TIMER_GROUP, TS_TIMER_ID, &config);
220     /* Load counter value */
221     timer_set_counter_value(TS_TIMER_GROUP, TS_TIMER_ID, 0x00000000ULL);
222     /* Start counting */
223     timer_start(TS_TIMER_GROUP, TS_TIMER_ID);
224 #endif // TS_USE_TIMERGROUP
225 }
226 
SEGGER_SYSVIEW_Conf(void)227 void SEGGER_SYSVIEW_Conf(void) {
228     U32 disable_evts = 0;
229 
230     SEGGER_SYSVIEW_TS_Init();
231     SEGGER_SYSVIEW_Init(SYSVIEW_TIMESTAMP_FREQ, SYSVIEW_CPU_FREQ,
232                         &SYSVIEW_X_OS_TraceAPI, _cbSendSystemDesc);
233     SEGGER_SYSVIEW_SetRAMBase(SYSVIEW_RAM_BASE);
234 
235 #if !CONFIG_APPTRACE_SV_EVT_OVERFLOW_ENABLE
236     disable_evts |= SYSVIEW_EVTMASK_OVERFLOW;
237 #endif
238 #if !CONFIG_APPTRACE_SV_EVT_ISR_ENTER_ENABLE
239     disable_evts |= SYSVIEW_EVTMASK_ISR_ENTER;
240 #endif
241 #if !CONFIG_APPTRACE_SV_EVT_ISR_EXIT_ENABLE
242     disable_evts |= SYSVIEW_EVTMASK_ISR_EXIT;
243 #endif
244 #if !CONFIG_APPTRACE_SV_EVT_TASK_START_EXEC_ENABLE
245     disable_evts |= SYSVIEW_EVTMASK_TASK_START_EXEC;
246 #endif
247 #if !CONFIG_APPTRACE_SV_EVT_TASK_STOP_EXEC_ENABLE
248     disable_evts |= SYSVIEW_EVTMASK_TASK_STOP_EXEC;
249 #endif
250 #if !CONFIG_APPTRACE_SV_EVT_TASK_START_READY_ENABLE
251     disable_evts |= SYSVIEW_EVTMASK_TASK_START_READY;
252 #endif
253 #if !CONFIG_APPTRACE_SV_EVT_TASK_STOP_READY_ENABLE
254     disable_evts |= SYSVIEW_EVTMASK_TASK_STOP_READY;
255 #endif
256 #if !CONFIG_APPTRACE_SV_EVT_TASK_CREATE_ENABLE
257     disable_evts |= SYSVIEW_EVTMASK_TASK_CREATE;
258 #endif
259 #if !CONFIG_APPTRACE_SV_EVT_TASK_TERMINATE_ENABLE
260     disable_evts |= SYSVIEW_EVTMASK_TASK_TERMINATE;
261 #endif
262 #if !CONFIG_APPTRACE_SV_EVT_IDLE_ENABLE
263     disable_evts |= SYSVIEW_EVTMASK_IDLE;
264 #endif
265 #if !CONFIG_APPTRACE_SV_EVT_ISR_TO_SCHED_ENABLE
266     disable_evts |= SYSVIEW_EVTMASK_ISR_TO_SCHEDULER;
267 #endif
268 #if !CONFIG_APPTRACE_SV_EVT_TIMER_ENTER_ENABLE
269     disable_evts |= SYSVIEW_EVTMASK_TIMER_ENTER;
270 #endif
271 #if !CONFIG_APPTRACE_SV_EVT_TIMER_EXIT_ENABLE
272     disable_evts |= SYSVIEW_EVTMASK_TIMER_EXIT;
273 #endif
274   SEGGER_SYSVIEW_DisableEvents(disable_evts);
275 }
276 
SEGGER_SYSVIEW_X_GetTimestamp(void)277 U32 SEGGER_SYSVIEW_X_GetTimestamp(void)
278 {
279 #if TS_USE_TIMERGROUP
280     uint64_t ts = 0;
281     timer_get_counter_value(TS_TIMER_GROUP, TS_TIMER_ID, &ts);
282     return (U32) ts; // return lower part of counter value
283 #elif TS_USE_CCOUNT
284     return portGET_RUN_TIME_COUNTER_VALUE();
285 #elif TS_USE_ESP_TIMER
286     return (U32) esp_timer_get_time(); // return lower part of counter value
287 #endif
288 }
289 
SEGGER_SYSVIEW_X_RTT_Lock(void)290 void SEGGER_SYSVIEW_X_RTT_Lock(void)
291 {
292 }
293 
SEGGER_SYSVIEW_X_RTT_Unlock(void)294 void SEGGER_SYSVIEW_X_RTT_Unlock(void)
295 {
296 }
297 
SEGGER_SYSVIEW_X_SysView_Lock(void)298 unsigned SEGGER_SYSVIEW_X_SysView_Lock(void)
299 {
300     esp_apptrace_tmo_t tmo;
301     esp_apptrace_tmo_init(&tmo, SEGGER_LOCK_WAIT_TMO);
302     esp_apptrace_lock_take(&s_sys_view_lock, &tmo);
303     // to be recursive save IRQ status on the stack of the caller to keep it from overwriting
304     return s_sys_view_lock.int_state;
305 }
306 
SEGGER_SYSVIEW_X_SysView_Unlock(unsigned int_state)307 void SEGGER_SYSVIEW_X_SysView_Unlock(unsigned int_state)
308 {
309     s_sys_view_lock.int_state = int_state;
310     esp_apptrace_lock_give(&s_sys_view_lock);
311 }
312 
313 /*************************** End of file ****************************/
314