luat_main.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. #include "luat_base.h"
  2. #include "luat_malloc.h"
  3. #include "luat_fs.h"
  4. #include "stdio.h"
  5. #include "luat_msgbus.h"
  6. #include "luat_timer.h"
  7. #include "luat_ota.h"
  8. #define LUAT_LOG_TAG "luat.main"
  9. #include "luat_log.h"
  10. #ifdef LUA_USE_WINDOWS
  11. #include <stdlib.h>
  12. extern int win32_argc;
  13. extern char** win32_argv;
  14. #endif
  15. static int report (lua_State *L, int status);
  16. lua_State *L;
  17. static uint8_t boot_mode = 1;
  18. void stopboot(void) {
  19. boot_mode = 0;
  20. }
  21. // lua_State * luat_get_state() {
  22. // return L;
  23. // }
  24. int luat_search_module(const char* name, char* filename);
  25. void luat_os_print_heapinfo(const char* tag);
  26. int luat_main_demo() { // 这是验证LuatVM最基础的消息/定时器/Task机制是否正常
  27. return luaL_dostring(L, "local sys = require \"sys\"\n"
  28. "log.info(\"main\", os.date())\n"
  29. "led = gpio.setup(19, 0)"
  30. "sys.taskInit(function ()\n"
  31. " while true do\n"
  32. " log.info(\"hi\", rtos.meminfo())\n"
  33. " sys.wait(500)\n"
  34. " led(1)\n"
  35. " sys.wait(500)\n"
  36. " led(0)\n"
  37. " end\n"
  38. "end)\n"
  39. "sys.run()\n");
  40. }
  41. static int pmain(lua_State *L) {
  42. int re = -2;
  43. luat_os_print_heapinfo("boot");
  44. // 加载内置库
  45. luat_openlibs(L);
  46. luat_os_print_heapinfo("loadlibs");
  47. lua_gc(L, LUA_GCSETPAUSE, 90); // 设置`垃圾收集器间歇率`要低于100%
  48. // 加载main.lua
  49. #ifdef LUA_USE_WINDOWS
  50. if (win32_argc > 1) {
  51. int slen = strlen(win32_argv[1]);
  52. if (slen > 4 && !strcmp(".lua", win32_argv[1] + (slen - 4)))
  53. re = luaL_dofile(L, win32_argv[1]);
  54. }
  55. #endif
  56. if (re == -2) {
  57. #ifndef LUAT_MAIN_DEMO
  58. char filename[32] = {0};
  59. if (luat_search_module("main", filename) == 0) {
  60. re = luaL_dofile(L, filename);
  61. }
  62. else {
  63. re = -1;
  64. luaL_error(L, "module '%s' not found", "main");
  65. }
  66. #else
  67. re = luat_main_demo();
  68. #endif
  69. }
  70. report(L, re);
  71. lua_pushboolean(L, re == LUA_OK); /* signal no errors */
  72. return 1;
  73. }
  74. /*
  75. ** Prints an error message, adding the program name in front of it
  76. ** (if present)
  77. */
  78. static void l_message (const char *pname, const char *msg) {
  79. if (pname) lua_writestringerror("%s: ", pname);
  80. lua_writestringerror("%s\n", msg);
  81. }
  82. /*
  83. ** Check whether 'status' is not OK and, if so, prints the error
  84. ** message on the top of the stack. It assumes that the error object
  85. ** is a string, as it was either generated by Lua or by 'msghandler'.
  86. */
  87. static int report (lua_State *L, int status) {
  88. if (status != LUA_OK) {
  89. const char *msg = lua_tostring(L, -1);
  90. l_message("LUAT", msg);
  91. lua_pop(L, 1); /* remove message */
  92. }
  93. return status;
  94. }
  95. static int panic (lua_State *L) {
  96. lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
  97. lua_tostring(L, -1));
  98. return 0; /* return to Lua to abort */
  99. }
  100. int luat_main_call(void) {
  101. // 4. init Lua State
  102. int status = 0;
  103. int result = 0;
  104. L = lua_newstate(luat_heap_alloc, NULL);
  105. if (L == NULL) {
  106. l_message("lua", "cannot create state: not enough memory\n");
  107. goto _exit;
  108. }
  109. if (L) lua_atpanic(L, &panic);
  110. //print_list_mem("after lua_newstate");
  111. lua_pushcfunction(L, &pmain); /* to call 'pmain' in protected mode */
  112. //lua_pushinteger(L, argc); /* 1st argument */
  113. //lua_pushlightuserdata(L, argv); /* 2nd argument */
  114. status = lua_pcall(L, 0, 1, 0); /* do the call */
  115. result = lua_toboolean(L, -1); /* get result */
  116. report(L, status);
  117. //lua_close(L);
  118. _exit:
  119. #ifdef LUA_USE_WINDOWS
  120. result = !result;
  121. LLOGE("Lua VM exit!! result:%d",result);
  122. exit(result);
  123. #endif
  124. return result;
  125. }
  126. /**
  127. * 常规流程, 单一入口, 执行脚本.
  128. * require "sys"
  129. *
  130. * ... 用户代码 ....
  131. *
  132. * sys.run()
  133. */
  134. int luat_main (void) {
  135. if (boot_mode == 0) {
  136. return 0; // just nop
  137. }
  138. #ifdef LUAT_BSP_VERSION
  139. LLOGI("LuatOS@%s core %s bsp %s", luat_os_bsp(), LUAT_VERSION, LUAT_BSP_VERSION);
  140. LLOGI("ROM Build: " __DATE__ " " __TIME__);
  141. #else
  142. LLOGI("LuatOS@%s %s, Build: " __DATE__ " " __TIME__, luat_os_bsp(), LUAT_VERSION);
  143. #if LUAT_VERSION_BETA
  144. LLOGD("This is a beta version, for testing");
  145. #endif
  146. #endif
  147. // 1. 初始化文件系统
  148. luat_fs_init();
  149. // 是否需要升级或者回滚
  150. luat_ota_update_or_rollback();
  151. int result = luat_main_call();
  152. LLOGE("Lua VM exit!! reboot in %dms", LUAT_EXIT_REBOOT_DELAY);
  153. luat_ota_reboot(LUAT_EXIT_REBOOT_DELAY);
  154. // 往下是肯定不会被执行的
  155. return 0;
  156. }
  157. #include "rotable.h"
  158. void luat_newlib(lua_State* l, const rotable_Reg* reg) {
  159. #ifdef LUAT_CONF_DISABLE_ROTABLE
  160. luaL_newlibtable(l,reg);
  161. int i;
  162. int nup = 0;
  163. luaL_checkstack(l, nup, "too many upvalues");
  164. for (; reg->name != NULL; reg++) { /* fill the table with given functions */
  165. for (i = 0; i < nup; i++) /* copy upvalues to the top */
  166. lua_pushvalue(l, -nup);
  167. if (reg->func)
  168. lua_pushcclosure(l, reg->func, nup); /* closure with those upvalues */
  169. else
  170. lua_pushinteger(l, reg->value);
  171. lua_setfield(l, -(nup + 2), reg->name);
  172. }
  173. lua_pop(l, nup); /* remove upvalues */
  174. #else
  175. rotable_newlib(l, reg);
  176. #endif
  177. }
  178. void luat_os_print_heapinfo(const char* tag) {
  179. size_t total; size_t used; size_t max_used;
  180. luat_meminfo_luavm(&total, &used, &max_used);
  181. LLOGD("%s luavm %ld %ld %ld", tag, total, used, max_used);
  182. luat_meminfo_sys(&total, &used, &max_used);
  183. LLOGD("%s sys %ld %ld %ld", tag, total, used, max_used);
  184. }