cmd.c 25.2 KB
Newer Older
1
/*
2
 * Copyright (c) 2006-2018, 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 30
 */

S
shaojinchun 已提交
31
#include <rthw.h>
32
#include <rtthread.h>
33 34 35

#ifdef RT_USING_FINSH

36 37
#include "finsh.h"

38
long hello(void)
39
{
40
    rt_kprintf("Hello RT-Thread!\n");
41

42
    return 0;
43
}
44
FINSH_FUNCTION_EXPORT(hello, say hello world);
45 46

extern void rt_show_version(void);
47
long version(void)
48
{
49
    rt_show_version();
50

51
    return 0;
52
}
53
FINSH_FUNCTION_EXPORT(version, show RT-Thread version information);
B
Bernard Xiong 已提交
54
MSH_CMD_EXPORT(version, show RT-Thread version information);
55

56
static int object_name_maxlen(const char *type_name, struct rt_list_node *list)
57
{
58
    struct rt_list_node *node;
59
    struct rt_object *object = NULL;
60
    int max_length = rt_strlen(type_name), length;
61

62 63 64 65
    rt_enter_critical();
    for (node = list->next; node != list; node = node->next)
    {
        object = rt_list_entry(node, struct rt_object, list);
66

67 68
        length = rt_strlen(object->name);
        if (length > max_length) max_length = length;
69
    }
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
    rt_exit_critical();

    if (max_length > RT_NAME_MAX || max_length == 0) max_length = RT_NAME_MAX;

    return max_length;
}

rt_inline void object_split(int len)
{
    while (len--) rt_kprintf("-");
}

static long _list_thread(struct rt_list_node *list)
{
    int maxlen;
    rt_uint8_t *ptr;
    struct rt_thread *thread;
    struct rt_list_node *node;
88
    const char *item_title = "thread";
89

90
    maxlen = object_name_maxlen(item_title, list);
91

S
shaojinchun 已提交
92 93 94 95
#ifdef RT_USING_SMP
    rt_kprintf("%-*.s cpu pri  status      sp     stack size max used left tick  error\n", maxlen, item_title); object_split(maxlen);
    rt_kprintf(     " --- ---  ------- ---------- ----------  ------  ---------- ---\n");
#else
96
    rt_kprintf("%-*.s pri  status      sp     stack size max used left tick  error\n", maxlen, item_title); object_split(maxlen);
97
    rt_kprintf(     " ---  ------- ---------- ----------  ------  ---------- ---\n");
S
shaojinchun 已提交
98
#endif /*RT_USING_SMP*/
99 100
    for (node = list->next; node != list; node = node->next)
    {
101
        rt_uint8_t stat;
102
        thread = rt_list_entry(node, struct rt_thread, list);
S
shaojinchun 已提交
103 104 105 106 107
#ifdef RT_USING_SMP
        if (thread->oncpu != RT_CPU_DETACHED)
            rt_kprintf("%-*.*s %3d %3d ", maxlen, RT_NAME_MAX, thread->name, thread->oncpu, thread->current_priority);
        else
            rt_kprintf("%-*.*s N/A %3d ", maxlen, RT_NAME_MAX, thread->name, thread->current_priority);
108

S
shaojinchun 已提交
109 110 111
#else
        rt_kprintf("%-*.*s %3d ", maxlen, RT_NAME_MAX, thread->name, thread->current_priority);
#endif /*RT_USING_SMP*/
112
        stat = (thread->stat & RT_THREAD_STAT_MASK);
113 114 115 116
        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  ");
117

118 119 120 121 122
#if defined(ARCH_CPU_STACK_GROWS_UPWARD)
        ptr = (rt_uint8_t *)thread->stack_addr + thread->stack_size;
        while (*ptr == '#')ptr --;

        rt_kprintf(" 0x%08x 0x%08x    %02d%%   0x%08x %03d\n",
123
                   ((rt_ubase_t)thread->sp - (rt_ubase_t)thread->stack_addr),
124
                   thread->stack_size,
125
                   ((rt_ubase_t)ptr - (rt_ubase_t)thread->stack_addr) * 100 / thread->stack_size,
126 127 128
                   thread->remaining_tick,
                   thread->error);
#else
129
        ptr = (rt_uint8_t *)thread->stack_addr;
130 131
        while (*ptr == '#')ptr ++;

132
        rt_kprintf(" 0x%08x 0x%08x    %02d%%   0x%08x %03d\n",
B
Bernard Xiong 已提交
133
                   thread->stack_size + ((rt_ubase_t)thread->stack_addr - (rt_ubase_t)thread->sp),
134
                   thread->stack_size,
B
Bernard Xiong 已提交
135
                   (thread->stack_size - ((rt_ubase_t) ptr - (rt_ubase_t) thread->stack_addr)) * 100
136
                        / thread->stack_size,
137 138
                   thread->remaining_tick,
                   thread->error);
139
#endif
140
    }
141

142
    return 0;
143
}
qiuyiuestc's avatar
qiuyiuestc 已提交
144 145 146

