cmd.c 29.1 KB
Newer Older
1
/*
S
Stanley Lwin 已提交
2
 * Copyright (c) 2006-2022, RT-Thread Development Team
3
 *
4
 * SPDX-License-Identifier: Apache-2.0
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * 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
23 24
 * 2010-04-21     yi.qiu       add list_module
 * 2012-04-29     goprife      improve the command line auto-complete feature.
25
 * 2012-06-02     lgnq         add list_memheap
26
 * 2012-10-22     Bernard      add MS VC++ patch.
27
 * 2016-06-02     armink       beautify the list_thread command
S
shaojinchun 已提交
28
 * 2018-11-22     Jesven       list_thread add smp support
29
 * 2018-12-27     Jesven       Fix the problem that disable interrupt too long in list_thread
30
 *                             Provide protection for the "first layer of objects" when list_*
31
 * 2020-04-07     chenhui      add clear
S
Stanley Lwin 已提交
32
 * 2022-07-02     Stanley Lwin add list command
33 34
 */

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

#ifdef RT_USING_FINSH
马志远 已提交
40
#include <finsh.h>
41

42 43
#define LIST_FIND_OBJ_NR 8

44
static long clear(void)
J
jch12138 已提交
45 46 47 48 49
{
    rt_kprintf("\x1b[2J\x1b[H");

    return 0;
}
马志远 已提交
50
MSH_CMD_EXPORT(clear, clear the terminal screen);
J
jch12138 已提交
51

52
extern void rt_show_version(void);
53
long version(void)
54
{
55
    rt_show_version();
56

57
    return 0;
58
}
G
guozhanxin 已提交
59
MSH_CMD_EXPORT(version, show RT-Thread version information);
60

61
rt_inline void object_split(int len)
62
{
63
    while (len--) rt_kprintf("-");
64 65
}

66
typedef struct
67
{
68 69 70 71 72 73 74 75 76 77 78 79
    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;

80
    info = rt_object_get_information((enum rt_object_class_type)type);
81 82 83 84 85 86 87
    list = &info->object_list;

    p->list = list;
    p->type = type;
    p->array = array;
    p->nr = nr;
    p->nr_out = 0;
88 89
}

90
static rt_list_t *list_get_next(rt_list_t *current, list_get_next_t *arg)
91
{
92
    int first_flag = 0;
93
    rt_base_t level;
94 95 96
    rt_list_t *node, *list;
    rt_list_t **array;
    int nr;
97

98 99 100 101 102 103 104 105
    arg->nr_out = 0;

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

    list = arg->list;
106 107 108 109 110 111 112 113 114 115 116 117 118

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

    level = rt_hw_interrupt_disable();

119
    if (!first_flag)
120
    {
121
        struct rt_object *obj;
122
        /* The node in the list? */
123 124
        obj = rt_list_entry(node, struct rt_object, list);
        if ((obj->type & ~RT_Object_Class_Static) != arg->type)
125 126 127 128 129 130
        {
            rt_hw_interrupt_enable(level);
            return (rt_list_t *)RT_NULL;
        }
    }

131 132 133
    nr = 0;
    array = arg->array;
    while (1)
134
    {
135 136 137 138 139 140 141 142 143 144 145 146 147
        node = node->next;

        if (node == list)
        {
            node = (rt_list_t *)RT_NULL;
            break;
        }
        nr++;
        *array++ = node;
        if (nr == arg->nr)
        {
            break;
        }
148
    }
149

150 151 152 153
    rt_hw_interrupt_enable(level);
    arg->nr_out = nr;
    return node;
}
154

