cmd.c 29.1 KB
Newer Older
1
/*
B
Bernard Xiong 已提交
2
 *  RT-Thread finsh shell commands
3
 *
B
Bernard Xiong 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team
 *
 *  This file is part of RT-Thread (http://www.rt-thread.org)
 *  Maintainer: bernard.xiong <bernard.xiong at gmail.com>
 *
 *  All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
 *
 * 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
42 43
 * 2010-04-21     yi.qiu       add list_module
 * 2012-04-29     goprife      improve the command line auto-complete feature.
44
 * 2012-06-02     lgnq         add list_memheap
45
 * 2012-10-22     Bernard      add MS VC++ patch.
46
 * 2016-06-02     armink       beautify the list_thread command
47 48 49
 */

#include <rtthread.h>
50 51
#include "finsh.h"

52
long hello(void)
53
{
54
    rt_kprintf("Hello RT-Thread!\n");
55

56
    return 0;
57
}
58
FINSH_FUNCTION_EXPORT(hello, say hello world);
59 60

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

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

extern struct rt_object_information rt_object_container[];

72
static int object_name_maxlen(struct rt_list_node *list)
73
{
74
    struct rt_list_node *node;
75 76
    struct rt_object *object = NULL;
    int max_length = 0, length;
77

78 79 80 81
    rt_enter_critical();
    for (node = list->next; node != list; node = node->next)
    {
        object = rt_list_entry(node, struct rt_object, list);
82

83 84
        length = rt_strlen(object->name);
        if (length > max_length) max_length = length;
85
    }
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
    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;
104

105 106
    maxlen = object_name_maxlen(list);

107 108
    rt_kprintf("%-*.s pri  status      sp     stack size max used left tick  error\n", maxlen, "thread"); object_split(maxlen);
    rt_kprintf(     " ---  ------- ---------- ----------  ------  ---------- ---\n");
109 110
    for (node = list->next; node != list; node = node->next)
    {
111
    	rt_uint8_t stat;
112
        thread = rt_list_entry(node, struct rt_thread, list);
113
        rt_kprintf("%-*.*s %3d ", maxlen, RT_NAME_MAX, thread->name, thread->current_priority);
114

115 116 117 118 119
		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  ");
120

121
        ptr = (rt_uint8_t *)thread->stack_addr;
122 123
        while (*ptr == '#')ptr ++;

124
        rt_kprintf(" 0x%08x 0x%08x    %02d%%   0x%08x %03d\n",
125 126
                   thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
                   thread->stack_size,
127 128
                   (thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t) thread->stack_addr)) * 100
                        / thread->stack_size,
129 130
                   thread->remaining_tick,
                   thread->error);
131
    }
132

133
    return 0;
134
}
qiuyiuestc's avatar
qiuyiuestc 已提交
135 136 137

long list_thread(void)
{
138
    return _list_thread(&rt_object_container[RT_Object_Class_Thread].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
139
}
140
FINSH_FUNCTION_EXPORT(list_thread, list thread);
B
Bernard Xiong 已提交
141
MSH_CMD_EXPORT(list_thread, list thread);
142

143
static void show_wait_queue(struct rt_list_node *list)
144
{
145 146 147 148 149 150 151
    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 已提交
152

153
        if (node->next != list)
D
dzzxzz@gmail.com 已提交
154
            rt_kprintf("/");
155
    }
156 157 158
}

