cmd.c 33.3 KB
Newer Older
1

2
/*
3
 * Copyright (c) 2006-2018, RT-Thread Development Team
4
 *
5
 * SPDX-License-Identifier: Apache-2.0
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * 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
24 25
 * 2010-04-21     yi.qiu       add list_module
 * 2012-04-29     goprife      improve the command line auto-complete feature.
26
 * 2012-06-02     lgnq         add list_memheap
27
 * 2012-10-22     Bernard      add MS VC++ patch.
28
 * 2016-06-02     armink       beautify the list_thread command
S
shaojinchun 已提交
29
 * 2018-11-22     Jesven       list_thread add smp support
30 31
 * 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_*
J
jch12138 已提交
32
 * 2020-04-07     chenhui      add clear 
33 34
 */

S
shaojinchun 已提交
35
#include <rthw.h>
36
#include <rtthread.h>
37 38 39

#ifdef RT_USING_FINSH

40 41
#include "finsh.h"

42 43
#define LIST_FIND_OBJ_NR 8

44
long hello(void)
45
{
46
    rt_kprintf("Hello RT-Thread!\n");
47

48
    return 0;
49
}
50
FINSH_FUNCTION_EXPORT(hello, say hello world);
51

52
static long clear(void)
J
jch12138 已提交
53 54 55 56 57 58 59 60
{
    rt_kprintf("\x1b[2J\x1b[H");

    return 0;
}
FINSH_FUNCTION_EXPORT(clear,clear the terminal screen);
MSH_CMD_EXPORT(clear,clear the terminal screen);

61
extern void rt_show_version(void);
62
long version(void)
63
{
64
    rt_show_version();
65

66
    return 0;
67
}
68
FINSH_FUNCTION_EXPORT(version, show RT-Thread version information);
B
Bernard Xiong 已提交
69
MSH_CMD_EXPORT(version, show RT-Thread version information);
70

71
rt_inline void object_split(int len)
72
{
73
    while (len--) rt_kprintf("-");
74 75
}

76
typedef struct
77
{
78 79 80 81 82 83 84 85 86 87 88 89
    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;

90
    info = rt_object_get_information((enum rt_object_class_type)type);
91 92 93 94 95 96 97
    list = &info->object_list;

    p->list = list;
    p->type = type;
    p->array = array;
    p->nr = nr;
    p->nr_out = 0;
98 99
}

100
static rt_list_t *list_get_next(rt_list_t *current, list_get_next_t *arg)
101
{
102 103
    int first_flag = 0;
    rt_ubase_t level;
104 105 106
    rt_list_t *node, *list;
    rt_list_t **array;
    int nr;
107

108 109 110 111 112 113 114 115
    arg->nr_out = 0;

    if (!arg->nr || !arg->type)
    {
        return (rt_list_t *)RT_NULL;
    }

    list = arg->list;
116 117 118 119 120 121 122 123 124 125 126 127 128

    if (!current) /* find first */
    {
        node = list;
        first_flag = 1;
    }
    else
    {
        node = current;
    }

    level = rt_hw_interrupt_disable();

129
    if (!first_flag)
130
    {
131
        struct rt_object *obj;
132
        /* The node in the list? */
133 134
        obj = rt_list_entry(node, struct rt_object, list);
        if ((obj->type & ~RT_Object_Class_Static) != arg->type)
135 136 137 138 139 140
        {
            rt_hw_interrupt_enable(level);
            return (rt_list_t *)RT_NULL;
        }
    }

141 142 143
    nr = 0;
    array = arg->array;
    while (1)
144
    {
145 146 147 148 149 150 151 152 153 154 155 156 157
        node = node->next;

        if (node == list)
        {
            node = (rt_list_t *)RT_NULL;
            break;
        }
        nr++;
        *array++ = node;
        if (nr == arg->nr)
        {
            break;
        }
158
    }
159 160 161 162 163
    
    rt_hw_interrupt_enable(level);
    arg->nr_out = nr;
    return node;
}
164