long list_thread(void)
{
S
shaojinchun 已提交
147
    rt_ubase_t level;
148
    struct rt_object_information *info;
S
shaojinchun 已提交
149
    long ret;
150

S
shaojinchun 已提交
151
    level = rt_hw_interrupt_disable();
152
    info = rt_object_get_information(RT_Object_Class_Thread);
S
shaojinchun 已提交
153 154 155
    ret = _list_thread(&info->object_list);
    rt_hw_interrupt_enable(level);
    return ret;
qiuyiuestc's avatar
qiuyiuestc 已提交
156
}
157
FINSH_FUNCTION_EXPORT(list_thread, list thread);
B
Bernard Xiong 已提交
158
MSH_CMD_EXPORT(list_thread, list thread);
159

160
static void show_wait_queue(struct rt_list_node *list)
161
{
162 163 164 165 166 167 168
    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 已提交
169

170
        if (node->next != list)
D
dzzxzz@gmail.com 已提交
171
            rt_kprintf("/");
172
    }
173 174 175
}

#ifdef RT_USING_SEMAPHORE
qiuyiuestc's avatar
qiuyiuestc 已提交
176
static long _list_sem(struct rt_list_node *list)
177
{
178
    int maxlen;
179 180
    struct rt_semaphore *sem;
    struct rt_list_node *node;
181
    const char *item_title = "semaphore";
182

183
    maxlen = object_name_maxlen(item_title, list);
184

185
    rt_kprintf("%-*.s v   suspend thread\n", maxlen, item_title); object_split(maxlen);
186
    rt_kprintf(     " --- --------------\n");
187 188
    for (node = list->next; node != list; node = node->next)
    {
189
        sem = (struct rt_semaphore *)(rt_list_entry(node, struct rt_object, list));
D
dzzxzz@gmail.com 已提交
190
        if (!rt_list_isempty(&sem->parent.suspend_thread))
191
        {
192 193
            rt_kprintf("%-*.*s %03d %d:",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
194 195 196
                       sem->parent.parent.name,
                       sem->value,
                       rt_list_len(&sem->parent.suspend_thread));
197 198 199 200 201
            show_wait_queue(&(sem->parent.suspend_thread));
            rt_kprintf("\n");
        }
        else
        {
202 203
            rt_kprintf("%-*.*s %03d %d\n",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
204 205 206
                       sem->parent.parent.name,
                       sem->value,
                       rt_list_len(&sem->parent.suspend_thread));
207 208 209 210
        }
    }

    return 0;
211
}
qiuyiuestc's avatar
qiuyiuestc 已提交
212 213 214

long list_sem(void)
{
215 216 217 218 219
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_Semaphore);

    return _list_sem(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
220
}
B
Bernard Xiong 已提交
221 222
FINSH_FUNCTION_EXPORT(list_sem, list semaphone in system);
MSH_CMD_EXPORT(list_sem, list semaphore in system);
223 224 225
#endif

#ifdef RT_USING_EVENT
qiuyiuestc's avatar
qiuyiuestc 已提交
226
static long _list_event(struct rt_list_node *list)
227
{
228
    int maxlen;
229 230
    struct rt_event *e;
    struct rt_list_node *node;
231
    const char *item_title = "event";
232

233
    maxlen = object_name_maxlen(item_title, list);
234

235
    rt_kprintf("%-*.s      set    suspend thread\n", maxlen, item_title); object_split(maxlen);
236
    rt_kprintf(     "  ---------- --------------\n");
237 238
    for (node = list->next; node != list; node = node->next)
    {
239 240
        e = (struct rt_event *)(rt_list_entry(node, struct rt_object, list));
        if (!rt_list_isempty(&e->parent.suspend_thread))
241
        {
242 243
            rt_kprintf("%-*.*s  0x%08x %03d:",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
244 245 246
                       e->parent.parent.name,
                       e->set,
                       rt_list_len(&e->parent.suspend_thread));
247 248 249 250 251
            show_wait_queue(&(e->parent.suspend_thread));
            rt_kprintf("\n");
        }
        else
        {
252 253
            rt_kprintf("%-*.*s  0x%08x 0\n",
                       maxlen, RT_NAME_MAX, e->parent.parent.name, e->set);
254 255 256 257
        }
    }

    return 0;
258
}
qiuyiuestc's avatar
qiuyiuestc 已提交
259 260 261

