luat_main.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. #include "luat_base.h"
  2. #include "luat_mem.h"
  3. #include "luat_fs.h"
  4. #include "stdio.h"
  5. #include "luat_msgbus.h"
  6. #include "luat_timer.h"
  7. #include "luat_rtos.h"
  8. #include "luat_ota.h"
  9. #define LUAT_LOG_TAG "main"
  10. #include "luat_log.h"
  11. #ifdef LUAT_USE_ERRDUMP
  12. #include "luat_errdump.h"
  13. #endif
  14. #ifdef LUAT_USE_PROFILER
  15. #include "luat_profiler.h"
  16. #endif
  17. #ifdef LUAT_USE_WDT
  18. #include "luat_wdt.h"
  19. #endif
  20. #ifdef LUAT_USE_HMETA
  21. #include "luat_hmeta.h"
  22. #endif
  23. static int report (lua_State *L, int status);
  24. lua_State *L;
  25. static luat_rtos_timer_t luar_error_timer;
  26. static char model[32] = {0};
  27. static LUAT_RT_RET_TYPE l_timer_error_cb(LUAT_RT_CB_PARAM) {
  28. LLOGE("未找到main.lua,请刷入脚本以运行程序,luatos快速入门教程: https://wiki.luatos.com/boardGuide/roadmap.html");
  29. LLOGE("The main.lua not found, please flash the script to run the program, luatos quick start: https://wiki.luatos.com/boardGuide/roadmap.html");
  30. }
  31. int luat_search_module(const char* name, char* filename);
  32. void luat_os_print_heapinfo(const char* tag);
  33. void luat_force_gc_all(void)
  34. {
  35. lua_gc(L, LUA_GCCOLLECT, 0);
  36. }
  37. static int dolibrary (lua_State *L, const char *name) {
  38. int status;
  39. lua_getglobal(L, "require");
  40. lua_pushstring(L, name);
  41. lua_call(L, 1, 1); /* call 'require(name)' */
  42. lua_setglobal(L, name); /* global[name] = require return */
  43. return 0;
  44. }
  45. int luat_main_demo() { // 这是验证LuatVM最基础的消息/定时器/Task机制是否正常
  46. return luaL_dostring(L, "local sys = require \"sys\"\n"
  47. "log.info(\"main\", os.date())\n"
  48. "leda = gpio.setup(3, 0)"
  49. "sys.taskInit(function ()\n"
  50. " while true do\n"
  51. " log.info(\"hi\", rtos.meminfo())\n"
  52. " sys.wait(500)\n"
  53. " leda(1)\n"
  54. " sys.wait(500)\n"
  55. " leda(0)\n"
  56. " log.info(\"main\", os.date())\n"
  57. " end\n"
  58. "end)\n"
  59. "sys.run()\n");
  60. }
  61. static int pmain(lua_State *L) {
  62. int re = -2;
  63. #ifndef LUAT_MAIN_DEMO
  64. char filename[32] = {0};
  65. #endif
  66. // 加载内置库
  67. luat_openlibs(L);
  68. #if !defined(LUAT_USE_PSRAM)
  69. lua_gc(L, LUA_GCCOLLECT, 0);
  70. #endif
  71. luat_os_print_heapinfo("loadlibs");
  72. lua_gc(L, LUA_GCSETPAUSE, 90); // 设置`垃圾收集器间歇率`要低于100%
  73. // Air8000硬等最多200ms, 梁健要加的, 有问题找他
  74. #if defined(LUAT_USE_AIRLINK) && !defined(LUAT_USE_VOLTE)
  75. if (memcmp("Air8000\0", model, 8) == 0 || memcmp("Air8000W\0", model, 9) == 0) {
  76. // LLOGD("等待Air8000s启动");
  77. size_t count = 0;
  78. #define AIRLINK_WAIT_MS (5)
  79. extern uint64_t g_airlink_last_cmd_timestamp;
  80. while (g_airlink_last_cmd_timestamp == 0 && count < 200) {
  81. luat_rtos_task_sleep(AIRLINK_WAIT_MS);
  82. count += AIRLINK_WAIT_MS;
  83. }
  84. // LLOGD("等待Air8000s结束");
  85. }
  86. #endif
  87. #ifdef LUAT_HAS_CUSTOM_LIB_INIT
  88. luat_custom_init(L);
  89. #endif
  90. if (re == -2) {
  91. #ifndef LUAT_MAIN_DEMO
  92. // add by wendal, 自动加载sys和sysplus
  93. #ifndef LUAT_CONF_AUTOLOAD_SYS_DISABLE
  94. dolibrary(L, "sys");
  95. #ifndef LUAT_CONF_AUTOLOAD_SYSPLUS_DISABLE
  96. dolibrary(L, "sysplus");
  97. #endif
  98. #endif
  99. if (luat_search_module("main", filename) == 0) {
  100. re = luaL_dofile(L, filename);
  101. }
  102. else {
  103. re = -1;
  104. luar_error_timer = luat_create_rtos_timer(l_timer_error_cb, NULL, NULL);
  105. luat_start_rtos_timer(luar_error_timer, 1000, 1);
  106. luaL_error(L, "module '%s' not found", "main");
  107. }
  108. #else
  109. re = luat_main_demo();
  110. #endif
  111. }
  112. report(L, re);
  113. lua_pushboolean(L, re == LUA_OK); /* signal no errors */
  114. return 1;
  115. }
  116. /*
  117. ** Prints an error message, adding the program name in front of it
  118. ** (if present)
  119. */
  120. static void l_message (const char *pname, const char *msg) {
  121. if (pname) LLOGE("%s: ", pname);
  122. #ifdef LUAT_LOG_NO_NEWLINE
  123. LLOGE("%s", strlen(msg), msg);
  124. #else
  125. LLOGE("%s\n", msg);
  126. #endif
  127. }
  128. /*
  129. ** Check whether 'status' is not OK and, if so, prints the error
  130. ** message on the top of the stack. It assumes that the error object
  131. ** is a string, as it was either generated by Lua or by 'msghandler'.
  132. */
  133. static int report (lua_State *L, int status) {
  134. size_t len = 0;
  135. if (status != LUA_OK) {
  136. const char *msg = lua_tolstring(L, -1, &len);
  137. //luaL_traceback(L, L, msg, 1);
  138. //msg = lua_tolstring(L, -1, &len);
  139. LLOGE("Luat: ");
  140. LLOGE("%s", msg);
  141. // LLOGD("MSG2 ==> %s %d", msg, len);
  142. // l_message("LUAT", msg);
  143. #ifdef LUAT_USE_ERRDUMP
  144. luat_errdump_save_file((const uint8_t *)msg, strlen(msg));
  145. #endif
  146. lua_pop(L, 1); /* remove message */
  147. }
  148. return status;
  149. }
  150. static int panic (lua_State *L) {
  151. LLOGE("PANIC: unprotected error in call to Lua API (%s)\n",
  152. lua_tostring(L, -1));
  153. return 0; /* return to Lua to abort */
  154. }
  155. int luat_main_call(void) {
  156. // 4. init Lua State
  157. int status = 0;
  158. int result = 0;
  159. #ifdef LUAT_USE_PROFILER
  160. L = lua_newstate(luat_profiler_alloc, NULL);
  161. #else
  162. L = lua_newstate(luat_heap_alloc, NULL);
  163. #endif
  164. if (L == NULL) {
  165. l_message("lua", "cannot create state: not enough memory\n");
  166. goto _exit;
  167. }
  168. if (L) lua_atpanic(L, &panic);
  169. //print_list_mem("after lua_newstate");
  170. lua_pushcfunction(L, &pmain); /* to call 'pmain' in protected mode */
  171. //lua_pushinteger(L, argc); /* 1st argument */
  172. //lua_pushlightuserdata(L, argv); /* 2nd argument */
  173. status = lua_pcall(L, 0, 1, 0); /* do the call */
  174. result = lua_toboolean(L, -1); /* get result */
  175. report(L, status);
  176. //lua_close(L);
  177. _exit:
  178. return result;
  179. }
  180. /**
  181. * 常规流程, 单一入口, 执行脚本.
  182. * require "sys"
  183. *
  184. * ... 用户代码 ....
  185. *
  186. * sys.run()
  187. */
  188. int luat_main (void) {
  189. #ifdef LUAT_USE_HMETA
  190. luat_hmeta_model_name(model);
  191. #endif
  192. if (model[0] == 0) {
  193. const char* tmp = luat_os_bsp();
  194. memcpy(model, tmp, strlen(tmp));
  195. }
  196. #ifdef LUAT_BSP_VERSION
  197. #ifdef LUAT_CONF_VM_64bit
  198. LLOGI("LuatOS@%s base %s bsp %s 64bit", model, LUAT_VERSION, LUAT_BSP_VERSION);
  199. #else
  200. LLOGI("LuatOS@%s base %s bsp %s 32bit", model, LUAT_VERSION, LUAT_BSP_VERSION);
  201. #endif
  202. /// 支持时间无关的编译, 符合幂等性
  203. #ifdef LUAT_BUILD_FINGER
  204. LLOGI("ROM Finger: " LUAT_BUILD_FINGER);
  205. #else
  206. LLOGI("ROM Build: " __DATE__ " " __TIME__);
  207. #endif
  208. // #if LUAT_VERSION_BETA
  209. // LLOGD("This is a beta/snapshot version, for testing");
  210. // #endif
  211. #else
  212. #ifdef LUAT_CONF_VM_64bit
  213. LLOGI("LuatOS@%s %s, Build: " __DATE__ " " __TIME__ " 64bit", model, LUAT_VERSION);
  214. #else
  215. LLOGI("LuatOS@%s %s, Build: " __DATE__ " " __TIME__ " 32bit", model, LUAT_VERSION);
  216. #endif
  217. #if LUAT_VERSION_BETA
  218. LLOGD("This is a beta version, for testing");
  219. #endif
  220. #endif
  221. // 1. 初始化文件系统
  222. luat_fs_init();
  223. #ifdef LUAT_USE_OTA
  224. if (luat_ota_exec() == 0) {
  225. luat_os_reboot(5);
  226. }
  227. #endif
  228. luat_main_call();
  229. LLOGE("Lua VM exit!! reboot in %dms", LUAT_EXIT_REBOOT_DELAY);
  230. #ifdef LUAT_USE_WDT
  231. for (size_t i = 1; i < LUAT_EXIT_REBOOT_DELAY / 1000; i++)
  232. {
  233. luat_wdt_feed();
  234. luat_timer_mdelay(1000);
  235. }
  236. luat_ota_reboot(1000);
  237. #else
  238. luat_ota_reboot(LUAT_EXIT_REBOOT_DELAY);
  239. #endif
  240. // 往下是肯定不会被执行的
  241. return 0;
  242. }