165 166 167 168 169 170 171 172
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;
173

174
    list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
175

176
    maxlen = RT_NAME_MAX;
177

S
shaojinchun 已提交
178
#ifdef RT_USING_SMP
179 180
    rt_kprintf("%-*.s cpu pri  status      sp     stack size max used left tick  error\n", maxlen, item_title); object_split(maxlen);
    rt_kprintf(     " --- ---  ------- ---------- ----------  ------  ---------- ---\n");
S
shaojinchun 已提交
181
#else
182 183
    rt_kprintf("%-*.s pri  status      sp     stack size max used left tick  error\n", maxlen, item_title); object_split(maxlen);
    rt_kprintf(     " ---  ------- ---------- ----------  ------  ---------- ---\n");
S
shaojinchun 已提交
184
#endif /*RT_USING_SMP*/
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212

    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;

S
shaojinchun 已提交
213
#ifdef RT_USING_SMP
214 215 216 217
                    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);
218

S
shaojinchun 已提交
219
#else
220
                    rt_kprintf("%-*.*s %3d ", maxlen, RT_NAME_MAX, thread->name, thread->current_priority);
S
shaojinchun 已提交
221
#endif /*RT_USING_SMP*/
222 223 224 225 226
                    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  ");
227
                    else if (stat == RT_THREAD_RUNNING) rt_kprintf(" running");
228

229
#if defined(ARCH_CPU_STACK_GROWS_UPWARD)
230 231 232 233 234 235 236 237 238
                    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);
239
#else
240 241 242 243 244 245 246 247 248 249
                    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);
250
#endif
251 252 253
                }
            }
        }
254
    }
255
    while (next != (rt_list_t*)RT_NULL);
256 257

    return 0;
qiuyiuestc's avatar
qiuyiuestc 已提交
258
}
259
FINSH_FUNCTION_EXPORT(list_thread, list thread);
B
Bernard Xiong 已提交
260
MSH_CMD_EXPORT(list_thread, list thread);
261

262
static void show_wait_queue(struct rt_list_node *list)
263
{
264 265 266 267 268 269 270
    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", thread->name);
D
dzzxzz@gmail.com 已提交
271

272
        if (node->next != list)
D
dzzxzz@gmail.com 已提交
273
            rt_kprintf("/");
274
    }
275 276 277
}

#ifdef RT_USING_SEMAPHORE
278
long list_sem(void)
279
{
280 281 282 283 284
    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;

285
    int maxlen;
286
    const char *item_title = "semaphore";
287

288 289 290
    list_find_init(&find_arg, RT_Object_Class_Semaphore, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));

    maxlen = RT_NAME_MAX;
291

292
    rt_kprintf("%-*.s v   suspend thread\n", maxlen, item_title); object_split(maxlen);
293
    rt_kprintf(     " --- --------------\n");
294 295

    do
296
    {
297
        next = list_get_next(next, &find_arg);
298
        {
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
            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));
                }
            }
334 335
        }
    }
336
    while (next != (rt_list_t*)RT_NULL);
337 338

    return 0;
339
}
340
FINSH_FUNCTION_EXPORT(list_sem, list semaphore in system);
B
Bernard Xiong 已提交
341
MSH_CMD_EXPORT(list_sem, list semaphore in system);
342 343 344
#endif

#ifdef RT_USING_EVENT
345
long list_event(void)
346
{
347 348 349 350 351
    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;

352
    int maxlen;
353
    const char *item_title = "event";
354

355 356 357
    list_find_init(&find_arg, RT_Object_Class_Event, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));

    maxlen = RT_NAME_MAX;
358

359
    rt_kprintf("%-*.s      set    suspend thread\n", maxlen, item_title); object_split(maxlen);
360
    rt_kprintf(     "  ---------- --------------\n");
361 362

    do
363
    {
364
        next = list_get_next(next, &find_arg);
365
        {
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
            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);
                }
            }
399 400
        }
    }
401
    while (next != (rt_list_t*)RT_NULL);
