| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- /*********************************************************************
- * SEGGER MICROCONTROLLER GmbH & Co. KG *
- * Solutions for real time microcontroller applications *
- **********************************************************************
- * *
- * (c) 2015 - 2016 SEGGER Microcontroller GmbH & Co. KG *
- * *
- * www.segger.com Support: support@segger.com *
- * *
- **********************************************************************
- * *
- * SEGGER SystemView * Real-time application analysis *
- * *
- **********************************************************************
- * *
- * All rights reserved. *
- * *
- * * This software may in its unmodified form be freely redistributed *
- * in source form. *
- * * The source code may be modified, provided the source code *
- * retains the above copyright notice, this list of conditions and *
- * the following disclaimer. *
- * * Modified versions of this software in source or linkable form *
- * may not be distributed without prior consent of SEGGER. *
- * *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND *
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, *
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
- * SEGGER Microcontroller BE LIABLE FOR ANY DIRECT, INDIRECT, *
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, *
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
- * *
- **********************************************************************
- * *
- * SystemView version: V2.40 *
- * *
- **********************************************************************
- -------------------------- END-OF-HEADER -----------------------------
- File : SEGGER_SYSVIEW_RTThread.c
- Purpose : Interface between RT-Thread and System View.
- Revision: $Rev: 3745 $
- */
- #include "rtthread.h"
- #include "SEGGER_SYSVIEW.h"
- #include "SEGGER_RTT.h"
- #ifndef PKG_USING_SYSTEMVIEW
- #error "SystemView is only works when feature PKG_USING_SYSTEMVIEW is enable."
- #endif
- static rt_thread_t tidle;
- static U64 _cbGetTime(void)
- {
- return (U64)(rt_tick_get() * 1000 / RT_TICK_PER_SECOND);
- }
- static void _cbSendTaskInfo(const rt_thread_t thread)
- {
- SEGGER_SYSVIEW_TASKINFO Info;
- rt_enter_critical();
- rt_memset(&Info, 0, sizeof(Info));
- Info.TaskID = (U32)thread;
- Info.sName = thread->name;
- Info.Prio = thread->current_priority;
- Info.StackBase = (U32)thread->stack_addr;
- Info.StackSize = thread->stack_size;
- SEGGER_SYSVIEW_SendTaskInfo(&Info);
- rt_exit_critical();
- }
- static void _cbSendTaskList(void)
- {
- struct rt_thread* thread;
- struct rt_list_node* node;
- struct rt_list_node* list;
- struct rt_object_information *info;
- info = rt_object_get_information(RT_Object_Class_Thread);
- list = &info->object_list;
- tidle = rt_thread_idle_gethandler();
- rt_enter_critical();
- for(node = list->next; node != list; node = node->next)
- {
- thread = rt_list_entry(node, struct rt_thread, list);
- /* skip idle thread */
- if(thread != tidle)
- _cbSendTaskInfo(thread);
- }
- rt_exit_critical();
- }
- static void _cb_thread_resume(rt_thread_t thread)
- {
- SEGGER_SYSVIEW_OnTaskStartReady((unsigned)thread);
- }
- static void _cb_thread_suspend(rt_thread_t thread)
- {
- SEGGER_SYSVIEW_OnTaskStopReady((unsigned)thread, 0);
- }
- static void _cb_scheduler(rt_thread_t from, rt_thread_t to)
- {
- SEGGER_SYSVIEW_OnTaskStopReady((unsigned)from, 0);
- if(to == tidle)
- SEGGER_SYSVIEW_OnIdle();
- else
- SEGGER_SYSVIEW_OnTaskStartExec((unsigned)to);
- }
- static void _cb_irq_enter(void)
- {
- SEGGER_SYSVIEW_RecordEnterISR();
- }
- static void _cb_irq_leave(void)
- {
- rt_thread_t current;
- if(rt_interrupt_get_nest())
- {
- SEGGER_SYSVIEW_RecordExitISR();
- return;
- }
- SEGGER_SYSVIEW_RecordExitISRToScheduler();
- current = rt_thread_self();
- if(current == tidle)
- SEGGER_SYSVIEW_OnIdle();
- else
- SEGGER_SYSVIEW_OnTaskStartExec((unsigned)current);
- }
- static void _cb_object_attach(struct rt_object* object)
- {
- switch(object->type)
- {
- case RT_Object_Class_Thread:
- SEGGER_SYSVIEW_OnTaskCreate((unsigned)object);
- _cbSendTaskInfo((rt_thread_t)object);
- break;
- default:
- break;
- }
- }
- static void _cb_object_detach(struct rt_object* object)
- {
- switch(object->type)
- {
- case RT_Object_Class_Thread:
- SEGGER_SYSVIEW_OnTaskStopExec();
- break;
- default:
- break;
- }
- }
- void SEGGER_SYSVIEW_RecordObject(unsigned EventID, struct rt_object *object)
- {
- U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32];
- U8* pPayload;
- pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
- pPayload = SEGGER_SYSVIEW_EncodeString(pPayload, object->name, RT_NAME_MAX); // Add object name
- if ((object->type & (~RT_Object_Class_Static)) == RT_Object_Class_Event)
- pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, ((rt_event_t)object)->set);
-
- SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, EventID); // Send the packet
- }
- static void _cb_object_trytake(struct rt_object *object)
- {
- switch (object->type & (~RT_Object_Class_Static))
- {
- case RT_Object_Class_Semaphore:
- SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_SEM_TRYTAKE, object);
- break;
- case RT_Object_Class_Mutex:
- SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_MUTEX_TRYTAKE, object);
- break;
- case RT_Object_Class_Event:
- SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_EVENT_TRYTAKE, object);
- break;
- case RT_Object_Class_MailBox:
- SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_MAILBOX_TRYTAKE, object);
- break;
- case RT_Object_Class_MessageQueue:
- SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_QUEUE_TRYTAKE, object);
- break;
- }
- }
- static void _cb_object_take(struct rt_object *object)
- {
- switch (object->type & (~RT_Object_Class_Static))
- {
- case RT_Object_Class_Semaphore:
- SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_SEM_TAKEN, object);
- break;
- case RT_Object_Class_Mutex:
- SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_MUTEX_TAKEN, object);
- break;
- case RT_Object_Class_Event:
- SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_EVENT_TAKEN, object);
- break;
- case RT_Object_Class_MailBox:
- SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_MAILBOX_TAKEN, object);
- break;
- case RT_Object_Class_MessageQueue:
- SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_QUEUE_TAKEN, object);
- break;
- }
- }
- static void _cb_object_put(struct rt_object *object)
- {
- switch (object->type & (~RT_Object_Class_Static))
- {
- case RT_Object_Class_Semaphore:
- SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_SEM_RELEASE, object);
- break;
- case RT_Object_Class_Mutex:
- SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_MUTEX_RELEASE, object);
- break;
- case RT_Object_Class_Event:
- SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_EVENT_RELEASE, object);
- break;
- case RT_Object_Class_MailBox:
- SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_MAILBOX_RELEASE, object);
- break;
- case RT_Object_Class_MessageQueue:
- SEGGER_SYSVIEW_RecordObject(RTT_TRACE_ID_QUEUE_RELEASE, object);
- break;
- }
- }
- // Services provided to SYSVIEW by RT-Thread
- const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI = {
- _cbGetTime, _cbSendTaskList,
- };
- // RT-Thread init trace component
- static int rt_trace_init(void)
- {
- tidle = rt_thread_idle_gethandler();
-
- SEGGER_SYSVIEW_Conf();
-
- // register hooks
- rt_object_attach_sethook(_cb_object_attach);
- rt_object_detach_sethook(_cb_object_detach);
- rt_object_trytake_sethook(_cb_object_trytake);
- rt_object_take_sethook(_cb_object_take);
- rt_object_put_sethook(_cb_object_put);
-
- rt_thread_suspend_sethook(_cb_thread_suspend);
- rt_thread_resume_sethook(_cb_thread_resume);
- rt_scheduler_sethook(_cb_scheduler);
- rt_interrupt_enter_sethook(_cb_irq_enter);
- rt_interrupt_leave_sethook(_cb_irq_leave);
-
- rt_kprintf("RTT Control Block Detection Address is 0x%x\n", &_SEGGER_RTT);
-
- return 0;
- }
- INIT_COMPONENT_EXPORT(rt_trace_init);
- int rtt_show_address(int argc, char **argv)
- {
- rt_kprintf("RTT Control Block Detection Address is 0x%x\n", &_SEGGER_RTT);
- return RT_EOK;
- }
- #ifdef FINSH_USING_MSH
- FINSH_FUNCTION_EXPORT_ALIAS(rtt_show_address, __cmd_rtt_show_address, Show RTT Control Block Address.);
- #endif
- /*************************** End of file ****************************/
|