finsh.h 8.6 KB

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