402 403

    return 0;
404
}
B
Bernard Xiong 已提交
405 406
FINSH_FUNCTION_EXPORT(list_event, list event in system);
MSH_CMD_EXPORT(list_event, list event in system);
407 408 409
#endif

#ifdef RT_USING_MUTEX
410
long list_mutex(void)
411
{
412 413 414 415 416
    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;

417
    int maxlen;
418
    const char *item_title = "mutex";
419

420 421 422
    list_find_init(&find_arg, RT_Object_Class_Mutex, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));

    maxlen = RT_NAME_MAX;
423 424

    rt_kprintf("%-*.s   owner  hold suspend thread\n", maxlen, item_title); object_split(maxlen);
425
    rt_kprintf(     " -------- ---- --------------\n");
426 427

    do
428
    {
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
        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));

            }
        }
458
    }
459
    while (next != (rt_list_t*)RT_NULL);
460 461

    return 0;
462
}
B
Bernard Xiong 已提交
463 464
FINSH_FUNCTION_EXPORT(list_mutex, list mutex in system);
MSH_CMD_EXPORT(list_mutex, list mutex in system);
465 466 467
#endif

#ifdef RT_USING_MAILBOX
468
long list_mailbox(void)
469
{
470 471 472 473 474
    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;

475
    int maxlen;
G
gbcwbz 已提交
476
    const char *item_title = "mailbox";
477

478 479 480
    list_find_init(&find_arg, RT_Object_Class_MailBox, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));

    maxlen = RT_NAME_MAX;
481

482 483
    rt_kprintf("%-*.s entry size suspend thread\n", maxlen, item_title); object_split(maxlen);
    rt_kprintf(     " ----  ---- --------------\n");
484 485

    do
486
    {
487
        next = list_get_next(next, &find_arg);
488
        {
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
            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));
                }

            }
528 529
        }
    }
530
    while (next != (rt_list_t*)RT_NULL);
531 532

    return 0;
533
}
B
Bernard Xiong 已提交
534 535
FINSH_FUNCTION_EXPORT(list_mailbox, list mail box in system);
MSH_CMD_EXPORT(list_mailbox, list mail box in system);
536 537 538
#endif

#ifdef RT_USING_MESSAGEQUEUE
539
long list_msgqueue(void)
540
{
541 542 543 544 545
    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;

546
    int maxlen;
G
gbcwbz 已提交
547
    const char *item_title = "msgqueue";
548

549 550 551
    list_find_init(&find_arg, RT_Object_Class_MessageQueue, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));

    maxlen = RT_NAME_MAX;
552

553
    rt_kprintf("%-*.s entry suspend thread\n", maxlen, item_title); object_split(maxlen);
554
    rt_kprintf(     " ----  --------------\n");
555
    do
556
    {
557
        next = list_get_next(next, &find_arg);
558
        {
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594
            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));
                }
            }
595 596
        }
    }
597
    while (next != (rt_list_t*)RT_NULL);
598 599

    return 0;
600
}
B
Bernard Xiong 已提交
601 602
FINSH_FUNCTION_EXPORT(list_msgqueue, list message queue in system);
MSH_CMD_EXPORT(list_msgqueue, list message queue in system);
603 604
#endif

605
#ifdef RT_USING_MEMHEAP
606
long list_memheap(void)
607
{
608 609 610 611 612
    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;

613
    int maxlen;
614
    const char *item_title = "memheap";
615

616 617 618
    list_find_init(&find_arg, RT_Object_Class_MemHeap, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));

    maxlen = RT_NAME_MAX;
619

620
    rt_kprintf("%-*.s  pool size  max used size available size\n", maxlen, item_title); object_split(maxlen);
621
    rt_kprintf(      " ---------- ------------- --------------\n");
622
    do
623
    {
624 625 626 627 628 629 630
        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;
631

632 633 634 635 636 637 638
                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;
                }
639

640
                rt_hw_interrupt_enable(level);
641

642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
                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;
