shell.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. * File : shell.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 the first verion for FinSH
  13. * 2006-05-08 Bernard change finsh thread stack to 2048
  14. * 2006-06-03 Bernard add support for skyeye
  15. * 2006-09-24 Bernard remove the code related with hardware
  16. */
  17. #include <rtthread.h>
  18. #include <rthw.h>
  19. #include "finsh.h"
  20. #if defined(__CC_ARM) /* ARMCC compiler */
  21. #ifdef FINSH_USING_SYMTAB
  22. extern int FSymTab$$Base;
  23. extern int FSymTab$$Limit;
  24. extern int VSymTab$$Base;
  25. extern int VSymTab$$Limit;
  26. #endif
  27. #elif defined(__ICCARM__) /* for IAR compiler */
  28. #ifdef FINSH_USING_SYMTAB
  29. #pragma section="FSymTab"
  30. #pragma section="VSymTab"
  31. #endif
  32. #endif
  33. /* finsh thread */
  34. struct rt_thread finsh_thread;
  35. char finsh_thread_stack[2048];
  36. struct rt_semaphore uart_sem;
  37. #ifdef RT_USING_DEVICE
  38. rt_device_t finsh_device;
  39. #endif
  40. #if !defined (RT_USING_NEWLIB) && !defined (RT_USING_MINILIBC)
  41. void *memccpy(void *dst, const void *src, int c, size_t count)
  42. {
  43. char *a = dst;
  44. const char *b = src;
  45. while (count--)
  46. {
  47. *a++ = *b;
  48. if (*b==c)
  49. {
  50. return (void *)a;
  51. }
  52. b++;
  53. }
  54. return 0;
  55. }
  56. int strcmp (const char *s1, const char *s2)
  57. {
  58. while (*s1 && *s1 == *s2) s1++, s2++;
  59. return (*s1 - *s2);
  60. }
  61. #ifdef RT_USING_HEAP
  62. char *strdup(const char *s)
  63. {
  64. size_t len = strlen(s) + 1;
  65. char *tmp = (char *)rt_malloc(len);
  66. if(!tmp) return NULL;
  67. rt_memcpy(tmp, s, len);
  68. return tmp;
  69. }
  70. #endif
  71. int isalpha( int ch )
  72. {
  73. return (unsigned int)((ch | 0x20) - 'a') < 26u;
  74. }
  75. int atoi(const char* s)
  76. {
  77. long int v=0;
  78. int sign=1;
  79. while ( *s == ' ' || (unsigned int)(*s - 9) < 5u) s++;
  80. switch (*s)
  81. {
  82. case '-': sign=-1;
  83. case '+': ++s;
  84. }
  85. while ((unsigned int) (*s - '0') < 10u)
  86. {
  87. v=v*10+*s-'0'; ++s;
  88. }
  89. return sign==-1?-v:v;
  90. }
  91. int isprint(unsigned char ch)
  92. {
  93. return (unsigned int)(ch - ' ') < 127u - ' ';
  94. }
  95. #endif
  96. #ifdef RT_USING_DEVICE
  97. static rt_err_t finsh_rx_ind(rt_device_t dev, rt_size_t size)
  98. {
  99. /* release semaphore to let finsh thread rx data */
  100. rt_sem_release(&uart_sem);
  101. return RT_EOK;
  102. }
  103. void finsh_set_device(char* device_name)
  104. {
  105. rt_device_t dev = RT_NULL;
  106. dev = rt_device_find(device_name);
  107. if (dev != RT_NULL && rt_device_open(dev, RT_DEVICE_OFLAG_RDWR) == RT_EOK)
  108. {
  109. if (finsh_device != RT_NULL)
  110. {
  111. /* close old finsh device */
  112. rt_device_close(finsh_device);
  113. }
  114. finsh_device = dev;
  115. rt_device_set_rx_indicate(dev, finsh_rx_ind);
  116. }
  117. else
  118. {
  119. rt_kprintf("finsh: can not find device:%s\n", device_name);
  120. }
  121. }
  122. #else
  123. void finsh_notify()
  124. {
  125. rt_sem_release(&uart_sem);
  126. }
  127. #endif
  128. void finsh_thread_entry(void* parameter)
  129. {
  130. struct finsh_parser parser;
  131. char line[256];
  132. int pos ;
  133. finsh_init(&parser);
  134. while (1)
  135. {
  136. rt_kprintf("finsh>>");
  137. memset(line, 0, sizeof(line));
  138. pos = 0;
  139. while (1)
  140. {
  141. if (rt_sem_take(&uart_sem, -1) == RT_EOK)
  142. {
  143. /* read one character from serial */
  144. char ch;
  145. #ifndef RT_USING_DEVICE
  146. ch = rt_serial_getc();
  147. if (ch != 0)
  148. #else
  149. rt_err_t rx_result;
  150. rx_result = rt_device_read(finsh_device, 0, &ch, 1);
  151. if (ch != 0 && rx_result == 1)
  152. #endif
  153. {
  154. line[pos] = ch;
  155. rt_kprintf("%c", line[pos]);
  156. /* if it's the end of line, break */
  157. if (line[pos] == 0xd || line[pos] == 0xa)
  158. {
  159. /* change to ';' and break */
  160. line[pos] = ';';
  161. break;
  162. }
  163. pos ++;
  164. }
  165. }
  166. }
  167. rt_kprintf("\n");
  168. finsh_parser_run(&parser, (unsigned char*)&line[0]);
  169. /* compile node root */
  170. if (finsh_errno() == 0)
  171. {
  172. finsh_compiler_run(parser.root);
  173. }
  174. else
  175. {
  176. rt_kprintf("%s\n", finsh_error_string(finsh_errno()));
  177. }
  178. /* run virtual machine */
  179. if (finsh_errno() == 0)
  180. {
  181. finsh_vm_run();
  182. if (isprint((unsigned char)finsh_stack_bottom()))
  183. {
  184. rt_kprintf("\t'%c', %d, 0x%08x\n",
  185. (unsigned char)finsh_stack_bottom(),
  186. (unsigned int)finsh_stack_bottom(),
  187. (unsigned int)finsh_stack_bottom());
  188. }
  189. else
  190. {
  191. rt_kprintf("\t%d, 0x%04x\n",
  192. (unsigned int)finsh_stack_bottom(),
  193. (unsigned int)finsh_stack_bottom());
  194. }
  195. }
  196. finsh_flush(&parser);
  197. }
  198. }
  199. void finsh_system_function_init(void* begin, void* end)
  200. {
  201. _syscall_table_begin = (struct finsh_syscall*) begin;
  202. _syscall_table_end = (struct finsh_syscall*) end;
  203. }
  204. void finsh_system_var_init(void* begin, void* end)
  205. {
  206. _sysvar_table_begin = (struct finsh_sysvar*) begin;
  207. _sysvar_table_end = (struct finsh_sysvar*) end;
  208. }
  209. /* init finsh */
  210. void finsh_system_init()
  211. {
  212. rt_sem_init(&uart_sem, "uart", 0, 0);
  213. #ifdef FINSH_USING_SYMTAB
  214. #ifdef __CC_ARM /* ARM C Compiler */
  215. finsh_system_function_init(&FSymTab$$Base, &FSymTab$$Limit);
  216. finsh_system_var_init(&VSymTab$$Base, &VSymTab$$Limit);
  217. #elif defined (__ICCARM__) /* for IAR Compiler */
  218. finsh_system_function_init(__section_begin("FSymTab"),
  219. __section_end("FSymTab"));
  220. finsh_system_var_init(__section_begin("VSymTab"),
  221. __section_end("VSymTab"));
  222. #elif defined (__GNUC__) /* GNU GCC Compiler */
  223. #endif
  224. #endif
  225. rt_thread_init(&finsh_thread,
  226. "tshell",
  227. finsh_thread_entry, RT_NULL,
  228. &finsh_thread_stack[0], sizeof(finsh_thread_stack),
  229. 20, 100);
  230. rt_thread_startup(&finsh_thread);
  231. }