luat_main.c 5.8 KB

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