lua_in_finsh.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /**
  2. * run lua interpreter from finsh
  3. */
  4. #include "rtthread.h"
  5. #include "finsh.h"
  6. #include "shell.h"
  7. struct
  8. {
  9. struct rt_semaphore sem;
  10. rt_device_t device;
  11. } dev4lua;
  12. extern int lua_main(int argc, char **argv);
  13. rt_err_t lua_rx_ind(rt_device_t dev, rt_size_t size)
  14. {
  15. rt_sem_release(&dev4lua.sem);
  16. return RT_EOK;
  17. }
  18. struct para{
  19. int argc;
  20. char *argv[3];
  21. };
  22. void finsh_lua(struct para *parameters)
  23. {
  24. rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
  25. rt_sem_init(&(dev4lua.sem), "luasem", 0, 0);
  26. /* save old rx_indicate */
  27. rx_indicate = dev4lua.device->rx_indicate;
  28. /* set new rx_indicate */
  29. rt_device_set_rx_indicate(dev4lua.device, lua_rx_ind);
  30. {
  31. int argc = parameters->argc;
  32. char **argv = parameters->argv;
  33. /*
  34. rt_kprintf("argc =%d, argv[1] =%d\n", argc, argv[1]);
  35. while(1);
  36. */
  37. /* run lua interpreter */
  38. lua_main(argc, argv);
  39. }
  40. if (parameters->argc > 1)
  41. rt_free(parameters->argv[1]);
  42. rt_free(parameters);
  43. /* recover old rx_indicate */
  44. rt_device_set_rx_indicate(dev4lua.device, rx_indicate);
  45. }
  46. static void lua(void *parameters)
  47. {
  48. rt_thread_t lua_thread;
  49. const char* device_name = finsh_get_device();
  50. rt_device_t device = rt_device_find(device_name);
  51. if (device == RT_NULL)
  52. {
  53. rt_kprintf("%s not find\n", device_name);
  54. return;
  55. }
  56. dev4lua.device = device;
  57. /*prepare parameters*/
  58. struct para *lua_parameters = rt_malloc(sizeof(struct para));
  59. if ( lua_parameters == NULL ){
  60. rt_kprintf("malloc failed at file: %s,line: %d", __FILE__, __LINE__);
  61. return;
  62. }
  63. lua_parameters->argc = 2;
  64. char **arg = lua_parameters->argv;
  65. arg[0] = "lua";
  66. if (parameters != NULL){
  67. rt_size_t len = strnlen(parameters, 50);
  68. arg[1] = rt_malloc(len + 1);
  69. if (arg[1] == NULL ){
  70. rt_kprintf("malloc failed at file: %s,line: %d", __FILE__, __LINE__);
  71. return;
  72. }
  73. rt_memset(arg[1], 0, len+1);
  74. strncpy(arg[1], parameters, len);
  75. }else{
  76. arg[1] = NULL;
  77. }
  78. arg[2] = NULL;
  79. /* Run lua interpreter in separate thread */
  80. lua_thread = rt_thread_create("lua",
  81. (void (*)(void *))finsh_lua,
  82. (void*)lua_parameters,
  83. 10240,
  84. rt_thread_self()->current_priority + 1,
  85. 20);
  86. if (lua_thread != RT_NULL)
  87. {
  88. rt_thread_startup(lua_thread);
  89. }
  90. return;
  91. }
  92. FINSH_FUNCTION_EXPORT(lua, lua interpreter);
  93. static void lua_msh(int argc, char **argv)
  94. {
  95. rt_thread_t lua_thread;
  96. const char* device_name = finsh_get_device();
  97. rt_device_t device = rt_device_find(device_name);
  98. if (device == RT_NULL)
  99. {
  100. rt_kprintf("%s not find\n", device_name);
  101. return;
  102. }
  103. dev4lua.device = device;
  104. /*prepare parameters*/
  105. struct para *parameters = rt_malloc(sizeof(struct para));
  106. if ( parameters == NULL ){
  107. rt_kprintf("malloc failed at file: %s,line: %d", __FILE__, __LINE__);
  108. return;
  109. }
  110. //parameters->argc = 2;
  111. parameters->argc = argc;
  112. char **arg = parameters->argv;
  113. arg[0] = "lua";
  114. if (argc > 1){
  115. rt_size_t len = strnlen(argv[1], 50);
  116. arg[1] = rt_malloc(len + 1);
  117. if (arg[1] == NULL ){
  118. rt_kprintf("malloc failed at file: %s,line: %d", __FILE__, __LINE__);
  119. return;
  120. }
  121. rt_memset(arg[1], 0, len+1);
  122. strncpy(arg[1], argv[1], len);
  123. }else{
  124. arg[1] = NULL;
  125. }
  126. arg[2] = NULL;
  127. /* Run lua interpreter in separate thread */
  128. lua_thread = rt_thread_create("lua_msh",
  129. (void (*)(void *))(finsh_lua),
  130. (void*)parameters,
  131. 10240,
  132. rt_thread_self()->current_priority + 1,
  133. 20);
  134. if (lua_thread != RT_NULL)
  135. {
  136. rt_thread_startup(lua_thread);
  137. }
  138. return;
  139. }
  140. MSH_CMD_EXPORT(lua_msh, lua in msh);
  141. int readline4lua(const char *prompt, char *buffer, int buffer_size)
  142. {
  143. char ch;
  144. int line_position;
  145. start:
  146. /* show prompt */
  147. rt_kprintf(prompt);
  148. line_position = 0;
  149. memset(buffer, 0, buffer_size);
  150. while (1)
  151. {
  152. if (rt_sem_take(&dev4lua.sem, RT_WAITING_FOREVER) != RT_EOK)
  153. {
  154. return 0;
  155. }
  156. while (rt_device_read(dev4lua.device, 0, &ch, 1) == 1)
  157. {
  158. /* handle CR key */
  159. if (ch == '\r')
  160. {
  161. char next;
  162. if (rt_device_read(dev4lua.device, 0, &next, 1) == 1)
  163. ch = next;
  164. }
  165. /* backspace key */
  166. else if (ch == 0x7f || ch == 0x08)
  167. {
  168. if (line_position > 0)
  169. {
  170. rt_kprintf("%c %c", ch, ch);
  171. line_position--;
  172. }
  173. buffer[line_position] = 0;
  174. continue;
  175. }
  176. /* EOF(ctrl+d) */
  177. else if (ch == 0x04)
  178. {
  179. if (line_position == 0)
  180. /* No input which makes lua interpreter close */
  181. return 0;
  182. else
  183. continue;
  184. }
  185. /* end of line */
  186. if (ch == '\r' || ch == '\n')
  187. {
  188. buffer[line_position] = 0;
  189. rt_kprintf("\n");
  190. if (line_position == 0)
  191. {
  192. /* Get a empty line, then go to get a new line */
  193. goto start;
  194. }
  195. else
  196. {
  197. return line_position;
  198. }
  199. }
  200. /* other control character or not an acsii character */
  201. if (ch < 0x20 || ch >= 0x80)
  202. {
  203. continue;
  204. }
  205. /* echo */
  206. rt_kprintf("%c", ch);
  207. buffer[line_position] = ch;
  208. ch = 0;
  209. line_position++;
  210. /* it's a large line, discard it */
  211. if (line_position >= buffer_size)
  212. line_position = 0;
  213. }
  214. }
  215. }