657
}
B
Bernard Xiong 已提交
658 659
FINSH_FUNCTION_EXPORT(list_memheap, list memory heap in system);
MSH_CMD_EXPORT(list_memheap, list memory heap in system);
660 661
#endif

662
#ifdef RT_USING_MEMPOOL
663
long list_mempool(void)
664
{
665 666 667 668 669
    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;

670
    int maxlen;
671
    const char *item_title = "mempool";
672

673 674 675
    list_find_init(&find_arg, RT_Object_Class_MemPool, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));

    maxlen = RT_NAME_MAX;
676

677
    rt_kprintf("%-*.s block total free suspend thread\n", maxlen, item_title); object_split(maxlen);
678
    rt_kprintf(     " ----  ----  ---- --------------\n");
679
    do
680
    {
681
        next = list_get_next(next, &find_arg);
682
        {
683 684 685 686 687
            int i;
            for (i = 0; i < find_arg.nr_out; i++)
            {
                struct rt_object *obj;
                struct rt_mempool *mp;
688 689
                int suspend_thread_count;
                rt_list_t *node;
690 691 692 693 694 695 696 697 698 699 700 701

                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;
702 703

                suspend_thread_count = 0;
704
                rt_list_for_each(node, &mp->suspend_thread)
705 706 707 708 709
                {
                    suspend_thread_count++;
                }

                if (suspend_thread_count > 0)
710 711 712 713 714 715 716
                {
                    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,
717
                            suspend_thread_count);
718 719 720 721 722 723 724 725 726 727 728
                    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,
729
                            suspend_thread_count);
730 731
                }
            }
732 733
        }
    }
734
    while (next != (rt_list_t*)RT_NULL);
735 736

    return 0;
737 738
}
FINSH_FUNCTION_EXPORT(list_mempool, list memory pool in system)
B
Bernard Xiong 已提交
739
MSH_CMD_EXPORT(list_mempool, list memory pool in system);
740 741
#endif

742
long list_timer(void)
743
{
744 745 746 747 748
    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;

749
    int maxlen;
750
    const char *item_title = "timer";
751

752 753 754
    list_find_init(&find_arg, RT_Object_Class_Timer, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));

    maxlen = RT_NAME_MAX;
755

756
    rt_kprintf("%-*.s  periodic   timeout       flag\n", maxlen, item_title); object_split(maxlen);
757
    rt_kprintf(     " ---------- ---------- -----------\n");
758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789
    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");

            }
        }
790
    }
791
    while (next != (rt_list_t*)RT_NULL);
792 793 794 795

    rt_kprintf("current tick:0x%08x\n", rt_tick_get());

    return 0;
796
}
B
Bernard Xiong 已提交
797 798
FINSH_FUNCTION_EXPORT(list_timer, list timer in system);
MSH_CMD_EXPORT(list_timer, list timer in system);
799 800

#ifdef RT_USING_DEVICE
801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821
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",
G
guozhanxin 已提交
822
    "Sensor Device",
T
tyustli 已提交
823
    "Touch Device",
824
    "Phy Device",
825 826 827 828
    "Unknown"
};

long list_device(void)
829
{
830 831 832 833 834
    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;

835
    int maxlen;
G
gbcwbz 已提交
836 837
    const char *item_title = "device";

838 839 840
    list_find_init(&find_arg, RT_Object_Class_Device, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));

    maxlen = RT_NAME_MAX;
841

842 843
    rt_kprintf("%-*.s         type         ref count\n", maxlen, item_title); object_split(maxlen);
    rt_kprintf(     " -------------------- ----------\n");
844
    do
845
    {
846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874
        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);

            }
        }
875
    }
876
    while (next != (rt_list_t*)RT_NULL);
877 878

    return 0;
879
}
B
Bernard Xiong 已提交
880 881
FINSH_FUNCTION_EXPORT(list_device, list device in system);
MSH_CMD_EXPORT(list_device, list device in system);
882 883
#endif