long list_event(void)
{
262 263 264 265
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_Event);
    return _list_event(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
266
}
B
Bernard Xiong 已提交
267 268
FINSH_FUNCTION_EXPORT(list_event, list event in system);
MSH_CMD_EXPORT(list_event, list event in system);
269 270 271
#endif

#ifdef RT_USING_MUTEX
qiuyiuestc's avatar
qiuyiuestc 已提交
272
static long _list_mutex(struct rt_list_node *list)
273
{
274
    int maxlen;
275 276
    struct rt_mutex *m;
    struct rt_list_node *node;
277
    const char *item_title = "mutex";
278

279 280 281
    maxlen = object_name_maxlen(item_title, list);

    rt_kprintf("%-*.s   owner  hold suspend thread\n", maxlen, item_title); object_split(maxlen);
282
    rt_kprintf(     " -------- ---- --------------\n");
283 284
    for (node = list->next; node != list; node = node->next)
    {
285
        m = (struct rt_mutex *)(rt_list_entry(node, struct rt_object, list));
286 287
        rt_kprintf("%-*.*s %-8.*s %04d %d\n",
                   maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
288 289 290 291 292
                   m->parent.parent.name,
                   RT_NAME_MAX,
                   m->owner->name,
                   m->hold,
                   rt_list_len(&m->parent.suspend_thread));
293 294 295
    }

    return 0;
296
}
qiuyiuestc's avatar
qiuyiuestc 已提交
297 298 299

long list_mutex(void)
{
300 301 302 303 304
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_Mutex);

    return _list_mutex(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
305
}
B
Bernard Xiong 已提交
306 307
FINSH_FUNCTION_EXPORT(list_mutex, list mutex in system);
MSH_CMD_EXPORT(list_mutex, list mutex in system);
308 309 310
#endif

#ifdef RT_USING_MAILBOX
qiuyiuestc's avatar
qiuyiuestc 已提交
311
static long _list_mailbox(struct rt_list_node *list)
312
{
313
    int maxlen;
314 315
    struct rt_mailbox *m;
    struct rt_list_node *node;
G
gbcwbz 已提交
316
    const char *item_title = "mailbox";
317

318
    maxlen = object_name_maxlen(item_title, list);
319

320 321
    rt_kprintf("%-*.s entry size suspend thread\n", maxlen, item_title); object_split(maxlen);
    rt_kprintf(     " ----  ---- --------------\n");
322 323
    for (node = list->next; node != list; node = node->next)
    {
324 325
        m = (struct rt_mailbox *)(rt_list_entry(node, struct rt_object, list));
        if (!rt_list_isempty(&m->parent.suspend_thread))
326
        {
327 328
            rt_kprintf("%-*.*s %04d  %04d %d:",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
329 330 331 332
                       m->parent.parent.name,
                       m->entry,
                       m->size,
                       rt_list_len(&m->parent.suspend_thread));
333 334 335 336 337
            show_wait_queue(&(m->parent.suspend_thread));
            rt_kprintf("\n");
        }
        else
        {
338 339
            rt_kprintf("%-*.*s %04d  %04d %d\n",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
340 341 342 343
                       m->parent.parent.name,
                       m->entry,
                       m->size,
                       rt_list_len(&m->parent.suspend_thread));
344 345 346 347
        }
    }

    return 0;
348
}
qiuyiuestc's avatar
qiuyiuestc 已提交
349 350 351

long list_mailbox(void)
{
352 353 354 355
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_MailBox);
    return _list_mailbox(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
356
}
B
Bernard Xiong 已提交
357 358
FINSH_FUNCTION_EXPORT(list_mailbox, list mail box in system);
MSH_CMD_EXPORT(list_mailbox, list mail box in system);
359 360 361
#endif

