finsh.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. /*
  2. * File : finsh.h
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2010, 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://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2010-03-22 Bernard first version
  13. */
  14. #ifndef __FINSH_H__
  15. #define __FINSH_H__
  16. #include <rtthread.h>
  17. #if defined(_MSC_VER)
  18. #pragma section("FSymTab$f",read)
  19. #pragma section("VSymTab",read)
  20. #endif
  21. /* -- the beginning of option -- */
  22. #define FINSH_NAME_MAX 16 /* max length of identifier */
  23. #define FINSH_NODE_MAX 16 /* max number of node */
  24. #define FINSH_HEAP_MAX 128 /* max length of heap */
  25. #define FINSH_STRING_MAX 128 /* max length of string */
  26. #define FINSH_VARIABLE_MAX 8 /* max number of variable */
  27. #define FINSH_STACK_MAX 64 /* max stack size */
  28. #define FINSH_TEXT_MAX 128 /* max text segment size */
  29. #define HEAP_ALIGNMENT 4 /* heap alignment */
  30. #define FINSH_GET16(x) (*(x)) | (*((x)+1) << 8)
  31. #define FINSH_GET32(x) (rt_uint32_t)(*(x)) | ((rt_uint32_t)*((x)+1) << 8) | \
  32. ((rt_uint32_t)*((x)+2) << 16) | ((rt_uint32_t)*((x)+3) << 24)
  33. #define FINSH_SET16(x, v) \
  34. do \
  35. { \
  36. *(x) = (v) & 0x00ff; \
  37. (*((x)+1)) = (v) >> 8; \
  38. } while ( 0 )
  39. #define FINSH_SET32(x, v) \
  40. do \
  41. { \
  42. *(x) = (rt_uint32_t)(v) & 0x000000ff; \
  43. (*((x)+1)) = ((rt_uint32_t)(v) >> 8) & 0x000000ff; \
  44. (*((x)+2)) = ((rt_uint32_t)(v) >> 16) & 0x000000ff; \
  45. (*((x)+3)) = ((rt_uint32_t)(v) >> 24); \
  46. } while ( 0 )
  47. /* -- the end of option -- */
  48. /* std header file */
  49. #include <stdio.h>
  50. #include <ctype.h>
  51. #include <stdlib.h>
  52. #include <stdint.h>
  53. #include <string.h>
  54. #define FINSH_VERSION_MAJOR 1
  55. #define FINSH_VERSION_MINOR 0
  56. /**
  57. * @addtogroup finsh
  58. */
  59. /*@{*/
  60. #define FINSH_ERROR_OK 0 /**< No error */
  61. #define FINSH_ERROR_INVALID_TOKEN 1 /**< Invalid token */
  62. #define FINSH_ERROR_EXPECT_TYPE 2 /**< Expect a type */
  63. #define FINSH_ERROR_UNKNOWN_TYPE 3 /**< Unknown type */
  64. #define FINSH_ERROR_VARIABLE_EXIST 4 /**< Variable exist */
  65. #define FINSH_ERROR_EXPECT_OPERATOR 5 /**< Expect a operator */
  66. #define FINSH_ERROR_MEMORY_FULL 6 /**< Memory full */
  67. #define FINSH_ERROR_UNKNOWN_OP 7 /**< Unknown operator */
  68. #define FINSH_ERROR_UNKNOWN_NODE 8 /**< Unknown node */
  69. #define FINSH_ERROR_EXPECT_CHAR 9 /**< Expect a character */
  70. #define FINSH_ERROR_UNEXPECT_END 10 /**< Unexpect end */
  71. #define FINSH_ERROR_UNKNOWN_TOKEN 11 /**< Unknown token */
  72. #define FINSH_ERROR_NO_FLOAT 12 /**< Float not supported */
  73. #define FINSH_ERROR_UNKNOWN_SYMBOL 13 /**< Unknown symbol */
  74. #define FINSH_ERROR_NULL_NODE 14 /**< Null node */
  75. /*@}*/
  76. typedef long (*syscall_func)();
  77. /* system call table */
  78. struct finsh_syscall
  79. {
  80. const char* name; /* the name of system call */
  81. #if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
  82. const char* desc; /* description of system call */
  83. #endif
  84. syscall_func func; /* the function address of system call */
  85. };
  86. /* system call item */
  87. struct finsh_syscall_item
  88. {
  89. struct finsh_syscall_item* next; /* next item */
  90. struct finsh_syscall syscall; /* syscall */
  91. };
  92. extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end;
  93. extern struct finsh_syscall_item *global_syscall_list;
  94. /* find out system call, which should be implemented in user program */
  95. struct finsh_syscall* finsh_syscall_lookup(const char* name);
  96. /* system variable table */
  97. struct finsh_sysvar
  98. {
  99. const char* name; /* the name of variable */
  100. #if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
  101. const char* desc; /* description of system variable */
  102. #endif
  103. uint8_t type; /* the type of variable */
  104. void* var ; /* the address of variable */
  105. };
  106. #if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
  107. struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call);
  108. struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call);
  109. #define FINSH_NEXT_SYSCALL(index) index=finsh_syscall_next(index)
  110. #define FINSH_NEXT_SYSVAR(index) index=finsh_sysvar_next(index)
  111. #else
  112. #define FINSH_NEXT_SYSCALL(index) index++
  113. #define FINSH_NEXT_SYSVAR(index) index++
  114. #endif
  115. /* system variable item */
  116. struct finsh_sysvar_item
  117. {
  118. struct finsh_sysvar_item *next; /* next item */
  119. struct finsh_sysvar sysvar; /* system variable */
  120. };
  121. extern struct finsh_sysvar *_sysvar_table_begin, *_sysvar_table_end;
  122. extern struct finsh_sysvar_item* global_sysvar_list;
  123. /* find out system variable, which should be implemented in user program */
  124. struct finsh_sysvar* finsh_sysvar_lookup(const char* name);
  125. #ifdef FINSH_USING_SYMTAB
  126. #ifdef __TI_COMPILER_VERSION__
  127. #define __TI_FINSH_EXPORT_FUNCTION(f) PRAGMA(DATA_SECTION(f,"FSymTab"))
  128. #define __TI_FINSH_EXPORT_VAR(v) PRAGMA(DATA_SECTION(v,"VSymTab"))
  129. #endif
  130. #ifdef FINSH_USING_DESCRIPTION
  131. #ifdef _MSC_VER
  132. #define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
  133. const char __fsym_##cmd##_name[] = #cmd; \
  134. const char __fsym_##cmd##_desc[] = #desc; \
  135. __declspec(allocate("FSymTab$f")) \
  136. const struct finsh_syscall __fsym_##cmd = \
  137. { \
  138. __fsym_##cmd##_name, \
  139. __fsym_##cmd##_desc, \
  140. (syscall_func)&name \
  141. };
  142. #pragma comment(linker, "/merge:FSymTab=mytext")
  143. #define FINSH_VAR_EXPORT(name, type, desc) \
  144. const char __vsym_##name##_name[] = #name; \
  145. const char __vsym_##name##_desc[] = #desc; \
  146. __declspec(allocate("VSymTab")) \
  147. const struct finsh_sysvar __vsym_##name = \
  148. { \
  149. __vsym_##name##_name, \
  150. __vsym_##name##_desc, \
  151. type, \
  152. (void*)&name \
  153. };
  154. #elif defined(__TI_COMPILER_VERSION__)
  155. #define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
  156. __TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
  157. const char __fsym_##cmd##_name[] = #cmd; \
  158. const char __fsym_##cmd##_desc[] = #desc; \
  159. const struct finsh_syscall __fsym_##cmd = \
  160. { \
  161. __fsym_##cmd##_name, \
  162. __fsym_##cmd##_desc, \
  163. (syscall_func)&name \
  164. };
  165. #define FINSH_VAR_EXPORT(name, type, desc) \
  166. __TI_FINSH_EXPORT_VAR(__vsym_##name); \
  167. const char __vsym_##name##_name[] = #name; \
  168. const char __vsym_##name##_desc[] = #desc; \
  169. const struct finsh_sysvar __vsym_##name = \
  170. { \
  171. __vsym_##name##_name, \
  172. __vsym_##name##_desc, \
  173. type, \
  174. (void*)&name \
  175. };
  176. #else
  177. #define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
  178. const char __fsym_##cmd##_name[] SECTION(".rodata.name") = #cmd; \
  179. const char __fsym_##cmd##_desc[] SECTION(".rodata.name") = #desc; \
  180. const struct finsh_syscall __fsym_##cmd SECTION("FSymTab")= \
  181. { \
  182. __fsym_##cmd##_name, \
  183. __fsym_##cmd##_desc, \
  184. (syscall_func)&name \
  185. };
  186. #define FINSH_VAR_EXPORT(name, type, desc) \
  187. const char __vsym_##name##_name[] SECTION(".rodata.name") = #name; \
  188. const char __vsym_##name##_desc[] SECTION(".rodata.name") = #desc; \
  189. const struct finsh_sysvar __vsym_##name SECTION("VSymTab")= \
  190. { \
  191. __vsym_##name##_name, \
  192. __vsym_##name##_desc, \
  193. type, \
  194. (void*)&name \
  195. };
  196. #endif
  197. #else
  198. #ifdef _MSC_VER
  199. #define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
  200. const char __fsym_##cmd##_name[] = #cmd; \
  201. __declspec(allocate("FSymTab$f")) \
  202. const struct finsh_syscall __fsym_##cmd = \
  203. { \
  204. __fsym_##cmd##_name, \
  205. (syscall_func)&name \
  206. };
  207. #pragma comment(linker, "/merge:FSymTab=mytext")
  208. #define FINSH_VAR_EXPORT(name, type, desc) \
  209. const char __vsym_##name##_name[] = #name; \
  210. __declspec(allocate("VSymTab")) const struct finsh_sysvar __vsym_##name = \
  211. { \
  212. __vsym_##name##_name, \
  213. type, \
  214. (void*)&name \
  215. };
  216. #elif defined(__TI_COMPILER_VERSION__)
  217. #define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
  218. __TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
  219. const char __fsym_##cmd##_name[] = #cmd; \
  220. const struct finsh_syscall __fsym_##cmd = \
  221. { \
  222. __fsym_##cmd##_name, \
  223. (syscall_func)&name \
  224. };
  225. #define FINSH_VAR_EXPORT(name, type, desc) \
  226. __TI_FINSH_EXPORT_VAR(__vsym_##name); \
  227. const char __vsym_##name##_name[] = #name; \
  228. const struct finsh_sysvar __vsym_##name = \
  229. { \
  230. __vsym_##name##_name, \
  231. type, \
  232. (void*)&name \
  233. };
  234. #else
  235. #define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
  236. const char __fsym_##cmd##_name[] = #cmd; \
  237. const struct finsh_syscall __fsym_##cmd SECTION("FSymTab")= \
  238. { \
  239. __fsym_##cmd##_name, \
  240. (syscall_func)&name \
  241. };
  242. #define FINSH_VAR_EXPORT(name, type, desc) \
  243. const char __vsym_##name##_name[] = #name; \
  244. const struct finsh_sysvar __vsym_##name SECTION("VSymTab")= \
  245. { \
  246. __vsym_##name##_name, \
  247. type, \
  248. (void*)&name \
  249. };
  250. #endif
  251. #endif /* end of FINSH_USING_DESCRIPTION */
  252. #endif /* end of FINSH_USING_SYMTAB */
  253. /**
  254. * @ingroup finsh
  255. *
  256. * This macro exports a system function to finsh shell.
  257. *
  258. * @param name the name of function.
  259. * @param desc the description of function, which will show in help.
  260. */
  261. #define FINSH_FUNCTION_EXPORT(name, desc) \
  262. FINSH_FUNCTION_EXPORT_CMD(name, name, desc)
  263. /**
  264. * @ingroup finsh
  265. *
  266. * This macro exports a system function with an alias name to finsh shell.
  267. *
  268. * @param name the name of function.
  269. * @param alias the alias name of function.
  270. * @param desc the description of function, which will show in help.
  271. */
  272. #define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc) \
  273. FINSH_FUNCTION_EXPORT_CMD(name, alias, desc)
  274. /**
  275. * @ingroup finsh
  276. *
  277. * This macro exports a command to module shell.
  278. *
  279. * @param command the name of command.
  280. * @param desc the description of command, which will show in help.
  281. */
  282. #ifdef FINSH_USING_MSH
  283. #define MSH_CMD_EXPORT(command, desc) \
  284. FINSH_FUNCTION_EXPORT_CMD(command, __cmd_##command, desc)
  285. #define MSH_CMD_EXPORT_ALIAS(command, alias, desc) \
  286. FINSH_FUNCTION_EXPORT_ALIAS(command, __cmd_##alias, desc)
  287. #else
  288. #define MSH_CMD_EXPORT(command, desc)
  289. #define MSH_CMD_EXPORT_ALIAS(command, alias, desc)
  290. #endif
  291. struct finsh_token
  292. {
  293. char eof;
  294. char replay;
  295. int position;
  296. uint8_t current_token;
  297. union {
  298. char char_value;
  299. int int_value;
  300. long long_value;
  301. } value;
  302. uint8_t string[FINSH_STRING_MAX];
  303. uint8_t* line;
  304. };
  305. #define FINSH_IDTYPE_VAR 0x01
  306. #define FINSH_IDTYPE_SYSVAR 0x02
  307. #define FINSH_IDTYPE_SYSCALL 0x04
  308. #define FINSH_IDTYPE_ADDRESS 0x08
  309. struct finsh_node
  310. {
  311. uint8_t node_type; /* node node_type */
  312. uint8_t data_type; /* node data node_type */
  313. uint8_t idtype; /* id node information */
  314. union { /* value node */
  315. char char_value;
  316. short short_value;
  317. int int_value;
  318. long long_value;
  319. void* ptr;
  320. } value;
  321. union
  322. {
  323. /* point to variable identifier or function identifier */
  324. struct finsh_var *var;
  325. struct finsh_sysvar *sysvar;
  326. struct finsh_syscall*syscall;
  327. }id;
  328. /* sibling and child node */
  329. struct finsh_node *sibling, *child;
  330. };
  331. struct finsh_parser
  332. {
  333. uint8_t* parser_string;
  334. struct finsh_token token;
  335. struct finsh_node* root;
  336. };
  337. /**
  338. * @ingroup finsh
  339. *
  340. * The basic data type in finsh shell
  341. */
  342. enum finsh_type {
  343. finsh_type_unknown = 0, /**< unknown data type */
  344. finsh_type_void, /**< void */
  345. finsh_type_voidp, /**< void pointer */
  346. finsh_type_char, /**< char */
  347. finsh_type_uchar, /**< unsigned char */
  348. finsh_type_charp, /**< char pointer */
  349. finsh_type_short, /**< short */
  350. finsh_type_ushort, /**< unsigned short */
  351. finsh_type_shortp, /**< short pointer */
  352. finsh_type_int, /**< int */
  353. finsh_type_uint, /**< unsigned int */
  354. finsh_type_intp, /**< int pointer */
  355. finsh_type_long, /**< long */
  356. finsh_type_ulong, /**< unsigned long */
  357. finsh_type_longp /**< long pointer */
  358. };
  359. /* init finsh environment */
  360. int finsh_init(struct finsh_parser* parser);
  361. /* flush finsh node, text segment */
  362. int finsh_flush(struct finsh_parser* parser);
  363. /* reset all of finsh */
  364. int finsh_reset(struct finsh_parser* parser);
  365. #ifdef RT_USING_DEVICE
  366. void finsh_set_device(const char* device_name);
  367. #endif
  368. /* run finsh parser to generate abstract synatx tree */
  369. void finsh_parser_run (struct finsh_parser* parser, const unsigned char* string);
  370. /* run compiler to compile abstract syntax tree */
  371. int finsh_compiler_run(struct finsh_node* node);
  372. /* run finsh virtual machine */
  373. void finsh_vm_run(void);
  374. /* get variable value */
  375. struct finsh_var* finsh_var_lookup(const char* name);
  376. /* get bottom value of stack */
  377. long finsh_stack_bottom(void);
  378. /* get error number of finsh */
  379. uint8_t finsh_errno(void);
  380. /* get error string */
  381. const char* finsh_error_string(uint8_t type);
  382. #ifdef RT_USING_HEAP
  383. /**
  384. * @ingroup finsh
  385. *
  386. * This function appends a system call to finsh runtime environment
  387. * @param name the name of system call
  388. * @param func the function pointer of system call
  389. */
  390. void finsh_syscall_append(const char* name, syscall_func func);
  391. /**
  392. * @ingroup finsh
  393. *
  394. * This function appends a system variable to finsh runtime environment
  395. * @param name the name of system variable
  396. * @param type the data type of system variable
  397. * @param addr the address of system variable
  398. */
  399. void finsh_sysvar_append(const char* name, uint8_t type, void* addr);
  400. #endif
  401. #endif