finsh.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. #ifndef __FINSH_H__
  2. #define __FINSH_H__
  3. #include <rtthread.h>
  4. /* -- the beginning of option -- */
  5. #define FINSH_NAME_MAX 16 /* max length of identifier */
  6. #define FINSH_NODE_MAX 16 /* max number of node */
  7. #define FINSH_HEAP_MAX 128 /* max length of heap */
  8. #define FINSH_STRING_MAX 128 /* max length of string */
  9. #define FINSH_VARIABLE_MAX 8 /* max number of variable */
  10. #define FINSH_STACK_MAX 128 /* max stack size */
  11. #define FINSH_TEXT_MAX 128 /* max text segment size */
  12. #define HEAP_ALIGNMENT 4 /* heap alignment */
  13. #define FINSH_GET16(x) (*(x)) | (*((x)+1) << 8)
  14. #define FINSH_GET32(x) (*(x)) | (*((x)+1) << 8) | (*((x)+2) << 16) | (*((x)+3) << 24)
  15. #define FINSH_SET16(x, v) \
  16. do \
  17. { \
  18. *(x) = (v) & 0x00ff; \
  19. (*((x)+1)) = (v) >> 8; \
  20. } while ( 0 )
  21. #define FINSH_SET32(x, v) \
  22. do \
  23. { \
  24. *(x) = (v) & 0x000000ff; \
  25. (*((x)+1)) = ((v) >> 8) & 0x000000ff; \
  26. (*((x)+2)) = ((v) >> 16) & 0x000000ff; \
  27. (*((x)+3)) = ((v) >> 24); \
  28. } while ( 0 )
  29. /* -- the end of option -- */
  30. /**
  31. * @defgroup finsh finsh shell
  32. *
  33. * finsh is a C-expression shell which gives user access to some symbols present in RT-Thread.
  34. */
  35. /*@{*/
  36. #if defined(RT_USING_NEWLIB) || defined (RT_USING_MINILIBC)
  37. #include <string.h>
  38. #else
  39. typedef unsigned char u_char;
  40. typedef unsigned short u_short;
  41. typedef unsigned long u_long;
  42. #if !defined(__CC_ARM) && !defined(__ICCARM__)
  43. typedef unsigned int size_t;
  44. #ifndef NULL
  45. #define NULL RT_NULL
  46. #endif
  47. #define memset rt_memset
  48. #define strlen rt_strlen
  49. #define strncpy rt_strncpy
  50. #define strncmp rt_strncmp
  51. #else
  52. #include <string.h>
  53. #endif
  54. int strcmp (const char *s1, const char *s2);
  55. char *strdup(const char *s);
  56. int isalpha( int ch );
  57. int atoi(const char* s);
  58. #endif
  59. #define FINSH_VERSION_MAJOR 0
  60. #define FINSH_VERSION_MINOR 5
  61. /* error code */
  62. #define FINSH_ERROR_OK 0 /** No error */
  63. #define FINSH_ERROR_INVALID_TOKEN 1 /** Invalid token */
  64. #define FINSH_ERROR_EXPECT_TYPE 2 /** Expect a type */
  65. #define FINSH_ERROR_UNKNOWN_TYPE 3 /** Unknown type */
  66. #define FINSH_ERROR_VARIABLE_EXIST 4 /** Variable exist */
  67. #define FINSH_ERROR_EXPECT_OPERATOR 5 /** Expect a operater */
  68. #define FINSH_ERROR_MEMORY_FULL 6 /** Memory full */
  69. #define FINSH_ERROR_UNKNOWN_OP 7 /** Unknown operator */
  70. #define FINSH_ERROR_UNKNOWN_NODE 8 /** Unknown node */
  71. #define FINSH_ERROR_EXPECT_CHAR 9 /** Expect a character */
  72. #define FINSH_ERROR_UNEXPECT_END 10 /** Unexpect end */
  73. #define FINSH_ERROR_UNKNOWN_TOKEN 11 /** Unknown token */
  74. #define FINSH_ERROR_NO_FLOAT 12 /** Float not supported */
  75. #define FINSH_ERROR_UNKNOWN_SYMBOL 13 /** Unknown symbol */
  76. #define FINSH_ERROR_NULL_NODE 14 /** Null node */
  77. typedef long (*syscall_func)();
  78. /* system call table */
  79. struct finsh_syscall
  80. {
  81. const char* name; /* the name of system call */
  82. #if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
  83. const char* desc; /* description of system call */
  84. #endif
  85. syscall_func func; /* the function address of system call */
  86. };
  87. /* system call item */
  88. struct finsh_syscall_item
  89. {
  90. struct finsh_syscall_item* next; /* next item */
  91. struct finsh_syscall syscall; /* syscall */
  92. };
  93. extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end;
  94. extern struct finsh_syscall_item *global_syscall_list;
  95. /* find out system call, which should be implemented in user program */
  96. struct finsh_syscall* finsh_syscall_lookup(const char* name);
  97. /* system variable table */
  98. struct finsh_sysvar
  99. {
  100. const char* name; /* the name of variable */
  101. #if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
  102. const char* desc; /* description of system variable */
  103. #endif
  104. u_char type; /* the type of variable */
  105. void* var ; /* the address of variable */
  106. };
  107. /* system variable item */
  108. struct finsh_sysvar_item
  109. {
  110. struct finsh_sysvar_item *next; /* next item */
  111. struct finsh_sysvar sysvar; /* system variable */
  112. };
  113. extern struct finsh_sysvar *_sysvar_table_begin, *_sysvar_table_end;
  114. extern struct finsh_sysvar_item* global_sysvar_list;
  115. /* find out system variable, which should be implemented in user program */
  116. struct finsh_sysvar* finsh_sysvar_lookup(const char* name);
  117. #ifdef FINSH_USING_SYMTAB
  118. #ifdef FINSH_USING_DESCRIPTION
  119. #define FINSH_FUNCTION_EXPORT(name, desc) \
  120. const char __fsym_##name##_name[] = #name; \
  121. const char __fsym_##name##_desc[] = #desc; \
  122. const struct finsh_syscall __fsym_##name SECTION("FSymTab")= \
  123. { \
  124. __fsym_##name##_name, \
  125. __fsym_##name##_desc, \
  126. (syscall_func)&name \
  127. };
  128. #define FINSH_VAR_EXPORT(name, type, desc) \
  129. const char __vsym_##name##_name[] = #name; \
  130. const char __vsym_##name##_desc[] = #desc; \
  131. const struct finsh_sysvar __vsym_##name SECTION("VSymTab")= \
  132. { \
  133. __vsym_##name##_name, \
  134. __vsym_##name##_desc, \
  135. type, \
  136. (void*)&name \
  137. };
  138. #else
  139. #define FINSH_FUNCTION_EXPORT(name, desc) \
  140. const char __fsym_##name##_name[] = #name; \
  141. const struct finsh_syscall __fsym_##name SECTION("FSymTab")= \
  142. { \
  143. __fsym_##name##_name, \
  144. (syscall_func)&name \
  145. };
  146. #define FINSH_VAR_EXPORT(name, type, desc) \
  147. const char __vsym_##name##_name[] = #name; \
  148. const struct finsh_sysvar __vsym_##name SECTION("VSymTab")= \
  149. { \
  150. __vsym_##name##_name, \
  151. type, \
  152. (void*)&name \
  153. };
  154. #endif
  155. #else
  156. #define FINSH_FUNCTION_EXPORT(name, desc)
  157. #define FINSH_VAR_EXPORT(name, type, desc)
  158. #endif
  159. struct finsh_token
  160. {
  161. char eof;
  162. char replay;
  163. int position;
  164. u_char current_token;
  165. union {
  166. char char_value;
  167. int int_value;
  168. long long_value;
  169. } value;
  170. u_char string[128];
  171. u_char* line;
  172. };
  173. #define FINSH_IDTYPE_VAR 0x01
  174. #define FINSH_IDTYPE_SYSVAR 0x02
  175. #define FINSH_IDTYPE_SYSCALL 0x04
  176. #define FINSH_IDTYPE_ADDRESS 0x08
  177. struct finsh_node
  178. {
  179. u_char node_type; /* node node_type */
  180. u_char data_type; /* node data node_type */
  181. u_char idtype; /* id node information */
  182. union { /* value node */
  183. char char_value;
  184. short short_value;
  185. int int_value;
  186. long long_value;
  187. void* ptr;
  188. } value;
  189. union
  190. {
  191. /* point to variable identifier or function identifier */
  192. struct finsh_var *var;
  193. struct finsh_sysvar *sysvar;
  194. struct finsh_syscall*syscall;
  195. }id;
  196. /* sibling and child node */
  197. struct finsh_node *sibling, *child;
  198. };
  199. struct finsh_parser
  200. {
  201. u_char* parser_string;
  202. struct finsh_token token;
  203. struct finsh_node* root;
  204. };
  205. /**
  206. * finsh basic data type
  207. */
  208. enum finsh_type {
  209. finsh_type_unknown = 0,
  210. finsh_type_void, /** void */
  211. finsh_type_voidp, /** void pointer */
  212. finsh_type_char, /** char */
  213. finsh_type_uchar, /** unsigned char */
  214. finsh_type_charp, /** char pointer */
  215. finsh_type_short, /** short */
  216. finsh_type_ushort, /** unsigned short */
  217. finsh_type_shortp, /** short pointer */
  218. finsh_type_int, /** int */
  219. finsh_type_uint, /** unsigned int */
  220. finsh_type_intp, /** int pointer */
  221. finsh_type_long, /** long */
  222. finsh_type_ulong, /** unsigned long */
  223. finsh_type_longp /** long pointer */
  224. };
  225. /* init finsh environment */
  226. int finsh_init(struct finsh_parser* parser);
  227. /* flush finsh node, text segment */
  228. int finsh_flush(struct finsh_parser* parser);
  229. /* reset all of finsh */
  230. int finsh_reset(struct finsh_parser* parser);
  231. #ifdef RT_USING_DEVICE
  232. /* set finsh device */
  233. void finsh_set_device(char* device_name);
  234. #endif
  235. /* run finsh parser to generate abstract synatx tree */
  236. void finsh_parser_run (struct finsh_parser* parser, const unsigned char* string);
  237. /* run compiler to compile abstract syntax tree */
  238. int finsh_compiler_run(struct finsh_node* node);
  239. /* run finsh virtual machine */
  240. void finsh_vm_run(void);
  241. /* get variable value */
  242. struct finsh_var* finsh_var_lookup(const char* name);
  243. /* get bottom value of stack */
  244. long finsh_stack_bottom(void);
  245. /* get error number of finsh */
  246. u_char finsh_errno(void);
  247. /* get error string */
  248. const char* finsh_error_string(u_char type);
  249. #ifdef RT_USING_HEAP
  250. /**
  251. * append a system call to finsh runtime environment
  252. * @param name the name of system call
  253. * @param func the function pointer of system call
  254. */
  255. void finsh_syscall_append(const char* name, syscall_func func);
  256. /**
  257. * append a system variable to finsh runtime environment
  258. * @param name the name of system variable
  259. * @param type the data type of system variable
  260. * @param addr the address of system variable
  261. */
  262. void finsh_sysvar_append(const char* name, u_char type, void* addr);
  263. #endif
  264. /*@}*/
  265. #endif