155 156
long list_thread(void)
{
157
    rt_base_t level;
158 159
    list_get_next_t find_arg;
    rt_list_t *obj_list[LIST_FIND_OBJ_NR];
马志远 已提交
160
    rt_list_t *next = (rt_list_t *)RT_NULL;
161 162
    const char *item_title = "thread";
    int maxlen;
163

马志远 已提交
164
    list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
165

166
    maxlen = RT_NAME_MAX;
167

S
shaojinchun 已提交
168
#ifdef RT_USING_SMP
马志远 已提交
169 170 171
    rt_kprintf("%-*.s cpu bind pri  status      sp     stack size max used left tick  error\n", maxlen, item_title);
    object_split(maxlen);
    rt_kprintf(" --- ---- ---  ------- ---------- ----------  ------  ---------- ---\n");
S
shaojinchun 已提交
172
#else
马志远 已提交
173 174 175
    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 已提交
176
#endif /*RT_USING_SMP*/
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196

    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 */
马志远 已提交
197
                rt_memcpy(&thread_info, obj, sizeof thread_info);
198 199
                rt_hw_interrupt_enable(level);

马志远 已提交
200
                thread = (struct rt_thread *)obj;
201 202 203 204
                {
                    rt_uint8_t stat;
                    rt_uint8_t *ptr;

S
shaojinchun 已提交
205
#ifdef RT_USING_SMP
206
                    if (thread->oncpu != RT_CPU_DETACHED)
207
                        rt_kprintf("%-*.*s %3d %3d %4d ", maxlen, RT_NAME_MAX, thread->name, thread->oncpu, thread->bind_cpu, thread->current_priority);
208
                    else
209
                        rt_kprintf("%-*.*s N/A %3d %4d ", maxlen, RT_NAME_MAX, thread->name, thread->bind_cpu, thread->current_priority);
210

S
shaojinchun 已提交
211
#else
212
                    rt_kprintf("%-*.*s %3d ", maxlen, RT_NAME_MAX, thread->name, thread->current_priority);
S
shaojinchun 已提交
213
#endif /*RT_USING_SMP*/
214 215 216 217 218
                    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  ");
219
                    else if (stat == RT_THREAD_RUNNING) rt_kprintf(" running");
220

221
#if defined(ARCH_CPU_STACK_GROWS_UPWARD)
222 223 224 225
                    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",
马志远 已提交
226 227 228 229 230
                               ((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);
231
#else
232
                    ptr = (rt_uint8_t *)thread->stack_addr;
233 234
                    while (*ptr == '#') ptr ++;
                    rt_kprintf(" 0x%08x 0x%08x    %02d%%   0x%08x %s\n",
马志远 已提交
235 236 237 238 239
                               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,
240
                               rt_strerror(thread->error));
241
#endif
242 243 244
                }
            }
        }
245
    }
马志远 已提交
246
    while (next != (rt_list_t *)RT_NULL);
247 248

    return 0;
qiuyiuestc's avatar
qiuyiuestc 已提交
249
}
250

251
static void show_wait_queue(struct rt_list_node *list)
252
{
253 254 255 256 257 258
    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);
马志远 已提交
259
        rt_kprintf("%.*s", RT_NAME_MAX, thread->name);
D
dzzxzz@gmail.com 已提交
260

261
        if (node->next != list)
D
dzzxzz@gmail.com 已提交
262
            rt_kprintf("/");
263
    }
264 265 266
}

#ifdef RT_USING_SEMAPHORE
267
long list_sem(void)
268
{
269
    rt_base_t level;
270 271
    list_get_next_t find_arg;
    rt_list_t *obj_list[LIST_FIND_OBJ_NR];
马志远 已提交
272
    rt_list_t *next = (rt_list_t *)RT_NULL;
273

274
    int maxlen;
275
    const char *item_title = "semaphore";
276

马志远 已提交
277
    list_find_init(&find_arg, RT_Object_Class_Semaphore, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
278 279

    maxlen = RT_NAME_MAX;
280

马志远 已提交
281 282 283
    rt_kprintf("%-*.s v   suspend thread\n", maxlen, item_title);
    object_split(maxlen);
    rt_kprintf(" --- --------------\n");
284 285

    do
286
    {
287
        next = list_get_next(next, &find_arg);
288
        {
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
            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);

马志远 已提交
304
                sem = (struct rt_semaphore *)obj;
305 306 307
                if (!rt_list_isempty(&sem->parent.suspend_thread))
                {
                    rt_kprintf("%-*.*s %03d %d:",
马志远 已提交
308 309 310 311
                               maxlen, RT_NAME_MAX,
                               sem->parent.parent.name,
                               sem->value,
                               rt_list_len(&sem->parent.suspend_thread));
312 313 314 315 316 317
                    show_wait_queue(&(sem->parent.suspend_thread));
                    rt_kprintf("\n");
                }
                else
                {
                    rt_kprintf("%-*.*s %03d %d\n",
马志远 已提交
318 319 320 321
                               maxlen, RT_NAME_MAX,
                               sem->parent.parent.name,
                               sem->value,
                               rt_list_len(&sem->parent.suspend_thread));
322 323
                }
            }
324 325
        }
    }
