SEGGER_SYSVIEW_FreeRTOS.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. * SPDX-FileCopyrightText: 1995-2021 SEGGER Microcontroller GmbH
  3. *
  4. * SPDX-License-Identifier: BSD-1-Clause
  5. *
  6. * SPDX-FileContributor: 2023 Espressif Systems (Shanghai) CO LTD
  7. */
  8. /*********************************************************************
  9. * SEGGER Microcontroller GmbH *
  10. * The Embedded Experts *
  11. **********************************************************************
  12. * *
  13. * (c) 1995 - 2021 SEGGER Microcontroller GmbH *
  14. * *
  15. * www.segger.com Support: support@segger.com *
  16. * *
  17. **********************************************************************
  18. * *
  19. * SEGGER SystemView * Real-time application analysis *
  20. * *
  21. **********************************************************************
  22. * *
  23. * All rights reserved. *
  24. * *
  25. * SEGGER strongly recommends to not make any changes *
  26. * to or modify the source code of this software in order to stay *
  27. * compatible with the SystemView and RTT protocol, and J-Link. *
  28. * *
  29. * Redistribution and use in source and binary forms, with or *
  30. * without modification, are permitted provided that the following *
  31. * condition is met: *
  32. * *
  33. * o Redistributions of source code must retain the above copyright *
  34. * notice, this condition and the following disclaimer. *
  35. * *
  36. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
  37. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
  38. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
  39. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
  40. * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
  41. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
  42. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
  43. * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
  44. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
  45. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
  46. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
  47. * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
  48. * DAMAGE. *
  49. * *
  50. **********************************************************************
  51. * *
  52. * SystemView version: 3.42 *
  53. * *
  54. **********************************************************************
  55. -------------------------- END-OF-HEADER -----------------------------
  56. File : SEGGER_SYSVIEW_FreeRTOS.c
  57. Purpose : Interface between FreeRTOS and SystemView.
  58. Revision: $Rev: 7947 $
  59. */
  60. #include "freertos/FreeRTOS.h"
  61. #include "freertos/task.h"
  62. #include "SEGGER_SYSVIEW.h"
  63. #include "SEGGER_SYSVIEW_FreeRTOS.h"
  64. #include "string.h" // Required for memset
  65. typedef struct SYSVIEW_FREERTOS_TASK_STATUS SYSVIEW_FREERTOS_TASK_STATUS;
  66. struct SYSVIEW_FREERTOS_TASK_STATUS {
  67. U32 xHandle;
  68. const char* pcTaskName;
  69. unsigned uxCurrentPriority;
  70. U32 pxStack;
  71. unsigned uStackHighWaterMark;
  72. };
  73. static SYSVIEW_FREERTOS_TASK_STATUS _aTasks[SYSVIEW_FREERTOS_MAX_NOF_TASKS];
  74. static unsigned _NumTasks;
  75. /*********************************************************************
  76. *
  77. * _cbSendTaskList()
  78. *
  79. * Function description
  80. * This function is part of the link between FreeRTOS and SYSVIEW.
  81. * Called from SystemView when asked by the host, it uses SYSVIEW
  82. * functions to send the entire task list to the host.
  83. */
  84. static void _cbSendTaskList(void) {
  85. unsigned n;
  86. for (n = 0; n < _NumTasks; n++) {
  87. #if INCLUDE_uxTaskGetStackHighWaterMark // Report Task Stack High Watermark
  88. _aTasks[n].uStackHighWaterMark = uxTaskGetStackHighWaterMark((TaskHandle_t)_aTasks[n].xHandle);
  89. #endif
  90. SYSVIEW_SendTaskInfo((U32)_aTasks[n].xHandle, _aTasks[n].pcTaskName, (unsigned)_aTasks[n].uxCurrentPriority, (U32)_aTasks[n].pxStack, (unsigned)_aTasks[n].uStackHighWaterMark);
  91. }
  92. }
  93. /*********************************************************************
  94. *
  95. * _cbGetTime()
  96. *
  97. * Function description
  98. * This function is part of the link between FreeRTOS and SYSVIEW.
  99. * Called from SystemView when asked by the host, returns the
  100. * current system time in micro seconds.
  101. */
  102. static U64 _cbGetTime(void) {
  103. U64 Time;
  104. Time = xTaskGetTickCountFromISR();
  105. Time *= portTICK_PERIOD_MS;
  106. Time *= 1000;
  107. return Time;
  108. }
  109. /*********************************************************************
  110. *
  111. * Global functions
  112. *
  113. **********************************************************************
  114. */
  115. /*********************************************************************
  116. *
  117. * SYSVIEW_AddTask()
  118. *
  119. * Function description
  120. * Add a task to the internal list and record its information.
  121. */
  122. void SYSVIEW_AddTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
  123. /* On multi-core we have several idle tasks with 'IDLEx' names
  124. Not best solution, because we can filter out user tasks starting with 'IDLE'.
  125. But we can not use 'xTaskGetIdleTaskHandle' because at the moment when this
  126. function is called array of idle tasks handles are not initialized yet. */
  127. if (memcmp(pcTaskName, "IDLE", 4) == 0) {
  128. return;
  129. }
  130. if (_NumTasks >= SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
  131. SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not record task information. Maximum number of tasks reached.");
  132. return;
  133. }
  134. _aTasks[_NumTasks].xHandle = xHandle;
  135. _aTasks[_NumTasks].pcTaskName = pcTaskName;
  136. _aTasks[_NumTasks].uxCurrentPriority = uxCurrentPriority;
  137. _aTasks[_NumTasks].pxStack = pxStack;
  138. _aTasks[_NumTasks].uStackHighWaterMark = uStackHighWaterMark;
  139. _NumTasks++;
  140. SYSVIEW_SendTaskInfo(xHandle, pcTaskName,uxCurrentPriority, pxStack, uStackHighWaterMark);
  141. }
  142. /*********************************************************************
  143. *
  144. * SYSVIEW_UpdateTask()
  145. *
  146. * Function description
  147. * Update a task in the internal list and record its information.
  148. */
  149. void SYSVIEW_UpdateTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
  150. unsigned n;
  151. /* On multi-core we have several idle tasks with 'IDLEx' names
  152. Not best solution, because we can filter out user tasks starting with 'IDLE'.
  153. But we can not use 'xTaskGetIdleTaskHandle' because at the moment when this
  154. function is called array of idle tasks handles are not initialized yet. */
  155. if (memcmp(pcTaskName, "IDLE", 4) == 0) {
  156. return;
  157. }
  158. for (n = 0; n < _NumTasks; n++) {
  159. if (_aTasks[n].xHandle == xHandle) {
  160. break;
  161. }
  162. }
  163. if (n < _NumTasks) {
  164. _aTasks[n].pcTaskName = pcTaskName;
  165. _aTasks[n].uxCurrentPriority = uxCurrentPriority;
  166. _aTasks[n].pxStack = pxStack;
  167. _aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
  168. SYSVIEW_SendTaskInfo(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
  169. } else {
  170. SYSVIEW_AddTask(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
  171. }
  172. }
  173. /*********************************************************************
  174. *
  175. * SYSVIEW_DeleteTask()
  176. *
  177. * Function description
  178. * Delete a task from the internal list.
  179. */
  180. void SYSVIEW_DeleteTask(U32 xHandle) {
  181. unsigned n;
  182. if (_NumTasks == 0) {
  183. return; // Early out
  184. }
  185. for (n = 0; n < _NumTasks; n++) {
  186. if (_aTasks[n].xHandle == xHandle) {
  187. break;
  188. }
  189. }
  190. if (n == (_NumTasks - 1)) {
  191. //
  192. // Task is last item in list.
  193. // Simply zero the item and decrement number of tasks.
  194. //
  195. memset(&_aTasks[n], 0, sizeof(_aTasks[n]));
  196. _NumTasks--;
  197. } else if (n < _NumTasks) {
  198. //
  199. // Task is in the middle of the list.
  200. // Move last item to current position and decrement number of tasks.
  201. // Order of tasks does not really matter, so no need to move all following items.
  202. //
  203. _aTasks[n].xHandle = _aTasks[_NumTasks - 1].xHandle;
  204. _aTasks[n].pcTaskName = _aTasks[_NumTasks - 1].pcTaskName;
  205. _aTasks[n].uxCurrentPriority = _aTasks[_NumTasks - 1].uxCurrentPriority;
  206. _aTasks[n].pxStack = _aTasks[_NumTasks - 1].pxStack;
  207. _aTasks[n].uStackHighWaterMark = _aTasks[_NumTasks - 1].uStackHighWaterMark;
  208. memset(&_aTasks[_NumTasks - 1], 0, sizeof(_aTasks[_NumTasks - 1]));
  209. _NumTasks--;
  210. }
  211. }
  212. /*********************************************************************
  213. *
  214. * SYSVIEW_SendTaskInfo()
  215. *
  216. * Function description
  217. * Record task information.
  218. */
  219. void SYSVIEW_SendTaskInfo(U32 TaskID, const char* sName, unsigned Prio, U32 StackBase, unsigned StackSize) {
  220. SEGGER_SYSVIEW_TASKINFO TaskInfo;
  221. memset(&TaskInfo, 0, sizeof(TaskInfo)); // Fill all elements with 0 to allow extending the structure in future version without breaking the code
  222. TaskInfo.TaskID = TaskID;
  223. TaskInfo.sName = sName;
  224. TaskInfo.Prio = Prio;
  225. TaskInfo.StackBase = StackBase;
  226. TaskInfo.StackSize = StackSize;
  227. SEGGER_SYSVIEW_SendTaskInfo(&TaskInfo);
  228. }
  229. /*********************************************************************
  230. *
  231. * Public API structures
  232. *
  233. **********************************************************************
  234. */
  235. // Callbacks provided to SYSTEMVIEW by FreeRTOS
  236. const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI = {
  237. _cbGetTime,
  238. _cbSendTaskList,
  239. };
  240. /*************************** End of file ****************************/