#ifdef RT_USING_MESSAGEQUEUE
qiuyiuestc's avatar
qiuyiuestc 已提交
362
static long _list_msgqueue(struct rt_list_node *list)
363
{
364
    int maxlen;
365 366
    struct rt_messagequeue *m;
    struct rt_list_node *node;
G
gbcwbz 已提交
367
    const char *item_title = "msgqueue";
368

369
    maxlen = object_name_maxlen(item_title, list);
370

371
    rt_kprintf("%-*.s entry suspend thread\n", maxlen, item_title); object_split(maxlen);
372
    rt_kprintf(     " ----  --------------\n");
373 374
    for (node = list->next; node != list; node = node->next)
    {
375 376
        m = (struct rt_messagequeue *)(rt_list_entry(node, struct rt_object, list));
        if (!rt_list_isempty(&m->parent.suspend_thread))
377
        {
378 379
            rt_kprintf("%-*.*s %04d  %d:",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
380 381 382
                       m->parent.parent.name,
                       m->entry,
                       rt_list_len(&m->parent.suspend_thread));
383 384 385 386 387
            show_wait_queue(&(m->parent.suspend_thread));
            rt_kprintf("\n");
        }
        else
        {
388 389
            rt_kprintf("%-*.*s %04d  %d\n",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
390 391 392
                       m->parent.parent.name,
                       m->entry,
                       rt_list_len(&m->parent.suspend_thread));
393 394 395 396
        }
    }

    return 0;
397
}
qiuyiuestc's avatar
qiuyiuestc 已提交
398 399 400

long list_msgqueue(void)
{
401 402 403 404
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_MessageQueue);
    return _list_msgqueue(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
405
}
B
Bernard Xiong 已提交
406 407
FINSH_FUNCTION_EXPORT(list_msgqueue, list message queue in system);
MSH_CMD_EXPORT(list_msgqueue, list message queue in system);
408 409
#endif

410 411 412
#ifdef RT_USING_MEMHEAP
static long _list_memheap(struct rt_list_node *list)
{
413
    int maxlen;
414 415
    struct rt_memheap *mh;
    struct rt_list_node *node;
416
    const char *item_title = "memheap";
417

418
    maxlen = object_name_maxlen(item_title, list);
419

420
    rt_kprintf("%-*.s  pool size  max used size available size\n", maxlen, item_title); object_split(maxlen);
421
    rt_kprintf(      " ---------- ------------- --------------\n");
422 423 424 425
    for (node = list->next; node != list; node = node->next)
    {
        mh = (struct rt_memheap *)rt_list_entry(node, struct rt_object, list);

426 427
        rt_kprintf("%-*.*s %-010d %-013d %-05d\n",
                   maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
428 429 430 431
                   mh->parent.name,
                   mh->pool_size,
                   mh->max_used_size,
                   mh->available_size);
432 433 434 435 436 437 438
    }

    return 0;
}

long list_memheap(void)
{
439 440 441 442
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_MemHeap);
    return _list_memheap(&info->object_list);
443
}
B
Bernard Xiong 已提交
444 445
FINSH_FUNCTION_EXPORT(list_memheap, list memory heap in system);
MSH_CMD_EXPORT(list_memheap, list memory heap in system);
446 447
#endif

448
#ifdef RT_USING_MEMPOOL
qiuyiuestc's avatar
qiuyiuestc 已提交
449
static long _list_mempool(struct rt_list_node *list)
450
{
451
    int maxlen;
452 453
    struct rt_mempool *mp;
    struct rt_list_node *node;
454
    const char *item_title = "mempool";
455

456
    maxlen = object_name_maxlen(item_title, list);
457

458
    rt_kprintf("%-*.s block total free suspend thread\n", maxlen, item_title); object_split(maxlen);
459
    rt_kprintf(     " ----  ----  ---- --------------\n");
460 461
    for (node = list->next; node != list; node = node->next)
    {
462
        mp = (struct rt_mempool *)rt_list_entry(node, struct rt_object, list);
463 464
        if (mp->suspend_thread_count > 0)
        {
465 466
            rt_kprintf("%-*.*s %04d  %04d  %04d %d:",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
467 468 469 470 471
                       mp->parent.name,
                       mp->block_size,
                       mp->block_total_count,
                       mp->block_free_count,
                       mp->suspend_thread_count);
472
            show_wait_queue(&(mp->suspend_thread));
D
dzzxzz@gmail.com 已提交
473
            rt_kprintf("\n");
474 475 476
        }
        else
        {
477 478
            rt_kprintf("%-*.*s %04d  %04d  %04d %d\n",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
479 480 481 482 483
                       mp->parent.name,
                       mp->block_size,
                       mp->block_total_count,
                       mp->block_free_count,
                       mp->suspend_thread_count);
484 485 486 487
        }
    }

    return 0;
488
}
qiuyiuestc's avatar
qiuyiuestc 已提交
489 490 491