马志远 已提交
326
    while (next != (rt_list_t *)RT_NULL);
327 328

    return 0;
329
}
330
#endif /* RT_USING_SEMAPHORE */
331 332

#ifdef RT_USING_EVENT
333
long list_event(void)
334
{
335
    rt_base_t level;
336 337
    list_get_next_t find_arg;
    rt_list_t *obj_list[LIST_FIND_OBJ_NR];
马志远 已提交
338
    rt_list_t *next = (rt_list_t *)RT_NULL;
339

340
    int maxlen;
341
    const char *item_title = "event";
342

马志远 已提交
343
    list_find_init(&find_arg, RT_Object_Class_Event, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
344 345

    maxlen = RT_NAME_MAX;
346

马志远 已提交
347 348 349
    rt_kprintf("%-*.s      set    suspend thread\n", maxlen, item_title);
    object_split(maxlen);
    rt_kprintf("  ---------- --------------\n");
350 351

    do
352
    {
353
        next = list_get_next(next, &find_arg);
354
        {
355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
            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:",
马志远 已提交
375 376 377 378
                               maxlen, RT_NAME_MAX,
                               e->parent.parent.name,
                               e->set,
                               rt_list_len(&e->parent.suspend_thread));
379 380 381 382 383 384
                    show_wait_queue(&(e->parent.suspend_thread));
                    rt_kprintf("\n");
                }
                else
                {
                    rt_kprintf("%-*.*s  0x%08x 0\n",
马志远 已提交
385
                               maxlen, RT_NAME_MAX, e->parent.parent.name, e->set);
386 387
                }
            }
388 389
        }
    }
马志远 已提交
390
    while (next != (rt_list_t *)RT_NULL);
391 392

    return 0;
393
}
394
#endif /* RT_USING_EVENT */
395 396

#ifdef RT_USING_MUTEX
397
long list_mutex(void)
398
{
399
    rt_base_t level;
400 401
    list_get_next_t find_arg;
    rt_list_t *obj_list[LIST_FIND_OBJ_NR];
马志远 已提交
402
    rt_list_t *next = (rt_list_t *)RT_NULL;
403

404
    int maxlen;
405
    const char *item_title = "mutex";
406

马志远 已提交
407
    list_find_init(&find_arg, RT_Object_Class_Mutex, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
408 409

    maxlen = RT_NAME_MAX;
410

B
Bernard Xiong 已提交
411
    rt_kprintf("%-*.s   owner  hold suspend thread priority\n", maxlen, item_title);
马志远 已提交
412
    object_split(maxlen);
B
Bernard Xiong 已提交
413
    rt_kprintf(" -------- ---- -------------- --------\n");
414 415

    do
416
    {
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435
        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;
B
Bernard Xiong 已提交
436
                rt_kprintf("%-*.*s %-8.*s %04d %d              %d\n",
马志远 已提交
437 438 439 440 441
                           maxlen, RT_NAME_MAX,
                           m->parent.parent.name,
                           RT_NAME_MAX,
                           m->owner->name,
                           m->hold,
B
Bernard Xiong 已提交
442 443
                           rt_list_len(&m->parent.suspend_thread),
                           m->priority);
444 445 446

            }
        }
447
    }
马志远 已提交
448
    while (next != (rt_list_t *)RT_NULL);
