From ed9a558da979035c38fac68d715bfa3ea553822d Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Thu, 27 Dec 2018 16:31:22 +0800 Subject: [PATCH] =?UTF-8?q?list=5F*=E6=97=B6=EF=BC=8C=E6=8F=90=E4=BE=9B?= =?UTF-8?q?=E5=AF=B9=E7=AC=AC=E4=B8=80=E5=B1=82object=E7=9A=84=E5=8E=9F?= =?UTF-8?q?=E5=AD=90=E4=BF=9D=E6=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/finsh/cmd.c | 946 +++++++++++++++++++++++++---------------- include/rtdef.h | 3 +- 2 files changed, 574 insertions(+), 375 deletions(-) diff --git a/components/finsh/cmd.c b/components/finsh/cmd.c index 1adefea652..aa6ee6c2fc 100644 --- a/components/finsh/cmd.c +++ b/components/finsh/cmd.c @@ -26,6 +26,8 @@ * 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_* */ #include @@ -35,6 +37,8 @@ #include "finsh.h" +#define LIST_FIND_OBJ_NR 8 + long hello(void) { rt_kprintf("Hello RT-Thread!\n"); @@ -53,45 +57,51 @@ long version(void) FINSH_FUNCTION_EXPORT(version, show RT-Thread version information); MSH_CMD_EXPORT(version, show RT-Thread version information); -static int object_name_maxlen(const char *type_name, struct rt_list_node *list) +rt_inline void object_split(int len) { - struct rt_list_node *node; - struct rt_object *object = NULL; - int max_length = rt_strlen(type_name), length; - - rt_enter_critical(); - for (node = list->next; node != list; node = node->next) - { - object = rt_list_entry(node, struct rt_object, list); - - length = rt_strlen(object->name); - if (length > max_length) max_length = length; - } - rt_exit_critical(); - - if (max_length > RT_NAME_MAX || max_length == 0) max_length = RT_NAME_MAX; - - return max_length; + while (len--) rt_kprintf("-"); } -rt_inline void object_split(int len) +typedef struct { - while (len--) rt_kprintf("-"); + 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(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_thread_next(rt_list_t *current, int *max_name_len) +static rt_list_t *list_get_next(rt_list_t *current, list_get_next_t *arg) { int first_flag = 0; rt_ubase_t level; - struct rt_object_information *info; - rt_list_t *node, *iter, *list; - struct rt_thread *thread; - const char *item_title = "thread"; - int maxlen; - struct rt_thread thread_info; + rt_list_t *node, *list; + rt_list_t **array; + int nr; - info = rt_object_get_information(RT_Object_Class_Thread); - list = &info->object_list; + arg->nr_out = 0; + + if (!arg->nr || !arg->type) + { + return (rt_list_t *)RT_NULL; + } + + list = arg->list; if (!current) /* find first */ { @@ -105,112 +115,132 @@ static rt_list_t *list_thread_next(rt_list_t *current, int *max_name_len) level = rt_hw_interrupt_disable(); - if (first_flag) - { - /* is find first */ - maxlen = object_name_maxlen(item_title, list); - *max_name_len = maxlen; - } - else + if (!first_flag) { + struct rt_object *obj; /* The node in the list? */ - for (iter = list->next; iter != list; iter = iter->next) - { - if (iter == node) - { - break; - } - } - if (iter == list) + obj = rt_list_entry(node, struct rt_object, list); + if ((obj->type & ~RT_Object_Class_Static) != arg->type) { - /* not found , error! */ rt_hw_interrupt_enable(level); return (rt_list_t *)RT_NULL; } - maxlen = *max_name_len; } - node = node->next; - if (node == list) + nr = 0; + array = arg->array; + while (1) { - /* At the end of list */ - rt_hw_interrupt_enable(level); - return (rt_list_t *)RT_NULL; + 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; +} - /* ok, found a thread */ - thread = rt_list_entry(node, struct rt_thread, list); - /* copy info */ - memcpy(&thread_info, thread, sizeof thread_info); +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; - rt_hw_interrupt_enable(level); + list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list)/sizeof(obj_list[0])); - /* now output thread info */ - { - rt_uint8_t stat; - rt_uint8_t *ptr; + maxlen = RT_NAME_MAX; - if (first_flag) - { #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"); + 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"); + 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 */ + 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_info.oncpu != RT_CPU_DETACHED) - rt_kprintf("%-*.*s %3d %3d ", maxlen, RT_NAME_MAX, thread_info.name, thread_info.oncpu, thread_info.current_priority); - else - rt_kprintf("%-*.*s N/A %3d ", maxlen, RT_NAME_MAX, thread_info.name, thread_info.current_priority); + 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_info.name, thread_info.current_priority); + rt_kprintf("%-*.*s %3d ", maxlen, RT_NAME_MAX, thread->name, thread->current_priority); #endif /*RT_USING_SMP*/ - stat = (thread_info.stat & RT_THREAD_STAT_MASK); - if (stat == RT_THREAD_READY) rt_kprintf(" ready "); - else if (stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend"); - else if (stat == RT_THREAD_INIT) rt_kprintf(" init "); - else if (stat == RT_THREAD_CLOSE) rt_kprintf(" close "); + stat = (thread->stat & RT_THREAD_STAT_MASK); + if (stat == RT_THREAD_READY) rt_kprintf(" ready "); + else if (stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend"); + else if (stat == RT_THREAD_INIT) rt_kprintf(" init "); + else if (stat == RT_THREAD_CLOSE) rt_kprintf(" close "); #if defined(ARCH_CPU_STACK_GROWS_UPWARD) - ptr = (rt_uint8_t *)thread_info.stack_addr + thread_info.stack_size - 1; - while (*ptr == '#')ptr --; - - rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %03d\n", - ((rt_ubase_t)thread_info.sp - (rt_ubase_t)thread_info.stack_addr), - thread_info.stack_size, - ((rt_ubase_t)ptr - (rt_ubase_t)thread_info.stack_addr) * 100 / thread_info.stack_size, - thread_info.remaining_tick, - thread_info.error); + 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_info.stack_addr; - while (*ptr == '#')ptr ++; - - rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %03d\n", - thread_info.stack_size + ((rt_ubase_t)thread_info.stack_addr - (rt_ubase_t)thread_info.sp), - thread_info.stack_size, - (thread_info.stack_size - ((rt_ubase_t) ptr - (rt_ubase_t) thread_info.stack_addr)) * 100 - / thread_info.stack_size, - thread_info.remaining_tick, - thread_info.error); + 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 + } + } + } } - return node; -} - -long list_thread(void) -{ - int maxlen; - rt_list_t *thread_list = (rt_list_t*)RT_NULL; - - do - { - thread_list = list_thread_next(thread_list, &maxlen); - } - while (thread_list != (rt_list_t*)RT_NULL); + while (next != (rt_list_t*)RT_NULL); return 0; } @@ -233,427 +263,595 @@ static void show_wait_queue(struct rt_list_node *list) } #ifdef RT_USING_SEMAPHORE -static long _list_sem(struct rt_list_node *list) +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; - struct rt_semaphore *sem; - struct rt_list_node *node; const char *item_title = "semaphore"; - maxlen = object_name_maxlen(item_title, list); + 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"); - for (node = list->next; node != list; node = node->next) + + do { - sem = (struct rt_semaphore *)(rt_list_entry(node, struct rt_object, list)); - 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 + next = list_get_next(next, &find_arg); { - rt_kprintf("%-*.*s %03d %d\n", - maxlen, RT_NAME_MAX, - sem->parent.parent.name, - sem->value, - rt_list_len(&sem->parent.suspend_thread)); + 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; } - -long list_sem(void) -{ - struct rt_object_information *info; - - info = rt_object_get_information(RT_Object_Class_Semaphore); - - return _list_sem(&info->object_list); -} -FINSH_FUNCTION_EXPORT(list_sem, list semaphone in system); +FINSH_FUNCTION_EXPORT(list_sem, list semaphore in system); MSH_CMD_EXPORT(list_sem, list semaphore in system); #endif #ifdef RT_USING_EVENT -static long _list_event(struct rt_list_node *list) +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; - struct rt_event *e; - struct rt_list_node *node; const char *item_title = "event"; - maxlen = object_name_maxlen(item_title, list); + 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"); - for (node = list->next; node != list; node = node->next) + + do { - e = (struct rt_event *)(rt_list_entry(node, struct rt_object, list)); - 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 + next = list_get_next(next, &find_arg); { - rt_kprintf("%-*.*s 0x%08x 0\n", - maxlen, RT_NAME_MAX, e->parent.parent.name, e->set); + 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; } - -long list_event(void) -{ - struct rt_object_information *info; - - info = rt_object_get_information(RT_Object_Class_Event); - return _list_event(&info->object_list); -} FINSH_FUNCTION_EXPORT(list_event, list event in system); MSH_CMD_EXPORT(list_event, list event in system); #endif #ifdef RT_USING_MUTEX -static long _list_mutex(struct rt_list_node *list) +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; - struct rt_mutex *m; - struct rt_list_node *node; const char *item_title = "mutex"; - maxlen = object_name_maxlen(item_title, list); + 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"); - for (node = list->next; node != list; node = node->next) + + do { - m = (struct rt_mutex *)(rt_list_entry(node, struct rt_object, list)); - 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)); - } + 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; - return 0; -} + 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; + } -long list_mutex(void) -{ - struct rt_object_information *info; + rt_hw_interrupt_enable(level); - info = rt_object_get_information(RT_Object_Class_Mutex); + 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 _list_mutex(&info->object_list); + return 0; } FINSH_FUNCTION_EXPORT(list_mutex, list mutex in system); MSH_CMD_EXPORT(list_mutex, list mutex in system); #endif #ifdef RT_USING_MAILBOX -static long _list_mailbox(struct rt_list_node *list) +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; - struct rt_mailbox *m; - struct rt_list_node *node; const char *item_title = "mailbox"; - maxlen = object_name_maxlen(item_title, list); + 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"); - for (node = list->next; node != list; node = node->next) + + do { - m = (struct rt_mailbox *)(rt_list_entry(node, struct rt_object, list)); - 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 + next = list_get_next(next, &find_arg); { - 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)); + 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; } - -long list_mailbox(void) -{ - struct rt_object_information *info; - - info = rt_object_get_information(RT_Object_Class_MailBox); - return _list_mailbox(&info->object_list); -} FINSH_FUNCTION_EXPORT(list_mailbox, list mail box in system); MSH_CMD_EXPORT(list_mailbox, list mail box in system); #endif #ifdef RT_USING_MESSAGEQUEUE -static long _list_msgqueue(struct rt_list_node *list) +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; - struct rt_messagequeue *m; - struct rt_list_node *node; const char *item_title = "msgqueue"; - maxlen = object_name_maxlen(item_title, list); + 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"); - for (node = list->next; node != list; node = node->next) + do { - m = (struct rt_messagequeue *)(rt_list_entry(node, struct rt_object, list)); - 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 + next = list_get_next(next, &find_arg); { - rt_kprintf("%-*.*s %04d %d\n", - maxlen, RT_NAME_MAX, - m->parent.parent.name, - m->entry, - rt_list_len(&m->parent.suspend_thread)); + 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; } - -long list_msgqueue(void) -{ - struct rt_object_information *info; - - info = rt_object_get_information(RT_Object_Class_MessageQueue); - return _list_msgqueue(&info->object_list); -} FINSH_FUNCTION_EXPORT(list_msgqueue, list message queue in system); MSH_CMD_EXPORT(list_msgqueue, list message queue in system); #endif #ifdef RT_USING_MEMHEAP -static long _list_memheap(struct rt_list_node *list) +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; - struct rt_memheap *mh; - struct rt_list_node *node; const char *item_title = "memheap"; - maxlen = object_name_maxlen(item_title, list); + 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"); - for (node = list->next; node != list; node = node->next) + do { - mh = (struct rt_memheap *)rt_list_entry(node, struct rt_object, list); - - rt_kprintf("%-*.*s %-010d %-013d %-05d\n", - maxlen, RT_NAME_MAX, - mh->parent.name, - mh->pool_size, - mh->max_used_size, - mh->available_size); - } + 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; - return 0; -} + 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; + } -long list_memheap(void) -{ - struct rt_object_information *info; + 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); - info = rt_object_get_information(RT_Object_Class_MemHeap); - return _list_memheap(&info->object_list); + return 0; } FINSH_FUNCTION_EXPORT(list_memheap, list memory heap in system); MSH_CMD_EXPORT(list_memheap, list memory heap in system); #endif #ifdef RT_USING_MEMPOOL -static long _list_mempool(struct rt_list_node *list) +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; - struct rt_mempool *mp; - struct rt_list_node *node; const char *item_title = "mempool"; - maxlen = object_name_maxlen(item_title, list); + 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"); - for (node = list->next; node != list; node = node->next) + do { - mp = (struct rt_mempool *)rt_list_entry(node, struct rt_object, list); - if (mp->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, - mp->suspend_thread_count); - show_wait_queue(&(mp->suspend_thread)); - rt_kprintf("\n"); - } - else + next = list_get_next(next, &find_arg); { - 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, - mp->suspend_thread_count); + int i; + for (i = 0; i < find_arg.nr_out; i++) + { + struct rt_object *obj; + struct rt_mempool *mp; + + 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; + if (mp->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, + mp->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, + mp->suspend_thread_count); + } + } } } + while (next != (rt_list_t*)RT_NULL); return 0; } - -long list_mempool(void) -{ - struct rt_object_information *info; - - info = rt_object_get_information(RT_Object_Class_MemPool); - return _list_mempool(&info->object_list); -} FINSH_FUNCTION_EXPORT(list_mempool, list memory pool in system) MSH_CMD_EXPORT(list_mempool, list memory pool in system); #endif -static long _list_timer(struct rt_list_node *list) +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; - struct rt_timer *timer; - struct rt_list_node *node; const char *item_title = "timer"; - maxlen = object_name_maxlen(item_title, list); + 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"); - for (node = list->next; node != list; node = node->next) - { - timer = (struct rt_timer *)(rt_list_entry(node, struct rt_object, list)); - 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"); + 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; } - -long list_timer(void) -{ - struct rt_object_information *info; - - info = rt_object_get_information(RT_Object_Class_Timer); - return _list_timer(&info->object_list); -} FINSH_FUNCTION_EXPORT(list_timer, list timer in system); MSH_CMD_EXPORT(list_timer, list timer in system); #ifdef RT_USING_DEVICE -static long _list_device(struct rt_list_node *list) +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", + "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; - struct rt_device *device; - struct rt_list_node *node; - 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", - "Unknown" - }; const char *item_title = "device"; - maxlen = object_name_maxlen(item_title, list); + 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"); - for (node = list->next; node != list; node = node->next) + do { - device = (struct rt_device *)(rt_list_entry(node, struct rt_object, list)); - 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); - } + 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; - return 0; -} + 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; + } -long list_device(void) -{ - struct rt_object_information *info; + rt_hw_interrupt_enable(level); - info = rt_object_get_information(RT_Object_Class_Device); - return _list_device(&info->object_list); + 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; } FINSH_FUNCTION_EXPORT(list_device, list device in system); MSH_CMD_EXPORT(list_device, list device in system); diff --git a/include/rtdef.h b/include/rtdef.h index 49551de9ee..ecdabd4490 100644 --- a/include/rtdef.h +++ b/include/rtdef.h @@ -367,7 +367,8 @@ typedef struct rt_object *rt_object_t; /**< Type for kernel obj */ enum rt_object_class_type { - RT_Object_Class_Thread = 0, /**< The object is a thread. */ + RT_Object_Class_Null = 0, /**< The object is not used. */ + RT_Object_Class_Thread, /**< The object is a thread. */ RT_Object_Class_Semaphore, /**< The object is a semaphore. */ RT_Object_Class_Mutex, /**< The object is a mutex. */ RT_Object_Class_Event, /**< The object is a event. */ -- GitLab