luat_main.c 7.0 KB

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