#ifdef RT_USING_SEMAPHORE
qiuyiuestc's avatar
qiuyiuestc 已提交
159
static long _list_sem(struct rt_list_node *list)
160
{
161
    int maxlen;
162 163 164
    struct rt_semaphore *sem;
    struct rt_list_node *node;

165 166 167 168 169
    maxlen = object_name_maxlen(list);
    if (maxlen < 9) maxlen = 9;

    rt_kprintf("%-*.s v   suspend thread\n", maxlen, "semaphore"); object_split(maxlen);
    rt_kprintf(     " --- --------------\n");
170 171
    for (node = list->next; node != list; node = node->next)
    {
172
        sem = (struct rt_semaphore *)(rt_list_entry(node, struct rt_object, list));
D
dzzxzz@gmail.com 已提交
173
        if (!rt_list_isempty(&sem->parent.suspend_thread))
174
        {
175 176
            rt_kprintf("%-*.*s %03d %d:",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
177 178 179
                       sem->parent.parent.name,
                       sem->value,
                       rt_list_len(&sem->parent.suspend_thread));
180 181 182 183 184
            show_wait_queue(&(sem->parent.suspend_thread));
            rt_kprintf("\n");
        }
        else
        {
185 186
            rt_kprintf("%-*.*s %03d %d\n",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
187 188 189
                       sem->parent.parent.name,
                       sem->value,
                       rt_list_len(&sem->parent.suspend_thread));
190 191 192 193
        }
    }

    return 0;
194
}
qiuyiuestc's avatar
qiuyiuestc 已提交
195 196 197