449 450

    return 0;
451
}
452
#endif /* RT_USING_MUTEX */
453 454

#ifdef RT_USING_MAILBOX
455
long list_mailbox(void)
456
{
457
    rt_base_t level;
458 459
    list_get_next_t find_arg;
    rt_list_t *obj_list[LIST_FIND_OBJ_NR];
马志远 已提交
460
    rt_list_t *next = (rt_list_t *)RT_NULL;
461

462
    int maxlen;
G
gbcwbz 已提交
463
    const char *item_title = "mailbox";
464

马志远 已提交
465
    list_find_init(&find_arg, RT_Object_Class_MailBox, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
466 467

    maxlen = RT_NAME_MAX;
468

马志远 已提交
469 470 471
    rt_kprintf("%-*.s entry size suspend thread\n", maxlen, item_title);
    object_split(maxlen);
    rt_kprintf(" ----  ---- --------------\n");
472 473

    do
474
    {
475
        next = list_get_next(next, &find_arg);
476
        {
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496
            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:",
马志远 已提交
497 498 499 500 501
                               maxlen, RT_NAME_MAX,
                               m->parent.parent.name,
                               m->entry,
                               m->size,
                               rt_list_len(&m->parent.suspend_thread));
502 503 504 505 506 507
                    show_wait_queue(&(m->parent.suspend_thread));
                    rt_kprintf("\n");
                }
                else
                {
                    rt_kprintf("%-*.*s %04d  %04d %d\n",
马志远 已提交
508 509 510 511 512
                               maxlen, RT_NAME_MAX,
                               m->parent.parent.name,
                               m->entry,
                               m->size,
                               rt_list_len(&m->parent.suspend_thread));
513 514 515
                }

            }
516 517
        }
    }
马志远 已提交
518
    while (next != (rt_list_t *)RT_NULL);
519 520

    return 0;
521
}
522
#endif /* RT_USING_MAILBOX */
523 524

#ifdef RT_USING_MESSAGEQUEUE
525
long list_msgqueue(void)
526
{
527
    rt_base_t level;
528 529
    list_get_next_t find_arg;
    rt_list_t *obj_list[LIST_FIND_OBJ_NR];
马志远 已提交
530
    rt_list_t *next = (rt_list_t *)RT_NULL;
531

532
    int maxlen;
G
gbcwbz 已提交
533
    const char *item_title = "msgqueue";
534

马志远 已提交
535
    list_find_init(&find_arg, RT_Object_Class_MessageQueue, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
536 537

    maxlen = RT_NAME_MAX;
538

马志远 已提交
539 540 541
    rt_kprintf("%-*.s entry suspend thread\n", maxlen, item_title);
    object_split(maxlen);
    rt_kprintf(" ----  --------------\n");
542
    do
543
    {
544
        next = list_get_next(next, &find_arg);
545
        {
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
            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:",
马志远 已提交
566 567 568 569
                               maxlen, RT_NAME_MAX,
                               m->parent.parent.name,
                               m->entry,
                               rt_list_len(&m->parent.suspend_thread));
570 571 572 573 574 575
                    show_wait_queue(&(m->parent.suspend_thread));
                    rt_kprintf("\n");
                }
                else
                {
                    rt_kprintf("%-*.*s %04d  %d\n",
马志远 已提交
576 577 578 579
                               maxlen, RT_NAME_MAX,
                               m->parent.parent.name,
                               m->entry,
                               rt_list_len(&m->parent.suspend_thread));
580 581
                }
            }
582 583
        }
    }
马志远 已提交
584
    while (next != (rt_list_t *)RT_NULL);
585 586

    return 0;
587
}
588
#endif /* RT_USING_MESSAGEQUEUE */
589

