cmd.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. /*
  2. * File : cmd.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://openlab.rt-thread.com/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2006-04-30 Bernard first implementation
  13. * 2006-05-04 Bernard add list_thread,
  14. * list_sem,
  15. * list_timer
  16. * 2006-05-20 Bernard add list_mutex,
  17. * list_mailbox,
  18. * list_msgqueue,
  19. * list_event,
  20. * list_fevent,
  21. * list_mempool
  22. * 2006-06-03 Bernard display stack information in list_thread
  23. * 2006-08-10 Bernard change version to invoke rt_show_version
  24. * 2008-09-10 Bernard update the list function for finsh syscall
  25. * list and sysvar list
  26. * 2009-05-30 Bernard add list_device
  27. */
  28. #include <rtthread.h>
  29. #include "finsh.h"
  30. long hello()
  31. {
  32. rt_kprintf("Hello RT-Thread!\n");
  33. return 0;
  34. }
  35. FINSH_FUNCTION_EXPORT(hello, say hello world)
  36. extern void rt_show_version(void);
  37. long version()
  38. {
  39. rt_show_version();
  40. return 0;
  41. }
  42. FINSH_FUNCTION_EXPORT(version, show RT-Thread version information)
  43. #define rt_list_entry(node, type, member) \
  44. ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
  45. extern struct rt_object_information rt_object_container[];
  46. int list_thread()
  47. {
  48. struct rt_thread *thread;
  49. struct rt_list_node *list, *node;
  50. rt_uint8_t* ptr;
  51. list = &rt_object_container[RT_Object_Class_Thread].object_list;
  52. rt_kprintf(" thread pri status sp stack size max used left tick error\n");
  53. rt_kprintf("-------- ---- ------- ---------- ---------- ---------- ---------- ---\n");
  54. for (node = list->next; node != list; node = node->next)
  55. {
  56. thread = rt_list_entry(node, struct rt_thread, list);
  57. rt_kprintf("%-8s 0x%02x", thread->name, thread->current_priority);
  58. if (thread->stat == RT_THREAD_READY) rt_kprintf(" ready ");
  59. else if (thread->stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
  60. else if (thread->stat == RT_THREAD_INIT) rt_kprintf(" init ");
  61. ptr = (rt_uint8_t*)thread->stack_addr;
  62. while (*ptr == '#')ptr ++;
  63. rt_kprintf(" 0x%08x 0x%08x 0x%08x 0x%08x %03d\n",
  64. thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
  65. thread->stack_size,
  66. thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t)thread->stack_addr),
  67. thread->remaining_tick,
  68. thread->error);
  69. }
  70. return 0;
  71. }
  72. FINSH_FUNCTION_EXPORT(list_thread, list thread)
  73. static void show_wait_queue(struct rt_list_node* list)
  74. {
  75. struct rt_thread *thread;
  76. struct rt_list_node *node;
  77. for (node = list->next; node != list; node = node->next)
  78. {
  79. thread = rt_list_entry(node, struct rt_thread, tlist);
  80. rt_kprintf("%s", thread->name);
  81. if (node->next != list) rt_kprintf("/");
  82. }
  83. }
  84. #ifdef RT_USING_SEMAPHORE
  85. int list_sem()
  86. {
  87. struct rt_semaphore *sem;
  88. struct rt_list_node *list, *node;
  89. list = &rt_object_container[RT_Object_Class_Semaphore].object_list;
  90. rt_kprintf("semaphore v suspend thread\n");
  91. rt_kprintf("-------- --- --------------\n");
  92. for (node = list->next; node != list; node = node->next)
  93. {
  94. sem = (struct rt_semaphore*)(rt_list_entry(node, struct rt_object, list));
  95. if (sem->parent.suspend_thread_count != 0)
  96. {
  97. rt_kprintf("%-8s %03d %d:", sem->parent.parent.name, sem->value, sem->parent.suspend_thread_count);
  98. show_wait_queue(&(sem->parent.suspend_thread));
  99. rt_kprintf("\n");
  100. }
  101. else
  102. {
  103. rt_kprintf("%-8s %03d %d\n", sem->parent.parent.name, sem->value, sem->parent.suspend_thread_count);
  104. }
  105. }
  106. return 0;
  107. }
  108. FINSH_FUNCTION_EXPORT(list_sem, list semaphone in system)
  109. #endif
  110. #ifdef RT_USING_EVENT
  111. int list_event()
  112. {
  113. struct rt_event *e;
  114. struct rt_list_node *list, *node;
  115. list = &rt_object_container[RT_Object_Class_Event].object_list;
  116. rt_kprintf("event set suspend thread\n");
  117. rt_kprintf("-------- ---------- --------------\n");
  118. for (node = list->next; node != list; node = node->next)
  119. {
  120. e = (struct rt_event*)(rt_list_entry(node, struct rt_object, list));
  121. rt_kprintf("%-8s 0x%08x %03d\n", e->parent.parent.name, e->set, e->parent.suspend_thread_count);
  122. }
  123. return 0;
  124. }
  125. FINSH_FUNCTION_EXPORT(list_event, list event in system)
  126. #endif
  127. #ifdef RT_USING_MUTEX
  128. int list_mutex()
  129. {
  130. struct rt_mutex *m;
  131. struct rt_list_node *list, *node;
  132. list = &rt_object_container[RT_Object_Class_Mutex].object_list;
  133. rt_kprintf("mutex owner hold suspend thread\n");
  134. rt_kprintf("-------- -------- ---- --------------\n");
  135. for (node = list->next; node != list; node = node->next)
  136. {
  137. m = (struct rt_mutex*)(rt_list_entry(node, struct rt_object, list));
  138. rt_kprintf("%-8s %-8s %04d %d\n", m->parent.parent.name, m->owner->name, m->hold, m->parent.suspend_thread_count);
  139. }
  140. return 0;
  141. }
  142. FINSH_FUNCTION_EXPORT(list_mutex, list mutex in system)
  143. #endif
  144. #ifdef RT_USING_MAILBOX
  145. int list_mailbox()
  146. {
  147. struct rt_mailbox *m;
  148. struct rt_list_node *list, *node;
  149. list = &rt_object_container[RT_Object_Class_MailBox].object_list;
  150. rt_kprintf("mailbox entry size suspend thread\n");
  151. rt_kprintf("-------- ---- ---- --------------\n");
  152. for (node = list->next; node != list; node = node->next)
  153. {
  154. m = (struct rt_mailbox*)(rt_list_entry(node, struct rt_object, list));
  155. if (m->parent.suspend_thread_count != 0)
  156. {
  157. rt_kprintf("%-8s %04d %04d %d:", m->parent.parent.name, m->entry, m->size, m->parent.suspend_thread_count);
  158. show_wait_queue(&(m->parent.suspend_thread));
  159. rt_kprintf("\n");
  160. }
  161. else
  162. {
  163. rt_kprintf("%-8s %04d %04d %d\n", m->parent.parent.name, m->entry, m->size, m->parent.suspend_thread_count);
  164. }
  165. }
  166. return 0;
  167. }
  168. FINSH_FUNCTION_EXPORT(list_mailbox, list mail box in system)
  169. #endif
  170. #ifdef RT_USING_MESSAGEQUEUE
  171. int list_msgqueue()
  172. {
  173. struct rt_messagequeue *m;
  174. struct rt_list_node *list, *node;
  175. list = &rt_object_container[RT_Object_Class_MessageQueue].object_list;
  176. rt_kprintf("msgqueue entry suspend thread\n");
  177. rt_kprintf("-------- ---- --------------\n");
  178. for (node = list->next; node != list; node = node->next)
  179. {
  180. m = (struct rt_messagequeue*)(rt_list_entry(node, struct rt_object, list));
  181. rt_kprintf("%-8s %04d %d\n", m->parent.parent.name, m->entry, m->parent.suspend_thread_count);
  182. }
  183. return 0;
  184. }
  185. FINSH_FUNCTION_EXPORT(list_msgqueue, list message queue in system)
  186. #endif
  187. #ifdef RT_USING_MEMPOOL
  188. int list_mempool()
  189. {
  190. struct rt_mempool *mp;
  191. struct rt_list_node *list, *node;
  192. list = &rt_object_container[RT_Object_Class_MemPool].object_list;
  193. rt_kprintf("mempool block total free suspend thread\n");
  194. rt_kprintf("-------- ---- ---- ---- --------------\n");
  195. for (node = list->next; node != list; node = node->next)
  196. {
  197. mp = (struct rt_mempool*)rt_list_entry(node, struct rt_object, list);
  198. rt_kprintf("%-8s %04d %04d %04d %d\n", mp->parent.name,
  199. mp->block_size, mp->block_total_count, mp->block_free_count,
  200. mp->suspend_thread_count);
  201. }
  202. return 0;
  203. }
  204. FINSH_FUNCTION_EXPORT(list_mempool, list memory pool in system)
  205. #endif
  206. int list_timer()
  207. {
  208. struct rt_timer *timer;
  209. struct rt_list_node *list, *node;
  210. list = &rt_object_container[RT_Object_Class_Timer].object_list;
  211. rt_kprintf("timer periodic timeout flag\n");
  212. rt_kprintf("-------- ---------- ---------- -----------\n");
  213. for (node = list->next; node != list; node = node->next)
  214. {
  215. timer = (struct rt_timer*)(rt_list_entry(node, struct rt_object, list));
  216. rt_kprintf("%-8s 0x%08x 0x%08x ", timer->parent.name, timer->init_tick, timer->timeout_tick);
  217. if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED) rt_kprintf("activated\n");
  218. else rt_kprintf("deactivated\n");
  219. }
  220. rt_kprintf("current tick:0x%08x\n", rt_tick_get());
  221. return 0;
  222. }
  223. FINSH_FUNCTION_EXPORT(list_timer, list timer in system)
  224. #ifdef RT_USING_DEVICE
  225. int list_device()
  226. {
  227. struct rt_device *device;
  228. struct rt_list_node *list, *node;
  229. const char *device_type_str[] =
  230. {
  231. "Character Device",
  232. "Block Device",
  233. "Network Interface",
  234. "MTD Device",
  235. "CAN",
  236. "RTC",
  237. "Unknown"
  238. };
  239. list = &rt_object_container[RT_Object_Class_Device].object_list;
  240. rt_kprintf("device type \n");
  241. rt_kprintf("-------- ---------- \n");
  242. for (node = list->next; node != list; node = node->next)
  243. {
  244. device = (struct rt_device*)(rt_list_entry(node, struct rt_object, list));
  245. rt_kprintf("%-8s %-8s \n", device->parent.name, device_type_str[device->type]);
  246. }
  247. return 0;
  248. }
  249. FINSH_FUNCTION_EXPORT(list_device, list device in system)
  250. #endif
  251. int list()
  252. {
  253. struct finsh_syscall_item* syscall_item;
  254. struct finsh_sysvar_item* sysvar_item;
  255. rt_kprintf("--Function List:\n");
  256. {
  257. struct finsh_syscall* index;
  258. for (index = _syscall_table_begin; index < _syscall_table_end; index ++)
  259. {
  260. #ifdef FINSH_USING_DESCRIPTION
  261. rt_kprintf("%-16s -- %s\n", index->name, index->desc);
  262. #else
  263. rt_kprintf("%s\n", index->name);
  264. #endif
  265. }
  266. }
  267. /* list syscall list */
  268. syscall_item = global_syscall_list;
  269. while (syscall_item != NULL)
  270. {
  271. rt_kprintf("[l] %s\n", syscall_item->syscall.name);
  272. syscall_item = syscall_item->next;
  273. }
  274. rt_kprintf("--Variable List:\n");
  275. {
  276. struct finsh_sysvar* index;
  277. for (index = _sysvar_table_begin; index < _sysvar_table_end; index ++)
  278. {
  279. #ifdef FINSH_USING_DESCRIPTION
  280. rt_kprintf("%-16s -- %s\n", index->name, index->desc);
  281. #else
  282. rt_kprintf("%s\n", index->name);
  283. #endif
  284. }
  285. }
  286. sysvar_item = global_sysvar_list;
  287. while (sysvar_item != NULL)
  288. {
  289. rt_kprintf("[l] %s\n", sysvar_item->sysvar.name);
  290. sysvar_item = sysvar_item->next;
  291. }
  292. return 0;
  293. }
  294. FINSH_FUNCTION_EXPORT(list, list all symbol in system)
  295. static int str_is_prefix(const char* prefix, const char* str)
  296. {
  297. while ((*prefix) && (*prefix == *str))
  298. {
  299. prefix ++;
  300. str ++;
  301. }
  302. if (*prefix == 0) return 0;
  303. return -1;
  304. }
  305. void list_prefix(char* prefix)
  306. {
  307. struct finsh_syscall_item* syscall_item;
  308. struct finsh_sysvar_item* sysvar_item;
  309. rt_uint16_t func_cnt, var_cnt;
  310. const char* name_ptr;
  311. func_cnt = 0;
  312. var_cnt = 0;
  313. {
  314. struct finsh_syscall* index;
  315. for (index = _syscall_table_begin; index < _syscall_table_end; index ++)
  316. {
  317. if (str_is_prefix(prefix, index->name) == 0)
  318. {
  319. if (func_cnt == 0)
  320. rt_kprintf("--function:\n");
  321. func_cnt ++;
  322. /* set name_ptr */
  323. name_ptr = index->name;
  324. #ifdef FINSH_USING_DESCRIPTION
  325. rt_kprintf("%-16s -- %s\n", index->name, index->desc);
  326. #else
  327. rt_kprintf("%s\n", index->name);
  328. #endif
  329. }
  330. }
  331. }
  332. /* list syscall list */
  333. syscall_item = global_syscall_list;
  334. while (syscall_item != NULL)
  335. {
  336. if (str_is_prefix(prefix, syscall_item->syscall.name) == 0)
  337. {
  338. if (func_cnt == 0)
  339. rt_kprintf("--function:\n");
  340. func_cnt ++;
  341. /* set name_ptr */
  342. name_ptr = syscall_item->syscall.name;
  343. rt_kprintf("[l] %s\n", syscall_item->syscall.name);
  344. }
  345. syscall_item = syscall_item->next;
  346. }
  347. {
  348. struct finsh_sysvar* index;
  349. for (index = _sysvar_table_begin; index < _sysvar_table_end; index ++)
  350. {
  351. if (str_is_prefix(prefix, index->name) == 0)
  352. {
  353. if (var_cnt == 0)
  354. rt_kprintf("--variable:\n");
  355. var_cnt ++;
  356. /* set name ptr */
  357. name_ptr = index->name;
  358. #ifdef FINSH_USING_DESCRIPTION
  359. rt_kprintf("%-16s -- %s\n", index->name, index->desc);
  360. #else
  361. rt_kprintf("%s\n", index->name);
  362. #endif
  363. }
  364. }
  365. }
  366. sysvar_item = global_sysvar_list;
  367. while (sysvar_item != NULL)
  368. {
  369. if (str_is_prefix(prefix, sysvar_item->sysvar.name) == 0)
  370. {
  371. if (var_cnt == 0)
  372. rt_kprintf("--variable:\n");
  373. var_cnt ++;
  374. /* set name ptr */
  375. name_ptr = sysvar_item->sysvar.name;
  376. rt_kprintf("[l] %s\n", sysvar_item->sysvar.name);
  377. }
  378. sysvar_item = sysvar_item->next;
  379. }
  380. /* only one matched */
  381. if ((func_cnt + var_cnt) == 1)
  382. {
  383. rt_strncpy(prefix, name_ptr, strlen(name_ptr));
  384. }
  385. }
  386. #ifdef FINSH_USING_SYMTAB
  387. static int dummy = 0;
  388. FINSH_VAR_EXPORT(dummy, finsh_type_int, dummy variable for finsh)
  389. #endif