long list_mempool(void)
{
492 493 494 495
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_MemPool);
    return _list_mempool(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
496
}
497
FINSH_FUNCTION_EXPORT(list_mempool, list memory pool in system)
B
Bernard Xiong 已提交
498
MSH_CMD_EXPORT(list_mempool, list memory pool in system);
499 500
#endif

qiuyiuestc's avatar
qiuyiuestc 已提交
501
static long _list_timer(struct rt_list_node *list)
502
{
503
    int maxlen;
504 505
    struct rt_timer *timer;
    struct rt_list_node *node;
506
    const char *item_title = "timer";
507

508
    maxlen = object_name_maxlen(item_title, list);
509

510
    rt_kprintf("%-*.s  periodic   timeout       flag\n", maxlen, item_title); object_split(maxlen);
511
    rt_kprintf(     " ---------- ---------- -----------\n");
512 513
    for (node = list->next; node != list; node = node->next)
    {
514
        timer = (struct rt_timer *)(rt_list_entry(node, struct rt_object, list));
515 516
        rt_kprintf("%-*.*s 0x%08x 0x%08x ",
                   maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
517 518 519
                   timer->parent.name,
                   timer->init_tick,
                   timer->timeout_tick);
520
        if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
D
dzzxzz@gmail.com 已提交
521
            rt_kprintf("activated\n");
522
        else
D
dzzxzz@gmail.com 已提交
523
            rt_kprintf("deactivated\n");
524 525 526 527 528
    }

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

    return 0;
529
}
qiuyiuestc's avatar
qiuyiuestc 已提交
530 531 532

long list_timer(void)
{
533 534 535 536
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_Timer);
    return _list_timer(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
537
}
B
Bernard Xiong 已提交
538 539
FINSH_FUNCTION_EXPORT(list_timer, list timer in system);
MSH_CMD_EXPORT(list_timer, list timer in system);
540 541

#ifdef RT_USING_DEVICE
qiuyiuestc's avatar
qiuyiuestc 已提交
542
static long _list_device(struct rt_list_node *list)
543
{
544
    int maxlen;
545 546
    struct rt_device *device;
    struct rt_list_node *node;
547
    char *const device_type_str[] =
548 549 550 551 552 553 554 555
    {
        "Character Device",
        "Block Device",
        "Network Interface",
        "MTD Device",
        "CAN Device",
        "RTC",
        "Sound Device",
556
        "Graphic Device",
557
        "I2C Bus",
558 559 560 561 562
        "USB Slave Device",
        "USB Host Bus",
        "SPI Bus",
        "SPI Device",
        "SDIO Bus",
563
        "PM Pseudo Device",
564 565
        "Pipe",
        "Portal Device",
566 567
        "Timer Device",
        "Miscellaneous Device",
568 569
        "Unknown"
    };
G
gbcwbz 已提交
570 571
    const char *item_title = "device";

572
    maxlen = object_name_maxlen(item_title, list);
573

574 575
    rt_kprintf("%-*.s         type         ref count\n", maxlen, item_title); object_split(maxlen);
    rt_kprintf(     " -------------------- ----------\n");
576 577
    for (node = list->next; node != list; node = node->next)
    {
578
        device = (struct rt_device *)(rt_list_entry(node, struct rt_object, list));
579 580
        rt_kprintf("%-*.*s %-20s %-8d\n",
                   maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
581 582 583
                   device->parent.name,
                   (device->type <= RT_Device_Class_Unknown) ?
                   device_type_str[device->type] :
584 585
                   device_type_str[RT_Device_Class_Unknown],
                   device->ref_count);
586 587 588
    }

    return 0;
589
}
qiuyiuestc's avatar
qiuyiuestc 已提交
590 591 592

long list_device(void)
{
593 594 595 596
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_Device);
    return _list_device(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
597
}
B
Bernard Xiong 已提交
598 599
FINSH_FUNCTION_EXPORT(list_device, list device in system);
MSH_CMD_EXPORT(list_device, list device in system);
600 601
#endif

