luat_lib_pm.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. @module pm
  3. @summary 电源管理
  4. @version 1.0
  5. @date 2020.07.02
  6. */
  7. #include "lua.h"
  8. #include "lauxlib.h"
  9. #include "luat_base.h"
  10. #include "luat_pm.h"
  11. #include "luat_msgbus.h"
  12. static int lua_event_cb = 0;
  13. /**
  14. 请求进入指定的休眠模式
  15. @api pm.request(mode)
  16. @int 休眠模式,例如pm.IDLE/LIGHT/DEEP/HIB
  17. @return boolean 处理结果,即使返回成功,也不一定会进入, 也不会马上进入
  18. @usage
  19. -- 请求进入休眠模式
  20. pm.request(pm.HIB)
  21. */
  22. static int l_pm_request(lua_State *L) {
  23. int mode = luaL_checkinteger(L, 1);
  24. if (luat_pm_request(mode) == 0)
  25. lua_pushboolean(L, 1);
  26. else
  27. lua_pushboolean(L, 0);
  28. return 1;
  29. }
  30. // static int l_pm_release(lua_State *L) {
  31. // int mode = luaL_checkinteger(L, 1);
  32. // if (luat_pm_release(mode) == 0)
  33. // lua_pushboolean(L, 1);
  34. // else
  35. // lua_pushboolean(L, 0);
  36. // return 1;
  37. // }
  38. /**
  39. 启动底层定时器,在休眠模式下依然生效. 只触发一次
  40. @api pm.dtimerStart(id, timeout)
  41. @int 定时器id,通常是0-3
  42. @int 定时时长,单位毫秒
  43. @return boolean 处理结果
  44. @usage
  45. -- 添加底层定时器
  46. pm.dtimerStart(0, 300 * 1000) -- 5分钟后唤醒
  47. */
  48. static int l_pm_dtimer_start(lua_State *L) {
  49. int dtimer_id = luaL_checkinteger(L, 1);
  50. int timeout = luaL_checkinteger(L, 2);
  51. if (luat_pm_dtimer_start(dtimer_id, timeout)) {
  52. lua_pushboolean(L, 0);
  53. }
  54. else {
  55. lua_pushboolean(L, 1);
  56. }
  57. return 1;
  58. }
  59. /**
  60. 关闭底层定时器
  61. @api pm.dtimerStop(id)
  62. @int 定时器id
  63. @usage
  64. -- 关闭底层定时器
  65. pm.dtimerStop(0) -- 关闭id=0的底层定时器
  66. */
  67. static int l_pm_dtimer_stop(lua_State *L) {
  68. int dtimer_id = luaL_checkinteger(L, 1);
  69. luat_pm_dtimer_stop(dtimer_id);
  70. return 0;
  71. }
  72. /**
  73. 检查底层定时器是不是在运行
  74. @api pm.dtimerCheck(id)
  75. @int 定时器id
  76. @return boolean 处理结果,true还在运行,false不在运行
  77. @usage
  78. -- 检查底层定时器是不是在运行
  79. pm.dtimerCheck(0) -- 检查id=0的底层定时器
  80. */
  81. static int l_pm_dtimer_check(lua_State *L) {
  82. int dtimer_id = luaL_checkinteger(L, 1);
  83. if (luat_pm_dtimer_check(dtimer_id))
  84. {
  85. lua_pushboolean(L, 1);
  86. }
  87. else
  88. {
  89. lua_pushboolean(L, 0);
  90. }
  91. return 1;
  92. }
  93. static int l_pm_dtimer_list(lua_State *L) {
  94. size_t c = 0;
  95. size_t dlist[24];
  96. luat_pm_dtimer_list(&c, dlist);
  97. lua_createtable(L, c, 0);
  98. for (size_t i = 0; i < c; i++)
  99. {
  100. if (dlist[i] > 0) {
  101. lua_pushinteger(L, dlist[i]);
  102. lua_seti(L, -3, i+1);
  103. }
  104. }
  105. return 1;
  106. }
  107. static int l_pm_dtimer_wakeup_id(lua_State *L) {
  108. int dtimer_id = 0xFF;
  109. luat_pm_dtimer_wakeup_id(&dtimer_id);
  110. if (dtimer_id != 0xFF) {
  111. lua_pushinteger(L, dtimer_id);
  112. }
  113. else {
  114. lua_pushinteger(L, -1);
  115. }
  116. return 1;
  117. }
  118. static int l_pm_on(lua_State *L) {
  119. if (lua_isfunction(L, 1)) {
  120. if (lua_event_cb != 0) {
  121. luaL_unref(L, LUA_REGISTRYINDEX, lua_event_cb);
  122. }
  123. lua_event_cb = luaL_ref(L, LUA_REGISTRYINDEX);
  124. }
  125. else if (lua_event_cb != 0) {
  126. luaL_unref(L, LUA_REGISTRYINDEX, lua_event_cb);
  127. }
  128. return 0;
  129. }
  130. /**
  131. 开机原因,用于判断是从休眠模块开机,还是电源/复位开机
  132. @api pm.lastReson()
  133. @return int 0-上电开机, RTC开机, WakeupIn/Pad开机
  134. @return int 0-普通开机(上电/复位),3-深睡眠开机,4-休眠开机
  135. @usage
  136. -- 是哪种方式开机呢
  137. log.info("pm", "last power reson", pm.lastReson)
  138. */
  139. static int l_pm_last_reson(lua_State *L) {
  140. int lastState = 0;
  141. int rtcOrPad = 0;
  142. luat_pm_last_state(&lastState, &rtcOrPad);
  143. lua_pushinteger(L, rtcOrPad);
  144. lua_pushinteger(L, lastState);
  145. return 2;
  146. }
  147. /**
  148. 强制进入指定的休眠模式
  149. @api pm.force(mode)
  150. @int 休眠模式,仅pm.DEEP/HIB
  151. @return boolean 处理结果,若返回成功,大概率会马上进入该休眠模式
  152. @usage
  153. -- 请求进入休眠模式
  154. pm.force(pm.HIB)
  155. */
  156. static int l_pm_force(lua_State *L) {
  157. lua_pushinteger(L, luat_pm_force(luaL_checkinteger(L, 1)));
  158. return 1;
  159. }
  160. /**
  161. 检查休眠状态
  162. @api pm.check()
  163. @return boolean 处理结果,如果能顺利进入休眠,返回true,否则返回false
  164. @return int 底层返回值,0代表能进入最底层休眠,其他值代表最低可休眠级别
  165. @usage
  166. -- 请求进入休眠模式,然后检查是否能真的休眠
  167. pm.request(pm.HIB)
  168. if pm.check() then
  169. log.info("pm", "it is ok to hib")
  170. else
  171. pm.force(pm.HIB) -- 强制休眠
  172. end
  173. */
  174. static int l_pm_check(lua_State *L) {
  175. int ret = luat_pm_check();
  176. lua_pushboolean(L, luat_pm_check() == 0 ? 1 : 0);
  177. lua_pushinteger(L, ret);
  178. return 2;
  179. }
  180. static int luat_pm_msg_handler(lua_State *L, void* ptr) {
  181. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  182. if (lua_event_cb == 0) {
  183. return 0;
  184. }
  185. lua_geti(L, LUA_REGISTRYINDEX, lua_event_cb);
  186. if (lua_isfunction(L, -1)) {
  187. lua_pushinteger(L, msg->arg1);
  188. lua_pushinteger(L, msg->arg2);
  189. lua_call(L, 2, 0);
  190. }
  191. return 0;
  192. }
  193. void luat_pm_cb(int event, int arg, void* args) {
  194. if (lua_event_cb != 0) {
  195. rtos_msg_t msg;
  196. msg.handler = luat_pm_msg_handler;
  197. msg.arg1 = event;
  198. msg.arg2 = arg;
  199. msg.ptr = NULL;
  200. luat_msgbus_put(&msg, 0);
  201. }
  202. }
  203. #include "rotable.h"
  204. static const rotable_Reg reg_pm[] =
  205. {
  206. { "request" , l_pm_request , 0},
  207. // { "release" , l_pm_release, 0},
  208. { "dtimerStart", l_pm_dtimer_start,0},
  209. { "dtimerStop" , l_pm_dtimer_stop, 0},
  210. { "dtimerCheck" , l_pm_dtimer_check, 0},
  211. { "dtimerList", l_pm_dtimer_list, 0 },
  212. { "dtimerWkId", l_pm_dtimer_wakeup_id, 0},
  213. //{ "on", l_pm_on, 0},
  214. { "force", l_pm_force, 0},
  215. { "check", l_pm_check, 0},
  216. { "lastReson", l_pm_last_reson, 0},
  217. { "IDLE", NULL, LUAT_PM_SLEEP_MODE_IDLE},
  218. { "LIGHT", NULL, LUAT_PM_SLEEP_MODE_LIGHT},
  219. { "DEEP", NULL, LUAT_PM_SLEEP_MODE_DEEP},
  220. { "HIB", NULL, LUAT_PM_SLEEP_MODE_STANDBY},
  221. { NULL, NULL , 0}
  222. };
  223. LUAMOD_API int luaopen_pm( lua_State *L ) {
  224. luat_newlib(L, reg_pm);
  225. return 1;
  226. }