finsh.h 9.3 KB

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