590
#ifdef RT_USING_MEMHEAP
591
long list_memheap(void)
592
{
593
    rt_base_t level;
594 595
    list_get_next_t find_arg;
    rt_list_t *obj_list[LIST_FIND_OBJ_NR];
马志远 已提交
596
    rt_list_t *next = (rt_list_t *)RT_NULL;
597

598
    int maxlen;
599
    const char *item_title = "memheap";
600

马志远 已提交
601
    list_find_init(&find_arg, RT_Object_Class_MemHeap, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
602 603

    maxlen = RT_NAME_MAX;
604

马志远 已提交
605 606 607
    rt_kprintf("%-*.s  pool size  max used size available size\n", maxlen, item_title);
    object_split(maxlen);
    rt_kprintf(" ---------- ------------- --------------\n");
608
    do
609
    {
610 611 612 613 614 615 616
        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;
617

618 619 620 621 622 623 624
                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;
                }
625

626
                rt_hw_interrupt_enable(level);
627

628 629 630
                mh = (struct rt_memheap *)obj;

                rt_kprintf("%-*.*s %-010d %-013d %-05d\n",
马志远 已提交
631 632 633 634 635
                           maxlen, RT_NAME_MAX,
                           mh->parent.name,
                           mh->pool_size,
                           mh->max_used_size,
                           mh->available_size);
636 637 638 639

            }
        }
    }
马志远 已提交
640
    while (next != (rt_list_t *)RT_NULL);
641 642

    return 0;
643
}
644
#endif /* RT_USING_MEMHEAP */
645

646
#ifdef RT_USING_MEMPOOL
647
long list_mempool(void)
648
{
649
    rt_base_t level;
650 651
    list_get_next_t find_arg;
    rt_list_t *obj_list[LIST_FIND_OBJ_NR];
马志远 已提交
652
    rt_list_t *next = (rt_list_t *)RT_NULL;
653

654
    int maxlen;
655
    const char *item_title = "mempool";
656

马志远 已提交
657
    list_find_init(&find_arg, RT_Object_Class_MemPool, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
658 659

    maxlen = RT_NAME_MAX;
660

马志远 已提交
661 662 663
    rt_kprintf("%-*.s block total free suspend thread\n", maxlen, item_title);
    object_split(maxlen);
    rt_kprintf(" ----  ----  ---- --------------\n");
664
    do
665
    {
666
        next = list_get_next(next, &find_arg);
667
        {
668 669 670 671 672
            int i;
            for (i = 0; i < find_arg.nr_out; i++)
            {
                struct rt_object *obj;
                struct rt_mempool *mp;
673 674
                int suspend_thread_count;
                rt_list_t *node;
675 676 677 678 679 680 681 682 683 684 685 686

                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;
687 688

                suspend_thread_count = 0;
689
                rt_list_for_each(node, &mp->suspend_thread)
690 691 692 693 694
                {
                    suspend_thread_count++;
                }

                if (suspend_thread_count > 0)
695 696
                {
                    rt_kprintf("%-*.*s %04d  %04d  %04d %d:",
马志远 已提交
697 698 699 700 701 702
                               maxlen, RT_NAME_MAX,
                               mp->parent.name,
                               mp->block_size,
                               mp->block_total_count,
                               mp->block_free_count,
                               suspend_thread_count);
703 704 705 706 707 708
                    show_wait_queue(&(mp->suspend_thread));
                    rt_kprintf("\n");
                }
                else
                {
                    rt_kprintf("%-*.*s %04d  %04d  %04d %d\n",
马志远 已提交
709 710 711 712 713 714
                               maxlen, RT_NAME_MAX,
                               mp->parent.name,
                               mp->block_size,
                               mp->block_total_count,
                               mp->block_free_count,
                               suspend_thread_count);
715 716
                }
            }
717 718
        }
    }
马志远 已提交
719
    while (next != (rt_list_t *)RT_NULL);
720 721

    return 0;
722
}
723
#endif /* RT_USING_MEMPOOL */
724

725
long list_timer(void)
726
{
727
    rt_base_t level;
728 729
    list_get_next_t find_arg;
    rt_list_t *obj_list[LIST_FIND_OBJ_NR];
马志远 已提交
730
    rt_list_t *next = (rt_list_t *)RT_NULL;
731

732
    int maxlen;
733
    const char *item_title = "timer";
734

马志远 已提交
735
    list_find_init(&find_arg, RT_Object_Class_Timer, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
736 737

    maxlen = RT_NAME_MAX;
738

armink_ztl's avatar
armink_ztl 已提交
739
    rt_kprintf("%-*.s  periodic   timeout    activated     mode\n", maxlen, item_title);
马志远 已提交
740
    object_split(maxlen);
armink_ztl's avatar
armink_ztl 已提交
741
    rt_kprintf(" ---------- ---------- ----------- ---------\n");
马志远 已提交
742
    do
armink_ztl's avatar
armink_ztl 已提交
743
    {
744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763
        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 ",
马志远 已提交
764 765 766 767
                           maxlen, RT_NAME_MAX,
                           timer->parent.name,
                           timer->init_tick,
                           timer->timeout_tick);
768
                if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
armink_ztl's avatar
armink_ztl 已提交
769 770 771 772 773
                    rt_kprintf("activated   ");
                else
                    rt_kprintf("deactivated ");
                if (timer->parent.flag & RT_TIMER_FLAG_PERIODIC)
                    rt_kprintf("periodic\n");
774
                else
armink_ztl's avatar
armink_ztl 已提交
775
                    rt_kprintf("one shot\n");
776 777 778

            }
        }
779
    }
