SEGGER_SYSVIEW_RTThread.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /*********************************************************************
  2. * SEGGER MICROCONTROLLER GmbH & Co. KG *
  3. * Solutions for real time microcontroller applications *
  4. **********************************************************************
  5. * *
  6. * (c) 2015 - 2016 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. * * This software may in its unmodified form be freely redistributed *
  19. * in source form. *
  20. * * The source code may be modified, provided the source code *
  21. * retains the above copyright notice, this list of conditions and *
  22. * the following disclaimer. *
  23. * * Modified versions of this software in source or linkable form *
  24. * may not be distributed without prior consent of SEGGER. *
  25. * *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND *
  27. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, *
  28. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
  29. * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
  30. * SEGGER Microcontroller BE LIABLE FOR ANY DIRECT, INDIRECT, *
  31. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
  32. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
  33. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
  34. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, *
  35. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
  36. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
  37. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
  38. * *
  39. **********************************************************************
  40. * *
  41. * SystemView version: V2.40 *
  42. * *
  43. **********************************************************************
  44. -------------------------- END-OF-HEADER -----------------------------
  45. File : SEGGER_SYSVIEW_RTThread.c
  46. Purpose : Interface between RT-Thread and System View.
  47. Revision: $Rev: 3745 $
  48. */
  49. #include "rtthread.h"
  50. #include "SEGGER_SYSVIEW.h"
  51. #include "SEGGER_RTT.h"
  52. #ifndef PKG_USING_SYSTEMVIEW
  53. #error "SystemView is only works when feature PKG_USING_SYSTEMVIEW is enable."
  54. #endif
  55. static rt_thread_t tidle;
  56. static U64 _cbGetTime(void)
  57. {
  58. return (U64)(rt_tick_get() * 1000 / RT_TICK_PER_SECOND);
  59. }
  60. static void _cbSendTaskInfo(const rt_thread_t thread)
  61. {
  62. SEGGER_SYSVIEW_TASKINFO Info;
  63. rt_enter_critical();
  64. rt_memset(&Info, 0, sizeof(Info));
  65. Info.TaskID = (U32)thread;
  66. Info.sName = thread->name;
  67. Info.Prio = thread->current_priority;
  68. Info.StackBase = (U32)thread->stack_addr;
  69. Info.StackSize = thread->stack_size;
  70. SEGGER_SYSVIEW_SendTaskInfo(&Info);
  71. rt_exit_critical();
  72. }
  73. static void _cbSendTaskList(void)
  74. {
  75. struct rt_thread* thread;
  76. struct rt_list_node* node;
  77. struct rt_list_node* list;
  78. struct rt_object_information *info;
  79. info = rt_object_get_information(RT_Object_Class_Thread);
  80. list = &info->object_list;
  81. tidle = rt_thread_idle_gethandler();
  82. rt_enter_critical();
  83. for(node = list->next; node != list; node = node->next)
  84. {
  85. thread = rt_list_entry(node, struct rt_thread, list);
  86. /* skip idle thread */
  87. if(thread != tidle)
  88. _cbSendTaskInfo(thread);
  89. }
  90. rt_exit_critical();
  91. }
  92. static void _cb_thread_resume(rt_thread_t thread)
  93. {
  94. SEGGER_SYSVIEW_OnTaskStartReady((unsigned)thread);
  95. }
  96. static void _cb_thread_suspend(rt_thread_t thread)
  97. {
  98. SEGGER_SYSVIEW_OnTaskStopReady((unsigned)thread, 0);
  99. }
  100. static void _cb_scheduler(rt_thread_t from, rt_thread_t to)
  101. {
  102. SEGGER_SYSVIEW_OnTaskStopReady((unsigned)from, 0);
  103. if(to == tidle)
  104. SEGGER_SYSVIEW_OnIdle();
  105. else
  106. SEGGER_SYSVIEW_OnTaskStartExec((unsigned)to);
  107. }
  108. static void _cb_irq_enter(void)
  109. {
  110. SEGGER_SYSVIEW_RecordEnterISR();
  111. }
  112. static void _cb_irq_leave(void)
  113. {
  114. rt_thread_t current;
  115. if(rt_interrupt_get_nest())
  116. {
  117. SEGGER_SYSVIEW_RecordExitISR();
  118. return;
  119. }
  120. SEGGER_SYSVIEW_RecordExitISRToScheduler();
  121. current = rt_thread_self();
  122. if(current == tidle)
  123. SEGGER_SYSVIEW_OnIdle();
  124. else
  125. SEGGER_SYSVIEW_OnTaskStartExec((unsigned)current);
  126. }
  127. static void _cb_object_attach(struct rt_object* object)
  128. {
  129. switch(object->type)
  130. {
  131. case RT_Object_Class_Thread:
  132. SEGGER_SYSVIEW_OnTaskCreate((unsigned)object);
  133. _cbSendTaskInfo((rt_thread_t)object);
  134. break;
  135. default:
  136. break;
  137. }
  138. }
  139. static void _cb_object_detach(struct rt_object* object)
  140. {
  141. switch(object->type)
  142. {
  143. case RT_Object_Class_Thread:
  144. SEGGER_SYSVIEW_OnTaskStopExec();
  145. break;
  146. default:
  147. break;
  148. }
  149. }
  150. void SEGGER_SYSVIEW_RecordObject(unsigned EventID, struct rt_object *object)
  151. {
  152. U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32];
  153. U8* pPayload;
  154. pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
  155. pPayload = SEGGER_SYSVIEW_EncodeString(pPayload, object->name, RT_NAME_MAX); // Add object name
  156. if ((object->type & (~RT_Object_Class_Static)) == RT_Object_Class_Event)
  157. pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, ((rt_event_t)object)->set);
  158. SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, EventID); // Send the packet
  159. }
  160. static void _cb_object_trytake(struct rt_object *object)
  161. {
  162. switch (object->type & (~RT_Object_Class_Static))
  163. {
  164. case RT_Object_Class_Semaphore:
  165. SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_SEM_TRYTAKE, object);
  166. break;
  167. case RT_Object_Class_Mutex:
  168. SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_MUTEX_TRYTAKE, object);
  169. break;
  170. case RT_Object_Class_Event:
  171. SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_EVENT_TRYTAKE, object);
  172. break;
  173. case RT_Object_Class_MailBox:
  174. SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_MAILBOX_TRYTAKE, object);
  175. break;
  176. case RT_Object_Class_MessageQueue:
  177. SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_QUEUE_TRYTAKE, object);
  178. break;
  179. }
  180. }
  181. static void _cb_object_take(struct rt_object *object)
  182. {
  183. switch (object->type & (~RT_Object_Class_Static))
  184. {
  185. case RT_Object_Class_Semaphore:
  186. SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_SEM_TAKEN, object);
  187. break;
  188. case RT_Object_Class_Mutex:
  189. SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_MUTEX_TAKEN, object);
  190. break;
  191. case RT_Object_Class_Event:
  192. SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_EVENT_TAKEN, object);
  193. break;
  194. case RT_Object_Class_MailBox:
  195. SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_MAILBOX_TAKEN, object);
  196. break;
  197. case RT_Object_Class_MessageQueue:
  198. SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_QUEUE_TAKEN, object);
  199. break;
  200. }
  201. }
  202. static void _cb_object_put(struct rt_object *object)
  203. {
  204. switch (object->type & (~RT_Object_Class_Static))
  205. {
  206. case RT_Object_Class_Semaphore:
  207. SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_SEM_RELEASE, object);
  208. break;
  209. case RT_Object_Class_Mutex:
  210. SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_MUTEX_RELEASE, object);
  211. break;
  212. case RT_Object_Class_Event:
  213. SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_EVENT_RELEASE, object);
  214. break;
  215. case RT_Object_Class_MailBox:
  216. SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_MAILBOX_RELEASE, object);
  217. break;
  218. case RT_Object_Class_MessageQueue:
  219. SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_QUEUE_RELEASE, object);
  220. break;
  221. }
  222. }
  223. // Services provided to SYSVIEW by RT-Thread
  224. const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI = {
  225. _cbGetTime, _cbSendTaskList,
  226. };
  227. // RT-Thread init trace component
  228. static int rt_trace_init(void)
  229. {
  230. tidle = rt_thread_idle_gethandler();
  231. SEGGER_SYSVIEW_Conf();
  232. // register hooks
  233. rt_object_attach_sethook(_cb_object_attach);
  234. rt_object_detach_sethook(_cb_object_detach);
  235. rt_object_trytake_sethook(_cb_object_trytake);
  236. rt_object_take_sethook(_cb_object_take);
  237. rt_object_put_sethook(_cb_object_put);
  238. rt_thread_suspend_sethook(_cb_thread_suspend);
  239. rt_thread_resume_sethook(_cb_thread_resume);
  240. rt_scheduler_sethook(_cb_scheduler);
  241. rt_interrupt_enter_sethook(_cb_irq_enter);
  242. rt_interrupt_leave_sethook(_cb_irq_leave);
  243. rt_kprintf("RTT Control Block Detection Address is 0x%x\n", &_SEGGER_RTT);
  244. return 0;
  245. }
  246. INIT_COMPONENT_EXPORT(rt_trace_init);
  247. int rtt_show_address(int argc, char **argv)
  248. {
  249. rt_kprintf("RTT Control Block Detection Address is 0x%x\n", &_SEGGER_RTT);
  250. return RT_EOK;
  251. }
  252. #ifdef FINSH_USING_MSH
  253. FINSH_FUNCTION_EXPORT_ALIAS(rtt_show_address, __cmd_rtt_show_address, Show RTT Control Block Address.);
  254. #endif
  255. /*************************** End of file ****************************/