RT-Thread RTOS 1.2.0
An open source embedded real-time operating system
载入中...
搜索中...
未找到
cmd.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2006-2022, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2006-04-30 Bernard first implementation
9 * 2006-05-04 Bernard add list_thread,
10 * list_sem,
11 * list_timer
12 * 2006-05-20 Bernard add list_mutex,
13 * list_mailbox,
14 * list_msgqueue,
15 * list_event,
16 * list_fevent,
17 * list_mempool
18 * 2006-06-03 Bernard display stack information in list_thread
19 * 2006-08-10 Bernard change version to invoke rt_show_version
20 * 2008-09-10 Bernard update the list function for finsh syscall
21 * list and sysvar list
22 * 2009-05-30 Bernard add list_device
23 * 2010-04-21 yi.qiu add list_module
24 * 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
28 * 2018-11-22 Jesven list_thread add smp support
29 * 2018-12-27 Jesven Fix the problem that disable interrupt too long in list_thread
30 * Provide protection for the "first layer of objects" when list_*
31 * 2020-04-07 chenhui add clear
32 * 2022-07-02 Stanley Lwin add list command
33 * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
34 * 2024-02-09 Bernard fix the version command
35 */
36
37#include <rthw.h>
38#include <rtthread.h>
39#include <string.h>
40
41#ifdef RT_USING_FINSH
42#include <finsh.h>
43
44#define LIST_DFS_OPT_ID 0x100
45#define LIST_FIND_OBJ_NR 8
46
47static long clear(void)
48{
49 rt_kprintf("\x1b[2J\x1b[H");
50
51 return 0;
52}
53MSH_CMD_EXPORT(clear, clear the terminal screen);
54
55static long version(void)
56{
58
59 return 0;
60}
61MSH_CMD_EXPORT(version, show RT-Thread version information);
62
63rt_inline void object_split(int len)
64{
65 while (len--) rt_kprintf("-");
66}
67
68typedef struct
69{
70 rt_list_t *list;
71 rt_list_t **array;
72 rt_uint8_t type;
73 int nr; /* input: max nr, can't be 0 */
74 int nr_out; /* out: got nr */
75} list_get_next_t;
76
77static void list_find_init(list_get_next_t *p, rt_uint8_t type, rt_list_t **array, int nr)
78{
79 struct rt_object_information *info;
80 rt_list_t *list;
81
83 list = &info->object_list;
84
85 p->list = list;
86 p->type = type;
87 p->array = array;
88 p->nr = nr;
89 p->nr_out = 0;
90}
91
92static rt_list_t *list_get_next(rt_list_t *current, list_get_next_t *arg)
93{
94 int first_flag = 0;
95 rt_base_t level;
96 rt_list_t *node, *list;
97 rt_list_t **array;
98 struct rt_object_information *info;
99 int nr;
100
101 arg->nr_out = 0;
102
103 if (!arg->nr || !arg->type)
104 {
105 return (rt_list_t *)RT_NULL;
106 }
107
108 list = arg->list;
109 info = rt_list_entry(list, struct rt_object_information, object_list);
110
111 if (!current) /* find first */
112 {
113 node = list;
114 first_flag = 1;
115 }
116 else
117 {
118 node = current;
119 }
120
121 level = rt_spin_lock_irqsave(&info->spinlock);
122
123 if (!first_flag)
124 {
125 struct rt_object *obj;
126 /* The node in the list? */
127 obj = rt_list_entry(node, struct rt_object, list);
128 if ((obj->type & ~RT_Object_Class_Static) != arg->type)
129 {
130 rt_spin_unlock_irqrestore(&info->spinlock, level);
131 return (rt_list_t *)RT_NULL;
132 }
133 }
134
135 nr = 0;
136 array = arg->array;
137 while (1)
138 {
139 node = node->next;
140
141 if (node == list)
142 {
143 node = (rt_list_t *)RT_NULL;
144 break;
145 }
146 nr++;
147 *array++ = node;
148 if (nr == arg->nr)
149 {
150 break;
151 }
152 }
153
154 rt_spin_unlock_irqrestore(&info->spinlock, level);
155 arg->nr_out = nr;
156 return node;
157}
158
159long list_thread(void)
160{
161 rt_base_t level;
162 list_get_next_t find_arg;
163 struct rt_object_information *info;
164 rt_list_t *obj_list[LIST_FIND_OBJ_NR];
165 rt_list_t *next = (rt_list_t *)RT_NULL;
166 const char *item_title = "thread";
167 const size_t tcb_strlen = sizeof(void *) * 2 + 2;
168 int maxlen;
169
170 list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
171 info = rt_list_entry(find_arg.list, struct rt_object_information, object_list);
172
173 maxlen = RT_NAME_MAX;
174
175#ifdef RT_USING_SMP
176 rt_kprintf("%-*.*s cpu bind pri status sp stack size max used left tick error tcb addr\n", maxlen, maxlen, item_title);
177 object_split(maxlen);
178 rt_kprintf(" --- ---- --- ------- ---------- ---------- ------ ---------- -------");
179 rt_kprintf(" ");
180 object_split(tcb_strlen);
181 rt_kprintf("\n");
182#else
183 rt_kprintf("%-*.*s pri status sp stack size max used left tick error tcb addr\n", maxlen, maxlen, item_title);
184 object_split(maxlen);
185 rt_kprintf(" --- ------- ---------- ---------- ------ ---------- -------");
186 rt_kprintf(" ");
187 object_split(tcb_strlen);
188 rt_kprintf("\n");
189#endif /*RT_USING_SMP*/
190
191 do
192 {
193 next = list_get_next(next, &find_arg);
194 {
195 int i;
196 for (i = 0; i < find_arg.nr_out; i++)
197 {
198 struct rt_object *obj;
199 struct rt_thread thread_info, *thread;
200
201 obj = rt_list_entry(obj_list[i], struct rt_object, list);
202 level = rt_spin_lock_irqsave(&info->spinlock);
203
204 if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
205 {
206 rt_spin_unlock_irqrestore(&info->spinlock, level);
207 continue;
208 }
209 /* copy info */
210 rt_memcpy(&thread_info, obj, sizeof thread_info);
211 rt_spin_unlock_irqrestore(&info->spinlock, level);
212
213 thread = (struct rt_thread *)obj;
214 {
216 rt_uint8_t *ptr;
217
218#ifdef RT_USING_SMP
219 /* no synchronization applied since it's only for debug */
220 if (RT_SCHED_CTX(thread).oncpu != RT_CPU_DETACHED)
221 rt_kprintf("%-*.*s %3d %3d %4d ", maxlen, RT_NAME_MAX,
222 thread->parent.name, RT_SCHED_CTX(thread).oncpu,
223 RT_SCHED_CTX(thread).bind_cpu,
224 RT_SCHED_PRIV(thread).current_priority);
225 else
226 rt_kprintf("%-*.*s N/A %3d %4d ", maxlen, RT_NAME_MAX,
227 thread->parent.name,
228 RT_SCHED_CTX(thread).bind_cpu,
229 RT_SCHED_PRIV(thread).current_priority);
230
231#else
232 /* no synchronization applied since it's only for debug */
233 rt_kprintf("%-*.*s %3d ", maxlen, RT_NAME_MAX, thread->parent.name, RT_SCHED_PRIV(thread).current_priority);
234#endif /*RT_USING_SMP*/
235 stat = (RT_SCHED_CTX(thread).stat & RT_THREAD_STAT_MASK);
236 if (stat == RT_THREAD_READY) rt_kprintf(" ready ");
238 else if (stat == RT_THREAD_INIT) rt_kprintf(" init ");
239 else if (stat == RT_THREAD_CLOSE) rt_kprintf(" close ");
240 else if (stat == RT_THREAD_RUNNING) rt_kprintf(" running");
241
242#if defined(ARCH_CPU_STACK_GROWS_UPWARD)
243 ptr = (rt_uint8_t *)thread->stack_addr + thread->stack_size - 1;
244 while (*ptr == '#')ptr --;
245
246 rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p\n",
247 ((rt_ubase_t)thread->sp - (rt_ubase_t)thread->stack_addr),
248 thread->stack_size,
249 ((rt_ubase_t)ptr - (rt_ubase_t)thread->stack_addr) * 100 / thread->stack_size,
250 thread->remaining_tick,
251 rt_strerror(thread->error),
252 thread);
253#else
254 ptr = (rt_uint8_t *)thread->stack_addr;
255 while (*ptr == '#') ptr ++;
256 rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p\n",
257 thread->stack_size + ((rt_ubase_t)thread->stack_addr - (rt_ubase_t)thread->sp),
258 thread->stack_size,
259 (thread->stack_size - ((rt_ubase_t) ptr - (rt_ubase_t) thread->stack_addr)) * 100
260 / thread->stack_size,
261 RT_SCHED_PRIV(thread).remaining_tick,
262 rt_strerror(thread->error),
263 thread);
264#endif
265 }
266 }
267 }
268 }
269 while (next != (rt_list_t *)RT_NULL);
270
271 return 0;
272}
273
274#ifdef RT_USING_SEMAPHORE
275long list_sem(void)
276{
277 rt_base_t level;
278 list_get_next_t find_arg;
279 struct rt_object_information *info;
280 rt_list_t *obj_list[LIST_FIND_OBJ_NR];
281 rt_list_t *next = (rt_list_t *)RT_NULL;
282
283 int maxlen;
284 const char *item_title = "semaphore";
285
286 list_find_init(&find_arg, RT_Object_Class_Semaphore, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
287 info = rt_list_entry(find_arg.list, struct rt_object_information, object_list);
288
289 maxlen = RT_NAME_MAX;
290
291 rt_kprintf("%-*.*s v suspend thread\n", maxlen, maxlen, item_title);
292 object_split(maxlen);
293 rt_kprintf(" --- --------------\n");
294
295 do
296 {
297 next = list_get_next(next, &find_arg);
298 {
299 int i;
300 for (i = 0; i < find_arg.nr_out; i++)
301 {
302 struct rt_object *obj;
303 struct rt_semaphore *sem;
304
305 obj = rt_list_entry(obj_list[i], struct rt_object, list);
306 level = rt_spin_lock_irqsave(&info->spinlock);
307 if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
308 {
309 rt_spin_unlock_irqrestore(&info->spinlock, level);
310 continue;
311 }
312 rt_spin_unlock_irqrestore(&info->spinlock, level);
313
314 sem = (struct rt_semaphore *)obj;
316 {
317 rt_kprintf("%-*.*s %03d %d:",
318 maxlen, RT_NAME_MAX,
319 sem->parent.parent.name,
320 sem->value,
323 rt_kprintf("\n");
324 }
325 else
326 {
327 rt_kprintf("%-*.*s %03d %d\n",
328 maxlen, RT_NAME_MAX,
329 sem->parent.parent.name,
330 sem->value,
332 }
333 }
334 }
335 }
336 while (next != (rt_list_t *)RT_NULL);
337
338 return 0;
339}
340#endif /* RT_USING_SEMAPHORE */
341
342#ifdef RT_USING_EVENT
343long list_event(void)
344{
345 rt_base_t level;
346 list_get_next_t find_arg;
347 struct rt_object_information *info;
348 rt_list_t *obj_list[LIST_FIND_OBJ_NR];
349 rt_list_t *next = (rt_list_t *)RT_NULL;
350
351 int maxlen;
352 const char *item_title = "event";
353
354 list_find_init(&find_arg, RT_Object_Class_Event, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
355 info = rt_list_entry(find_arg.list, struct rt_object_information, object_list);
356
357 maxlen = RT_NAME_MAX;
358
359 rt_kprintf("%-*.*s set suspend thread\n", maxlen, maxlen, item_title);
360 object_split(maxlen);
361 rt_kprintf(" ---------- --------------\n");
362
363 do
364 {
365 next = list_get_next(next, &find_arg);
366 {
367 int i;
368 for (i = 0; i < find_arg.nr_out; i++)
369 {
370 struct rt_object *obj;
371 struct rt_event *e;
372
373 obj = rt_list_entry(obj_list[i], struct rt_object, list);
374 level = rt_spin_lock_irqsave(&info->spinlock);
375 if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
376 {
377 rt_spin_unlock_irqrestore(&info->spinlock, level);
378 continue;
379 }
380
381 rt_spin_unlock_irqrestore(&info->spinlock, level);
382
383 e = (struct rt_event *)obj;
385 {
386 rt_kprintf("%-*.*s 0x%08x %03d:",
387 maxlen, RT_NAME_MAX,
388 e->parent.parent.name,
389 e->set,
392 rt_kprintf("\n");
393 }
394 else
395 {
396 rt_kprintf("%-*.*s 0x%08x 0\n",
397 maxlen, RT_NAME_MAX, e->parent.parent.name, e->set);
398 }
399 }
400 }
401 }
402 while (next != (rt_list_t *)RT_NULL);
403
404 return 0;
405}
406#endif /* RT_USING_EVENT */
407
408#ifdef RT_USING_MUTEX
409long list_mutex(void)
410{
411 rt_base_t level;
412 list_get_next_t find_arg;
413 struct rt_object_information *info;
414 rt_list_t *obj_list[LIST_FIND_OBJ_NR];
415 rt_list_t *next = (rt_list_t *)RT_NULL;
416
417 int maxlen;
418 const char *item_title = "mutex";
419
420 list_find_init(&find_arg, RT_Object_Class_Mutex, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
421 info = rt_list_entry(find_arg.list, struct rt_object_information, object_list);
422
423 maxlen = RT_NAME_MAX;
424
425 rt_kprintf("%-*.*s owner hold priority suspend thread \n", maxlen, maxlen, item_title);
426 object_split(maxlen);
427 rt_kprintf(" -------- ---- -------- --------------\n");
428
429 do
430 {
431 next = list_get_next(next, &find_arg);
432 {
433 int i;
434 for (i = 0; i < find_arg.nr_out; i++)
435 {
436 struct rt_object *obj;
437 struct rt_mutex *m;
438
439 obj = rt_list_entry(obj_list[i], struct rt_object, list);
440 level = rt_spin_lock_irqsave(&info->spinlock);
441 if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
442 {
443 rt_spin_unlock_irqrestore(&info->spinlock, level);
444 continue;
445 }
446
447 rt_spin_unlock_irqrestore(&info->spinlock, level);
448
449 m = (struct rt_mutex *)obj;
451 {
452 rt_kprintf("%-*.*s %-8.*s %04d %8d %04d ",
453 maxlen, RT_NAME_MAX,
454 m->parent.parent.name,
455 RT_NAME_MAX,
456 m->owner->parent.name,
457 m->hold,
458 m->priority,
461 rt_kprintf("\n");
462 }
463 else
464 {
465 rt_kprintf("%-*.*s %-8.*s %04d %8d %04d\n",
466 maxlen, RT_NAME_MAX,
467 m->parent.parent.name,
468 RT_NAME_MAX,
469 m->owner->parent.name,
470 m->hold,
471 m->priority,
473 }
474 }
475 }
476 }
477 while (next != (rt_list_t *)RT_NULL);
478
479 return 0;
480}
481#endif /* RT_USING_MUTEX */
482
483#ifdef RT_USING_MAILBOX
484long list_mailbox(void)
485{
486 rt_base_t level;
487 list_get_next_t find_arg;
488 struct rt_object_information *info;
489 rt_list_t *obj_list[LIST_FIND_OBJ_NR];
490 rt_list_t *next = (rt_list_t *)RT_NULL;
491
492 int maxlen;
493 const char *item_title = "mailbox";
494
495 list_find_init(&find_arg, RT_Object_Class_MailBox, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
496 info = rt_list_entry(find_arg.list, struct rt_object_information, object_list);
497
498 maxlen = RT_NAME_MAX;
499
500 rt_kprintf("%-*.*s entry size suspend thread\n", maxlen, maxlen, item_title);
501 object_split(maxlen);
502 rt_kprintf(" ---- ---- --------------\n");
503
504 do
505 {
506 next = list_get_next(next, &find_arg);
507 {
508 int i;
509 for (i = 0; i < find_arg.nr_out; i++)
510 {
511 struct rt_object *obj;
512 struct rt_mailbox *m;
513
514 obj = rt_list_entry(obj_list[i], struct rt_object, list);
515 level = rt_spin_lock_irqsave(&info->spinlock);
516 if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
517 {
518 rt_spin_unlock_irqrestore(&info->spinlock, level);
519 continue;
520 }
521
522 rt_spin_unlock_irqrestore(&info->spinlock, level);
523
524 m = (struct rt_mailbox *)obj;
526 {
527 rt_kprintf("%-*.*s %04d %04d %d:",
528 maxlen, RT_NAME_MAX,
529 m->parent.parent.name,
530 m->entry,
531 m->size,
534 rt_kprintf("\n");
535 }
536 else
537 {
538 rt_kprintf("%-*.*s %04d %04d %d\n",
539 maxlen, RT_NAME_MAX,
540 m->parent.parent.name,
541 m->entry,
542 m->size,
544 }
545
546 }
547 }
548 }
549 while (next != (rt_list_t *)RT_NULL);
550
551 return 0;
552}
553#endif /* RT_USING_MAILBOX */
554
555#ifdef RT_USING_MESSAGEQUEUE
557{
558 rt_base_t level;
559 list_get_next_t find_arg;
560 struct rt_object_information *info;
561 rt_list_t *obj_list[LIST_FIND_OBJ_NR];
562 rt_list_t *next = (rt_list_t *)RT_NULL;
563
564 int maxlen;
565 const char *item_title = "msgqueue";
566
567 list_find_init(&find_arg, RT_Object_Class_MessageQueue, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
568 info = rt_list_entry(find_arg.list, struct rt_object_information, object_list);
569
570 maxlen = RT_NAME_MAX;
571
572 rt_kprintf("%-*.*s entry suspend thread\n", maxlen, maxlen, item_title);
573 object_split(maxlen);
574 rt_kprintf(" ---- --------------\n");
575 do
576 {
577 next = list_get_next(next, &find_arg);
578 {
579 int i;
580 for (i = 0; i < find_arg.nr_out; i++)
581 {
582 struct rt_object *obj;
583 struct rt_messagequeue *m;
584
585 obj = rt_list_entry(obj_list[i], struct rt_object, list);
586 level = rt_spin_lock_irqsave(&info->spinlock);
587 if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
588 {
589 rt_spin_unlock_irqrestore(&info->spinlock, level);
590 continue;
591 }
592
593 rt_spin_unlock_irqrestore(&info->spinlock, level);
594
595 m = (struct rt_messagequeue *)obj;
597 {
598 rt_kprintf("%-*.*s %04d %d:",
599 maxlen, RT_NAME_MAX,
600 m->parent.parent.name,
601 m->entry,
604 rt_kprintf("\n");
605 }
606 else
607 {
608 rt_kprintf("%-*.*s %04d %d\n",
609 maxlen, RT_NAME_MAX,
610 m->parent.parent.name,
611 m->entry,
613 }
614 }
615 }
616 }
617 while (next != (rt_list_t *)RT_NULL);
618
619 return 0;
620}
621#endif /* RT_USING_MESSAGEQUEUE */
622
623#ifdef RT_USING_MEMHEAP
624long list_memheap(void)
625{
626 rt_base_t level;
627 list_get_next_t find_arg;
628 struct rt_object_information *info;
629 rt_list_t *obj_list[LIST_FIND_OBJ_NR];
630 rt_list_t *next = (rt_list_t *)RT_NULL;
631
632 int maxlen;
633 const char *item_title = "memheap";
634
635 list_find_init(&find_arg, RT_Object_Class_MemHeap, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
636 info = rt_list_entry(find_arg.list, struct rt_object_information, object_list);
637
638 maxlen = RT_NAME_MAX;
639
640 rt_kprintf("%-*.*s pool size max used size available size\n", maxlen, maxlen, item_title);
641 object_split(maxlen);
642 rt_kprintf(" ---------- ------------- --------------\n");
643 do
644 {
645 next = list_get_next(next, &find_arg);
646 {
647 int i;
648 for (i = 0; i < find_arg.nr_out; i++)
649 {
650 struct rt_object *obj;
651 struct rt_memheap *mh;
652
653 obj = rt_list_entry(obj_list[i], struct rt_object, list);
654 level = rt_spin_lock_irqsave(&info->spinlock);
655 if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
656 {
657 rt_spin_unlock_irqrestore(&info->spinlock, level);
658 continue;
659 }
660
661 rt_spin_unlock_irqrestore(&info->spinlock, level);
662
663 mh = (struct rt_memheap *)obj;
664
665 rt_kprintf("%-*.*s %-010d %-013d %-05d\n",
666 maxlen, RT_NAME_MAX,
667 mh->parent.name,
668 mh->pool_size,
669 mh->max_used_size,
670 mh->available_size);
671
672 }
673 }
674 }
675 while (next != (rt_list_t *)RT_NULL);
676
677 return 0;
678}
679#endif /* RT_USING_MEMHEAP */
680
681#ifdef RT_USING_MEMPOOL
682long list_mempool(void)
683{
684 rt_base_t level;
685 list_get_next_t find_arg;
686 struct rt_object_information *info;
687 rt_list_t *obj_list[LIST_FIND_OBJ_NR];
688 rt_list_t *next = (rt_list_t *)RT_NULL;
689
690 int maxlen;
691 const char *item_title = "mempool";
692
693 list_find_init(&find_arg, RT_Object_Class_MemPool, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
694 info = rt_list_entry(find_arg.list, struct rt_object_information, object_list);
695
696 maxlen = RT_NAME_MAX;
697
698 rt_kprintf("%-*.*s block total free suspend thread\n", maxlen, maxlen, item_title);
699 object_split(maxlen);
700 rt_kprintf(" ---- ---- ---- --------------\n");
701 do
702 {
703 next = list_get_next(next, &find_arg);
704 {
705 int i;
706 for (i = 0; i < find_arg.nr_out; i++)
707 {
708 struct rt_object *obj;
709 struct rt_mempool *mp;
710 int suspend_thread_count;
711 rt_list_t *node;
712
713 obj = rt_list_entry(obj_list[i], struct rt_object, list);
714 level = rt_spin_lock_irqsave(&info->spinlock);
715 if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
716 {
717 rt_spin_unlock_irqrestore(&info->spinlock, level);
718 continue;
719 }
720
721 rt_spin_unlock_irqrestore(&info->spinlock, level);
722
723 mp = (struct rt_mempool *)obj;
724
725 suspend_thread_count = 0;
727 {
728 suspend_thread_count++;
729 }
730
731 if (suspend_thread_count > 0)
732 {
733 rt_kprintf("%-*.*s %04d %04d %04d %d:",
734 maxlen, RT_NAME_MAX,
735 mp->parent.name,
736 mp->block_size,
739 suspend_thread_count);
741 rt_kprintf("\n");
742 }
743 else
744 {
745 rt_kprintf("%-*.*s %04d %04d %04d %d\n",
746 maxlen, RT_NAME_MAX,
747 mp->parent.name,
748 mp->block_size,
751 suspend_thread_count);
752 }
753 }
754 }
755 }
756 while (next != (rt_list_t *)RT_NULL);
757
758 return 0;
759}
760#endif /* RT_USING_MEMPOOL */
761
762long list_timer(void)
763{
764 rt_base_t level;
765 list_get_next_t find_arg;
766 struct rt_object_information *info;
767 rt_list_t *obj_list[LIST_FIND_OBJ_NR];
768 rt_list_t *next = (rt_list_t *)RT_NULL;
769
770 int maxlen;
771 const char *item_title = "timer";
772
773 list_find_init(&find_arg, RT_Object_Class_Timer, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
774 info = rt_list_entry(find_arg.list, struct rt_object_information, object_list);
775
776 maxlen = RT_NAME_MAX;
777
778 rt_kprintf("%-*.*s periodic timeout activated mode\n", maxlen, maxlen, item_title);
779 object_split(maxlen);
780 rt_kprintf(" ---------- ---------- ----------- ---------\n");
781 do
782 {
783 next = list_get_next(next, &find_arg);
784 {
785 int i;
786 for (i = 0; i < find_arg.nr_out; i++)
787 {
788 struct rt_object *obj;
789 struct rt_timer *timer;
790
791 obj = rt_list_entry(obj_list[i], struct rt_object, list);
792 level = rt_spin_lock_irqsave(&info->spinlock);
793 if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
794 {
795 rt_spin_unlock_irqrestore(&info->spinlock, level);
796 continue;
797 }
798
799 rt_spin_unlock_irqrestore(&info->spinlock, level);
800
801 timer = (struct rt_timer *)obj;
802 rt_kprintf("%-*.*s 0x%08x 0x%08x ",
803 maxlen, RT_NAME_MAX,
804 timer->parent.name,
805 timer->init_tick,
806 timer->timeout_tick);
808 rt_kprintf("activated ");
809 else
810 rt_kprintf("deactivated ");
812 rt_kprintf("periodic\n");
813 else
814 rt_kprintf("one shot\n");
815
816 }
817 }
818 }
819 while (next != (rt_list_t *)RT_NULL);
820
821 rt_kprintf("current tick:0x%08x\n", rt_tick_get());
822
823 return 0;
824}
825
826#ifdef RT_USING_DEVICE
827static char *const device_type_str[RT_Device_Class_Unknown] =
828{
829 "Character Device",
830 "Block Device",
831 "Network Interface",
832 "MTD Device",
833 "CAN Device",
834 "RTC",
835 "Sound Device",
836 "Graphic Device",
837 "I2C Bus",
838 "USB Slave Device",
839 "USB Host Bus",
840 "USB OTG Bus",
841 "SPI Bus",
842 "SPI Device",
843 "SDIO Bus",
844 "PM Pseudo Device",
845 "Pipe",
846 "Portal Device",
847 "Timer Device",
848 "Miscellaneous Device",
849 "Sensor Device",
850 "Touch Device",
851 "Phy Device",
852 "Security Device",
853 "WLAN Device",
854 "Pin Device",
855 "ADC Device",
856 "DAC Device",
857 "WDT Device",
858 "PWM Device",
859 "Bus Device",
860};
861
862long list_device(void)
863{
864 rt_base_t level;
865 list_get_next_t find_arg;
866 struct rt_object_information *info;
867 rt_list_t *obj_list[LIST_FIND_OBJ_NR];
868 rt_list_t *next = (rt_list_t *)RT_NULL;
869 const char *device_type;
870
871 int maxlen;
872 const char *item_title = "device";
873
874 list_find_init(&find_arg, RT_Object_Class_Device, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
875 info = rt_list_entry(find_arg.list, struct rt_object_information, object_list);
876
877 maxlen = RT_NAME_MAX;
878
879 rt_kprintf("%-*.*s type ref count\n", maxlen, maxlen, item_title);
880 object_split(maxlen);
881 rt_kprintf(" -------------------- ----------\n");
882 do
883 {
884 next = list_get_next(next, &find_arg);
885 {
886 int i;
887 for (i = 0; i < find_arg.nr_out; i++)
888 {
889 struct rt_object *obj;
890 struct rt_device *device;
891
892 obj = rt_list_entry(obj_list[i], struct rt_object, list);
893 level = rt_spin_lock_irqsave(&info->spinlock);
894 if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
895 {
896 rt_spin_unlock_irqrestore(&info->spinlock, level);
897 continue;
898 }
899
900 rt_spin_unlock_irqrestore(&info->spinlock, level);
901
902 device = (struct rt_device *)obj;
903 device_type = "Unknown";
904 if (device->type < RT_Device_Class_Unknown &&
905 device_type_str[device->type] != RT_NULL)
906 {
907 device_type = device_type_str[device->type];
908 }
909 rt_kprintf("%-*.*s %-20s %-8d\n",
910 maxlen, RT_NAME_MAX,
911 device->parent.name,
912 device_type,
913 device->ref_count);
914
915 }
916 }
917 }
918 while (next != (rt_list_t *)RT_NULL);
919
920 return 0;
921}
922#endif /* RT_USING_DEVICE */
923
924#ifndef FINSH_USING_OPTION_COMPLETION
925static int cmd_list(int argc, char **argv)
926{
927 if(argc == 2)
928 {
929 if(strcmp(argv[1], "thread") == 0)
930 {
931 list_thread();
932 }
933 else if(strcmp(argv[1], "timer") == 0)
934 {
935 list_timer();
936 }
937#ifdef RT_USING_SEMAPHORE
938 else if(strcmp(argv[1], "sem") == 0)
939 {
940 list_sem();
941 }
942#endif /* RT_USING_SEMAPHORE */
943#ifdef RT_USING_EVENT
944 else if(strcmp(argv[1], "event") == 0)
945 {
946 list_event();
947 }
948#endif /* RT_USING_EVENT */
949#ifdef RT_USING_MUTEX
950 else if(strcmp(argv[1], "mutex") == 0)
951 {
952 list_mutex();
953 }
954#endif /* RT_USING_MUTEX */
955#ifdef RT_USING_MAILBOX
956 else if(strcmp(argv[1], "mailbox") == 0)
957 {
958 list_mailbox();
959 }
960#endif /* RT_USING_MAILBOX */
961#ifdef RT_USING_MESSAGEQUEUE
962 else if(strcmp(argv[1], "msgqueue") == 0)
963 {
965 }
966#endif /* RT_USING_MESSAGEQUEUE */
967#ifdef RT_USING_MEMHEAP
968 else if(strcmp(argv[1], "memheap") == 0)
969 {
970 list_memheap();
971 }
972#endif /* RT_USING_MEMHEAP */
973#ifdef RT_USING_MEMPOOL
974 else if(strcmp(argv[1], "mempool") == 0)
975 {
976 list_mempool();
977 }
978#endif /* RT_USING_MEMPOOL */
979#ifdef RT_USING_DEVICE
980 else if(strcmp(argv[1], "device") == 0)
981 {
982 list_device();
983 }
984#endif /* RT_USING_DEVICE */
985#ifdef RT_USING_DFS
986 else if(strcmp(argv[1], "fd") == 0)
987 {
988 extern int list_fd(void);
989 list_fd();
990 }
991#endif /* RT_USING_DFS */
992 else
993 {
994 goto _usage;
995 }
996
997 return 0;
998 }
999
1000_usage:
1001 rt_kprintf("Usage: list [options]\n");
1002 rt_kprintf("[options]:\n");
1003 rt_kprintf(" %-12s - list threads\n", "thread");
1004 rt_kprintf(" %-12s - list timers\n", "timer");
1005#ifdef RT_USING_SEMAPHORE
1006 rt_kprintf(" %-12s - list semaphores\n", "sem");
1007#endif /* RT_USING_SEMAPHORE */
1008#ifdef RT_USING_MUTEX
1009 rt_kprintf(" %-12s - list mutexs\n", "mutex");
1010#endif /* RT_USING_MUTEX */
1011#ifdef RT_USING_EVENT
1012 rt_kprintf(" %-12s - list events\n", "event");
1013#endif /* RT_USING_EVENT */
1014#ifdef RT_USING_MAILBOX
1015 rt_kprintf(" %-12s - list mailboxs\n", "mailbox");
1016#endif /* RT_USING_MAILBOX */
1017#ifdef RT_USING_MESSAGEQUEUE
1018 rt_kprintf(" %-12s - list message queues\n", "msgqueue");
1019#endif /* RT_USING_MESSAGEQUEUE */
1020#ifdef RT_USING_MEMHEAP
1021 rt_kprintf(" %-12s - list memory heaps\n", "memheap");
1022#endif /* RT_USING_MEMHEAP */
1023#ifdef RT_USING_MEMPOOL
1024 rt_kprintf(" %-12s - list memory pools\n", "mempool");
1025#endif /* RT_USING_MEMPOOL */
1026#ifdef RT_USING_DEVICE
1027 rt_kprintf(" %-12s - list devices\n", "device");
1028#endif /* RT_USING_DEVICE */
1029#ifdef RT_USING_DFS
1030 rt_kprintf(" %-12s - list file descriptors\n", "fd");
1031#endif /* RT_USING_DFS */
1032
1033 return 0;
1034}
1035
1036#else
1037CMD_OPTIONS_STATEMENT(cmd_list)
1038static int cmd_list(int argc, char **argv)
1039{
1040 if (argc == 2)
1041 {
1042 switch (MSH_OPT_ID_GET(cmd_list))
1043 {
1044 case RT_Object_Class_Thread: list_thread(); break;
1045 case RT_Object_Class_Timer: list_timer(); break;
1046#ifdef RT_USING_SEMAPHORE
1047 case RT_Object_Class_Semaphore: list_sem(); break;
1048#endif /* RT_USING_SEMAPHORE */
1049#ifdef RT_USING_EVENT
1050 case RT_Object_Class_Event: list_event(); break;
1051#endif /* RT_USING_EVENT */
1052#ifdef RT_USING_MUTEX
1053 case RT_Object_Class_Mutex: list_mutex(); break;
1054#endif /* RT_USING_MUTEX */
1055#ifdef RT_USING_MAILBOX
1057#endif /* RT_USING_MAILBOX */
1058#ifdef RT_USING_MESSAGEQUEUE
1060#endif /* RT_USING_MESSAGEQUEUE */
1061#ifdef RT_USING_MEMHEAP
1062 case RT_Object_Class_MemHeap: list_memheap(); break;
1063#endif /* RT_USING_MEMHEAP */
1064#ifdef RT_USING_MEMPOOL
1066#endif /* RT_USING_MEMPOOL */
1067#ifdef RT_USING_DEVICE
1068 case RT_Object_Class_Device: list_device(); break;
1069#endif /* RT_USING_DEVICE */
1070#ifdef RT_USING_DFS
1071 case LIST_DFS_OPT_ID:
1072 {
1073 extern int list_fd(void);
1074 list_fd();
1075 break;
1076 }
1077#endif /* RT_USING_DFS */
1078 default:
1079 goto _usage;
1080 };
1081
1082 return 0;
1083 }
1084
1085_usage:
1086 rt_kprintf("Usage: list [options]\n");
1087 rt_kprintf("[options]:\n");
1088 MSH_OPT_DUMP(cmd_list);
1089 return 0;
1090}
1091CMD_OPTIONS_NODE_START(cmd_list)
1092CMD_OPTIONS_NODE(RT_Object_Class_Thread, thread, list threads)
1093CMD_OPTIONS_NODE(RT_Object_Class_Timer, timer, list timers)
1094#ifdef RT_USING_SEMAPHORE
1095CMD_OPTIONS_NODE(RT_Object_Class_Semaphore, sem, list semaphores)
1096#endif /* RT_USING_SEMAPHORE */
1097#ifdef RT_USING_EVENT
1098CMD_OPTIONS_NODE(RT_Object_Class_Event, event, list events)
1099#endif /* RT_USING_EVENT */
1100#ifdef RT_USING_MUTEX
1101CMD_OPTIONS_NODE(RT_Object_Class_Mutex, mutex, list mutexs)
1102#endif /* RT_USING_MUTEX */
1103#ifdef RT_USING_MAILBOX
1104CMD_OPTIONS_NODE(RT_Object_Class_MailBox, mailbox, list mailboxs)
1105#endif /* RT_USING_MAILBOX */
1106#ifdef RT_USING_MESSAGEQUEUE
1107CMD_OPTIONS_NODE(RT_Object_Class_MessageQueue, msgqueue, list message queues)
1108#endif /* RT_USING_MESSAGEQUEUE */
1109#ifdef RT_USING_MEMHEAP
1110CMD_OPTIONS_NODE(RT_Object_Class_MemHeap, memheap, list memory heaps)
1111#endif /* RT_USING_MEMHEAP */
1112#ifdef RT_USING_MEMPOOL
1113CMD_OPTIONS_NODE(RT_Object_Class_MemPool, mempool, list memory pools)
1114#endif /* RT_USING_MEMPOOL */
1115#ifdef RT_USING_DEVICE
1116CMD_OPTIONS_NODE(RT_Object_Class_Device, device, list devices)
1117#endif /* RT_USING_DEVICE */
1118#ifdef RT_USING_DFS
1119CMD_OPTIONS_NODE(LIST_DFS_OPT_ID, fd, list file descriptors)
1120#endif /* RT_USING_DFS */
1122#endif /* FINSH_USING_OPTION_COMPLETION */
1123MSH_CMD_EXPORT_ALIAS(cmd_list, list, list objects, optenable);
1124
1125#endif /* RT_USING_FINSH */
long list_thread(void)
定义 cmd.c:159
long list_sem(void)
定义 cmd.c:275
long list_mempool(void)
定义 cmd.c:682
#define LIST_FIND_OBJ_NR
定义 cmd.c:45
long list_mailbox(void)
定义 cmd.c:484
long list_msgqueue(void)
定义 cmd.c:556
long list_device(void)
定义 cmd.c:862
#define LIST_DFS_OPT_ID
定义 cmd.c:44
rt_inline void object_split(int len)
定义 cmd.c:63
long list_mutex(void)
定义 cmd.c:409
long list_timer(void)
定义 cmd.c:762
long list_event(void)
定义 cmd.c:343
#define CMD_OPTIONS_NODE(_id, _name, _des)
#define MSH_OPT_ID_GET(fun)
#define CMD_OPTIONS_NODE_END
#define MSH_OPT_DUMP(fun)
#define CMD_OPTIONS_STATEMENT(command)
#define CMD_OPTIONS_NODE_START(command)
#define RT_TIMER_FLAG_ACTIVATED
#define RT_TIMER_FLAG_PERIODIC
rt_tick_t rt_tick_get(void)
This function will return current tick from operating system startup.
定义 clock.c:69
int list_fd(void)
定义 dfs.c:922
@ RT_Device_Class_Unknown
int stat(const char *file, struct stat *buf)
rt_base_t rt_spin_lock_irqsave(struct rt_spinlock *lock)
This function will disable the local interrupt and then lock the spinlock, will lock the thread sched...
void rt_susp_list_print(rt_list_t *list)
Print thread on suspend list to system console
定义 ipc.c:290
void rt_spin_unlock_irqrestore(struct rt_spinlock *lock, rt_base_t level)
This function will unlock the spinlock and then restore current cpu interrupt status,...
rt_object_class_type
struct rt_object_information * rt_object_get_information(enum rt_object_class_type type)
This function will return the specified type of object information.
@ RT_Object_Class_MemHeap
@ RT_Object_Class_Timer
@ RT_Object_Class_MessageQueue
@ RT_Object_Class_MemPool
@ RT_Object_Class_Thread
@ RT_Object_Class_MailBox
@ RT_Object_Class_Semaphore
@ RT_Object_Class_Event
@ RT_Object_Class_Static
@ RT_Object_Class_Device
@ RT_Object_Class_Mutex
#define rt_list_for_each(pos, head)
void rt_show_version(void)
This function will show the version of rt-thread rtos
rt_inline int rt_list_isempty(const rt_list_t *l)
tests whether a list is empty
#define rt_kprintf(...)
#define rt_list_entry(node, type, member)
get the struct for this entry
rt_inline unsigned int rt_list_len(const rt_list_t *l)
get the list length
#define RT_THREAD_CLOSE
#define RT_THREAD_READY
#define RT_THREAD_STAT_MASK
#define RT_THREAD_RUNNING
#define RT_THREAD_SUSPEND_MASK
#define RT_THREAD_INIT
#define MSH_CMD_EXPORT_ALIAS(...)
#define MSH_CMD_EXPORT(...)
#define RT_SCHED_CTX(thread)
#define RT_SCHED_PRIV(thread)
rt_int32_t rt_base_t
unsigned char rt_uint8_t
struct rt_list_node rt_list_t
rt_uint32_t rt_ubase_t
#define RT_NULL
enum rt_device_class_type type
rt_uint8_t ref_count
struct rt_object parent
rt_uint32_t set
struct rt_ipc_object parent
struct rt_object parent
rt_list_t suspend_thread
struct rt_list_node * next
struct rt_ipc_object parent
rt_uint16_t entry
rt_uint16_t size
rt_size_t block_total_count
rt_size_t block_size
rt_list_t suspend_thread
struct rt_object parent
rt_size_t block_free_count
struct rt_ipc_object parent
rt_uint16_t entry
struct rt_ipc_object parent
rt_uint8_t priority
struct rt_thread * owner
rt_uint8_t hold
struct rt_spinlock spinlock
enum rt_object_class_type type
rt_list_t list
rt_uint8_t type
rt_uint8_t flag
const char * name
rt_uint16_t value
struct rt_ipc_object parent
void * stack_addr
rt_err_t error
struct rt_object parent
void * sp
rt_uint32_t stack_size
struct rt_object parent
rt_tick_t init_tick
rt_tick_t timeout_tick