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