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