D
dzzxzz 已提交
884
long list(void)
885
{
B
bernard 已提交
886
#ifndef FINSH_USING_MSH_ONLY
887 888
    struct finsh_syscall_item *syscall_item;
    struct finsh_sysvar_item *sysvar_item;
B
bernard 已提交
889
#endif
890

891 892
    rt_kprintf("--Function List:\n");
    {
893
        struct finsh_syscall *index;
D
dzzxzz@gmail.com 已提交
894
        for (index = _syscall_table_begin;
895 896
                index < _syscall_table_end;
                FINSH_NEXT_SYSCALL(index))
897
        {
898 899
            /* skip the internal command */
            if (strncmp((char *)index->name, "__", 2) == 0) continue;
B
Bernard Xiong 已提交
900

901
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
902
            rt_kprintf("%-16s -- %s\n", index->name, index->desc);
903
#else
904
            rt_kprintf("%s\n", index->name);
905
#endif
906 907 908
        }
    }

B
bernard 已提交
909
#ifndef FINSH_USING_MSH_ONLY
910 911 912 913 914 915 916 917 918 919
    /* list syscall list */
    syscall_item = global_syscall_list;
    while (syscall_item != NULL)
    {
        rt_kprintf("[l] %s\n", syscall_item->syscall.name);
        syscall_item = syscall_item->next;
    }

    rt_kprintf("--Variable List:\n");
    {
920
        struct finsh_sysvar *index;
921
        for (index = _sysvar_table_begin;
922 923
                index < _sysvar_table_end;
                FINSH_NEXT_SYSVAR(index))
924
        {
925
#ifdef FINSH_USING_DESCRIPTION
926
            rt_kprintf("%-16s -- %s\n", index->name, index->desc);
927
#else
928
            rt_kprintf("%s\n", index->name);
929
#endif
930 931
        }
    }
932

933 934 935 936 937 938
    sysvar_item = global_sysvar_list;
    while (sysvar_item != NULL)
    {
        rt_kprintf("[l] %s\n", sysvar_item->sysvar.name);
        sysvar_item = sysvar_item->next;
    }
B
bernard 已提交
939
#endif
940

941
    return 0;
942 943 944
}
FINSH_FUNCTION_EXPORT(list, list all symbol in system)

B
bernard 已提交
945
#ifndef FINSH_USING_MSH_ONLY
946
static int str_is_prefix(const char *prefix, const char *str)
947
{
948 949 950 951 952 953
    while ((*prefix) && (*prefix == *str))
    {
        prefix ++;
        str ++;
    }

954
    if (*prefix == 0)
D
dzzxzz@gmail.com 已提交
955 956
        return 0;

957 958 959
    return -1;
}

960
static int str_common(const char *str1, const char *str2)
961
{
962
    const char *str = str1;
963

964
    while ((*str != 0) && (*str2 != 0) && (*str == *str2))
965 966 967 968 969 970
    {
        str ++;
        str2 ++;
    }

    return (str - str1);
971 972
}