马志远 已提交
780
    while (next != (rt_list_t *)RT_NULL);
781 782 783 784

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

    return 0;
785 786 787
}

#ifdef RT_USING_DEVICE
788
static char *const device_type_str[RT_Device_Class_Unknown] =
789 790 791 792 793 794 795 796 797 798 799 800
{
    "Character Device",
    "Block Device",
    "Network Interface",
    "MTD Device",
    "CAN Device",
    "RTC",
    "Sound Device",
    "Graphic Device",
    "I2C Bus",
    "USB Slave Device",
    "USB Host Bus",
801
    "USB OTG Bus",
802 803 804 805 806 807 808 809
    "SPI Bus",
    "SPI Device",
    "SDIO Bus",
    "PM Pseudo Device",
    "Pipe",
    "Portal Device",
    "Timer Device",
    "Miscellaneous Device",
G
guozhanxin 已提交
810
    "Sensor Device",
T
tyustli 已提交
811
    "Touch Device",
812
    "Phy Device",
813
    "Security Device",
G
guo 已提交
814 815 816 817 818 819
    "WLAN Device",
    "Pin Device",
    "ADC Device",
    "DAC Device",
    "WDT Device",
    "PWM Device",
820 821 822
};

long list_device(void)
823
{
824
    rt_base_t level;
825 826
    list_get_next_t find_arg;
    rt_list_t *obj_list[LIST_FIND_OBJ_NR];
马志远 已提交
827
    rt_list_t *next = (rt_list_t *)RT_NULL;
828
    const char *device_type;
829

830
    int maxlen;
G
gbcwbz 已提交
831 832
    const char *item_title = "device";

马志远 已提交
833
    list_find_init(&find_arg, RT_Object_Class_Device, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
834 835

    maxlen = RT_NAME_MAX;
836

马志远 已提交
837 838 839
    rt_kprintf("%-*.s         type         ref count\n", maxlen, item_title);
    object_split(maxlen);
    rt_kprintf(" -------------------- ----------\n");
840
    do
841
    {
842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860
        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;
861 862 863 864 865 866
                device_type = "Unknown";
                if (device->type < RT_Device_Class_Unknown &&
                    device_type_str[device->type] != RT_NULL)
                {
                    device_type = device_type_str[device->type];
                }
867
                rt_kprintf("%-*.*s %-20s %-8d\n",
马志远 已提交
868 869
                           maxlen, RT_NAME_MAX,
                           device->parent.name,
870
                           device_type,
马志远 已提交
871
                           device->ref_count);
872 873 874

            }
        }
875
    }
马志远 已提交
876
    while (next != (rt_list_t *)RT_NULL);
877 878

    return 0;
879
}
880
#endif /* RT_USING_DEVICE */
881