D
dzzxzz 已提交
602
long list(void)
603
{
B
bernard 已提交
604
#ifndef FINSH_USING_MSH_ONLY
605 606
    struct finsh_syscall_item *syscall_item;
    struct finsh_sysvar_item *sysvar_item;
B
bernard 已提交
607
#endif
608

609 610
    rt_kprintf("--Function List:\n");
    {
611
        struct finsh_syscall *index;
D
dzzxzz@gmail.com 已提交
612
        for (index = _syscall_table_begin;
613 614
                index < _syscall_table_end;
                FINSH_NEXT_SYSCALL(index))
615
        {
616 617
            /* skip the internal command */
            if (strncmp((char *)index->name, "__", 2) == 0) continue;
B
Bernard Xiong 已提交
618

619
#ifdef FINSH_USING_DESCRIPTION
620
            rt_kprintf("%-16s -- %s\n", index->name, index->desc);
621
#else
622
            rt_kprintf("%s\n", index->name);
623
#endif
624 625 626
        }
    }

B
bernard 已提交
627
#ifndef FINSH_USING_MSH_ONLY
628 629 630 631 632 633 634 635 636 637
    /* 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");
    {
638
        struct finsh_sysvar *index;
639
        for (index = _sysvar_table_begin;
640 641
                index < _sysvar_table_end;
                FINSH_NEXT_SYSVAR(index))
642
        {
643
#ifdef FINSH_USING_DESCRIPTION
644
            rt_kprintf("%-16s -- %s\n", index->name, index->desc);
645
#else
646
            rt_kprintf("%s\n", index->name);
647
#endif
648 649
        }
    }
650

651 652 653 654 655 656
    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 已提交
657
#endif
658

659
    return 0;
660 661 662
}
FINSH_FUNCTION_EXPORT(list, list all symbol in system)

B
bernard 已提交
663
#ifndef FINSH_USING_MSH_ONLY
664
static int str_is_prefix(const char *prefix, const char *str)
665
{
666 667 668 669 670 671
    while ((*prefix) && (*prefix == *str))
    {
        prefix ++;
        str ++;
    }

672
    if (*prefix == 0)
D
dzzxzz@gmail.com 已提交
673 674
        return 0;

675 676 677
    return -1;
}

678
static int str_common(const char *str1, const char *str2)
679
{
680
    const char *str = str1;
681

682
    while ((*str != 0) && (*str2 != 0) && (*str == *str2))
683 684 685 686 687 688
    {
        str ++;
        str2 ++;
    }

    return (str - str1);
689 690
}

691
void list_prefix(char *prefix)
692
{
693 694
    struct finsh_syscall_item *syscall_item;
    struct finsh_sysvar_item *sysvar_item;
695 696
    rt_uint16_t func_cnt, var_cnt;
    int length, min_length;
697
    const char *name_ptr;
698 699 700

    func_cnt = 0;
    var_cnt  = 0;
D
dzzxzz@gmail.com 已提交
701
    min_length = 0;
702 703 704 705
    name_ptr = RT_NULL;

    /* checks in system function call */
    {
D
dzzxzz@gmail.com 已提交
706 707
        struct finsh_syscall *index;
        for (index = _syscall_table_begin;
708 709
                index < _syscall_table_end;
                FINSH_NEXT_SYSCALL(index))
710
        {
711 712 713
            /* skip internal command */
            if (str_is_prefix("__", index->name) == 0) continue;

714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737
            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;
                }
738 739

#ifdef FINSH_USING_DESCRIPTION
740
                rt_kprintf("%-16s -- %s\n", index->name, index->desc);
741
#else
742
                rt_kprintf("%s\n", index->name);
743
#endif
744 745 746 747 748 749 750 751 752 753 754 755 756 757 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
            }
        }
    }

    /* 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 */
    {
783
        struct finsh_sysvar *index;
784
        for (index = _sysvar_table_begin;
785 786
                index < _sysvar_table_end;
                FINSH_NEXT_SYSVAR(index))
787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812
        {
            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 已提交
813

814
#ifdef FINSH_USING_DESCRIPTION
815
                rt_kprintf("%-16s -- %s\n", index->name, index->desc);
816
#else
817
                rt_kprintf("%s\n", index->name);
818
#endif
819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860
            }
        }
    }

    /* 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);
    }
861
}
B
bernard 已提交
862
#endif
863

B
bernard 已提交
864
#if defined(FINSH_USING_SYMTAB) && !defined(FINSH_USING_MSH_ONLY)
865 866 867
static int dummy = 0;
FINSH_VAR_EXPORT(dummy, finsh_type_int, dummy variable for finsh)
#endif
868 869 870

#endif /* RT_USING_FINSH */