| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081 |
- /*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2006-04-30 Bernard first implementation
- * 2006-05-04 Bernard add list_thread,
- * list_sem,
- * list_timer
- * 2006-05-20 Bernard add list_mutex,
- * list_mailbox,
- * list_msgqueue,
- * list_event,
- * list_fevent,
- * list_mempool
- * 2006-06-03 Bernard display stack information in list_thread
- * 2006-08-10 Bernard change version to invoke rt_show_version
- * 2008-09-10 Bernard update the list function for finsh syscall
- * list and sysvar list
- * 2009-05-30 Bernard add list_device
- * 2010-04-21 yi.qiu add list_module
- * 2012-04-29 goprife improve the command line auto-complete feature.
- * 2012-06-02 lgnq add list_memheap
- * 2012-10-22 Bernard add MS VC++ patch.
- * 2016-06-02 armink beautify the list_thread command
- * 2018-11-22 Jesven list_thread add smp support
- * 2018-12-27 Jesven Fix the problem that disable interrupt too long in list_thread
- * Provide protection for the "first layer of objects" when list_*
- * 2020-04-07 chenhui add clear
- */
- #include <rthw.h>
- #include <rtthread.h>
- #include <string.h>
- #ifdef RT_USING_FINSH
- #include <finsh.h>
- #define LIST_FIND_OBJ_NR 8
- long hello(void)
- {
- rt_kprintf("Hello RT-Thread!\n");
- return 0;
- }
- MSH_CMD_EXPORT(hello, say hello world);
- static long clear(void)
- {
- rt_kprintf("\x1b[2J\x1b[H");
- return 0;
- }
- MSH_CMD_EXPORT(clear, clear the terminal screen);
- extern void rt_show_version(void);
- long version(void)
- {
- rt_show_version();
- return 0;
- }
- MSH_CMD_EXPORT(version, show RT-Thread version information);
- rt_inline void object_split(int len)
- {
- while (len--) rt_kprintf("-");
- }
- typedef struct
- {
- rt_list_t *list;
- rt_list_t **array;
- rt_uint8_t type;
- int nr; /* input: max nr, can't be 0 */
- int nr_out; /* out: got nr */
- } list_get_next_t;
- static void list_find_init(list_get_next_t *p, rt_uint8_t type, rt_list_t **array, int nr)
- {
- struct rt_object_information *info;
- rt_list_t *list;
- info = rt_object_get_information((enum rt_object_class_type)type);
- list = &info->object_list;
- p->list = list;
- p->type = type;
- p->array = array;
- p->nr = nr;
- p->nr_out = 0;
- }
- static rt_list_t *list_get_next(rt_list_t *current, list_get_next_t *arg)
- {
- int first_flag = 0;
- rt_ubase_t level;
- rt_list_t *node, *list;
- rt_list_t **array;
- int nr;
- arg->nr_out = 0;
- if (!arg->nr || !arg->type)
- {
- return (rt_list_t *)RT_NULL;
- }
- list = arg->list;
- if (!current) /* find first */
- {
- node = list;
- first_flag = 1;
- }
- else
- {
- node = current;
- }
- level = rt_hw_interrupt_disable();
- if (!first_flag)
- {
- struct rt_object *obj;
- /* The node in the list? */
- obj = rt_list_entry(node, struct rt_object, list);
- if ((obj->type & ~RT_Object_Class_Static) != arg->type)
- {
- rt_hw_interrupt_enable(level);
- return (rt_list_t *)RT_NULL;
- }
- }
- nr = 0;
- array = arg->array;
- while (1)
- {
- node = node->next;
- if (node == list)
- {
- node = (rt_list_t *)RT_NULL;
- break;
- }
- nr++;
- *array++ = node;
- if (nr == arg->nr)
- {
- break;
- }
- }
- rt_hw_interrupt_enable(level);
- arg->nr_out = nr;
- return node;
- }
- long list_thread(void)
- {
- rt_ubase_t level;
- list_get_next_t find_arg;
- rt_list_t *obj_list[LIST_FIND_OBJ_NR];
- rt_list_t *next = (rt_list_t*)RT_NULL;
- const char *item_title = "thread";
- int maxlen;
- list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
- maxlen = RT_NAME_MAX;
- #ifdef RT_USING_SMP
- rt_kprintf("%-*.s cpu pri status sp stack size max used left tick error\n", maxlen, item_title); object_split(maxlen);
- rt_kprintf( " --- --- ------- ---------- ---------- ------ ---------- ---\n");
- #else
- rt_kprintf("%-*.s pri status sp stack size max used left tick error\n", maxlen, item_title); object_split(maxlen);
- rt_kprintf( " --- ------- ---------- ---------- ------ ---------- ---\n");
- #endif /*RT_USING_SMP*/
- do
- {
- next = list_get_next(next, &find_arg);
- {
- int i;
- for (i = 0; i < find_arg.nr_out; i++)
- {
- struct rt_object *obj;
- struct rt_thread thread_info, *thread;
- obj = rt_list_entry(obj_list[i], struct rt_object, list);
- level = rt_hw_interrupt_disable();
- if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
- {
- rt_hw_interrupt_enable(level);
- continue;
- }
- /* copy info */
- rt_memcpy(&thread_info, obj, sizeof thread_info);
- rt_hw_interrupt_enable(level);
- thread = (struct rt_thread*)obj;
- {
- rt_uint8_t stat;
- rt_uint8_t *ptr;
- #ifdef RT_USING_SMP
- if (thread->oncpu != RT_CPU_DETACHED)
- rt_kprintf("%-*.*s %3d %3d ", maxlen, RT_NAME_MAX, thread->name, thread->oncpu, thread->current_priority);
- else
- rt_kprintf("%-*.*s N/A %3d ", maxlen, RT_NAME_MAX, thread->name, thread->current_priority);
- #else
- rt_kprintf("%-*.*s %3d ", maxlen, RT_NAME_MAX, thread->name, thread->current_priority);
- #endif /*RT_USING_SMP*/
- stat = (thread->stat & RT_THREAD_STAT_MASK);
- if (stat == RT_THREAD_READY) rt_kprintf(" ready ");
- else if ((stat & RT_THREAD_SUSPEND_MASK) == RT_THREAD_SUSPEND_MASK) rt_kprintf(" suspend");
- else if (stat == RT_THREAD_INIT) rt_kprintf(" init ");
- else if (stat == RT_THREAD_CLOSE) rt_kprintf(" close ");
- else if (stat == RT_THREAD_RUNNING) rt_kprintf(" running");
- #if defined(ARCH_CPU_STACK_GROWS_UPWARD)
- ptr = (rt_uint8_t *)thread->stack_addr + thread->stack_size - 1;
- while (*ptr == '#')ptr --;
- rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %03d\n",
- ((rt_ubase_t)thread->sp - (rt_ubase_t)thread->stack_addr),
- thread->stack_size,
- ((rt_ubase_t)ptr - (rt_ubase_t)thread->stack_addr) * 100 / thread->stack_size,
- thread->remaining_tick,
- thread->error);
- #else
- ptr = (rt_uint8_t *)thread->stack_addr;
- while (*ptr == '#')ptr ++;
- rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %03d\n",
- thread->stack_size + ((rt_ubase_t)thread->stack_addr - (rt_ubase_t)thread->sp),
- thread->stack_size,
- (thread->stack_size - ((rt_ubase_t) ptr - (rt_ubase_t) thread->stack_addr)) * 100
- / thread->stack_size,
- thread->remaining_tick,
- thread->error);
- #endif
- }
- }
- }
- }
- while (next != (rt_list_t*)RT_NULL);
- return 0;
- }
- MSH_CMD_EXPORT(list_thread, list thread);
- static void show_wait_queue(struct rt_list_node *list)
- {
- struct rt_thread *thread;
- struct rt_list_node *node;
- for (node = list->next; node != list; node = node->next)
- {
- thread = rt_list_entry(node, struct rt_thread, tlist);
- rt_kprintf("%.*s", RT_NAME_MAX, thread->name);
- if (node->next != list)
- rt_kprintf("/");
- }
- }
- #ifdef RT_USING_SEMAPHORE
- long list_sem(void)
- {
- rt_ubase_t level;
- list_get_next_t find_arg;
- rt_list_t *obj_list[LIST_FIND_OBJ_NR];
- rt_list_t *next = (rt_list_t*)RT_NULL;
- int maxlen;
- const char *item_title = "semaphore";
- list_find_init(&find_arg, RT_Object_Class_Semaphore, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
- maxlen = RT_NAME_MAX;
- rt_kprintf("%-*.s v suspend thread\n", maxlen, item_title); object_split(maxlen);
- rt_kprintf( " --- --------------\n");
- do
- {
- next = list_get_next(next, &find_arg);
- {
- int i;
- for (i = 0; i < find_arg.nr_out; i++)
- {
- struct rt_object *obj;
- struct rt_semaphore *sem;
- obj = rt_list_entry(obj_list[i], struct rt_object, list);
- level = rt_hw_interrupt_disable();
- if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
- {
- rt_hw_interrupt_enable(level);
- continue;
- }
- rt_hw_interrupt_enable(level);
- sem = (struct rt_semaphore*)obj;
- if (!rt_list_isempty(&sem->parent.suspend_thread))
- {
- rt_kprintf("%-*.*s %03d %d:",
- maxlen, RT_NAME_MAX,
- sem->parent.parent.name,
- sem->value,
- rt_list_len(&sem->parent.suspend_thread));
- show_wait_queue(&(sem->parent.suspend_thread));
- rt_kprintf("\n");
- }
- else
- {
- rt_kprintf("%-*.*s %03d %d\n",
- maxlen, RT_NAME_MAX,
- sem->parent.parent.name,
- sem->value,
- rt_list_len(&sem->parent.suspend_thread));
- }
- }
- }
- }
- while (next != (rt_list_t*)RT_NULL);
- return 0;
- }
- MSH_CMD_EXPORT(list_sem, list semaphore in system);
- #endif
- #ifdef RT_USING_EVENT
- long list_event(void)
- {
- rt_ubase_t level;
- list_get_next_t find_arg;
- rt_list_t *obj_list[LIST_FIND_OBJ_NR];
- rt_list_t *next = (rt_list_t*)RT_NULL;
- int maxlen;
- const char *item_title = "event";
- list_find_init(&find_arg, RT_Object_Class_Event, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
- maxlen = RT_NAME_MAX;
- rt_kprintf("%-*.s set suspend thread\n", maxlen, item_title); object_split(maxlen);
- rt_kprintf( " ---------- --------------\n");
- do
- {
- next = list_get_next(next, &find_arg);
- {
- int i;
- for (i = 0; i < find_arg.nr_out; i++)
- {
- struct rt_object *obj;
- struct rt_event *e;
- obj = rt_list_entry(obj_list[i], struct rt_object, list);
- level = rt_hw_interrupt_disable();
- if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
- {
- rt_hw_interrupt_enable(level);
- continue;
- }
- rt_hw_interrupt_enable(level);
- e = (struct rt_event *)obj;
- if (!rt_list_isempty(&e->parent.suspend_thread))
- {
- rt_kprintf("%-*.*s 0x%08x %03d:",
- maxlen, RT_NAME_MAX,
- e->parent.parent.name,
- e->set,
- rt_list_len(&e->parent.suspend_thread));
- show_wait_queue(&(e->parent.suspend_thread));
- rt_kprintf("\n");
- }
- else
- {
- rt_kprintf("%-*.*s 0x%08x 0\n",
- maxlen, RT_NAME_MAX, e->parent.parent.name, e->set);
- }
- }
- }
- }
- while (next != (rt_list_t*)RT_NULL);
- return 0;
- }
- MSH_CMD_EXPORT(list_event, list event in system);
- #endif
- #ifdef RT_USING_MUTEX
- long list_mutex(void)
- {
- rt_ubase_t level;
- list_get_next_t find_arg;
- rt_list_t *obj_list[LIST_FIND_OBJ_NR];
- rt_list_t *next = (rt_list_t*)RT_NULL;
- int maxlen;
- const char *item_title = "mutex";
- list_find_init(&find_arg, RT_Object_Class_Mutex, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
- maxlen = RT_NAME_MAX;
- rt_kprintf("%-*.s owner hold suspend thread\n", maxlen, item_title); object_split(maxlen);
- rt_kprintf( " -------- ---- --------------\n");
- do
- {
- next = list_get_next(next, &find_arg);
- {
- int i;
- for (i = 0; i < find_arg.nr_out; i++)
- {
- struct rt_object *obj;
- struct rt_mutex *m;
- obj = rt_list_entry(obj_list[i], struct rt_object, list);
- level = rt_hw_interrupt_disable();
- if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
- {
- rt_hw_interrupt_enable(level);
- continue;
- }
- rt_hw_interrupt_enable(level);
- m = (struct rt_mutex *)obj;
- rt_kprintf("%-*.*s %-8.*s %04d %d\n",
- maxlen, RT_NAME_MAX,
- m->parent.parent.name,
- RT_NAME_MAX,
- m->owner->name,
- m->hold,
- rt_list_len(&m->parent.suspend_thread));
- }
- }
- }
- while (next != (rt_list_t*)RT_NULL);
- return 0;
- }
- MSH_CMD_EXPORT(list_mutex, list mutex in system);
- #endif
- #ifdef RT_USING_MAILBOX
- long list_mailbox(void)
- {
- rt_ubase_t level;
- list_get_next_t find_arg;
- rt_list_t *obj_list[LIST_FIND_OBJ_NR];
- rt_list_t *next = (rt_list_t*)RT_NULL;
- int maxlen;
- const char *item_title = "mailbox";
- list_find_init(&find_arg, RT_Object_Class_MailBox, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
- maxlen = RT_NAME_MAX;
- rt_kprintf("%-*.s entry size suspend thread\n", maxlen, item_title); object_split(maxlen);
- rt_kprintf( " ---- ---- --------------\n");
- do
- {
- next = list_get_next(next, &find_arg);
- {
- int i;
- for (i = 0; i < find_arg.nr_out; i++)
- {
- struct rt_object *obj;
- struct rt_mailbox *m;
- obj = rt_list_entry(obj_list[i], struct rt_object, list);
- level = rt_hw_interrupt_disable();
- if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
- {
- rt_hw_interrupt_enable(level);
- continue;
- }
- rt_hw_interrupt_enable(level);
- m = (struct rt_mailbox *)obj;
- if (!rt_list_isempty(&m->parent.suspend_thread))
- {
- rt_kprintf("%-*.*s %04d %04d %d:",
- maxlen, RT_NAME_MAX,
- m->parent.parent.name,
- m->entry,
- m->size,
- rt_list_len(&m->parent.suspend_thread));
- show_wait_queue(&(m->parent.suspend_thread));
- rt_kprintf("\n");
- }
- else
- {
- rt_kprintf("%-*.*s %04d %04d %d\n",
- maxlen, RT_NAME_MAX,
- m->parent.parent.name,
- m->entry,
- m->size,
- rt_list_len(&m->parent.suspend_thread));
- }
- }
- }
- }
- while (next != (rt_list_t*)RT_NULL);
- return 0;
- }
- MSH_CMD_EXPORT(list_mailbox, list mail box in system);
- #endif
- #ifdef RT_USING_MESSAGEQUEUE
- long list_msgqueue(void)
- {
- rt_ubase_t level;
- list_get_next_t find_arg;
- rt_list_t *obj_list[LIST_FIND_OBJ_NR];
- rt_list_t *next = (rt_list_t*)RT_NULL;
- int maxlen;
- const char *item_title = "msgqueue";
- list_find_init(&find_arg, RT_Object_Class_MessageQueue, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
- maxlen = RT_NAME_MAX;
- rt_kprintf("%-*.s entry suspend thread\n", maxlen, item_title); object_split(maxlen);
- rt_kprintf( " ---- --------------\n");
- do
- {
- next = list_get_next(next, &find_arg);
- {
- int i;
- for (i = 0; i < find_arg.nr_out; i++)
- {
- struct rt_object *obj;
- struct rt_messagequeue *m;
- obj = rt_list_entry(obj_list[i], struct rt_object, list);
- level = rt_hw_interrupt_disable();
- if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
- {
- rt_hw_interrupt_enable(level);
- continue;
- }
- rt_hw_interrupt_enable(level);
- m = (struct rt_messagequeue *)obj;
- if (!rt_list_isempty(&m->parent.suspend_thread))
- {
- rt_kprintf("%-*.*s %04d %d:",
- maxlen, RT_NAME_MAX,
- m->parent.parent.name,
- m->entry,
- rt_list_len(&m->parent.suspend_thread));
- show_wait_queue(&(m->parent.suspend_thread));
- rt_kprintf("\n");
- }
- else
- {
- rt_kprintf("%-*.*s %04d %d\n",
- maxlen, RT_NAME_MAX,
- m->parent.parent.name,
- m->entry,
- rt_list_len(&m->parent.suspend_thread));
- }
- }
- }
- }
- while (next != (rt_list_t*)RT_NULL);
- return 0;
- }
- MSH_CMD_EXPORT(list_msgqueue, list message queue in system);
- #endif
- #ifdef RT_USING_MEMHEAP
- long list_memheap(void)
- {
- rt_ubase_t level;
- list_get_next_t find_arg;
- rt_list_t *obj_list[LIST_FIND_OBJ_NR];
- rt_list_t *next = (rt_list_t*)RT_NULL;
- int maxlen;
- const char *item_title = "memheap";
- list_find_init(&find_arg, RT_Object_Class_MemHeap, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
- maxlen = RT_NAME_MAX;
- rt_kprintf("%-*.s pool size max used size available size\n", maxlen, item_title); object_split(maxlen);
- rt_kprintf( " ---------- ------------- --------------\n");
- do
- {
- next = list_get_next(next, &find_arg);
- {
- int i;
- for (i = 0; i < find_arg.nr_out; i++)
- {
- struct rt_object *obj;
- struct rt_memheap *mh;
- obj = rt_list_entry(obj_list[i], struct rt_object, list);
- level = rt_hw_interrupt_disable();
- if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
- {
- rt_hw_interrupt_enable(level);
- continue;
- }
- rt_hw_interrupt_enable(level);
- mh = (struct rt_memheap *)obj;
- rt_kprintf("%-*.*s %-010d %-013d %-05d\n",
- maxlen, RT_NAME_MAX,
- mh->parent.name,
- mh->pool_size,
- mh->max_used_size,
- mh->available_size);
- }
- }
- }
- while (next != (rt_list_t*)RT_NULL);
- return 0;
- }
- MSH_CMD_EXPORT(list_memheap, list memory heap in system);
- #endif
- #ifdef RT_USING_MEMPOOL
- long list_mempool(void)
- {
- rt_ubase_t level;
- list_get_next_t find_arg;
- rt_list_t *obj_list[LIST_FIND_OBJ_NR];
- rt_list_t *next = (rt_list_t*)RT_NULL;
- int maxlen;
- const char *item_title = "mempool";
- list_find_init(&find_arg, RT_Object_Class_MemPool, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
- maxlen = RT_NAME_MAX;
- rt_kprintf("%-*.s block total free suspend thread\n", maxlen, item_title); object_split(maxlen);
- rt_kprintf( " ---- ---- ---- --------------\n");
- do
- {
- next = list_get_next(next, &find_arg);
- {
- int i;
- for (i = 0; i < find_arg.nr_out; i++)
- {
- struct rt_object *obj;
- struct rt_mempool *mp;
- int suspend_thread_count;
- rt_list_t *node;
- obj = rt_list_entry(obj_list[i], struct rt_object, list);
- level = rt_hw_interrupt_disable();
- if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
- {
- rt_hw_interrupt_enable(level);
- continue;
- }
- rt_hw_interrupt_enable(level);
- mp = (struct rt_mempool *)obj;
- suspend_thread_count = 0;
- rt_list_for_each(node, &mp->suspend_thread)
- {
- suspend_thread_count++;
- }
- if (suspend_thread_count > 0)
- {
- rt_kprintf("%-*.*s %04d %04d %04d %d:",
- maxlen, RT_NAME_MAX,
- mp->parent.name,
- mp->block_size,
- mp->block_total_count,
- mp->block_free_count,
- suspend_thread_count);
- show_wait_queue(&(mp->suspend_thread));
- rt_kprintf("\n");
- }
- else
- {
- rt_kprintf("%-*.*s %04d %04d %04d %d\n",
- maxlen, RT_NAME_MAX,
- mp->parent.name,
- mp->block_size,
- mp->block_total_count,
- mp->block_free_count,
- suspend_thread_count);
- }
- }
- }
- }
- while (next != (rt_list_t*)RT_NULL);
- return 0;
- }
- MSH_CMD_EXPORT(list_mempool, list memory pool in system);
- #endif
- long list_timer(void)
- {
- rt_ubase_t level;
- list_get_next_t find_arg;
- rt_list_t *obj_list[LIST_FIND_OBJ_NR];
- rt_list_t *next = (rt_list_t*)RT_NULL;
- int maxlen;
- const char *item_title = "timer";
- list_find_init(&find_arg, RT_Object_Class_Timer, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
- maxlen = RT_NAME_MAX;
- rt_kprintf("%-*.s periodic timeout flag\n", maxlen, item_title); object_split(maxlen);
- rt_kprintf( " ---------- ---------- -----------\n");
- do {
- next = list_get_next(next, &find_arg);
- {
- int i;
- for (i = 0; i < find_arg.nr_out; i++)
- {
- struct rt_object *obj;
- struct rt_timer *timer;
- obj = rt_list_entry(obj_list[i], struct rt_object, list);
- level = rt_hw_interrupt_disable();
- if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
- {
- rt_hw_interrupt_enable(level);
- continue;
- }
- rt_hw_interrupt_enable(level);
- timer = (struct rt_timer *)obj;
- rt_kprintf("%-*.*s 0x%08x 0x%08x ",
- maxlen, RT_NAME_MAX,
- timer->parent.name,
- timer->init_tick,
- timer->timeout_tick);
- if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
- rt_kprintf("activated\n");
- else
- rt_kprintf("deactivated\n");
- }
- }
- }
- while (next != (rt_list_t*)RT_NULL);
- rt_kprintf("current tick:0x%08x\n", rt_tick_get());
- return 0;
- }
- MSH_CMD_EXPORT(list_timer, list timer in system);
- #ifdef RT_USING_DEVICE
- static char *const device_type_str[] =
- {
- "Character Device",
- "Block Device",
- "Network Interface",
- "MTD Device",
- "CAN Device",
- "RTC",
- "Sound Device",
- "Graphic Device",
- "I2C Bus",
- "USB Slave Device",
- "USB Host Bus",
- "SPI Bus",
- "SPI Device",
- "SDIO Bus",
- "PM Pseudo Device",
- "Pipe",
- "Portal Device",
- "Timer Device",
- "Miscellaneous Device",
- "Sensor Device",
- "Touch Device",
- "Phy Device",
- "Unknown"
- };
- long list_device(void)
- {
- rt_ubase_t level;
- list_get_next_t find_arg;
- rt_list_t *obj_list[LIST_FIND_OBJ_NR];
- rt_list_t *next = (rt_list_t*)RT_NULL;
- int maxlen;
- const char *item_title = "device";
- list_find_init(&find_arg, RT_Object_Class_Device, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
- maxlen = RT_NAME_MAX;
- rt_kprintf("%-*.s type ref count\n", maxlen, item_title); object_split(maxlen);
- rt_kprintf( " -------------------- ----------\n");
- do
- {
- next = list_get_next(next, &find_arg);
- {
- int i;
- for (i = 0; i < find_arg.nr_out; i++)
- {
- struct rt_object *obj;
- struct rt_device *device;
- obj = rt_list_entry(obj_list[i], struct rt_object, list);
- level = rt_hw_interrupt_disable();
- if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
- {
- rt_hw_interrupt_enable(level);
- continue;
- }
- rt_hw_interrupt_enable(level);
- device = (struct rt_device *)obj;
- rt_kprintf("%-*.*s %-20s %-8d\n",
- maxlen, RT_NAME_MAX,
- device->parent.name,
- (device->type <= RT_Device_Class_Unknown) ?
- device_type_str[device->type] :
- device_type_str[RT_Device_Class_Unknown],
- device->ref_count);
- }
- }
- }
- while (next != (rt_list_t*)RT_NULL);
- return 0;
- }
- MSH_CMD_EXPORT(list_device, list device in system);
- #endif
- long list(void)
- {
- rt_kprintf("--Function List:\n");
- {
- struct finsh_syscall *index;
- for (index = _syscall_table_begin;
- index < _syscall_table_end;
- FINSH_NEXT_SYSCALL(index))
- {
- /* skip the internal command */
- if (strncmp((char *)index->name, "__", 2) == 0) continue;
- #if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
- rt_kprintf("%-16s -- %s\n", index->name, index->desc);
- #else
- rt_kprintf("%s\n", index->name);
- #endif
- }
- }
- return 0;
- }
- MSH_CMD_EXPORT(list, list all symbol in system)
- #ifdef RT_USING_LWP
- #include <lwp.h>
- #ifdef RT_USING_USERSPACE
- #include <lwp_mm_area.h>
- #endif
- #ifdef RT_USING_HEAP
- extern void list_mem(void);
- extern long list_memheap(void);
- #endif
- static rt_ubase_t rt_tick_mark = 0;
- static char top_ch;
- static void top_tick_hook(void)
- {
- rt_base_t level;
- struct rt_thread *thread;
- level = rt_hw_interrupt_disable();
- thread = rt_thread_self();
- if (thread)
- {
- if (thread->tick_mark != rt_tick_mark)
- {
- thread->run_tick = 0;
- thread->tick_mark = rt_tick_mark;
- }
- thread->run_tick++;
- }
- rt_hw_interrupt_enable(level);
- }
- static void top_getchar_entry(void* parameter)
- {
- rt_sem_t sem = (rt_sem_t)parameter;
- while (1)
- {
- top_ch = getchar();
- rt_sem_release(sem);
- if (top_ch == 'q')
- {
- break;
- }
- }
- }
- long top(void)
- {
- rt_thread_t tid;
- list_get_next_t find_arg;
- rt_list_t *next = (rt_list_t*)RT_NULL;
- rt_list_t *obj_list[LIST_FIND_OBJ_NR];
- const char *item_title = "THREAD";
- int maxlen;
- rt_sem_t top_char_sem;
- rt_base_t level;
- top_ch = 0;
- top_char_sem = rt_sem_create("top_char", 0, RT_IPC_FLAG_FIFO);
- tid = rt_thread_create("top_getchar", top_getchar_entry, top_char_sem,
- 1024, 2, 10);
- if (tid)
- {
- rt_thread_startup(tid);
- }
- while (1)
- {
- rt_ubase_t tick_diff;
- rt_ubase_t wait_tick;
- level = rt_hw_interrupt_disable();
- rt_tick_mark = rt_tick_get();
- rt_tick_sethook(top_tick_hook);
- rt_hw_interrupt_enable(level);
- wait_tick = RT_TICK_PER_SECOND + rt_tick_mark;
- while (rt_tick_get() < wait_tick)
- {
- rt_sem_take(top_char_sem, wait_tick - rt_tick_get());
- if (top_ch == 'q')
- {
- rt_sem_delete(top_char_sem);
- level = rt_hw_interrupt_disable();
- rt_tick_sethook(0);
- rt_hw_interrupt_enable(level);
- return 0;
- }
- }
- level = rt_hw_interrupt_disable();
- rt_tick_sethook(0);
- rt_hw_interrupt_enable(level);
- tick_diff = rt_tick_get() - rt_tick_mark;
- list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
- maxlen = RT_NAME_MAX;
- rt_kprintf("\033[2J");
- #ifdef RT_USING_HEAP
- #ifdef RT_USING_MEMHEAP_AS_HEAP
- list_memheap();
- #else
- list_mem();
- #endif
- #endif
- object_split(maxlen);
- rt_kprintf( "----------------\n");
- rt_kprintf("%-*.s PID PRI A %%CPU VIRT\n", maxlen, item_title); object_split(maxlen);
- rt_kprintf( " ----- --- - ---- ----\n");
- do
- {
- next = list_get_next(next, &find_arg);
- {
- int i;
- for (i = 0; i < find_arg.nr_out; i++)
- {
- struct rt_object *obj;
- struct rt_thread thread_info, *thread;
- obj = rt_list_entry(obj_list[i], struct rt_object, list);
- level = rt_hw_interrupt_disable();
- if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
- {
- rt_hw_interrupt_enable(level);
- continue;
- }
- /* copy info */
- memcpy(&thread_info, obj, sizeof thread_info);
- rt_hw_interrupt_enable(level);
- thread = (struct rt_thread*)obj;
- {
- if (thread->tick_mark != rt_tick_mark)
- {
- thread->run_tick = 0;
- }
- level = rt_hw_interrupt_disable();
- if (thread->lwp)
- {
- pid_t pid;
- struct rt_lwp *lwp;
- lwp = (struct rt_lwp*)thread->lwp;
- lwp_ref_inc(lwp);
- rt_hw_interrupt_enable(level);
- pid = lwp_to_pid(lwp);
- rt_kprintf("%-*.*s %5d %3d ", maxlen, RT_NAME_MAX, thread->name, pid, thread->current_priority);
- #ifdef RT_USING_USERSPACE
- {
- size_t virt;
- level = rt_hw_interrupt_disable();
- virt = lwp_vmem_count(lwp->map_area);
- rt_hw_interrupt_enable(level);
- rt_kprintf(" U %3d 0x%08x\n", thread->run_tick * 100/tick_diff, virt);
- }
- #else
- rt_kprintf(" U %3d\n", thread->run_tick * 100/tick_diff);
- #endif
- lwp_ref_dec(lwp);
- }
- else
- {
- rt_hw_interrupt_enable(level);
- rt_kprintf("%-*.*s %3d ", maxlen, RT_NAME_MAX, thread->name, thread->current_priority);
- rt_kprintf(" K %3d\n", thread->run_tick * 100/tick_diff);
- }
- }
- }
- }
- }
- while (next != (rt_list_t*)RT_NULL);
- }
- return 0;
- }
- MSH_CMD_EXPORT(top, disaplay system info);
- #endif /* end of RT_USING_LWP */
- #endif /* RT_USING_FINSH */
|