cmd.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870
  1. /*
  2. * Copyright (c) 2006-2018, 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. */
  30. #include <rthw.h>
  31. #include <rtthread.h>
  32. #ifdef RT_USING_FINSH
  33. #include "finsh.h"
  34. long hello(void)
  35. {
  36. rt_kprintf("Hello RT-Thread!\n");
  37. return 0;
  38. }
  39. FINSH_FUNCTION_EXPORT(hello, say hello world);
  40. extern void rt_show_version(void);
  41. long version(void)
  42. {
  43. rt_show_version();
  44. return 0;
  45. }
  46. FINSH_FUNCTION_EXPORT(version, show RT-Thread version information);
  47. MSH_CMD_EXPORT(version, show RT-Thread version information);
  48. static int object_name_maxlen(const char *type_name, struct rt_list_node *list)
  49. {
  50. struct rt_list_node *node;
  51. struct rt_object *object = NULL;
  52. int max_length = rt_strlen(type_name), length;
  53. rt_enter_critical();
  54. for (node = list->next; node != list; node = node->next)
  55. {
  56. object = rt_list_entry(node, struct rt_object, list);
  57. length = rt_strlen(object->name);
  58. if (length > max_length) max_length = length;
  59. }
  60. rt_exit_critical();
  61. if (max_length > RT_NAME_MAX || max_length == 0) max_length = RT_NAME_MAX;
  62. return max_length;
  63. }
  64. rt_inline void object_split(int len)
  65. {
  66. while (len--) rt_kprintf("-");
  67. }
  68. static long _list_thread(struct rt_list_node *list)
  69. {
  70. int maxlen;
  71. rt_uint8_t *ptr;
  72. struct rt_thread *thread;
  73. struct rt_list_node *node;
  74. const char *item_title = "thread";
  75. maxlen = object_name_maxlen(item_title, list);
  76. #ifdef RT_USING_SMP
  77. rt_kprintf("%-*.s cpu pri status sp stack size max used left tick error\n", maxlen, item_title); object_split(maxlen);
  78. rt_kprintf( " --- --- ------- ---------- ---------- ------ ---------- ---\n");
  79. #else
  80. rt_kprintf("%-*.s pri status sp stack size max used left tick error\n", maxlen, item_title); object_split(maxlen);
  81. rt_kprintf( " --- ------- ---------- ---------- ------ ---------- ---\n");
  82. #endif /*RT_USING_SMP*/
  83. for (node = list->next; node != list; node = node->next)
  84. {
  85. rt_uint8_t stat;
  86. thread = rt_list_entry(node, struct rt_thread, list);
  87. #ifdef RT_USING_SMP
  88. if (thread->oncpu != RT_CPU_DETACHED)
  89. rt_kprintf("%-*.*s %3d %3d ", maxlen, RT_NAME_MAX, thread->name, thread->oncpu, thread->current_priority);
  90. else
  91. rt_kprintf("%-*.*s N/A %3d ", maxlen, RT_NAME_MAX, thread->name, thread->current_priority);
  92. #else
  93. rt_kprintf("%-*.*s %3d ", maxlen, RT_NAME_MAX, thread->name, thread->current_priority);
  94. #endif /*RT_USING_SMP*/
  95. stat = (thread->stat & RT_THREAD_STAT_MASK);
  96. if (stat == RT_THREAD_READY) rt_kprintf(" ready ");
  97. else if (stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
  98. else if (stat == RT_THREAD_INIT) rt_kprintf(" init ");
  99. else if (stat == RT_THREAD_CLOSE) rt_kprintf(" close ");
  100. #if defined(ARCH_CPU_STACK_GROWS_UPWARD)
  101. ptr = (rt_uint8_t *)thread->stack_addr + thread->stack_size - 1;
  102. while (*ptr == '#')ptr --;
  103. rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %03d\n",
  104. ((rt_ubase_t)thread->sp - (rt_ubase_t)thread->stack_addr),
  105. thread->stack_size,
  106. ((rt_ubase_t)ptr - (rt_ubase_t)thread->stack_addr) * 100 / thread->stack_size,
  107. thread->remaining_tick,
  108. thread->error);
  109. #else
  110. ptr = (rt_uint8_t *)thread->stack_addr;
  111. while (*ptr == '#')ptr ++;
  112. rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %03d\n",
  113. thread->stack_size + ((rt_ubase_t)thread->stack_addr - (rt_ubase_t)thread->sp),
  114. thread->stack_size,
  115. (thread->stack_size - ((rt_ubase_t) ptr - (rt_ubase_t) thread->stack_addr)) * 100
  116. / thread->stack_size,
  117. thread->remaining_tick,
  118. thread->error);
  119. #endif
  120. }
  121. return 0;
  122. }
  123. long list_thread(void)
  124. {
  125. rt_ubase_t level;
  126. struct rt_object_information *info;
  127. long ret;
  128. level = rt_hw_interrupt_disable();
  129. info = rt_object_get_information(RT_Object_Class_Thread);
  130. ret = _list_thread(&info->object_list);
  131. rt_hw_interrupt_enable(level);
  132. return ret;
  133. }
  134. FINSH_FUNCTION_EXPORT(list_thread, list thread);
  135. MSH_CMD_EXPORT(list_thread, list thread);
  136. static void show_wait_queue(struct rt_list_node *list)
  137. {
  138. struct rt_thread *thread;
  139. struct rt_list_node *node;
  140. for (node = list->next; node != list; node = node->next)
  141. {
  142. thread = rt_list_entry(node, struct rt_thread, tlist);
  143. rt_kprintf("%s", thread->name);
  144. if (node->next != list)
  145. rt_kprintf("/");
  146. }
  147. }
  148. #ifdef RT_USING_SEMAPHORE
  149. static long _list_sem(struct rt_list_node *list)
  150. {
  151. int maxlen;
  152. struct rt_semaphore *sem;
  153. struct rt_list_node *node;
  154. const char *item_title = "semaphore";
  155. maxlen = object_name_maxlen(item_title, list);
  156. rt_kprintf("%-*.s v suspend thread\n", maxlen, item_title); object_split(maxlen);
  157. rt_kprintf( " --- --------------\n");
  158. for (node = list->next; node != list; node = node->next)
  159. {
  160. sem = (struct rt_semaphore *)(rt_list_entry(node, struct rt_object, list));
  161. if (!rt_list_isempty(&sem->parent.suspend_thread))
  162. {
  163. rt_kprintf("%-*.*s %03d %d:",
  164. maxlen, RT_NAME_MAX,
  165. sem->parent.parent.name,
  166. sem->value,
  167. rt_list_len(&sem->parent.suspend_thread));
  168. show_wait_queue(&(sem->parent.suspend_thread));
  169. rt_kprintf("\n");
  170. }
  171. else
  172. {
  173. rt_kprintf("%-*.*s %03d %d\n",
  174. maxlen, RT_NAME_MAX,
  175. sem->parent.parent.name,
  176. sem->value,
  177. rt_list_len(&sem->parent.suspend_thread));
  178. }
  179. }
  180. return 0;
  181. }
  182. long list_sem(void)
  183. {
  184. struct rt_object_information *info;
  185. info = rt_object_get_information(RT_Object_Class_Semaphore);
  186. return _list_sem(&info->object_list);
  187. }
  188. FINSH_FUNCTION_EXPORT(list_sem, list semaphone in system);
  189. MSH_CMD_EXPORT(list_sem, list semaphore in system);
  190. #endif
  191. #ifdef RT_USING_EVENT
  192. static long _list_event(struct rt_list_node *list)
  193. {
  194. int maxlen;
  195. struct rt_event *e;
  196. struct rt_list_node *node;
  197. const char *item_title = "event";
  198. maxlen = object_name_maxlen(item_title, list);
  199. rt_kprintf("%-*.s set suspend thread\n", maxlen, item_title); object_split(maxlen);
  200. rt_kprintf( " ---------- --------------\n");
  201. for (node = list->next; node != list; node = node->next)
  202. {
  203. e = (struct rt_event *)(rt_list_entry(node, struct rt_object, list));
  204. if (!rt_list_isempty(&e->parent.suspend_thread))
  205. {
  206. rt_kprintf("%-*.*s 0x%08x %03d:",
  207. maxlen, RT_NAME_MAX,
  208. e->parent.parent.name,
  209. e->set,
  210. rt_list_len(&e->parent.suspend_thread));
  211. show_wait_queue(&(e->parent.suspend_thread));
  212. rt_kprintf("\n");
  213. }
  214. else
  215. {
  216. rt_kprintf("%-*.*s 0x%08x 0\n",
  217. maxlen, RT_NAME_MAX, e->parent.parent.name, e->set);
  218. }
  219. }
  220. return 0;
  221. }
  222. long list_event(void)
  223. {
  224. struct rt_object_information *info;
  225. info = rt_object_get_information(RT_Object_Class_Event);
  226. return _list_event(&info->object_list);
  227. }
  228. FINSH_FUNCTION_EXPORT(list_event, list event in system);
  229. MSH_CMD_EXPORT(list_event, list event in system);
  230. #endif
  231. #ifdef RT_USING_MUTEX
  232. static long _list_mutex(struct rt_list_node *list)
  233. {
  234. int maxlen;
  235. struct rt_mutex *m;
  236. struct rt_list_node *node;
  237. const char *item_title = "mutex";
  238. maxlen = object_name_maxlen(item_title, list);
  239. rt_kprintf("%-*.s owner hold suspend thread\n", maxlen, item_title); object_split(maxlen);
  240. rt_kprintf( " -------- ---- --------------\n");
  241. for (node = list->next; node != list; node = node->next)
  242. {
  243. m = (struct rt_mutex *)(rt_list_entry(node, struct rt_object, list));
  244. rt_kprintf("%-*.*s %-8.*s %04d %d\n",
  245. maxlen, RT_NAME_MAX,
  246. m->parent.parent.name,
  247. RT_NAME_MAX,
  248. m->owner->name,
  249. m->hold,
  250. rt_list_len(&m->parent.suspend_thread));
  251. }
  252. return 0;
  253. }
  254. long list_mutex(void)
  255. {
  256. struct rt_object_information *info;
  257. info = rt_object_get_information(RT_Object_Class_Mutex);
  258. return _list_mutex(&info->object_list);
  259. }
  260. FINSH_FUNCTION_EXPORT(list_mutex, list mutex in system);
  261. MSH_CMD_EXPORT(list_mutex, list mutex in system);
  262. #endif
  263. #ifdef RT_USING_MAILBOX
  264. static long _list_mailbox(struct rt_list_node *list)
  265. {
  266. int maxlen;
  267. struct rt_mailbox *m;
  268. struct rt_list_node *node;
  269. const char *item_title = "mailbox";
  270. maxlen = object_name_maxlen(item_title, list);
  271. rt_kprintf("%-*.s entry size suspend thread\n", maxlen, item_title); object_split(maxlen);
  272. rt_kprintf( " ---- ---- --------------\n");
  273. for (node = list->next; node != list; node = node->next)
  274. {
  275. m = (struct rt_mailbox *)(rt_list_entry(node, struct rt_object, list));
  276. if (!rt_list_isempty(&m->parent.suspend_thread))
  277. {
  278. rt_kprintf("%-*.*s %04d %04d %d:",
  279. maxlen, RT_NAME_MAX,
  280. m->parent.parent.name,
  281. m->entry,
  282. m->size,
  283. rt_list_len(&m->parent.suspend_thread));
  284. show_wait_queue(&(m->parent.suspend_thread));
  285. rt_kprintf("\n");
  286. }
  287. else
  288. {
  289. rt_kprintf("%-*.*s %04d %04d %d\n",
  290. maxlen, RT_NAME_MAX,
  291. m->parent.parent.name,
  292. m->entry,
  293. m->size,
  294. rt_list_len(&m->parent.suspend_thread));
  295. }
  296. }
  297. return 0;
  298. }
  299. long list_mailbox(void)
  300. {
  301. struct rt_object_information *info;
  302. info = rt_object_get_information(RT_Object_Class_MailBox);
  303. return _list_mailbox(&info->object_list);
  304. }
  305. FINSH_FUNCTION_EXPORT(list_mailbox, list mail box in system);
  306. MSH_CMD_EXPORT(list_mailbox, list mail box in system);
  307. #endif
  308. #ifdef RT_USING_MESSAGEQUEUE
  309. static long _list_msgqueue(struct rt_list_node *list)
  310. {
  311. int maxlen;
  312. struct rt_messagequeue *m;
  313. struct rt_list_node *node;
  314. const char *item_title = "msgqueue";
  315. maxlen = object_name_maxlen(item_title, list);
  316. rt_kprintf("%-*.s entry suspend thread\n", maxlen, item_title); object_split(maxlen);
  317. rt_kprintf( " ---- --------------\n");
  318. for (node = list->next; node != list; node = node->next)
  319. {
  320. m = (struct rt_messagequeue *)(rt_list_entry(node, struct rt_object, list));
  321. if (!rt_list_isempty(&m->parent.suspend_thread))
  322. {
  323. rt_kprintf("%-*.*s %04d %d:",
  324. maxlen, RT_NAME_MAX,
  325. m->parent.parent.name,
  326. m->entry,
  327. rt_list_len(&m->parent.suspend_thread));
  328. show_wait_queue(&(m->parent.suspend_thread));
  329. rt_kprintf("\n");
  330. }
  331. else
  332. {
  333. rt_kprintf("%-*.*s %04d %d\n",
  334. maxlen, RT_NAME_MAX,
  335. m->parent.parent.name,
  336. m->entry,
  337. rt_list_len(&m->parent.suspend_thread));
  338. }
  339. }
  340. return 0;
  341. }
  342. long list_msgqueue(void)
  343. {
  344. struct rt_object_information *info;
  345. info = rt_object_get_information(RT_Object_Class_MessageQueue);
  346. return _list_msgqueue(&info->object_list);
  347. }
  348. FINSH_FUNCTION_EXPORT(list_msgqueue, list message queue in system);
  349. MSH_CMD_EXPORT(list_msgqueue, list message queue in system);
  350. #endif
  351. #ifdef RT_USING_MEMHEAP
  352. static long _list_memheap(struct rt_list_node *list)
  353. {
  354. int maxlen;
  355. struct rt_memheap *mh;
  356. struct rt_list_node *node;
  357. const char *item_title = "memheap";
  358. maxlen = object_name_maxlen(item_title, list);
  359. rt_kprintf("%-*.s pool size max used size available size\n", maxlen, item_title); object_split(maxlen);
  360. rt_kprintf( " ---------- ------------- --------------\n");
  361. for (node = list->next; node != list; node = node->next)
  362. {
  363. mh = (struct rt_memheap *)rt_list_entry(node, struct rt_object, list);
  364. rt_kprintf("%-*.*s %-010d %-013d %-05d\n",
  365. maxlen, RT_NAME_MAX,
  366. mh->parent.name,
  367. mh->pool_size,
  368. mh->max_used_size,
  369. mh->available_size);
  370. }
  371. return 0;
  372. }
  373. long list_memheap(void)
  374. {
  375. struct rt_object_information *info;
  376. info = rt_object_get_information(RT_Object_Class_MemHeap);
  377. return _list_memheap(&info->object_list);
  378. }
  379. FINSH_FUNCTION_EXPORT(list_memheap, list memory heap in system);
  380. MSH_CMD_EXPORT(list_memheap, list memory heap in system);
  381. #endif
  382. #ifdef RT_USING_MEMPOOL
  383. static long _list_mempool(struct rt_list_node *list)
  384. {
  385. int maxlen;
  386. struct rt_mempool *mp;
  387. struct rt_list_node *node;
  388. const char *item_title = "mempool";
  389. maxlen = object_name_maxlen(item_title, list);
  390. rt_kprintf("%-*.s block total free suspend thread\n", maxlen, item_title); object_split(maxlen);
  391. rt_kprintf( " ---- ---- ---- --------------\n");
  392. for (node = list->next; node != list; node = node->next)
  393. {
  394. mp = (struct rt_mempool *)rt_list_entry(node, struct rt_object, list);
  395. if (mp->suspend_thread_count > 0)
  396. {
  397. rt_kprintf("%-*.*s %04d %04d %04d %d:",
  398. maxlen, RT_NAME_MAX,
  399. mp->parent.name,
  400. mp->block_size,
  401. mp->block_total_count,
  402. mp->block_free_count,
  403. mp->suspend_thread_count);
  404. show_wait_queue(&(mp->suspend_thread));
  405. rt_kprintf("\n");
  406. }
  407. else
  408. {
  409. rt_kprintf("%-*.*s %04d %04d %04d %d\n",
  410. maxlen, RT_NAME_MAX,
  411. mp->parent.name,
  412. mp->block_size,
  413. mp->block_total_count,
  414. mp->block_free_count,
  415. mp->suspend_thread_count);
  416. }
  417. }
  418. return 0;
  419. }
  420. long list_mempool(void)
  421. {
  422. struct rt_object_information *info;
  423. info = rt_object_get_information(RT_Object_Class_MemPool);
  424. return _list_mempool(&info->object_list);
  425. }
  426. FINSH_FUNCTION_EXPORT(list_mempool, list memory pool in system)
  427. MSH_CMD_EXPORT(list_mempool, list memory pool in system);
  428. #endif
  429. static long _list_timer(struct rt_list_node *list)
  430. {
  431. int maxlen;
  432. struct rt_timer *timer;
  433. struct rt_list_node *node;
  434. const char *item_title = "timer";
  435. maxlen = object_name_maxlen(item_title, list);
  436. rt_kprintf("%-*.s periodic timeout flag\n", maxlen, item_title); object_split(maxlen);
  437. rt_kprintf( " ---------- ---------- -----------\n");
  438. for (node = list->next; node != list; node = node->next)
  439. {
  440. timer = (struct rt_timer *)(rt_list_entry(node, struct rt_object, list));
  441. rt_kprintf("%-*.*s 0x%08x 0x%08x ",
  442. maxlen, RT_NAME_MAX,
  443. timer->parent.name,
  444. timer->init_tick,
  445. timer->timeout_tick);
  446. if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
  447. rt_kprintf("activated\n");
  448. else
  449. rt_kprintf("deactivated\n");
  450. }
  451. rt_kprintf("current tick:0x%08x\n", rt_tick_get());
  452. return 0;
  453. }
  454. long list_timer(void)
  455. {
  456. struct rt_object_information *info;
  457. info = rt_object_get_information(RT_Object_Class_Timer);
  458. return _list_timer(&info->object_list);
  459. }
  460. FINSH_FUNCTION_EXPORT(list_timer, list timer in system);
  461. MSH_CMD_EXPORT(list_timer, list timer in system);
  462. #ifdef RT_USING_DEVICE
  463. static long _list_device(struct rt_list_node *list)
  464. {
  465. int maxlen;
  466. struct rt_device *device;
  467. struct rt_list_node *node;
  468. char *const device_type_str[] =
  469. {
  470. "Character Device",
  471. "Block Device",
  472. "Network Interface",
  473. "MTD Device",
  474. "CAN Device",
  475. "RTC",
  476. "Sound Device",
  477. "Graphic Device",
  478. "I2C Bus",
  479. "USB Slave Device",
  480. "USB Host Bus",
  481. "SPI Bus",
  482. "SPI Device",
  483. "SDIO Bus",
  484. "PM Pseudo Device",
  485. "Pipe",
  486. "Portal Device",
  487. "Timer Device",
  488. "Miscellaneous Device",
  489. "Unknown"
  490. };
  491. const char *item_title = "device";
  492. maxlen = object_name_maxlen(item_title, list);
  493. rt_kprintf("%-*.s type ref count\n", maxlen, item_title); object_split(maxlen);
  494. rt_kprintf( " -------------------- ----------\n");
  495. for (node = list->next; node != list; node = node->next)
  496. {
  497. device = (struct rt_device *)(rt_list_entry(node, struct rt_object, list));
  498. rt_kprintf("%-*.*s %-20s %-8d\n",
  499. maxlen, RT_NAME_MAX,
  500. device->parent.name,
  501. (device->type <= RT_Device_Class_Unknown) ?
  502. device_type_str[device->type] :
  503. device_type_str[RT_Device_Class_Unknown],
  504. device->ref_count);
  505. }
  506. return 0;
  507. }
  508. long list_device(void)
  509. {
  510. struct rt_object_information *info;
  511. info = rt_object_get_information(RT_Object_Class_Device);
  512. return _list_device(&info->object_list);
  513. }
  514. FINSH_FUNCTION_EXPORT(list_device, list device in system);
  515. MSH_CMD_EXPORT(list_device, list device in system);
  516. #endif
  517. long list(void)
  518. {
  519. #ifndef FINSH_USING_MSH_ONLY
  520. struct finsh_syscall_item *syscall_item;
  521. struct finsh_sysvar_item *sysvar_item;
  522. #endif
  523. rt_kprintf("--Function List:\n");
  524. {
  525. struct finsh_syscall *index;
  526. for (index = _syscall_table_begin;
  527. index < _syscall_table_end;
  528. FINSH_NEXT_SYSCALL(index))
  529. {
  530. /* skip the internal command */
  531. if (strncmp((char *)index->name, "__", 2) == 0) continue;
  532. #ifdef FINSH_USING_DESCRIPTION
  533. rt_kprintf("%-16s -- %s\n", index->name, index->desc);
  534. #else
  535. rt_kprintf("%s\n", index->name);
  536. #endif
  537. }
  538. }
  539. #ifndef FINSH_USING_MSH_ONLY
  540. /* list syscall list */
  541. syscall_item = global_syscall_list;
  542. while (syscall_item != NULL)
  543. {
  544. rt_kprintf("[l] %s\n", syscall_item->syscall.name);
  545. syscall_item = syscall_item->next;
  546. }
  547. rt_kprintf("--Variable List:\n");
  548. {
  549. struct finsh_sysvar *index;
  550. for (index = _sysvar_table_begin;
  551. index < _sysvar_table_end;
  552. FINSH_NEXT_SYSVAR(index))
  553. {
  554. #ifdef FINSH_USING_DESCRIPTION
  555. rt_kprintf("%-16s -- %s\n", index->name, index->desc);
  556. #else
  557. rt_kprintf("%s\n", index->name);
  558. #endif
  559. }
  560. }
  561. sysvar_item = global_sysvar_list;
  562. while (sysvar_item != NULL)
  563. {
  564. rt_kprintf("[l] %s\n", sysvar_item->sysvar.name);
  565. sysvar_item = sysvar_item->next;
  566. }
  567. #endif
  568. return 0;
  569. }
  570. FINSH_FUNCTION_EXPORT(list, list all symbol in system)
  571. #ifndef FINSH_USING_MSH_ONLY
  572. static int str_is_prefix(const char *prefix, const char *str)
  573. {
  574. while ((*prefix) && (*prefix == *str))
  575. {
  576. prefix ++;
  577. str ++;
  578. }
  579. if (*prefix == 0)
  580. return 0;
  581. return -1;
  582. }
  583. static int str_common(const char *str1, const char *str2)
  584. {
  585. const char *str = str1;
  586. while ((*str != 0) && (*str2 != 0) && (*str == *str2))
  587. {
  588. str ++;
  589. str2 ++;
  590. }
  591. return (str - str1);
  592. }
  593. void list_prefix(char *prefix)
  594. {
  595. struct finsh_syscall_item *syscall_item;
  596. struct finsh_sysvar_item *sysvar_item;
  597. rt_uint16_t func_cnt, var_cnt;
  598. int length, min_length;
  599. const char *name_ptr;
  600. func_cnt = 0;
  601. var_cnt = 0;
  602. min_length = 0;
  603. name_ptr = RT_NULL;
  604. /* checks in system function call */
  605. {
  606. struct finsh_syscall *index;
  607. for (index = _syscall_table_begin;
  608. index < _syscall_table_end;
  609. FINSH_NEXT_SYSCALL(index))
  610. {
  611. /* skip internal command */
  612. if (str_is_prefix("__", index->name) == 0) continue;
  613. if (str_is_prefix(prefix, index->name) == 0)
  614. {
  615. if (func_cnt == 0)
  616. {
  617. rt_kprintf("--function:\n");
  618. if (*prefix != 0)
  619. {
  620. /* set name_ptr */
  621. name_ptr = index->name;
  622. /* set initial length */
  623. min_length = strlen(name_ptr);
  624. }
  625. }
  626. func_cnt ++;
  627. if (*prefix != 0)
  628. {
  629. length = str_common(name_ptr, index->name);
  630. if (length < min_length)
  631. min_length = length;
  632. }
  633. #ifdef FINSH_USING_DESCRIPTION
  634. rt_kprintf("%-16s -- %s\n", index->name, index->desc);
  635. #else
  636. rt_kprintf("%s\n", index->name);
  637. #endif
  638. }
  639. }
  640. }
  641. /* checks in dynamic system function call */
  642. syscall_item = global_syscall_list;
  643. while (syscall_item != NULL)
  644. {
  645. if (str_is_prefix(prefix, syscall_item->syscall.name) == 0)
  646. {
  647. if (func_cnt == 0)
  648. {
  649. rt_kprintf("--function:\n");
  650. if (*prefix != 0 && name_ptr == NULL)
  651. {
  652. /* set name_ptr */
  653. name_ptr = syscall_item->syscall.name;
  654. /* set initial length */
  655. min_length = strlen(name_ptr);
  656. }
  657. }
  658. func_cnt ++;
  659. if (*prefix != 0)
  660. {
  661. length = str_common(name_ptr, syscall_item->syscall.name);
  662. if (length < min_length)
  663. min_length = length;
  664. }
  665. rt_kprintf("[l] %s\n", syscall_item->syscall.name);
  666. }
  667. syscall_item = syscall_item->next;
  668. }
  669. /* checks in system variable */
  670. {
  671. struct finsh_sysvar *index;
  672. for (index = _sysvar_table_begin;
  673. index < _sysvar_table_end;
  674. FINSH_NEXT_SYSVAR(index))
  675. {
  676. if (str_is_prefix(prefix, index->name) == 0)
  677. {
  678. if (var_cnt == 0)
  679. {
  680. rt_kprintf("--variable:\n");
  681. if (*prefix != 0 && name_ptr == NULL)
  682. {
  683. /* set name_ptr */
  684. name_ptr = index->name;
  685. /* set initial length */
  686. min_length = strlen(name_ptr);
  687. }
  688. }
  689. var_cnt ++;
  690. if (*prefix != 0)
  691. {
  692. length = str_common(name_ptr, index->name);
  693. if (length < min_length)
  694. min_length = length;
  695. }
  696. #ifdef FINSH_USING_DESCRIPTION
  697. rt_kprintf("%-16s -- %s\n", index->name, index->desc);
  698. #else
  699. rt_kprintf("%s\n", index->name);
  700. #endif
  701. }
  702. }
  703. }
  704. /* checks in dynamic system variable */
  705. sysvar_item = global_sysvar_list;
  706. while (sysvar_item != NULL)
  707. {
  708. if (str_is_prefix(prefix, sysvar_item->sysvar.name) == 0)
  709. {
  710. if (var_cnt == 0)
  711. {
  712. rt_kprintf("--variable:\n");
  713. if (*prefix != 0 && name_ptr == NULL)
  714. {
  715. /* set name_ptr */
  716. name_ptr = sysvar_item->sysvar.name;
  717. /* set initial length */
  718. min_length = strlen(name_ptr);
  719. }
  720. }
  721. var_cnt ++;
  722. if (*prefix != 0)
  723. {
  724. length = str_common(name_ptr, sysvar_item->sysvar.name);
  725. if (length < min_length)
  726. min_length = length;
  727. }
  728. rt_kprintf("[v] %s\n", sysvar_item->sysvar.name);
  729. }
  730. sysvar_item = sysvar_item->next;
  731. }
  732. /* only one matched */
  733. if (name_ptr != NULL)
  734. {
  735. rt_strncpy(prefix, name_ptr, min_length);
  736. }
  737. }
  738. #endif
  739. #if defined(FINSH_USING_SYMTAB) && !defined(FINSH_USING_MSH_ONLY)
  740. static int dummy = 0;
  741. FINSH_VAR_EXPORT(dummy, finsh_type_int, dummy variable for finsh)
  742. #endif
  743. #endif /* RT_USING_FINSH */