973
void list_prefix(char *prefix)
974
{
975 976
    struct finsh_syscall_item *syscall_item;
    struct finsh_sysvar_item *sysvar_item;
977 978
    rt_uint16_t func_cnt, var_cnt;
    int length, min_length;
979
    const char *name_ptr;
980 981 982

    func_cnt = 0;
    var_cnt  = 0;
D
dzzxzz@gmail.com 已提交
983
    min_length = 0;
984 985 986 987
    name_ptr = RT_NULL;

    /* checks in system function call */
    {
D
dzzxzz@gmail.com 已提交
988 989
        struct finsh_syscall *index;
        for (index = _syscall_table_begin;
990 991
                index < _syscall_table_end;
                FINSH_NEXT_SYSCALL(index))
992
        {
993 994 995
            /* skip internal command */
            if (str_is_prefix("__", index->name) == 0) continue;

996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019
            if (str_is_prefix(prefix, index->name) == 0)
            {
                if (func_cnt == 0)
                {
                    rt_kprintf("--function:\n");

                    if (*prefix != 0)
                    {
                        /* set name_ptr */
                        name_ptr = index->name;

                        /* set initial length */
                        min_length = strlen(name_ptr);
                    }
                }

                func_cnt ++;

                if (*prefix != 0)
                {
                    length = str_common(name_ptr, index->name);
                    if (length < min_length)
                        min_length = length;
                }
1020 1021

#ifdef FINSH_USING_DESCRIPTION
1022
                rt_kprintf("%-16s -- %s\n", index->name, index->desc);
1023
#else
1024
                rt_kprintf("%s\n", index->name);
1025
#endif
1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064
            }
        }
    }

    /* checks in dynamic system function call */
    syscall_item = global_syscall_list;
    while (syscall_item != NULL)
    {
        if (str_is_prefix(prefix, syscall_item->syscall.name) == 0)
        {
            if (func_cnt == 0)
            {
                rt_kprintf("--function:\n");
                if (*prefix != 0 && name_ptr == NULL)
                {
                    /* set name_ptr */
                    name_ptr = syscall_item->syscall.name;

                    /* set initial length */
                    min_length = strlen(name_ptr);
                }
            }

            func_cnt ++;

            if (*prefix != 0)
            {
                length = str_common(name_ptr, syscall_item->syscall.name);
                if (length < min_length)
                    min_length = length;
            }

            rt_kprintf("[l] %s\n", syscall_item->syscall.name);
        }
        syscall_item = syscall_item->next;
    }

    /* checks in system variable */
    {
1065
        struct finsh_sysvar *index;
1066
        for (index = _sysvar_table_begin;
1067 1068
                index < _sysvar_table_end;
                FINSH_NEXT_SYSVAR(index))
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094
        {
            if (str_is_prefix(prefix, index->name) == 0)
            {
                if (var_cnt == 0)
                {
                    rt_kprintf("--variable:\n");

                    if (*prefix != 0 && name_ptr == NULL)
                    {
                        /* set name_ptr */
                        name_ptr = index->name;

                        /* set initial length */
                        min_length = strlen(name_ptr);

                    }
                }

                var_cnt ++;

                if (*prefix != 0)
                {
                    length = str_common(name_ptr, index->name);
                    if (length < min_length)
                        min_length = length;
                }
B
bernard.xiong 已提交
1095

1096
#ifdef FINSH_USING_DESCRIPTION
1097
                rt_kprintf("%-16s -- %s\n", index->name, index->desc);
1098
#else
1099
                rt_kprintf("%s\n", index->name);
1100
#endif
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142
            }
        }
    }

    /* checks in dynamic system variable */
    sysvar_item = global_sysvar_list;
    while (sysvar_item != NULL)
    {
        if (str_is_prefix(prefix, sysvar_item->sysvar.name) == 0)
        {
            if (var_cnt == 0)
            {
                rt_kprintf("--variable:\n");
                if (*prefix != 0 && name_ptr == NULL)
                {
                    /* set name_ptr */
                    name_ptr = sysvar_item->sysvar.name;

                    /* set initial length */
                    min_length = strlen(name_ptr);
                }
            }

            var_cnt ++;

            if (*prefix != 0)
            {
                length = str_common(name_ptr, sysvar_item->sysvar.name);
                if (length < min_length)
                    min_length = length;
            }

            rt_kprintf("[v] %s\n", sysvar_item->sysvar.name);
        }
        sysvar_item = sysvar_item->next;
    }

    /* only one matched */
    if (name_ptr != NULL)
    {
        rt_strncpy(prefix, name_ptr, min_length);
    }
1143
}
B
bernard 已提交
1144
#endif
1145

B
bernard 已提交
1146
#if defined(FINSH_USING_SYMTAB) && !defined(FINSH_USING_MSH_ONLY)
1147 1148 1149
static int dummy = 0;
FINSH_VAR_EXPORT(dummy, finsh_type_int, dummy variable for finsh)
#endif
1150 1151 1152

#endif /* RT_USING_FINSH */