long list_sem(void)
{
198
    return _list_sem(&rt_object_container[RT_Object_Class_Semaphore].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
199
}
B
Bernard Xiong 已提交
200 201
FINSH_FUNCTION_EXPORT(list_sem, list semaphone in system);
MSH_CMD_EXPORT(list_sem, list semaphore in system);
202 203 204
#endif

#ifdef RT_USING_EVENT
qiuyiuestc's avatar
qiuyiuestc 已提交
205
static long _list_event(struct rt_list_node *list)
206
{
207
    int maxlen;
208 209 210
    struct rt_event *e;
    struct rt_list_node *node;

211 212
    maxlen = object_name_maxlen(list);

213 214
    rt_kprintf("%-*.s      set    suspend thread\n", maxlen, "event"); object_split(maxlen);
    rt_kprintf(     "  ---------- --------------\n");
215 216
    for (node = list->next; node != list; node = node->next)
    {
217 218
        e = (struct rt_event *)(rt_list_entry(node, struct rt_object, list));
        if (!rt_list_isempty(&e->parent.suspend_thread))
219
        {
220 221
            rt_kprintf("%-*.*s  0x%08x %03d:",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
222 223 224
                       e->parent.parent.name,
                       e->set,
                       rt_list_len(&e->parent.suspend_thread));
225 226 227 228 229
            show_wait_queue(&(e->parent.suspend_thread));
            rt_kprintf("\n");
        }
        else
        {
230 231
            rt_kprintf("%-*.*s  0x%08x 0\n",
                       maxlen, RT_NAME_MAX, e->parent.parent.name, e->set);
232 233 234 235
        }
    }

    return 0;
236
}
qiuyiuestc's avatar
qiuyiuestc 已提交
237 238 239

long list_event(void)
{
240
    return _list_event(&rt_object_container[RT_Object_Class_Event].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
241
}
B
Bernard Xiong 已提交
242 243
FINSH_FUNCTION_EXPORT(list_event, list event in system);
MSH_CMD_EXPORT(list_event, list event in system);
244 245 246
#endif

#ifdef RT_USING_MUTEX
qiuyiuestc's avatar
qiuyiuestc 已提交
247
static long _list_mutex(struct rt_list_node *list)
248
{
249
    int maxlen;
250 251 252
    struct rt_mutex *m;
    struct rt_list_node *node;

253
    maxlen = object_name_maxlen(list);
254 255
    rt_kprintf("%-*.s   owner  hold suspend thread\n", maxlen, "mutex"); object_split(maxlen);
    rt_kprintf(     " -------- ---- --------------\n");
256 257
    for (node = list->next; node != list; node = node->next)
    {
258
        m = (struct rt_mutex *)(rt_list_entry(node, struct rt_object, list));
259 260
        rt_kprintf("%-*.*s %-8.*s %04d %d\n",
                   maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
261 262 263 264 265
                   m->parent.parent.name,
                   RT_NAME_MAX,
                   m->owner->name,
                   m->hold,
                   rt_list_len(&m->parent.suspend_thread));
266 267 268
    }

    return 0;
269
}
qiuyiuestc's avatar
qiuyiuestc 已提交
270 271 272

long list_mutex(void)
{
273
    return _list_mutex(&rt_object_container[RT_Object_Class_Mutex].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
274
}
B
Bernard Xiong 已提交
275 276
FINSH_FUNCTION_EXPORT(list_mutex, list mutex in system);
MSH_CMD_EXPORT(list_mutex, list mutex in system);
277 278 279
#endif

#ifdef RT_USING_MAILBOX
qiuyiuestc's avatar
qiuyiuestc 已提交
280
static long _list_mailbox(struct rt_list_node *list)
281
{
282
    int maxlen;
283 284
    struct rt_mailbox *m;
    struct rt_list_node *node;
G
gbcwbz 已提交
285 286
    int item_title_len;
    const char *item_title = "mailbox";
287

G
gbcwbz 已提交
288
    item_title_len = rt_strlen(item_title);
289
    maxlen = object_name_maxlen(list);
G
gbcwbz 已提交
290
    if(maxlen < item_title_len) maxlen = item_title_len;
291

292 293
    rt_kprintf("%-*.s entry size suspend thread\n", maxlen, item_title); object_split(maxlen);
    rt_kprintf(     " ----  ---- --------------\n");
294 295
    for (node = list->next; node != list; node = node->next)
    {
296 297
        m = (struct rt_mailbox *)(rt_list_entry(node, struct rt_object, list));
        if (!rt_list_isempty(&m->parent.suspend_thread))
298
        {
299 300
            rt_kprintf("%-*.*s %04d  %04d %d:",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
301 302 303 304
                       m->parent.parent.name,
                       m->entry,
                       m->size,
                       rt_list_len(&m->parent.suspend_thread));
305 306 307 308 309
            show_wait_queue(&(m->parent.suspend_thread));
            rt_kprintf("\n");
        }
        else
        {
310 311
            rt_kprintf("%-*.*s %04d  %04d %d\n",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
312 313 314 315
                       m->parent.parent.name,
                       m->entry,
                       m->size,
                       rt_list_len(&m->parent.suspend_thread));
316 317 318 319
        }
    }

    return 0;
320
}
qiuyiuestc's avatar
qiuyiuestc 已提交
321 322 323

long list_mailbox(void)
{
324
    return _list_mailbox(&rt_object_container[RT_Object_Class_MailBox].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
325
}
B
Bernard Xiong 已提交
326 327
FINSH_FUNCTION_EXPORT(list_mailbox, list mail box in system);
MSH_CMD_EXPORT(list_mailbox, list mail box in system);
328 329 330
#endif

#ifdef RT_USING_MESSAGEQUEUE
qiuyiuestc's avatar
qiuyiuestc 已提交
331
static long _list_msgqueue(struct rt_list_node *list)
332
{
333
    int maxlen;
334 335
    struct rt_messagequeue *m;
    struct rt_list_node *node;
G
gbcwbz 已提交
336 337
    int item_title_len;
    const char *item_title = "msgqueue";
338

G
gbcwbz 已提交
339
    item_title_len = rt_strlen(item_title);
340
    maxlen = object_name_maxlen(list);
G
gbcwbz 已提交
341
    if(maxlen < item_title_len) maxlen = item_title_len;
342

343
    rt_kprintf("%-*.s entry suspend thread\n", maxlen, item_title); object_split(maxlen);
344
    rt_kprintf(     " ----  --------------\n");
345 346
    for (node = list->next; node != list; node = node->next)
    {
347 348
        m = (struct rt_messagequeue *)(rt_list_entry(node, struct rt_object, list));
        if (!rt_list_isempty(&m->parent.suspend_thread))
349
        {
350 351
            rt_kprintf("%-*.*s %04d  %d:",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
352 353 354
                       m->parent.parent.name,
                       m->entry,
                       rt_list_len(&m->parent.suspend_thread));
355 356 357 358 359
            show_wait_queue(&(m->parent.suspend_thread));
            rt_kprintf("\n");
        }
        else
        {
360 361
            rt_kprintf("%-*.*s %04d  %d\n",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
362 363 364
                       m->parent.parent.name,
                       m->entry,
                       rt_list_len(&m->parent.suspend_thread));
365 366 367 368
        }
    }

    return 0;
369
}
qiuyiuestc's avatar
qiuyiuestc 已提交
370 371 372

long list_msgqueue(void)
{
373
    return _list_msgqueue(&rt_object_container[RT_Object_Class_MessageQueue].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
374
}
B
Bernard Xiong 已提交
375 376
FINSH_FUNCTION_EXPORT(list_msgqueue, list message queue in system);
MSH_CMD_EXPORT(list_msgqueue, list message queue in system);
377 378
#endif

379 380 381
#ifdef RT_USING_MEMHEAP
static long _list_memheap(struct rt_list_node *list)
{
382
    int maxlen;
383 384 385
    struct rt_memheap *mh;
    struct rt_list_node *node;

386 387 388 389
    maxlen = object_name_maxlen(list);

    rt_kprintf("%-*.s  pool size  max used size available size\n", maxlen, "memheap"); object_split(maxlen);
    rt_kprintf(      " ---------- ------------- --------------\n");
390 391 392 393
    for (node = list->next; node != list; node = node->next)
    {
        mh = (struct rt_memheap *)rt_list_entry(node, struct rt_object, list);

394 395
        rt_kprintf("%-*.*s %-010d %-013d %-05d\n",
                   maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
396 397 398 399
                   mh->parent.name,
                   mh->pool_size,
                   mh->max_used_size,
                   mh->available_size);
400 401 402 403 404 405 406 407 408
    }

    return 0;
}

long list_memheap(void)
{
    return _list_memheap(&rt_object_container[RT_Object_Class_MemHeap].object_list);
}
B
Bernard Xiong 已提交
409 410
FINSH_FUNCTION_EXPORT(list_memheap, list memory heap in system);
MSH_CMD_EXPORT(list_memheap, list memory heap in system);
411 412
#endif

413
#ifdef RT_USING_MEMPOOL
qiuyiuestc's avatar
qiuyiuestc 已提交
414
static long _list_mempool(struct rt_list_node *list)
415
{
416
    int maxlen;
417 418 419
    struct rt_mempool *mp;
    struct rt_list_node *node;

420 421
    maxlen = object_name_maxlen(list);

422 423
    rt_kprintf("%-*.s block total free suspend thread\n", maxlen, "mempool"); object_split(maxlen);
    rt_kprintf(     " ----  ----  ---- --------------\n");
424 425
    for (node = list->next; node != list; node = node->next)
    {
426
        mp = (struct rt_mempool *)rt_list_entry(node, struct rt_object, list);
427 428
        if (mp->suspend_thread_count > 0)
        {
429 430
            rt_kprintf("%-*.*s %04d  %04d  %04d %d:",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
431 432 433 434 435
                       mp->parent.name,
                       mp->block_size,
                       mp->block_total_count,
                       mp->block_free_count,
                       mp->suspend_thread_count);
436
            show_wait_queue(&(mp->suspend_thread));
D
dzzxzz@gmail.com 已提交
437
            rt_kprintf("\n");
438 439 440
        }
        else
        {
441 442
            rt_kprintf("%-*.*s %04d  %04d  %04d %d\n",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
443 444 445 446 447
                       mp->parent.name,
                       mp->block_size,
                       mp->block_total_count,
                       mp->block_free_count,
                       mp->suspend_thread_count);
448 449 450 451
        }
    }

    return 0;
452
}
qiuyiuestc's avatar
qiuyiuestc 已提交
453 454 455

long list_mempool(void)
{
456
    return _list_mempool(&rt_object_container[RT_Object_Class_MemPool].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
457
}
458
FINSH_FUNCTION_EXPORT(list_mempool, list memory pool in system)
B
Bernard Xiong 已提交
459
MSH_CMD_EXPORT(list_mempool, list memory pool in system);
460 461
#endif

qiuyiuestc's avatar
qiuyiuestc 已提交
462
static long _list_timer(struct rt_list_node *list)
463
{
464
    int maxlen;
465 466 467
    struct rt_timer *timer;
    struct rt_list_node *node;

468 469
    maxlen = object_name_maxlen(list);

470 471
    rt_kprintf("%-*.s  periodic   timeout       flag\n", maxlen, "timer"); object_split(maxlen);
    rt_kprintf(     " ---------- ---------- -----------\n");
472 473
    for (node = list->next; node != list; node = node->next)
    {
474
        timer = (struct rt_timer *)(rt_list_entry(node, struct rt_object, list));
475 476
        rt_kprintf("%-*.*s 0x%08x 0x%08x ",
                   maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
477 478 479
                   timer->parent.name,
                   timer->init_tick,
                   timer->timeout_tick);
480
        if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
D
dzzxzz@gmail.com 已提交
481
            rt_kprintf("activated\n");
482
        else
D
dzzxzz@gmail.com 已提交
483
            rt_kprintf("deactivated\n");
484 485 486 487 488
    }

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

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

long list_timer(void)
{
493
    return _list_timer(&rt_object_container[RT_Object_Class_Timer].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
494
}
B
Bernard Xiong 已提交
495 496
FINSH_FUNCTION_EXPORT(list_timer, list timer in system);
MSH_CMD_EXPORT(list_timer, list timer in system);
497 498

#ifdef RT_USING_DEVICE
qiuyiuestc's avatar
qiuyiuestc 已提交
499
static long _list_device(struct rt_list_node *list)
500
{
501
    int maxlen;
502 503
    struct rt_device *device;
    struct rt_list_node *node;
504
    char *const device_type_str[] =
505 506 507 508 509 510 511 512
    {
        "Character Device",
        "Block Device",
        "Network Interface",
        "MTD Device",
        "CAN Device",
        "RTC",
        "Sound Device",
513
        "Graphic Device",
514
        "I2C Bus",
515 516 517 518 519
        "USB Slave Device",
        "USB Host Bus",
        "SPI Bus",
        "SPI Device",
        "SDIO Bus",
520
        "PM Pseudo Device",
521 522
        "Pipe",
        "Portal Device",
523 524
        "Timer Device",
        "Miscellaneous Device",
525 526
        "Unknown"
    };
G
gbcwbz 已提交
527 528 529 530
    int item_title_len;
    const char *item_title = "device";

    item_title_len = rt_strlen(item_title);
531
    maxlen = object_name_maxlen(list);
G
gbcwbz 已提交
532
    if(maxlen < item_title_len) maxlen = item_title_len;
533

534 535
    rt_kprintf("%-*.s         type         ref count\n", maxlen, item_title); object_split(maxlen);
    rt_kprintf(     " -------------------- ----------\n");
536 537
    for (node = list->next; node != list; node = node->next)
    {
538
        device = (struct rt_device *)(rt_list_entry(node, struct rt_object, list));
539 540
        rt_kprintf("%-*.*s %-20s %-8d\n",
                   maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
541 542 543
                   device->parent.name,
                   (device->type <= RT_Device_Class_Unknown) ?
                   device_type_str[device->type] :
544 545
                   device_type_str[RT_Device_Class_Unknown],
                   device->ref_count);
546 547 548
    }

    return 0;
549
}
qiuyiuestc's avatar
qiuyiuestc 已提交
550 551 552

long list_device(void)
{
553
    return _list_device(&rt_object_container[RT_Object_Class_Device].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
554
}
B
Bernard Xiong 已提交
555 556
FINSH_FUNCTION_EXPORT(list_device, list device in system);
MSH_CMD_EXPORT(list_device, list device in system);
557 558
#endif

qiuyiuestc's avatar
qiuyiuestc 已提交
559
#ifdef RT_USING_MODULE
qiuyiuestc's avatar
qiuyiuestc 已提交
560 561
#include <rtm.h>

562
int list_module(void)
qiuyiuestc's avatar
qiuyiuestc 已提交
563
{
564
    int maxlen;
565 566
    struct rt_module *module;
    struct rt_list_node *list, *node;
qiuyiuestc's avatar
qiuyiuestc 已提交
567

568
    list = &rt_object_container[RT_Object_Class_Module].object_list;
qiuyiuestc's avatar
qiuyiuestc 已提交
569

570 571 572 573
    maxlen = object_name_maxlen(list);

    rt_kprintf("%-*.s ref      address \n", maxlen, "module"); object_split(maxlen);
    rt_kprintf(         " -------- ------------\n");
574 575
    for (node = list->next; node != list; node = node->next)
    {
576
        module = (struct rt_module *)(rt_list_entry(node, struct rt_object, list));
577 578 579
        rt_kprintf("%-*.*s %-04d  0x%08x\n",
                   maxlen, RT_NAME_MAX, 
                   module->parent.name, module->nref, module->module_space);
580
    }
M
mbbill@gmail.com 已提交
581

582
    return 0;
qiuyiuestc's avatar
qiuyiuestc 已提交
583
}
B
bernard 已提交
584 585
FINSH_FUNCTION_EXPORT(list_module, list module in system);
MSH_CMD_EXPORT(list_module, list module in system);
qiuyiuestc's avatar
qiuyiuestc 已提交
586

587
int list_mod_detail(const char *name)
qiuyiuestc's avatar
qiuyiuestc 已提交
588
{
589 590
    int i;
    struct rt_module *module;
591

592
    /* find module */
593
    if ((module = rt_module_find(name)) != RT_NULL)
594 595
    {
        /* module has entry point */
596
        if (!(module->parent.flag & RT_MODULE_FLAG_WITHOUTENTRY))
597
        {
598 599
            struct rt_thread *thread;
            struct rt_list_node *tlist;
600
            rt_uint8_t *ptr;
601 602

            /* list main thread in module */
603
            if (module->module_thread != RT_NULL)
B
bernard 已提交
604
            {
605 606
            	rt_uint8_t stat;
				
607 608 609 610 611
                rt_kprintf("main thread  pri  status      sp     stack size max used   left tick  error\n");
                rt_kprintf("------------- ---- ------- ---------- ---------- ---------- ---------- ---\n");
                thread = module->module_thread;
                rt_kprintf("%-8.*s 0x%02x", RT_NAME_MAX, thread->name, thread->current_priority);

612 613 614 615
				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   ");
616

617
                ptr = (rt_uint8_t *)thread->stack_addr;
618 619 620
                while (*ptr == '#')ptr ++;

                rt_kprintf(" 0x%08x 0x%08x 0x%08x 0x%08x %03d\n",
621 622 623 624 625
                           thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
                           thread->stack_size,
                           thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t)thread->stack_addr),
                           thread->remaining_tick,
                           thread->error);
B
bernard 已提交
626
            }
627 628 629

            /* list sub thread in module */
            tlist = &module->module_object[RT_Object_Class_Thread].object_list;
630
            if (!rt_list_isempty(tlist)) _list_thread(tlist);
qiuyiuestc's avatar
qiuyiuestc 已提交
631
#ifdef RT_USING_SEMAPHORE
632 633
            /* list semaphored in module */
            tlist = &module->module_object[RT_Object_Class_Semaphore].object_list;
634
            if (!rt_list_isempty(tlist)) _list_sem(tlist);
qiuyiuestc's avatar
qiuyiuestc 已提交
635 636
#endif
#ifdef RT_USING_MUTEX
637 638
            /* list mutex in module */
            tlist = &module->module_object[RT_Object_Class_Mutex].object_list;
639
            if (!rt_list_isempty(tlist)) _list_mutex(tlist);
qiuyiuestc's avatar
qiuyiuestc 已提交
640 641
#endif
#ifdef RT_USING_EVENT
642 643
            /* list event in module */
            tlist = &module->module_object[RT_Object_Class_Event].object_list;
644
            if (!rt_list_isempty(tlist)) _list_event(tlist);
qiuyiuestc's avatar
qiuyiuestc 已提交
645 646
#endif
#ifdef RT_USING_MAILBOX
647 648
            /* list mailbox in module */
            tlist = &module->module_object[RT_Object_Class_MailBox].object_list;
649
            if (!rt_list_isempty(tlist)) _list_mailbox(tlist);
qiuyiuestc's avatar
qiuyiuestc 已提交
650 651
#endif
#ifdef RT_USING_MESSAGEQUEUE
652 653
            /* list message queue in module */
            tlist = &module->module_object[RT_Object_Class_MessageQueue].object_list;
654 655 656 657 658 659
            if (!rt_list_isempty(tlist)) _list_msgqueue(tlist);
#endif
#ifdef RT_USING_MEMHEAP
            /* list memory heap in module */
            tlist = &module->module_object[RT_Object_Class_MemHeap].object_list;
            if (!rt_list_isempty(tlist)) _list_memheap(tlist);
qiuyiuestc's avatar
qiuyiuestc 已提交
660 661
#endif
#ifdef RT_USING_MEMPOOL
662 663
            /* list memory pool in module */
            tlist = &module->module_object[RT_Object_Class_MemPool].object_list;
664
            if (!rt_list_isempty(tlist)) _list_mempool(tlist);
qiuyiuestc's avatar
qiuyiuestc 已提交
665 666
#endif
#ifdef RT_USING_DEVICE
667 668
            /* list device in module */
            tlist = &module->module_object[RT_Object_Class_Device].object_list;
669
            if (!rt_list_isempty(tlist)) _list_device(tlist);
qiuyiuestc's avatar
qiuyiuestc 已提交
670
#endif
671 672
            /* list timer in module */
            tlist = &module->module_object[RT_Object_Class_Timer].object_list;
673
            if (!rt_list_isempty(tlist)) _list_timer(tlist);
674 675
        }

676 677 678 679 680 681 682 683 684 685 686 687
        if (module->nsym > 0)
        {
            rt_kprintf("symbol    address   \n");
            rt_kprintf("-------- ----------\n");

            /* list module export symbols */
            for (i = 0; i < module->nsym; i++)
            {
                rt_kprintf("%s 0x%x\n",
                           module->symtab[i].name, module->symtab[i].addr);
            }
        }
688 689 690
    }

    return 0;
qiuyiuestc's avatar
qiuyiuestc 已提交
691
}
qiuyiuestc's avatar
qiuyiuestc 已提交
692
FINSH_FUNCTION_EXPORT(list_mod_detail, list module objects in system)
qiuyiuestc's avatar
qiuyiuestc 已提交
693 694
#endif

D
dzzxzz 已提交
695
long list(void)
696
{
B
bernard 已提交
697
#ifndef FINSH_USING_MSH_ONLY
698 699
    struct finsh_syscall_item *syscall_item;
    struct finsh_sysvar_item *sysvar_item;
B
bernard 已提交
700
#endif
701

702 703
    rt_kprintf("--Function List:\n");
    {
704
        struct finsh_syscall *index;
D
dzzxzz@gmail.com 已提交
705
        for (index = _syscall_table_begin;
706 707
                index < _syscall_table_end;
                FINSH_NEXT_SYSCALL(index))
708
        {
709 710
            /* skip the internal command */
            if (strncmp((char *)index->name, "__", 2) == 0) continue;
B
Bernard Xiong 已提交
711

712
#ifdef FINSH_USING_DESCRIPTION
713
            rt_kprintf("%-16s -- %s\n", index->name, index->desc);
714
#else
715
            rt_kprintf("%s\n", index->name);
716
#endif
717 718 719
        }
    }

B
bernard 已提交
720
#ifndef FINSH_USING_MSH_ONLY
721 722 723 724 725 726 727 728 729 730
    /* 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");
    {
731
        struct finsh_sysvar *index;
732
        for (index = _sysvar_table_begin;
733 734
                index < _sysvar_table_end;
                FINSH_NEXT_SYSVAR(index))
735
        {
736
#ifdef FINSH_USING_DESCRIPTION
737
            rt_kprintf("%-16s -- %s\n", index->name, index->desc);
738
#else
739
            rt_kprintf("%s\n", index->name);
740
#endif
741 742
        }
    }
743

744 745 746 747 748 749
    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 已提交
750
#endif
751

752
    return 0;
753 754 755
}
FINSH_FUNCTION_EXPORT(list, list all symbol in system)

B
bernard 已提交
756
#ifndef FINSH_USING_MSH_ONLY
757
static int str_is_prefix(const char *prefix, const char *str)
758
{
759 760 761 762 763 764
    while ((*prefix) && (*prefix == *str))
    {
        prefix ++;
        str ++;
    }

765
    if (*prefix == 0)
D
dzzxzz@gmail.com 已提交
766 767
        return 0;

768 769 770
    return -1;
}

771
static int str_common(const char *str1, const char *str2)
772
{
773
    const char *str = str1;
774

775
    while ((*str != 0) && (*str2 != 0) && (*str == *str2))
776 777 778 779 780 781
    {
        str ++;
        str2 ++;
    }

    return (str - str1);
782 783
}

784
void list_prefix(char *prefix)
785
{
786 787
    struct finsh_syscall_item *syscall_item;
    struct finsh_sysvar_item *sysvar_item;
788 789
    rt_uint16_t func_cnt, var_cnt;
    int length, min_length;
790
    const char *name_ptr;
791 792 793

    func_cnt = 0;
    var_cnt  = 0;
D
dzzxzz@gmail.com 已提交
794
    min_length = 0;
795 796 797 798
    name_ptr = RT_NULL;

    /* checks in system function call */
    {
D
dzzxzz@gmail.com 已提交
799 800
        struct finsh_syscall *index;
        for (index = _syscall_table_begin;
801 802
                index < _syscall_table_end;
                FINSH_NEXT_SYSCALL(index))
803
        {
804 805 806
            /* skip internal command */
            if (str_is_prefix("__", index->name) == 0) continue;

807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830
            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;
                }
831 832

#ifdef FINSH_USING_DESCRIPTION
833
                rt_kprintf("%-16s -- %s\n", index->name, index->desc);
834
#else
835
                rt_kprintf("%s\n", index->name);
836
#endif
837 838 839 840 841 842 843 844 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 875
            }
        }
    }

    /* 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 */
    {
876
        struct finsh_sysvar *index;
877
        for (index = _sysvar_table_begin;
878 879
                index < _sysvar_table_end;
                FINSH_NEXT_SYSVAR(index))
880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905
        {
            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 已提交
906

907
#ifdef FINSH_USING_DESCRIPTION
908
                rt_kprintf("%-16s -- %s\n", index->name, index->desc);
909
#else
910
                rt_kprintf("%s\n", index->name);
911
#endif
912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953
            }
        }
    }

    /* 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);
    }
954
}
B
bernard 已提交
955
#endif
956

B
bernard 已提交
957
#if defined(FINSH_USING_SYMTAB) && !defined(FINSH_USING_MSH_ONLY)
958 959 960
static int dummy = 0;
FINSH_VAR_EXPORT(dummy, finsh_type_int, dummy variable for finsh)
#endif