S
Stanley Lwin 已提交
882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923
int cmd_list(int argc, char **argv)
{
    if(argc == 2)
    {
        if(strcmp(argv[1], "thread") == 0)
        {
            list_thread();
        }
        else if(strcmp(argv[1], "timer") == 0)
        {
            list_timer();
        }
#ifdef RT_USING_SEMAPHORE
        else if(strcmp(argv[1], "sem") == 0)
        {
            list_sem();
        }
#endif /* RT_USING_SEMAPHORE */
#ifdef RT_USING_EVENT
        else if(strcmp(argv[1], "event") == 0)
        {
            list_event();
        }
#endif /* RT_USING_EVENT */
#ifdef RT_USING_MUTEX
        else if(strcmp(argv[1], "mutex") == 0)
        {
            list_mutex();
        }
#endif /* RT_USING_MUTEX */
#ifdef RT_USING_MAILBOX
        else if(strcmp(argv[1], "mailbox") == 0)
        {
            list_mailbox();
        }
#endif  /* RT_USING_MAILBOX */
#ifdef RT_USING_MESSAGEQUEUE
        else if(strcmp(argv[1], "msgqueue") == 0)
        {
            list_msgqueue();
        }
#endif /* RT_USING_MESSAGEQUEUE */
924 925 926 927 928 929
#ifdef RT_USING_MEMHEAP
        else if(strcmp(argv[1], "memheap") == 0)
        {
            list_memheap();
        }
#endif /* RT_USING_MEMHEAP */
S
Stanley Lwin 已提交
930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976
#ifdef RT_USING_MEMPOOL
        else if(strcmp(argv[1], "mempool") == 0)
        {
            list_mempool();
        }
#endif /* RT_USING_MEMPOOL */
#ifdef RT_USING_DEVICE
        else if(strcmp(argv[1], "device") == 0)
        {
            list_device();
        }
#endif /* RT_USING_DEVICE */
#ifdef RT_USING_DFS
        else if(strcmp(argv[1], "fd") == 0)
        {
            extern int list_fd(void);
            list_fd();
        }
#endif /* RT_USING_DFS */
        else
        {
            goto _usage;
        }

        return 0;
    }

_usage:
    rt_kprintf("Usage: list [options]\n");
    rt_kprintf("[options]:\n");
    rt_kprintf("    thread - list threads\n");
    rt_kprintf("    timer - list timers\n");
#ifdef RT_USING_SEMAPHORE
    rt_kprintf("    sem - list semaphores\n");
#endif /* RT_USING_SEMAPHORE */
#ifdef RT_USING_MUTEX
    rt_kprintf("    mutex - list mutexs\n");
#endif /* RT_USING_MUTEX */
#ifdef RT_USING_EVENT
    rt_kprintf("    event - list events\n");
#endif /* RT_USING_EVENT */
#ifdef RT_USING_MAILBOX
    rt_kprintf("    mailbox - list mailboxs\n");
#endif /* RT_USING_MAILBOX */
#ifdef RT_USING_MESSAGEQUEUE
    rt_kprintf("    msgqueue - list message queues\n");
#endif /* RT_USING_MESSAGEQUEUE */
977 978 979
#ifdef RT_USING_MEMHEAP
    rt_kprintf("    memheap - list memory heaps\n");
#endif /* RT_USING_MEMHEAP */
S
Stanley Lwin 已提交
980 981 982 983 984 985 986 987 988 989 990 991 992 993
#ifdef RT_USING_MEMPOOL
    rt_kprintf("    mempool - list memory pools\n");
#endif /* RT_USING_MEMPOOL */
#ifdef RT_USING_DEVICE
    rt_kprintf("    device - list devices\n");
#endif /* RT_USING_DEVICE */
#ifdef RT_USING_DFS
    rt_kprintf("    fd - list file descriptors\n");
#endif /* RT_USING_DFS */

    return 0;
}
MSH_CMD_EXPORT_ALIAS(cmd_list, list, list objects);

994
#endif /* RT_USING_FINSH */