|
@@ -26,6 +26,7 @@
|
|
|
#include "flash_fs.h"
|
|
|
#include "user_version.h"
|
|
|
#include "rom.h"
|
|
|
+#include "task/task.h"
|
|
|
|
|
|
#define CPU80MHZ 80
|
|
|
#define CPU160MHZ 160
|
|
@@ -448,6 +449,39 @@ static int node_compile( lua_State* L )
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+// Task callback handler for node.tasknow()
|
|
|
+static task_handle_t do_node_task_handle;
|
|
|
+static void do_node_task (task_param_t task_fn_ref, uint8_t prio)
|
|
|
+{
|
|
|
+ UNUSED(prio);
|
|
|
+ lua_State* L = lua_getstate();
|
|
|
+ lua_rawgeti(L, LUA_REGISTRYINDEX, (int)task_fn_ref);
|
|
|
+ luaL_unref(L, LUA_REGISTRYINDEX, (int)task_fn_ref);
|
|
|
+ lua_pushinteger(L, prio);
|
|
|
+ lua_call(L, 1, 0);
|
|
|
+}
|
|
|
+
|
|
|
+// Lua: node.tasknow(task_cb)) -- schedule a task for execution next
|
|
|
+static int node_task_post( lua_State* L )
|
|
|
+{
|
|
|
+ int n = 1, Ltype = lua_type(L, 1);
|
|
|
+ unsigned priority = TASK_PRIORITY_MEDIUM;
|
|
|
+ if (Ltype == LUA_TNUMBER) {
|
|
|
+ priority = (unsigned) luaL_checkint(L, 1);
|
|
|
+ luaL_argcheck(L, priority <= TASK_PRIORITY_HIGH, 1, "invalid priority");
|
|
|
+ Ltype = lua_type(L, ++n);
|
|
|
+ }
|
|
|
+ luaL_argcheck(L, Ltype == LUA_TFUNCTION || Ltype == LUA_TLIGHTFUNCTION, n, "invalid function");
|
|
|
+ lua_pushvalue(L, n);
|
|
|
+
|
|
|
+ int task_fn_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
|
|
+
|
|
|
+ if (!do_node_task_handle) // bind the task handle to do_node_task on 1st call
|
|
|
+ do_node_task_handle = task_get_id(do_node_task);
|
|
|
+
|
|
|
+ task_post(priority, do_node_task_handle, (task_param_t)task_fn_ref);
|
|
|
+}
|
|
|
+
|
|
|
// Lua: setcpufreq(mhz)
|
|
|
// mhz is either CPU80MHZ od CPU160MHZ
|
|
|
static int node_setcpufreq(lua_State* L)
|
|
@@ -554,29 +588,37 @@ static int node_stripdebug (lua_State *L) {
|
|
|
#endif
|
|
|
|
|
|
// Lua: node.egc.setmode( mode, [param])
|
|
|
-// where the mode is one of the node.egc constants NOT_ACTIVE , ON_ALLOC_FAILURE,
|
|
|
+// where the mode is one of the node.egc constants NOT_ACTIVE , ON_ALLOC_FAILURE,
|
|
|
// ON_MEM_LIMIT, ALWAYS. In the case of ON_MEM_LIMIT an integer parameter is reqired
|
|
|
// See legc.h and lecg.c.
|
|
|
static int node_egc_setmode(lua_State* L) {
|
|
|
unsigned mode = luaL_checkinteger(L, 1);
|
|
|
unsigned limit = luaL_optinteger (L, 2, 0);
|
|
|
-
|
|
|
+
|
|
|
luaL_argcheck(L, mode <= (EGC_ON_ALLOC_FAILURE | EGC_ON_MEM_LIMIT | EGC_ALWAYS), 1, "invalid mode");
|
|
|
luaL_argcheck(L, !(mode & EGC_ON_MEM_LIMIT) || limit>0, 1, "limit must be non-zero");
|
|
|
-
|
|
|
+
|
|
|
legc_set_mode( L, mode, limit );
|
|
|
return 0;
|
|
|
}
|
|
|
// Module function map
|
|
|
|
|
|
static const LUA_REG_TYPE node_egc_map[] = {
|
|
|
- { LSTRKEY( "setmode" ), LFUNCVAL( node_egc_setmode ) },
|
|
|
+ { LSTRKEY( "setmode" ), LFUNCVAL( node_egc_setmode ) },
|
|
|
{ LSTRKEY( "NOT_ACTIVE" ), LNUMVAL( EGC_NOT_ACTIVE ) },
|
|
|
{ LSTRKEY( "ON_ALLOC_FAILURE" ), LNUMVAL( EGC_ON_ALLOC_FAILURE ) },
|
|
|
{ LSTRKEY( "ON_MEM_LIMIT" ), LNUMVAL( EGC_ON_MEM_LIMIT ) },
|
|
|
{ LSTRKEY( "ALWAYS" ), LNUMVAL( EGC_ALWAYS ) },
|
|
|
{ LNILKEY, LNILVAL }
|
|
|
};
|
|
|
+static const LUA_REG_TYPE node_task_map[] = {
|
|
|
+ { LSTRKEY( "post" ), LFUNCVAL( node_task_post ) },
|
|
|
+ { LSTRKEY( "LOW_PRIORITY" ), LNUMVAL( TASK_PRIORITY_LOW ) },
|
|
|
+ { LSTRKEY( "MEDIUM_PRIORITY" ), LNUMVAL( TASK_PRIORITY_MEDIUM ) },
|
|
|
+ { LSTRKEY( "HIGH_PRIORITY" ), LNUMVAL( TASK_PRIORITY_HIGH ) },
|
|
|
+ { LNILKEY, LNILVAL }
|
|
|
+};
|
|
|
+
|
|
|
static const LUA_REG_TYPE node_map[] =
|
|
|
{
|
|
|
{ LSTRKEY( "restart" ), LFUNCVAL( node_restart ) },
|
|
@@ -603,7 +645,8 @@ static const LUA_REG_TYPE node_map[] =
|
|
|
#ifdef LUA_OPTIMIZE_DEBUG
|
|
|
{ LSTRKEY( "stripdebug" ), LFUNCVAL( node_stripdebug ) },
|
|
|
#endif
|
|
|
- { LSTRKEY( "egc" ), LROVAL( node_egc_map ) },
|
|
|
+ { LSTRKEY( "egc" ), LROVAL( node_egc_map ) },
|
|
|
+ { LSTRKEY( "task" ), LROVAL( node_task_map ) },
|
|
|
|
|
|
// Combined to dsleep(us, option)
|
|
|
// { LSTRKEY( "dsleepsetoption" ), LFUNCVAL( node_deepsleep_setoption) },
|