cmd.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968
  1. /*
  2. * RT-Thread finsh shell commands
  3. *
  4. * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team
  5. *
  6. * This file is part of RT-Thread (http://www.rt-thread.org)
  7. * Maintainer: bernard.xiong <bernard.xiong at gmail.com>
  8. *
  9. * All rights reserved.
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License along
  22. * with this program; if not, write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  24. *
  25. * Change Logs:
  26. * Date Author Notes
  27. * 2006-04-30 Bernard first implementation
  28. * 2006-05-04 Bernard add list_thread,
  29. * list_sem,
  30. * list_timer
  31. * 2006-05-20 Bernard add list_mutex,
  32. * list_mailbox,
  33. * list_msgqueue,
  34. * list_event,
  35. * list_fevent,
  36. * list_mempool
  37. * 2006-06-03 Bernard display stack information in list_thread
  38. * 2006-08-10 Bernard change version to invoke rt_show_version
  39. * 2008-09-10 Bernard update the list function for finsh syscall
  40. * list and sysvar list
  41. * 2009-05-30 Bernard add list_device
  42. * 2010-04-21 yi.qiu add list_module
  43. * 2012-04-29 goprife improve the command line auto-complete feature.
  44. * 2012-06-02 lgnq add list_memheap
  45. * 2012-10-22 Bernard add MS VC++ patch.
  46. * 2016-06-02 armink beautify the list_thread command
  47. */
  48. #include <rtthread.h>
  49. #include "finsh.h"
  50. rt_inline unsigned int rt_list_len(const rt_list_t *l)
  51. {
  52. unsigned int len = 0;
  53. const rt_list_t *p = l;
  54. while (p->next != l)
  55. {
  56. p = p->next;
  57. len ++;
  58. }
  59. return len;
  60. }
  61. long hello(void)
  62. {
  63. rt_kprintf("Hello RT-Thread!\n");
  64. return 0;
  65. }
  66. FINSH_FUNCTION_EXPORT(hello, say hello world);
  67. extern void rt_show_version(void);
  68. long version(void)
  69. {
  70. rt_show_version();
  71. return 0;
  72. }
  73. FINSH_FUNCTION_EXPORT(version, show RT-Thread version information);
  74. MSH_CMD_EXPORT(version, show RT-Thread version information);
  75. extern struct rt_object_information rt_object_container[];
  76. static int object_name_maxlen(struct rt_list_node *list)
  77. {
  78. struct rt_list_node *node;
  79. struct rt_object *object = NULL;
  80. int max_length = 0, length;
  81. rt_enter_critical();
  82. for (node = list->next; node != list; node = node->next)
  83. {
  84. object = rt_list_entry(node, struct rt_object, list);
  85. length = rt_strlen(object->name);
  86. if (length > max_length) max_length = length;
  87. }
  88. rt_exit_critical();
  89. if (max_length > RT_NAME_MAX || max_length == 0) max_length = RT_NAME_MAX;
  90. return max_length;
  91. }
  92. rt_inline void object_split(int len)
  93. {
  94. while (len--) rt_kprintf("-");
  95. }
  96. static long _list_thread(struct rt_list_node *list)
  97. {
  98. int maxlen;
  99. rt_uint8_t *ptr;
  100. struct rt_thread *thread;
  101. struct rt_list_node *node;
  102. maxlen = object_name_maxlen(list);
  103. rt_kprintf("%-*.s pri status sp stack size max used left tick error\n", maxlen, "thread"); object_split(maxlen);
  104. rt_kprintf( " --- ------- ---------- ---------- ------ ---------- ---\n");
  105. for (node = list->next; node != list; node = node->next)
  106. {
  107. thread = rt_list_entry(node, struct rt_thread, list);
  108. rt_kprintf("%-*.*s %3d ", maxlen, RT_NAME_MAX, thread->name, thread->current_priority);
  109. if (thread->stat == RT_THREAD_READY) rt_kprintf(" ready ");
  110. else if (thread->stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
  111. else if (thread->stat == RT_THREAD_INIT) rt_kprintf(" init ");
  112. else if (thread->stat == RT_THREAD_CLOSE) rt_kprintf(" close ");
  113. ptr = (rt_uint8_t *)thread->stack_addr;
  114. while (*ptr == '#')ptr ++;
  115. rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %03d\n",
  116. thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
  117. thread->stack_size,
  118. (thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t) thread->stack_addr)) * 100
  119. / thread->stack_size,
  120. thread->remaining_tick,
  121. thread->error);
  122. }
  123. return 0;
  124. }
  125. long list_thread(void)
  126. {
  127. return _list_thread(&rt_object_container[RT_Object_Class_Thread].object_list);
  128. }
  129. FINSH_FUNCTION_EXPORT(list_thread, list thread);
  130. MSH_CMD_EXPORT(list_thread, list thread);
  131. static void show_wait_queue(struct rt_list_node *list)
  132. {
  133. struct rt_thread *thread;
  134. struct rt_list_node *node;
  135. for (node = list->next; node != list; node = node->next)
  136. {
  137. thread = rt_list_entry(node, struct rt_thread, tlist);
  138. rt_kprintf("%s", thread->name);
  139. if (node->next != list)
  140. rt_kprintf("/");
  141. }
  142. }
  143. #ifdef RT_USING_SEMAPHORE
  144. static long _list_sem(struct rt_list_node *list)
  145. {
  146. int maxlen;
  147. struct rt_semaphore *sem;
  148. struct rt_list_node *node;
  149. maxlen = object_name_maxlen(list);
  150. if (maxlen < 9) maxlen = 9;
  151. rt_kprintf("%-*.s v suspend thread\n", maxlen, "semaphore"); object_split(maxlen);
  152. rt_kprintf( " --- --------------\n");
  153. for (node = list->next; node != list; node = node->next)
  154. {
  155. sem = (struct rt_semaphore *)(rt_list_entry(node, struct rt_object, list));
  156. if (!rt_list_isempty(&sem->parent.suspend_thread))
  157. {
  158. rt_kprintf("%-*.*s %03d %d:",
  159. maxlen, RT_NAME_MAX,
  160. sem->parent.parent.name,
  161. sem->value,
  162. rt_list_len(&sem->parent.suspend_thread));
  163. show_wait_queue(&(sem->parent.suspend_thread));
  164. rt_kprintf("\n");
  165. }
  166. else
  167. {
  168. rt_kprintf("%-*.*s %03d %d\n",
  169. maxlen, RT_NAME_MAX,
  170. sem->parent.parent.name,
  171. sem->value,
  172. rt_list_len(&sem->parent.suspend_thread));
  173. }
  174. }
  175. return 0;
  176. }
  177. long list_sem(void)
  178. {
  179. return _list_sem(&rt_object_container[RT_Object_Class_Semaphore].object_list);
  180. }
  181. FINSH_FUNCTION_EXPORT(list_sem, list semaphone in system);
  182. MSH_CMD_EXPORT(list_sem, list semaphore in system);
  183. #endif
  184. #ifdef RT_USING_EVENT
  185. static long _list_event(struct rt_list_node *list)
  186. {
  187. int maxlen;
  188. struct rt_event *e;
  189. struct rt_list_node *node;
  190. maxlen = object_name_maxlen(list);
  191. rt_kprintf("%-*.s set suspend thread\n", maxlen, "event"); object_split(maxlen);
  192. rt_kprintf( " ---------- --------------\n");
  193. for (node = list->next; node != list; node = node->next)
  194. {
  195. e = (struct rt_event *)(rt_list_entry(node, struct rt_object, list));
  196. if (!rt_list_isempty(&e->parent.suspend_thread))
  197. {
  198. rt_kprintf("%-*.*s 0x%08x %03d:",
  199. maxlen, RT_NAME_MAX,
  200. e->parent.parent.name,
  201. e->set,
  202. rt_list_len(&e->parent.suspend_thread));
  203. show_wait_queue(&(e->parent.suspend_thread));
  204. rt_kprintf("\n");
  205. }
  206. else
  207. {
  208. rt_kprintf("%-*.*s 0x%08x 0\n",
  209. maxlen, RT_NAME_MAX, e->parent.parent.name, e->set);
  210. }
  211. }
  212. return 0;
  213. }
  214. long list_event(void)
  215. {
  216. return _list_event(&rt_object_container[RT_Object_Class_Event].object_list);
  217. }
  218. FINSH_FUNCTION_EXPORT(list_event, list event in system);
  219. MSH_CMD_EXPORT(list_event, list event in system);
  220. #endif
  221. #ifdef RT_USING_MUTEX
  222. static long _list_mutex(struct rt_list_node *list)
  223. {
  224. int maxlen;
  225. struct rt_mutex *m;
  226. struct rt_list_node *node;
  227. maxlen = object_name_maxlen(list);
  228. rt_kprintf("%-*.s owner hold suspend thread\n", maxlen, "mutex"); object_split(maxlen);
  229. rt_kprintf( " -------- ---- --------------\n");
  230. for (node = list->next; node != list; node = node->next)
  231. {
  232. m = (struct rt_mutex *)(rt_list_entry(node, struct rt_object, list));
  233. rt_kprintf("%-*.*s %-8.*s %04d %d\n",
  234. maxlen, RT_NAME_MAX,
  235. m->parent.parent.name,
  236. RT_NAME_MAX,
  237. m->owner->name,
  238. m->hold,
  239. rt_list_len(&m->parent.suspend_thread));
  240. }
  241. return 0;
  242. }
  243. long list_mutex(void)
  244. {
  245. return _list_mutex(&rt_object_container[RT_Object_Class_Mutex].object_list);
  246. }
  247. FINSH_FUNCTION_EXPORT(list_mutex, list mutex in system);
  248. MSH_CMD_EXPORT(list_mutex, list mutex in system);
  249. #endif
  250. #ifdef RT_USING_MAILBOX
  251. static long _list_mailbox(struct rt_list_node *list)
  252. {
  253. int maxlen;
  254. struct rt_mailbox *m;
  255. struct rt_list_node *node;
  256. int item_title_len;
  257. const char *item_title = "mailbox";
  258. item_title_len = rt_strlen(item_title);
  259. maxlen = object_name_maxlen(list);
  260. if(maxlen < item_title_len) maxlen = item_title_len;
  261. rt_kprintf("%-*.s entry size suspend thread\n", maxlen, item_title); object_split(maxlen);
  262. rt_kprintf( " ---- ---- --------------\n");
  263. for (node = list->next; node != list; node = node->next)
  264. {
  265. m = (struct rt_mailbox *)(rt_list_entry(node, struct rt_object, list));
  266. if (!rt_list_isempty(&m->parent.suspend_thread))
  267. {
  268. rt_kprintf("%-*.*s %04d %04d %d:",
  269. maxlen, RT_NAME_MAX,
  270. m->parent.parent.name,
  271. m->entry,
  272. m->size,
  273. rt_list_len(&m->parent.suspend_thread));
  274. show_wait_queue(&(m->parent.suspend_thread));
  275. rt_kprintf("\n");
  276. }
  277. else
  278. {
  279. rt_kprintf("%-*.*s %04d %04d %d\n",
  280. maxlen, RT_NAME_MAX,
  281. m->parent.parent.name,
  282. m->entry,
  283. m->size,
  284. rt_list_len(&m->parent.suspend_thread));
  285. }
  286. }
  287. return 0;
  288. }
  289. long list_mailbox(void)
  290. {
  291. return _list_mailbox(&rt_object_container[RT_Object_Class_MailBox].object_list);
  292. }
  293. FINSH_FUNCTION_EXPORT(list_mailbox, list mail box in system);
  294. MSH_CMD_EXPORT(list_mailbox, list mail box in system);
  295. #endif
  296. #ifdef RT_USING_MESSAGEQUEUE
  297. static long _list_msgqueue(struct rt_list_node *list)
  298. {
  299. int maxlen;
  300. struct rt_messagequeue *m;
  301. struct rt_list_node *node;
  302. int item_title_len;
  303. const char *item_title = "msgqueue";
  304. item_title_len = rt_strlen(item_title);
  305. maxlen = object_name_maxlen(list);
  306. if(maxlen < item_title_len) maxlen = item_title_len;
  307. rt_kprintf("%-*.s entry suspend thread\n", maxlen, item_title); object_split(maxlen);
  308. rt_kprintf( " ---- --------------\n");
  309. for (node = list->next; node != list; node = node->next)
  310. {
  311. m = (struct rt_messagequeue *)(rt_list_entry(node, struct rt_object, list));
  312. if (!rt_list_isempty(&m->parent.suspend_thread))
  313. {
  314. rt_kprintf("%-*.*s %04d %d:",
  315. maxlen, RT_NAME_MAX,
  316. m->parent.parent.name,
  317. m->entry,
  318. rt_list_len(&m->parent.suspend_thread));
  319. show_wait_queue(&(m->parent.suspend_thread));
  320. rt_kprintf("\n");
  321. }
  322. else
  323. {
  324. rt_kprintf("%-*.*s %04d %d\n",
  325. maxlen, RT_NAME_MAX,
  326. m->parent.parent.name,
  327. m->entry,
  328. rt_list_len(&m->parent.suspend_thread));
  329. }
  330. }
  331. return 0;
  332. }
  333. long list_msgqueue(void)
  334. {
  335. return _list_msgqueue(&rt_object_container[RT_Object_Class_MessageQueue].object_list);
  336. }
  337. FINSH_FUNCTION_EXPORT(list_msgqueue, list message queue in system);
  338. MSH_CMD_EXPORT(list_msgqueue, list message queue in system);
  339. #endif
  340. #ifdef RT_USING_MEMHEAP
  341. static long _list_memheap(struct rt_list_node *list)
  342. {
  343. int maxlen;
  344. struct rt_memheap *mh;
  345. struct rt_list_node *node;
  346. maxlen = object_name_maxlen(list);
  347. rt_kprintf("%-*.s pool size max used size available size\n", maxlen, "memheap"); object_split(maxlen);
  348. rt_kprintf( " ---------- ------------- --------------\n");
  349. for (node = list->next; node != list; node = node->next)
  350. {
  351. mh = (struct rt_memheap *)rt_list_entry(node, struct rt_object, list);
  352. rt_kprintf("%-*.*s %-010d %-013d %-05d\n",
  353. maxlen, RT_NAME_MAX,
  354. mh->parent.name,
  355. mh->pool_size,
  356. mh->max_used_size,
  357. mh->available_size);
  358. }
  359. return 0;
  360. }
  361. long list_memheap(void)
  362. {
  363. return _list_memheap(&rt_object_container[RT_Object_Class_MemHeap].object_list);
  364. }
  365. FINSH_FUNCTION_EXPORT(list_memheap, list memory heap in system);
  366. MSH_CMD_EXPORT(list_memheap, list memory heap in system);
  367. #endif
  368. #ifdef RT_USING_MEMPOOL
  369. static long _list_mempool(struct rt_list_node *list)
  370. {
  371. int maxlen;
  372. struct rt_mempool *mp;
  373. struct rt_list_node *node;
  374. maxlen = object_name_maxlen(list);
  375. rt_kprintf("%-*.s block total free suspend thread\n", maxlen, "mempool"); object_split(maxlen);
  376. rt_kprintf( " ---- ---- ---- --------------\n");
  377. for (node = list->next; node != list; node = node->next)
  378. {
  379. mp = (struct rt_mempool *)rt_list_entry(node, struct rt_object, list);
  380. if (mp->suspend_thread_count > 0)
  381. {
  382. rt_kprintf("%-*.*s %04d %04d %04d %d:",
  383. maxlen, RT_NAME_MAX,
  384. mp->parent.name,
  385. mp->block_size,
  386. mp->block_total_count,
  387. mp->block_free_count,
  388. mp->suspend_thread_count);
  389. show_wait_queue(&(mp->suspend_thread));
  390. rt_kprintf("\n");
  391. }
  392. else
  393. {
  394. rt_kprintf("%-*.*s %04d %04d %04d %d\n",
  395. maxlen, RT_NAME_MAX,
  396. mp->parent.name,
  397. mp->block_size,
  398. mp->block_total_count,
  399. mp->block_free_count,
  400. mp->suspend_thread_count);
  401. }
  402. }
  403. return 0;
  404. }
  405. long list_mempool(void)
  406. {
  407. return _list_mempool(&rt_object_container[RT_Object_Class_MemPool].object_list);
  408. }
  409. FINSH_FUNCTION_EXPORT(list_mempool, list memory pool in system)
  410. MSH_CMD_EXPORT(list_mempool, list memory pool in system);
  411. #endif
  412. static long _list_timer(struct rt_list_node *list)
  413. {
  414. int maxlen;
  415. struct rt_timer *timer;
  416. struct rt_list_node *node;
  417. maxlen = object_name_maxlen(list);
  418. rt_kprintf("%-*.s periodic timeout flag\n", maxlen, "timer"); object_split(maxlen);
  419. rt_kprintf( " ---------- ---------- -----------\n");
  420. for (node = list->next; node != list; node = node->next)
  421. {
  422. timer = (struct rt_timer *)(rt_list_entry(node, struct rt_object, list));
  423. rt_kprintf("%-*.*s 0x%08x 0x%08x ",
  424. maxlen, RT_NAME_MAX,
  425. timer->parent.name,
  426. timer->init_tick,
  427. timer->timeout_tick);
  428. if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
  429. rt_kprintf("activated\n");
  430. else
  431. rt_kprintf("deactivated\n");
  432. }
  433. rt_kprintf("current tick:0x%08x\n", rt_tick_get());
  434. return 0;
  435. }
  436. long list_timer(void)
  437. {
  438. return _list_timer(&rt_object_container[RT_Object_Class_Timer].object_list);
  439. }
  440. FINSH_FUNCTION_EXPORT(list_timer, list timer in system);
  441. MSH_CMD_EXPORT(list_timer, list timer in system);
  442. #ifdef RT_USING_DEVICE
  443. static long _list_device(struct rt_list_node *list)
  444. {
  445. int maxlen;
  446. struct rt_device *device;
  447. struct rt_list_node *node;
  448. char *const device_type_str[] =
  449. {
  450. "Character Device",
  451. "Block Device",
  452. "Network Interface",
  453. "MTD Device",
  454. "CAN Device",
  455. "RTC",
  456. "Sound Device",
  457. "Graphic Device",
  458. "I2C Bus",
  459. "USB Slave Device",
  460. "USB Host Bus",
  461. "SPI Bus",
  462. "SPI Device",
  463. "SDIO Bus",
  464. "PM Pseudo Device",
  465. "Pipe",
  466. "Portal Device",
  467. "Timer Device",
  468. "Miscellaneous Device",
  469. "Unknown"
  470. };
  471. int item_title_len;
  472. const char *item_title = "device";
  473. item_title_len = rt_strlen(item_title);
  474. maxlen = object_name_maxlen(list);
  475. if(maxlen < item_title_len) maxlen = item_title_len;
  476. rt_kprintf("%-*.s type ref count\n", maxlen, item_title); object_split(maxlen);
  477. rt_kprintf( " -------------------- ----------\n");
  478. for (node = list->next; node != list; node = node->next)
  479. {
  480. device = (struct rt_device *)(rt_list_entry(node, struct rt_object, list));
  481. rt_kprintf("%-*.*s %-20s %-8d\n",
  482. maxlen, RT_NAME_MAX,
  483. device->parent.name,
  484. (device->type <= RT_Device_Class_Unknown) ?
  485. device_type_str[device->type] :
  486. device_type_str[RT_Device_Class_Unknown],
  487. device->ref_count);
  488. }
  489. return 0;
  490. }
  491. long list_device(void)
  492. {
  493. return _list_device(&rt_object_container[RT_Object_Class_Device].object_list);
  494. }
  495. FINSH_FUNCTION_EXPORT(list_device, list device in system);
  496. MSH_CMD_EXPORT(list_device, list device in system);
  497. #endif
  498. #ifdef RT_USING_MODULE
  499. #include <rtm.h>
  500. int list_module(void)
  501. {
  502. int maxlen;
  503. struct rt_module *module;
  504. struct rt_list_node *list, *node;
  505. list = &rt_object_container[RT_Object_Class_Module].object_list;
  506. maxlen = object_name_maxlen(list);
  507. rt_kprintf("%-*.s ref address \n", maxlen, "module"); object_split(maxlen);
  508. rt_kprintf( " -------- ------------\n");
  509. for (node = list->next; node != list; node = node->next)
  510. {
  511. module = (struct rt_module *)(rt_list_entry(node, struct rt_object, list));
  512. rt_kprintf("%-*.*s %-04d 0x%08x\n",
  513. maxlen, RT_NAME_MAX,
  514. module->parent.name, module->nref, module->module_space);
  515. }
  516. return 0;
  517. }
  518. FINSH_FUNCTION_EXPORT(list_module, list module in system);
  519. MSH_CMD_EXPORT(list_module, list module in system);
  520. int list_mod_detail(const char *name)
  521. {
  522. int i;
  523. struct rt_module *module;
  524. /* find module */
  525. if ((module = rt_module_find(name)) != RT_NULL)
  526. {
  527. /* module has entry point */
  528. if (!(module->parent.flag & RT_MODULE_FLAG_WITHOUTENTRY))
  529. {
  530. struct rt_thread *thread;
  531. struct rt_list_node *tlist;
  532. rt_uint8_t *ptr;
  533. /* list main thread in module */
  534. if (module->module_thread != RT_NULL)
  535. {
  536. rt_kprintf("main thread pri status sp stack size max used left tick error\n");
  537. rt_kprintf("------------- ---- ------- ---------- ---------- ---------- ---------- ---\n");
  538. thread = module->module_thread;
  539. rt_kprintf("%-8.*s 0x%02x", RT_NAME_MAX, thread->name, thread->current_priority);
  540. if (thread->stat == RT_THREAD_READY) rt_kprintf(" ready ");
  541. else if (thread->stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
  542. else if (thread->stat == RT_THREAD_INIT) rt_kprintf(" init ");
  543. ptr = (rt_uint8_t *)thread->stack_addr;
  544. while (*ptr == '#')ptr ++;
  545. rt_kprintf(" 0x%08x 0x%08x 0x%08x 0x%08x %03d\n",
  546. thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
  547. thread->stack_size,
  548. thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t)thread->stack_addr),
  549. thread->remaining_tick,
  550. thread->error);
  551. }
  552. /* list sub thread in module */
  553. tlist = &module->module_object[RT_Object_Class_Thread].object_list;
  554. if (!rt_list_isempty(tlist)) _list_thread(tlist);
  555. #ifdef RT_USING_SEMAPHORE
  556. /* list semaphored in module */
  557. tlist = &module->module_object[RT_Object_Class_Semaphore].object_list;
  558. if (!rt_list_isempty(tlist)) _list_sem(tlist);
  559. #endif
  560. #ifdef RT_USING_MUTEX
  561. /* list mutex in module */
  562. tlist = &module->module_object[RT_Object_Class_Mutex].object_list;
  563. if (!rt_list_isempty(tlist)) _list_mutex(tlist);
  564. #endif
  565. #ifdef RT_USING_EVENT
  566. /* list event in module */
  567. tlist = &module->module_object[RT_Object_Class_Event].object_list;
  568. if (!rt_list_isempty(tlist)) _list_event(tlist);
  569. #endif
  570. #ifdef RT_USING_MAILBOX
  571. /* list mailbox in module */
  572. tlist = &module->module_object[RT_Object_Class_MailBox].object_list;
  573. if (!rt_list_isempty(tlist)) _list_mailbox(tlist);
  574. #endif
  575. #ifdef RT_USING_MESSAGEQUEUE
  576. /* list message queue in module */
  577. tlist = &module->module_object[RT_Object_Class_MessageQueue].object_list;
  578. if (!rt_list_isempty(tlist)) _list_msgqueue(tlist);
  579. #endif
  580. #ifdef RT_USING_MEMHEAP
  581. /* list memory heap in module */
  582. tlist = &module->module_object[RT_Object_Class_MemHeap].object_list;
  583. if (!rt_list_isempty(tlist)) _list_memheap(tlist);
  584. #endif
  585. #ifdef RT_USING_MEMPOOL
  586. /* list memory pool in module */
  587. tlist = &module->module_object[RT_Object_Class_MemPool].object_list;
  588. if (!rt_list_isempty(tlist)) _list_mempool(tlist);
  589. #endif
  590. #ifdef RT_USING_DEVICE
  591. /* list device in module */
  592. tlist = &module->module_object[RT_Object_Class_Device].object_list;
  593. if (!rt_list_isempty(tlist)) _list_device(tlist);
  594. #endif
  595. /* list timer in module */
  596. tlist = &module->module_object[RT_Object_Class_Timer].object_list;
  597. if (!rt_list_isempty(tlist)) _list_timer(tlist);
  598. }
  599. if (module->nsym > 0)
  600. {
  601. rt_kprintf("symbol address \n");
  602. rt_kprintf("-------- ----------\n");
  603. /* list module export symbols */
  604. for (i = 0; i < module->nsym; i++)
  605. {
  606. rt_kprintf("%s 0x%x\n",
  607. module->symtab[i].name, module->symtab[i].addr);
  608. }
  609. }
  610. }
  611. return 0;
  612. }
  613. FINSH_FUNCTION_EXPORT(list_mod_detail, list module objects in system)
  614. #endif
  615. long list(void)
  616. {
  617. #ifndef FINSH_USING_MSH_ONLY
  618. struct finsh_syscall_item *syscall_item;
  619. struct finsh_sysvar_item *sysvar_item;
  620. #endif
  621. rt_kprintf("--Function List:\n");
  622. {
  623. struct finsh_syscall *index;
  624. for (index = _syscall_table_begin;
  625. index < _syscall_table_end;
  626. FINSH_NEXT_SYSCALL(index))
  627. {
  628. /* skip the internal command */
  629. if (strncmp((char *)index->name, "__", 2) == 0) continue;
  630. #ifdef FINSH_USING_DESCRIPTION
  631. rt_kprintf("%-16s -- %s\n", index->name, index->desc);
  632. #else
  633. rt_kprintf("%s\n", index->name);
  634. #endif
  635. }
  636. }
  637. #ifndef FINSH_USING_MSH_ONLY
  638. /* list syscall list */
  639. syscall_item = global_syscall_list;
  640. while (syscall_item != NULL)
  641. {
  642. rt_kprintf("[l] %s\n", syscall_item->syscall.name);
  643. syscall_item = syscall_item->next;
  644. }
  645. rt_kprintf("--Variable List:\n");
  646. {
  647. struct finsh_sysvar *index;
  648. for (index = _sysvar_table_begin;
  649. index < _sysvar_table_end;
  650. FINSH_NEXT_SYSVAR(index))
  651. {
  652. #ifdef FINSH_USING_DESCRIPTION
  653. rt_kprintf("%-16s -- %s\n", index->name, index->desc);
  654. #else
  655. rt_kprintf("%s\n", index->name);
  656. #endif
  657. }
  658. }
  659. sysvar_item = global_sysvar_list;
  660. while (sysvar_item != NULL)
  661. {
  662. rt_kprintf("[l] %s\n", sysvar_item->sysvar.name);
  663. sysvar_item = sysvar_item->next;
  664. }
  665. #endif
  666. return 0;
  667. }
  668. FINSH_FUNCTION_EXPORT(list, list all symbol in system)
  669. #ifndef FINSH_USING_MSH_ONLY
  670. static int str_is_prefix(const char *prefix, const char *str)
  671. {
  672. while ((*prefix) && (*prefix == *str))
  673. {
  674. prefix ++;
  675. str ++;
  676. }
  677. if (*prefix == 0)
  678. return 0;
  679. return -1;
  680. }
  681. static int str_common(const char *str1, const char *str2)
  682. {
  683. const char *str = str1;
  684. while ((*str != 0) && (*str2 != 0) && (*str == *str2))
  685. {
  686. str ++;
  687. str2 ++;
  688. }
  689. return (str - str1);
  690. }
  691. void list_prefix(char *prefix)
  692. {
  693. struct finsh_syscall_item *syscall_item;
  694. struct finsh_sysvar_item *sysvar_item;
  695. rt_uint16_t func_cnt, var_cnt;
  696. int length, min_length;
  697. const char *name_ptr;
  698. func_cnt = 0;
  699. var_cnt = 0;
  700. min_length = 0;
  701. name_ptr = RT_NULL;
  702. /* checks in system function call */
  703. {
  704. struct finsh_syscall *index;
  705. for (index = _syscall_table_begin;
  706. index < _syscall_table_end;
  707. FINSH_NEXT_SYSCALL(index))
  708. {
  709. /* skip internal command */
  710. if (str_is_prefix("__", index->name) == 0) continue;
  711. if (str_is_prefix(prefix, index->name) == 0)
  712. {
  713. if (func_cnt == 0)
  714. {
  715. rt_kprintf("--function:\n");
  716. if (*prefix != 0)
  717. {
  718. /* set name_ptr */
  719. name_ptr = index->name;
  720. /* set initial length */
  721. min_length = strlen(name_ptr);
  722. }
  723. }
  724. func_cnt ++;
  725. if (*prefix != 0)
  726. {
  727. length = str_common(name_ptr, index->name);
  728. if (length < min_length)
  729. min_length = length;
  730. }
  731. #ifdef FINSH_USING_DESCRIPTION
  732. rt_kprintf("%-16s -- %s\n", index->name, index->desc);
  733. #else
  734. rt_kprintf("%s\n", index->name);
  735. #endif
  736. }
  737. }
  738. }
  739. /* checks in dynamic system function call */
  740. syscall_item = global_syscall_list;
  741. while (syscall_item != NULL)
  742. {
  743. if (str_is_prefix(prefix, syscall_item->syscall.name) == 0)
  744. {
  745. if (func_cnt == 0)
  746. {
  747. rt_kprintf("--function:\n");
  748. if (*prefix != 0 && name_ptr == NULL)
  749. {
  750. /* set name_ptr */
  751. name_ptr = syscall_item->syscall.name;
  752. /* set initial length */
  753. min_length = strlen(name_ptr);
  754. }
  755. }
  756. func_cnt ++;
  757. if (*prefix != 0)
  758. {
  759. length = str_common(name_ptr, syscall_item->syscall.name);
  760. if (length < min_length)
  761. min_length = length;
  762. }
  763. rt_kprintf("[l] %s\n", syscall_item->syscall.name);
  764. }
  765. syscall_item = syscall_item->next;
  766. }
  767. /* checks in system variable */
  768. {
  769. struct finsh_sysvar *index;
  770. for (index = _sysvar_table_begin;
  771. index < _sysvar_table_end;
  772. FINSH_NEXT_SYSVAR(index))
  773. {
  774. if (str_is_prefix(prefix, index->name) == 0)
  775. {
  776. if (var_cnt == 0)
  777. {
  778. rt_kprintf("--variable:\n");
  779. if (*prefix != 0 && name_ptr == NULL)
  780. {
  781. /* set name_ptr */
  782. name_ptr = index->name;
  783. /* set initial length */
  784. min_length = strlen(name_ptr);
  785. }
  786. }
  787. var_cnt ++;
  788. if (*prefix != 0)
  789. {
  790. length = str_common(name_ptr, index->name);
  791. if (length < min_length)
  792. min_length = length;
  793. }
  794. #ifdef FINSH_USING_DESCRIPTION
  795. rt_kprintf("%-16s -- %s\n", index->name, index->desc);
  796. #else
  797. rt_kprintf("%s\n", index->name);
  798. #endif
  799. }
  800. }
  801. }
  802. /* checks in dynamic system variable */
  803. sysvar_item = global_sysvar_list;
  804. while (sysvar_item != NULL)
  805. {
  806. if (str_is_prefix(prefix, sysvar_item->sysvar.name) == 0)
  807. {
  808. if (var_cnt == 0)
  809. {
  810. rt_kprintf("--variable:\n");
  811. if (*prefix != 0 && name_ptr == NULL)
  812. {
  813. /* set name_ptr */
  814. name_ptr = sysvar_item->sysvar.name;
  815. /* set initial length */
  816. min_length = strlen(name_ptr);
  817. }
  818. }
  819. var_cnt ++;
  820. if (*prefix != 0)
  821. {
  822. length = str_common(name_ptr, sysvar_item->sysvar.name);
  823. if (length < min_length)
  824. min_length = length;
  825. }
  826. rt_kprintf("[v] %s\n", sysvar_item->sysvar.name);
  827. }
  828. sysvar_item = sysvar_item->next;
  829. }
  830. /* only one matched */
  831. if (name_ptr != NULL)
  832. {
  833. rt_strncpy(prefix, name_ptr, min_length);
  834. }
  835. }
  836. #endif
  837. #if defined(FINSH_USING_SYMTAB) && !defined(FINSH_USING_MSH_ONLY)
  838. static int dummy = 0;
  839. FINSH_VAR_EXPORT(dummy, finsh_type_int, dummy variable for finsh)
  840. #endif