cmd.c 26.6 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 47 48
 */

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

rt_inline unsigned int rt_list_len(const rt_list_t *l)
{
53 54
    unsigned int len = 0;
    const rt_list_t *p = l;
55
    while (p->next != l)
56 57
    {
        p = p->next;
58
        len ++;
59
    }
D
dzzxzz@gmail.com 已提交
60

61
    return len;
M
mbbill 已提交
62
}
63

64
long hello(void)
65
{
66
    rt_kprintf("Hello RT-Thread!\n");
67

68
    return 0;
69
}
70
FINSH_FUNCTION_EXPORT(hello, say hello world);
71 72

extern void rt_show_version(void);
73
long version(void)
74
{
75
    rt_show_version();
76

77
    return 0;
78
}
79
FINSH_FUNCTION_EXPORT(version, show RT-Thread version information);
B
Bernard Xiong 已提交
80
MSH_CMD_EXPORT(version, show RT-Thread version information);
81 82 83

extern struct rt_object_information rt_object_container[];

84
static long _list_thread(struct rt_list_node *list)
85
{
86 87
    struct rt_thread *thread;
    struct rt_list_node *node;
88
    rt_uint8_t *ptr;
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111

    rt_kprintf(" thread  pri  status      sp     stack size max used   left tick  error\n");
    rt_kprintf("-------- ---- ------- ---------- ---------- ---------- ---------- ---\n");
    for (node = list->next; node != list; node = node->next)
    {
        thread = rt_list_entry(node, struct rt_thread, list);
        rt_kprintf("%-8.*s 0x%02x", RT_NAME_MAX, thread->name, thread->current_priority);

        if (thread->stat == RT_THREAD_READY)        rt_kprintf(" ready  ");
        else if (thread->stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
        else if (thread->stat == RT_THREAD_INIT)    rt_kprintf(" init   ");
        else if (thread->stat == RT_THREAD_CLOSE)   rt_kprintf(" close  ");

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

        rt_kprintf(" 0x%08x 0x%08x 0x%08x 0x%08x %03d\n",
            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);
    }
112
	
113
    return 0;
114
}
qiuyiuestc's avatar
qiuyiuestc 已提交
115 116 117

long list_thread(void)
{
118
    return _list_thread(&rt_object_container[RT_Object_Class_Thread].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
119
}
120
FINSH_FUNCTION_EXPORT(list_thread, list thread);
B
Bernard Xiong 已提交
121
MSH_CMD_EXPORT(list_thread, list thread);
122

123
static void show_wait_queue(struct rt_list_node *list)
124
{
125 126 127 128 129 130 131
    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 已提交
132

133
        if (node->next != list)
D
dzzxzz@gmail.com 已提交
134
            rt_kprintf("/");
135
    }
136 137 138
}

#ifdef RT_USING_SEMAPHORE
qiuyiuestc's avatar
qiuyiuestc 已提交
139
static long _list_sem(struct rt_list_node *list)
140
{
141 142 143 144 145 146 147
    struct rt_semaphore *sem;
    struct rt_list_node *node;

    rt_kprintf("semaphore v   suspend thread\n");
    rt_kprintf("--------  --- --------------\n");
    for (node = list->next; node != list; node = node->next)
    {
148
        sem = (struct rt_semaphore *)(rt_list_entry(node, struct rt_object, list));
D
dzzxzz@gmail.com 已提交
149
        if (!rt_list_isempty(&sem->parent.suspend_thread))
150
        {
D
dzzxzz@gmail.com 已提交
151 152 153 154 155
            rt_kprintf("%-8.*s  %03d %d:", 
                       RT_NAME_MAX,
                       sem->parent.parent.name,
                       sem->value,
                       rt_list_len(&sem->parent.suspend_thread));
156 157 158 159 160
            show_wait_queue(&(sem->parent.suspend_thread));
            rt_kprintf("\n");
        }
        else
        {
D
dzzxzz@gmail.com 已提交
161 162 163 164 165
            rt_kprintf("%-8.*s  %03d %d\n",
                       RT_NAME_MAX,
                       sem->parent.parent.name,
                       sem->value,
                       rt_list_len(&sem->parent.suspend_thread));
166 167 168 169
        }
    }

    return 0;
170
}
qiuyiuestc's avatar
qiuyiuestc 已提交
171 172 173

long list_sem(void)
{
174
    return _list_sem(&rt_object_container[RT_Object_Class_Semaphore].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
175
}
B
Bernard Xiong 已提交
176 177
FINSH_FUNCTION_EXPORT(list_sem, list semaphone in system);
MSH_CMD_EXPORT(list_sem, list semaphore in system);
178 179 180
#endif

#ifdef RT_USING_EVENT
qiuyiuestc's avatar
qiuyiuestc 已提交
181
static long _list_event(struct rt_list_node *list)
182
{
183 184 185 186 187 188 189
    struct rt_event *e;
    struct rt_list_node *node;

    rt_kprintf("event    set        suspend thread\n");
    rt_kprintf("-------- ---------- --------------\n");
    for (node = list->next; node != list; node = node->next)
    {
190 191
        e = (struct rt_event *)(rt_list_entry(node, struct rt_object, list));
        if (!rt_list_isempty(&e->parent.suspend_thread))
192
        {
D
dzzxzz@gmail.com 已提交
193 194 195 196 197
            rt_kprintf("%-8.*s  0x%08x %03d:",
                       RT_NAME_MAX,
                       e->parent.parent.name,
                       e->set,
                       rt_list_len(&e->parent.suspend_thread));
198 199 200 201 202
            show_wait_queue(&(e->parent.suspend_thread));
            rt_kprintf("\n");
        }
        else
        {
D
dzzxzz@gmail.com 已提交
203 204
            rt_kprintf("%-8.*s  0x%08x 0\n",
                       RT_NAME_MAX, e->parent.parent.name, e->set);
205 206 207 208
        }
    }

    return 0;
209
}
qiuyiuestc's avatar
qiuyiuestc 已提交
210 211 212

long list_event(void)
{
213
    return _list_event(&rt_object_container[RT_Object_Class_Event].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
214
}
B
Bernard Xiong 已提交
215 216
FINSH_FUNCTION_EXPORT(list_event, list event in system);
MSH_CMD_EXPORT(list_event, list event in system);
217 218 219
#endif

#ifdef RT_USING_MUTEX
qiuyiuestc's avatar
qiuyiuestc 已提交
220
static long _list_mutex(struct rt_list_node *list)
221
{
222 223 224 225 226 227 228
    struct rt_mutex *m;
    struct rt_list_node *node;

    rt_kprintf("mutex    owner    hold suspend thread\n");
    rt_kprintf("-------- -------- ---- --------------\n");
    for (node = list->next; node != list; node = node->next)
    {
229
        m = (struct rt_mutex *)(rt_list_entry(node, struct rt_object, list));
D
dzzxzz@gmail.com 已提交
230 231 232 233 234 235 236
        rt_kprintf("%-8.*s %-8.*s %04d %d\n",
                   RT_NAME_MAX,
                   m->parent.parent.name,
                   RT_NAME_MAX,
                   m->owner->name,
                   m->hold,
                   rt_list_len(&m->parent.suspend_thread));
237 238 239
    }

    return 0;
240
}
qiuyiuestc's avatar
qiuyiuestc 已提交
241 242 243

long list_mutex(void)
{
244
    return _list_mutex(&rt_object_container[RT_Object_Class_Mutex].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
245
}
B
Bernard Xiong 已提交
246 247
FINSH_FUNCTION_EXPORT(list_mutex, list mutex in system);
MSH_CMD_EXPORT(list_mutex, list mutex in system);
248 249 250
#endif

#ifdef RT_USING_MAILBOX
qiuyiuestc's avatar
qiuyiuestc 已提交
251
static long _list_mailbox(struct rt_list_node *list)
252
{
253 254 255 256 257 258 259
    struct rt_mailbox *m;
    struct rt_list_node *node;

    rt_kprintf("mailbox  entry size suspend thread\n");
    rt_kprintf("-------- ----  ---- --------------\n");
    for (node = list->next; node != list; node = node->next)
    {
260 261
        m = (struct rt_mailbox *)(rt_list_entry(node, struct rt_object, list));
        if (!rt_list_isempty(&m->parent.suspend_thread))
262
        {
D
dzzxzz@gmail.com 已提交
263 264 265 266 267 268
            rt_kprintf("%-8.*s %04d  %04d %d:",
                       RT_NAME_MAX,
                       m->parent.parent.name,
                       m->entry,
                       m->size,
                       rt_list_len(&m->parent.suspend_thread));
269 270 271 272 273
            show_wait_queue(&(m->parent.suspend_thread));
            rt_kprintf("\n");
        }
        else
        {
D
dzzxzz@gmail.com 已提交
274 275 276 277 278 279
            rt_kprintf("%-8.*s %04d  %04d %d\n",
                       RT_NAME_MAX,
                       m->parent.parent.name,
                       m->entry,
                       m->size,
                       rt_list_len(&m->parent.suspend_thread));
280 281 282 283
        }
    }

    return 0;
284
}
qiuyiuestc's avatar
qiuyiuestc 已提交
285 286 287

long list_mailbox(void)
{
288
    return _list_mailbox(&rt_object_container[RT_Object_Class_MailBox].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
289
}
B
Bernard Xiong 已提交
290 291
FINSH_FUNCTION_EXPORT(list_mailbox, list mail box in system);
MSH_CMD_EXPORT(list_mailbox, list mail box in system);
292 293 294
#endif

#ifdef RT_USING_MESSAGEQUEUE
qiuyiuestc's avatar
qiuyiuestc 已提交
295
static long _list_msgqueue(struct rt_list_node *list)
296
{
297 298 299 300 301 302 303
    struct rt_messagequeue *m;
    struct rt_list_node *node;

    rt_kprintf("msgqueue entry suspend thread\n");
    rt_kprintf("-------- ----  --------------\n");
    for (node = list->next; node != list; node = node->next)
    {
304 305
        m = (struct rt_messagequeue *)(rt_list_entry(node, struct rt_object, list));
        if (!rt_list_isempty(&m->parent.suspend_thread))
306
        {
D
dzzxzz@gmail.com 已提交
307 308 309 310 311
            rt_kprintf("%-8.*s %04d  %d:",
                       RT_NAME_MAX,
                       m->parent.parent.name,
                       m->entry,
                       rt_list_len(&m->parent.suspend_thread));
312 313 314 315 316
            show_wait_queue(&(m->parent.suspend_thread));
            rt_kprintf("\n");
        }
        else
        {
D
dzzxzz@gmail.com 已提交
317 318 319 320 321
            rt_kprintf("%-8.*s %04d  %d\n",
                       RT_NAME_MAX,
                       m->parent.parent.name,
                       m->entry,
                       rt_list_len(&m->parent.suspend_thread));
322 323 324 325
        }
    }

    return 0;
326
}
qiuyiuestc's avatar
qiuyiuestc 已提交
327 328 329

long list_msgqueue(void)
{
330
    return _list_msgqueue(&rt_object_container[RT_Object_Class_MessageQueue].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
331
}
B
Bernard Xiong 已提交
332 333
FINSH_FUNCTION_EXPORT(list_msgqueue, list message queue in system);
MSH_CMD_EXPORT(list_msgqueue, list message queue in system);
334 335
#endif

336 337 338 339 340 341
#ifdef RT_USING_MEMHEAP
static long _list_memheap(struct rt_list_node *list)
{
    struct rt_memheap *mh;
    struct rt_list_node *node;

342 343
    rt_kprintf("memheap  pool size  max used size available size\n");
    rt_kprintf("-------- ---------- ------------- --------------\n");
344 345 346 347
    for (node = list->next; node != list; node = node->next)
    {
        mh = (struct rt_memheap *)rt_list_entry(node, struct rt_object, list);

D
dzzxzz@gmail.com 已提交
348 349 350 351 352 353
        rt_kprintf("%-8.*s %-010d %-013d %-05d\n",
                   RT_NAME_MAX,
                   mh->parent.name,
                   mh->pool_size,
                   mh->max_used_size,
                   mh->available_size);
354 355 356 357 358 359 360 361 362
    }

    return 0;
}

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

367
#ifdef RT_USING_MEMPOOL
qiuyiuestc's avatar
qiuyiuestc 已提交
368
static long _list_mempool(struct rt_list_node *list)
369
{
370 371 372 373 374 375 376
    struct rt_mempool *mp;
    struct rt_list_node *node;

    rt_kprintf("mempool  block total free suspend thread\n");
    rt_kprintf("-------- ----  ----  ---- --------------\n");
    for (node = list->next; node != list; node = node->next)
    {
377
        mp = (struct rt_mempool *)rt_list_entry(node, struct rt_object, list);
378 379
        if (mp->suspend_thread_count > 0)
        {
D
dzzxzz@gmail.com 已提交
380 381 382 383 384 385 386
            rt_kprintf("%-8.*s %04d  %04d  %04d %d:",
                       RT_NAME_MAX,
                       mp->parent.name,
                       mp->block_size,
                       mp->block_total_count,
                       mp->block_free_count,
                       mp->suspend_thread_count);
387
            show_wait_queue(&(mp->suspend_thread));
D
dzzxzz@gmail.com 已提交
388
            rt_kprintf("\n");
389 390 391
        }
        else
        {
D
dzzxzz@gmail.com 已提交
392 393 394 395 396 397 398
            rt_kprintf("%-8.*s %04d  %04d  %04d %d\n",
                       RT_NAME_MAX,
                       mp->parent.name,
                       mp->block_size,
                       mp->block_total_count,
                       mp->block_free_count,
                       mp->suspend_thread_count);
399 400 401 402
        }
    }

    return 0;
403
}
qiuyiuestc's avatar
qiuyiuestc 已提交
404 405 406

long list_mempool(void)
{
407
    return _list_mempool(&rt_object_container[RT_Object_Class_MemPool].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
408
}
409
FINSH_FUNCTION_EXPORT(list_mempool, list memory pool in system)
B
Bernard Xiong 已提交
410
MSH_CMD_EXPORT(list_mempool, list memory pool in system);
411 412
#endif

qiuyiuestc's avatar
qiuyiuestc 已提交
413
static long _list_timer(struct rt_list_node *list)
414
{
415 416 417 418 419 420 421
    struct rt_timer *timer;
    struct rt_list_node *node;

    rt_kprintf("timer    periodic   timeout    flag\n");
    rt_kprintf("-------- ---------- ---------- -----------\n");
    for (node = list->next; node != list; node = node->next)
    {
422
        timer = (struct rt_timer *)(rt_list_entry(node, struct rt_object, list));
D
dzzxzz@gmail.com 已提交
423 424 425 426 427
        rt_kprintf("%-8.*s 0x%08x 0x%08x ",
                   RT_NAME_MAX,
                   timer->parent.name,
                   timer->init_tick,
                   timer->timeout_tick);
428
        if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
D
dzzxzz@gmail.com 已提交
429
            rt_kprintf("activated\n");
430
        else
D
dzzxzz@gmail.com 已提交
431
            rt_kprintf("deactivated\n");
432 433 434 435 436
    }

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

    return 0;
437
}
qiuyiuestc's avatar
qiuyiuestc 已提交
438 439 440

long list_timer(void)
{
441
    return _list_timer(&rt_object_container[RT_Object_Class_Timer].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
442
}
B
Bernard Xiong 已提交
443 444
FINSH_FUNCTION_EXPORT(list_timer, list timer in system);
MSH_CMD_EXPORT(list_timer, list timer in system);
445 446

#ifdef RT_USING_DEVICE
qiuyiuestc's avatar
qiuyiuestc 已提交
447
static long _list_device(struct rt_list_node *list)
448
{
449 450
    struct rt_device *device;
    struct rt_list_node *node;
451
    char * const device_type_str[] =
452 453 454 455 456 457 458 459
    {
        "Character Device",
        "Block Device",
        "Network Interface",
        "MTD Device",
        "CAN Device",
        "RTC",
        "Sound Device",
460
        "Graphic Device",
461
        "I2C Bus",
462 463 464 465 466
        "USB Slave Device",
        "USB Host Bus",
        "SPI Bus",
        "SPI Device",
        "SDIO Bus",
B
Bernard Xiong 已提交
467
		"PM Pseudo Device",
468 469
        "Pipe",
        "Portal Device",
H
heyuanjie87 已提交
470
		"Timer Device",
B
Bernard Xiong 已提交
471
		"Miscellaneous Device",
472 473 474
        "Unknown"
    };

475 476
    rt_kprintf("device   type                 ref count\n");
    rt_kprintf("-------- -------------------- ----------\n");
477 478
    for (node = list->next; node != list; node = node->next)
    {
479
        device = (struct rt_device *)(rt_list_entry(node, struct rt_object, list));
480
        rt_kprintf("%-8.*s %-20s %-8d\n",
D
dzzxzz@gmail.com 已提交
481 482 483 484
                   RT_NAME_MAX,
                   device->parent.name,
                   (device->type <= RT_Device_Class_Unknown) ?
                   device_type_str[device->type] :
485 486
                   device_type_str[RT_Device_Class_Unknown],
                   device->ref_count);
487 488 489
    }

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

long list_device(void)
{
494
    return _list_device(&rt_object_container[RT_Object_Class_Device].object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
495
}
B
Bernard Xiong 已提交
496 497
FINSH_FUNCTION_EXPORT(list_device, list device in system);
MSH_CMD_EXPORT(list_device, list device in system);
498 499
#endif

qiuyiuestc's avatar
qiuyiuestc 已提交
500
#ifdef RT_USING_MODULE
qiuyiuestc's avatar
qiuyiuestc 已提交
501 502
#include <rtm.h>

503
int list_module(void)
qiuyiuestc's avatar
qiuyiuestc 已提交
504
{
505 506
    struct rt_module *module;
    struct rt_list_node *list, *node;
qiuyiuestc's avatar
qiuyiuestc 已提交
507

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

510 511 512 513
    rt_kprintf("module name     ref\n");
    rt_kprintf("------------ --------\n");
    for (node = list->next; node != list; node = node->next)
    {
514
        module = (struct rt_module *)(rt_list_entry(node, struct rt_object, list));
D
dzzxzz@gmail.com 已提交
515 516
        rt_kprintf("%-16.*s %-04d\n",
                   RT_NAME_MAX, module->parent.name, module->nref);
517
    }
M
mbbill@gmail.com 已提交
518

519
    return 0;
qiuyiuestc's avatar
qiuyiuestc 已提交
520
}
B
bernard 已提交
521 522
FINSH_FUNCTION_EXPORT(list_module, list module in system);
MSH_CMD_EXPORT(list_module, list module in system);
qiuyiuestc's avatar
qiuyiuestc 已提交
523

524
int list_mod_detail(const char *name)
qiuyiuestc's avatar
qiuyiuestc 已提交
525
{
526 527 528 529
    int i;
    struct rt_module *module;
    
    /* find module */
530
    if ((module = rt_module_find(name)) != RT_NULL)
531 532
    {
        /* module has entry point */
533
        if (!(module->parent.flag & RT_MODULE_FLAG_WITHOUTENTRY))
534 535 536
        {   
            struct rt_thread *thread;
            struct rt_list_node *tlist;
537
            rt_uint8_t *ptr;
538 539

            /* list main thread in module */
540
            if (module->module_thread != RT_NULL)
B
bernard 已提交
541
            {
542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559
                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);

                if (thread->stat == RT_THREAD_READY)        rt_kprintf(" ready  ");
                else if (thread->stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
                else if (thread->stat == RT_THREAD_INIT)    rt_kprintf(" init   ");

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

                rt_kprintf(" 0x%08x 0x%08x 0x%08x 0x%08x %03d\n",
                    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 已提交
560
            }
561 562 563

            /* list sub thread in module */
            tlist = &module->module_object[RT_Object_Class_Thread].object_list;
564
            if (!rt_list_isempty(tlist)) _list_thread(tlist);
qiuyiuestc's avatar
qiuyiuestc 已提交
565
#ifdef RT_USING_SEMAPHORE
566 567
            /* list semaphored in module */
            tlist = &module->module_object[RT_Object_Class_Semaphore].object_list;
568
            if (!rt_list_isempty(tlist)) _list_sem(tlist);
qiuyiuestc's avatar
qiuyiuestc 已提交
569 570
#endif
#ifdef RT_USING_MUTEX
571 572
            /* list mutex in module */
            tlist = &module->module_object[RT_Object_Class_Mutex].object_list;
573
            if (!rt_list_isempty(tlist)) _list_mutex(tlist);
qiuyiuestc's avatar
qiuyiuestc 已提交
574 575
#endif
#ifdef RT_USING_EVENT
576 577
            /* list event in module */
            tlist = &module->module_object[RT_Object_Class_Event].object_list;
578
            if (!rt_list_isempty(tlist)) _list_event(tlist);
qiuyiuestc's avatar
qiuyiuestc 已提交
579 580
#endif
#ifdef RT_USING_MAILBOX
581 582
            /* list mailbox in module */
            tlist = &module->module_object[RT_Object_Class_MailBox].object_list;
583
            if (!rt_list_isempty(tlist)) _list_mailbox(tlist);
qiuyiuestc's avatar
qiuyiuestc 已提交
584 585
#endif
#ifdef RT_USING_MESSAGEQUEUE
586 587
            /* list message queue in module */
            tlist = &module->module_object[RT_Object_Class_MessageQueue].object_list;
588 589 590 591 592 593
            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 已提交
594 595
#endif
#ifdef RT_USING_MEMPOOL
596 597
            /* list memory pool in module */
            tlist = &module->module_object[RT_Object_Class_MemPool].object_list;
598
            if (!rt_list_isempty(tlist)) _list_mempool(tlist);
qiuyiuestc's avatar
qiuyiuestc 已提交
599 600
#endif
#ifdef RT_USING_DEVICE
601 602
            /* list device in module */
            tlist = &module->module_object[RT_Object_Class_Device].object_list;
603
            if (!rt_list_isempty(tlist)) _list_device(tlist);
qiuyiuestc's avatar
qiuyiuestc 已提交
604
#endif
605 606
            /* list timer in module */
            tlist = &module->module_object[RT_Object_Class_Timer].object_list;
607
            if (!rt_list_isempty(tlist)) _list_timer(tlist);
608 609
        }

B
bernard 已提交
610 611 612 613 614 615 616 617 618 619 620 621
		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);
	        }
		}
622 623 624
    }

    return 0;
qiuyiuestc's avatar
qiuyiuestc 已提交
625
}
qiuyiuestc's avatar
qiuyiuestc 已提交
626
FINSH_FUNCTION_EXPORT(list_mod_detail, list module objects in system)
qiuyiuestc's avatar
qiuyiuestc 已提交
627 628
#endif

D
dzzxzz 已提交
629
long list(void)
630
{
B
bernard 已提交
631
#ifndef FINSH_USING_MSH_ONLY
632 633
    struct finsh_syscall_item *syscall_item;
    struct finsh_sysvar_item *sysvar_item;
B
bernard 已提交
634 635
#endif
	
636 637
    rt_kprintf("--Function List:\n");
    {
638
        struct finsh_syscall *index;
D
dzzxzz@gmail.com 已提交
639 640 641
        for (index = _syscall_table_begin;
             index < _syscall_table_end;
             FINSH_NEXT_SYSCALL(index))
642
        {
B
Bernard Xiong 已提交
643
			/* skip the internal command */
644
			if (strncmp((char*)index->name, "__", 2) == 0) continue;
B
Bernard Xiong 已提交
645

646
#ifdef FINSH_USING_DESCRIPTION
647
            rt_kprintf("%-16s -- %s\n", index->name, index->desc);
648
#else
649
            rt_kprintf("%s\n", index->name);
650
#endif
651 652 653
        }
    }

B
bernard 已提交
654
#ifndef FINSH_USING_MSH_ONLY
655 656 657 658 659 660 661 662 663 664
    /* 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");
    {
665
        struct finsh_sysvar *index;
666 667 668
        for (index = _sysvar_table_begin;
             index < _sysvar_table_end;
             FINSH_NEXT_SYSVAR(index))
669
        {
670
#ifdef FINSH_USING_DESCRIPTION
671
            rt_kprintf("%-16s -- %s\n", index->name, index->desc);
672
#else
673
            rt_kprintf("%s\n", index->name);
674
#endif
675 676
        }
    }
677

678 679 680 681 682 683
    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 已提交
684 685
#endif
	
686
    return 0;
687 688 689
}
FINSH_FUNCTION_EXPORT(list, list all symbol in system)

B
bernard 已提交
690
#ifndef FINSH_USING_MSH_ONLY
691
static int str_is_prefix(const char *prefix, const char *str)
692
{
693 694 695 696 697 698
    while ((*prefix) && (*prefix == *str))
    {
        prefix ++;
        str ++;
    }

699
    if (*prefix == 0)
D
dzzxzz@gmail.com 已提交
700 701
        return 0;

702 703 704
    return -1;
}

705
static int str_common(const char *str1, const char *str2)
706
{
707
    const char *str = str1;
708

709
    while ((*str != 0) && (*str2 != 0) && (*str == *str2))
710 711 712 713 714 715
    {
        str ++;
        str2 ++;
    }

    return (str - str1);
716 717
}

718
void list_prefix(char *prefix)
719
{
720 721
    struct finsh_syscall_item *syscall_item;
    struct finsh_sysvar_item *sysvar_item;
722 723
    rt_uint16_t func_cnt, var_cnt;
    int length, min_length;
724
    const char *name_ptr;
725 726 727

    func_cnt = 0;
    var_cnt  = 0;
D
dzzxzz@gmail.com 已提交
728
    min_length = 0;
729 730 731 732
    name_ptr = RT_NULL;

    /* checks in system function call */
    {
D
dzzxzz@gmail.com 已提交
733 734 735 736
        struct finsh_syscall *index;
        for (index = _syscall_table_begin;
             index < _syscall_table_end;
             FINSH_NEXT_SYSCALL(index))
737
        {
B
Bernard Xiong 已提交
738 739 740
			/* skip internal command */
			if (str_is_prefix("__", index->name) == 0) continue;
			
741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764
            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;
                }
765 766

#ifdef FINSH_USING_DESCRIPTION
767
                rt_kprintf("%-16s -- %s\n", index->name, index->desc);
768
#else
769
                rt_kprintf("%s\n", index->name);
770
#endif
771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810
            }
        }
    }

    /* 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 */
    {
        struct finsh_sysvar* index;
811 812 813
        for (index = _sysvar_table_begin;
             index < _sysvar_table_end;
             FINSH_NEXT_SYSVAR(index))
814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839
        {
            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 已提交
840

841
#ifdef FINSH_USING_DESCRIPTION
842
                rt_kprintf("%-16s -- %s\n", index->name, index->desc);
843
#else
844
                rt_kprintf("%s\n", index->name);
845
#endif
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 876 877 878 879 880 881 882 883 884 885 886 887
            }
        }
    }

    /* 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);
    }
888
}
B
bernard 已提交
889
#endif
890

B
bernard 已提交
891
#if defined(FINSH_USING_SYMTAB) && !defined(FINSH_USING_MSH_ONLY)
892 893 894
static int dummy = 0;
FINSH_VAR_EXPORT(dummy, finsh_type_int, dummy variable for finsh)
#endif