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_FreeRTOS.c
61 Purpose : Interface between FreeRTOS and SystemView.
62 Revision: $Rev: 3734 $
63 */
64 #include "freertos/FreeRTOS.h"
65 #include "freertos/task.h"
66 #include "SEGGER_SYSVIEW.h"
67 #include "SEGGER_SYSVIEW_FreeRTOS.h"
68 #include "string.h" // Required for memset
69
70
71
72 typedef struct SYSVIEW_FREERTOS_TASK_STATUS SYSVIEW_FREERTOS_TASK_STATUS;
73
74 struct SYSVIEW_FREERTOS_TASK_STATUS {
75 U32 xHandle;
76 const char* pcTaskName;
77 unsigned uxCurrentPriority;
78 U32 pxStack;
79 unsigned uStackHighWaterMark;
80 };
81
82 static SYSVIEW_FREERTOS_TASK_STATUS _aTasks[SYSVIEW_FREERTOS_MAX_NOF_TASKS];
83
84 /*********************************************************************
85 *
86 * _cbSendTaskList()
87 *
88 * Function description
89 * This function is part of the link between FreeRTOS and SYSVIEW.
90 * Called from SystemView when asked by the host, it uses SYSVIEW
91 * functions to send the entire task list to the host.
92 */
_cbSendTaskList(void)93 static void _cbSendTaskList(void) {
94 unsigned n;
95
96 for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
97 if (_aTasks[n].xHandle) {
98 #if INCLUDE_uxTaskGetStackHighWaterMark // Report Task Stack High Watermark
99 _aTasks[n].uStackHighWaterMark = uxTaskGetStackHighWaterMark((TaskHandle_t)_aTasks[n].xHandle);
100 #endif
101 SYSVIEW_SendTaskInfo((U32)_aTasks[n].xHandle, _aTasks[n].pcTaskName, (unsigned)_aTasks[n].uxCurrentPriority, (U32)_aTasks[n].pxStack, (unsigned)_aTasks[n].uStackHighWaterMark);
102 }
103 }
104 }
105
106 /*********************************************************************
107 *
108 * _cbGetTime()
109 *
110 * Function description
111 * This function is part of the link between FreeRTOS and SYSVIEW.
112 * Called from SystemView when asked by the host, returns the
113 * current system time in micro seconds.
114 */
_cbGetTime(void)115 static U64 _cbGetTime(void) {
116 U64 Time;
117
118 Time = xTaskGetTickCountFromISR();
119 Time *= portTICK_PERIOD_MS;
120 Time *= 1000;
121 return Time;
122 }
123
124 /*********************************************************************
125 *
126 * Global functions
127 *
128 **********************************************************************
129 */
130 /*********************************************************************
131 *
132 * SYSVIEW_AddTask()
133 *
134 * Function description
135 * Add a task to the internal list and record its information.
136 */
SYSVIEW_AddTask(U32 xHandle,const char * pcTaskName,unsigned uxCurrentPriority,U32 pxStack,unsigned uStackHighWaterMark)137 void SYSVIEW_AddTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
138 unsigned n;
139
140 if (memcmp(pcTaskName, "IDLE", 5) == 0) {
141 return;
142 }
143
144 for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
145 if (_aTasks[n].xHandle == 0) {
146 break;
147 }
148 }
149 if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
150 SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not record task information. Maximum number of tasks reached.");
151 return;
152 }
153
154 _aTasks[n].xHandle = xHandle;
155 _aTasks[n].pcTaskName = pcTaskName;
156 _aTasks[n].uxCurrentPriority = uxCurrentPriority;
157 _aTasks[n].pxStack = pxStack;
158 _aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
159
160 SYSVIEW_SendTaskInfo(xHandle, pcTaskName,uxCurrentPriority, pxStack, uStackHighWaterMark);
161
162 }
163
164 /*********************************************************************
165 *
166 * SYSVIEW_UpdateTask()
167 *
168 * Function description
169 * Update a task in the internal list and record its information.
170 */
SYSVIEW_UpdateTask(U32 xHandle,const char * pcTaskName,unsigned uxCurrentPriority,U32 pxStack,unsigned uStackHighWaterMark)171 void SYSVIEW_UpdateTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
172 unsigned n;
173
174 if (memcmp(pcTaskName, "IDLE", 5) == 0) {
175 return;
176 }
177
178 for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
179 if (_aTasks[n].xHandle == xHandle) {
180 break;
181 }
182 }
183 if (n < SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
184 _aTasks[n].pcTaskName = pcTaskName;
185 _aTasks[n].uxCurrentPriority = uxCurrentPriority;
186 _aTasks[n].pxStack = pxStack;
187 _aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
188
189 SYSVIEW_SendTaskInfo(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
190 } else {
191 SYSVIEW_AddTask(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
192 }
193 }
194
195 /*********************************************************************
196 *
197 * SYSVIEW_DeleteTask()
198 *
199 * Function description
200 * Delete a task from the internal list.
201 */
SYSVIEW_DeleteTask(U32 xHandle)202 void SYSVIEW_DeleteTask(U32 xHandle) {
203 unsigned n;
204
205 for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
206 if (_aTasks[n].xHandle == xHandle) {
207 break;
208 }
209 }
210 if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
211 SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not find task information. Cannot delete task.");
212 return;
213 }
214
215 _aTasks[n].xHandle = 0;
216 }
217
218 /*********************************************************************
219 *
220 * SYSVIEW_SendTaskInfo()
221 *
222 * Function description
223 * Record task information.
224 */
SYSVIEW_SendTaskInfo(U32 TaskID,const char * sName,unsigned Prio,U32 StackBase,unsigned StackSize)225 void SYSVIEW_SendTaskInfo(U32 TaskID, const char* sName, unsigned Prio, U32 StackBase, unsigned StackSize) {
226 SEGGER_SYSVIEW_TASKINFO TaskInfo;
227
228 memset(&TaskInfo, 0, sizeof(TaskInfo)); // Fill all elements with 0 to allow extending the structure in future version without breaking the code
229 TaskInfo.TaskID = TaskID;
230 TaskInfo.sName = sName;
231 TaskInfo.Prio = Prio;
232 TaskInfo.StackBase = StackBase;
233 TaskInfo.StackSize = StackSize;
234 SEGGER_SYSVIEW_SendTaskInfo(&TaskInfo);
235 }
236
237 /*********************************************************************
238 *
239 * SYSVIEW_RecordU32x4()
240 *
241 * Function description
242 * Record an event with 4 parameters
243 */
SYSVIEW_RecordU32x4(unsigned Id,U32 Para0,U32 Para1,U32 Para2,U32 Para3)244 void SYSVIEW_RecordU32x4(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3) {
245 U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32];
246 U8* pPayload;
247 //
248 pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
249 pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
250 pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
251 pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet
252 pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet
253 //
254 SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet
255 }
256
257 /*********************************************************************
258 *
259 * SYSVIEW_RecordU32x5()
260 *
261 * Function description
262 * Record an event with 5 parameters
263 */
SYSVIEW_RecordU32x5(unsigned Id,U32 Para0,U32 Para1,U32 Para2,U32 Para3,U32 Para4)264 void SYSVIEW_RecordU32x5(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4) {
265 U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 5 * SEGGER_SYSVIEW_QUANTA_U32];
266 U8* pPayload;
267 //
268 pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
269 pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
270 pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
271 pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet
272 pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet
273 pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para4); // Add the fifth parameter to the packet
274 //
275 SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet
276 }
277
278 /*********************************************************************
279 *
280 * Public API structures
281 *
282 **********************************************************************
283 */
284 // Callbacks provided to SYSTEMVIEW by FreeRTOS
285 const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI = {
286 _cbGetTime,
287 _cbSendTaskList,
288 };
289
290 /*************************** End of file ****************************/
291