luat_main.c 6.3 KB

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