luat_main.c 4.9 KB

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