Implement panic call handling for all modules (#3163)
This commit is contained in:
parent
4e689e9839
commit
1f2e5bba4a
31
.gdbinitlua
31
.gdbinitlua
|
@ -50,32 +50,25 @@ define prTV
|
|||
printf "Boolean: %u\n", $val.n
|
||||
end
|
||||
if $type == 2
|
||||
# ROTable
|
||||
printf "ROTable: %p\n", $val.p
|
||||
end
|
||||
if $type == 3
|
||||
# Light Function
|
||||
printf "Light Func: %p\n", $val.p
|
||||
end
|
||||
if $type == 4
|
||||
# Light User Data
|
||||
printf "Light Udata: %p\n", $val.p
|
||||
end
|
||||
if $type == 5
|
||||
if $type == 3
|
||||
# Number
|
||||
printf "Number: %u\n", $val.n
|
||||
end
|
||||
if $type == 6
|
||||
prTS $arg0
|
||||
if $type == 4
|
||||
# String
|
||||
printf "String: %s\n", (char *)($val.p)+16
|
||||
end
|
||||
if $type == 7
|
||||
if $type == 5
|
||||
# Table
|
||||
set $o = &($val->gc.h)
|
||||
printf "Common header: next = %p, marked = 0x%01x\n", $o->next, $o->marked
|
||||
printf "Nodes: %4i %p\n", 2<<($o->lsizenode), $o->node
|
||||
printf "Arry: %4i %p\n", $o->sizearray, $o->array
|
||||
end
|
||||
if $type == 8
|
||||
if $type == 6
|
||||
# Function
|
||||
set $o = &($val->gc.cl.c)
|
||||
printf "Common header: next = %p, marked = 0x%01x\n", $o->next, $o->marked
|
||||
|
@ -88,16 +81,24 @@ define prTV
|
|||
$o->nupvalues, $o->gclist, $o->env, $o->f
|
||||
end
|
||||
end
|
||||
if $type == 9
|
||||
if $type == 7
|
||||
# UserData
|
||||
set $o = &($val->gc.u.uv)
|
||||
printf "Common header: next = %p, marked = 0x%01x\n", $o->next, $o->marked
|
||||
printf "UD = %p Userdata: metatable = ", ($o+1))
|
||||
print ($o)->metatable
|
||||
end
|
||||
if $type == 10
|
||||
if $type == 8
|
||||
# Thread
|
||||
end
|
||||
if $type == 21
|
||||
# ROTable
|
||||
printf "ROTable: %p\n", $val.p
|
||||
end
|
||||
if $type == 38
|
||||
# Light Function
|
||||
printf "Light Func: %p\n", $val.p
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -684,6 +684,26 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
|
|||
}
|
||||
|
||||
|
||||
LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref) {
|
||||
int reft;
|
||||
/*
|
||||
* If the ref is positive and the entry in table t exists then
|
||||
* overwrite the value otherwise fall through to luaL_ref()
|
||||
*/
|
||||
if (ref) {
|
||||
if (*ref >= 0) {
|
||||
t = abs_index(L, t);
|
||||
lua_rawgeti(L, t, *ref);
|
||||
reft = lua_type(L, -1);
|
||||
lua_pop(L, 1);
|
||||
if (reft != LUA_TNIL) {
|
||||
lua_rawseti(L, t, *ref);
|
||||
return;
|
||||
}
|
||||
}
|
||||
*ref = luaL_ref(L, t);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
|
@ -899,23 +919,23 @@ LUALIB_API void luaL_assertfail(const char *file, int line, const char *message)
|
|||
* is the option to exit the interactive session and start the Xtensa remote GDB
|
||||
* which will then sync up with the remote GDB client to allow forensics of the error.
|
||||
*/
|
||||
#ifdef LUA_CROSS_COMPILER
|
||||
LUALIB_API void lua_debugbreak(void) {
|
||||
puts(" lua_debugbreak "); /* allows BT analysis of assert fails */
|
||||
}
|
||||
#else
|
||||
extern void gdbstub_init(void);
|
||||
extern void gdbstub_redirect_output(int);
|
||||
|
||||
LUALIB_API void lua_debugbreak(void) {
|
||||
LUALIB_API void lua_debugbreak (void) {
|
||||
#ifdef LUA_CROSS_COMPILER
|
||||
puts(" lua_debugbreak "); /* allows gdb BT analysis of assert fails */
|
||||
#else
|
||||
static int repeat_entry = 0;
|
||||
if (repeat_entry == 0) {
|
||||
dbg_printf("Start up the gdb stub if not already started\n");
|
||||
gdbstub_init();
|
||||
gdbstub_redirect_output(1);
|
||||
repeat_entry = 1;
|
||||
}
|
||||
asm("break 0,0" ::);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -73,6 +73,8 @@ LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
|
|||
|
||||
LUALIB_API int (luaL_ref) (lua_State *L, int t);
|
||||
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
|
||||
#define luaL_unref2(l,t,r) luaL_unref(L, (t), (r)); r = LUA_NOREF
|
||||
LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref);
|
||||
|
||||
LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
|
||||
|
||||
|
@ -160,7 +162,6 @@ LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
|
|||
|
||||
/* }====================================================== */
|
||||
|
||||
LUALIB_API int luaL_traceback (lua_State *L);
|
||||
LUALIB_API int luaL_pcallx (lua_State *L, int narg, int nres);
|
||||
LUALIB_API int luaL_posttask( lua_State* L, int prio );
|
||||
|
||||
|
|
|
@ -668,7 +668,7 @@ static int isinstack (CallInfo *ci, const TValue *o) {
|
|||
|
||||
void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
|
||||
const char *name = NULL;
|
||||
const char *t = luaT_typenames[ttype(o)];
|
||||
const char *t = luaT_typenames[basettype(o)];
|
||||
const char *kind = (isinstack(L->ci, o)) ?
|
||||
getobjname(L, L->ci, cast_int(o - L->base), &name) :
|
||||
NULL;
|
||||
|
@ -696,8 +696,8 @@ void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
|
|||
|
||||
|
||||
int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
|
||||
const char *t1 = luaT_typenames[ttype(p1)];
|
||||
const char *t2 = luaT_typenames[ttype(p2)];
|
||||
const char *t1 = luaT_typenames[basettype(p1)];
|
||||
const char *t2 = luaT_typenames[basettype(p2)];
|
||||
if (t1[2] == t2[2])
|
||||
luaG_runerror(L, "attempt to compare two %s values", t1);
|
||||
else
|
||||
|
|
|
@ -138,7 +138,7 @@ static void flashErase(uint32_t start, uint32_t end){
|
|||
}
|
||||
|
||||
/* =====================================================================================
|
||||
* luaN_init(), luaN_reload_reboot() and luaN_index() are exported via lflash.h.
|
||||
* luaN_init() is exported via lflash.h.
|
||||
* The first is the startup hook used in lstate.c and the last two are
|
||||
* implementations of the node.flash API calls.
|
||||
*/
|
||||
|
@ -194,10 +194,12 @@ static int loadLFS (lua_State *L);
|
|||
static int loadLFSgc (lua_State *L);
|
||||
static void procFirstPass (void);
|
||||
|
||||
/* lua_lfsreload() and lua_lfsindex() are exported via lua.h */
|
||||
|
||||
/*
|
||||
* Library function called by node.flashreload(filename).
|
||||
*/
|
||||
LUALIB_API int luaN_reload_reboot (lua_State *L) {
|
||||
LUALIB_API int lua_lfsreload (lua_State *L) {
|
||||
const char *fn = lua_tostring(L, 1), *msg = "";
|
||||
int status;
|
||||
|
||||
|
@ -266,7 +268,7 @@ LUALIB_API int luaN_reload_reboot (lua_State *L) {
|
|||
* - The base address and length of the LFS
|
||||
* - An array of the module names in the LFS
|
||||
*/
|
||||
LUAI_FUNC int luaN_index (lua_State *L) {
|
||||
LUAI_FUNC int lua_lfsindex (lua_State *L) {
|
||||
int n = lua_gettop(L);
|
||||
|
||||
/* Return nil + the LFS base address if the LFS size > 0 and it isn't loaded */
|
||||
|
|
|
@ -26,27 +26,31 @@
|
|||
** directly through the task interface the call is wrapped in a C closure with
|
||||
** the error string as an Upval and this is posted to call the Lua reporter.
|
||||
*/
|
||||
static int report_traceback (lua_State *L) {
|
||||
// **Temp** lua_rawgeti(L, LUA_REGISTRYINDEX, G(L)->error_reporter);
|
||||
lua_getglobal(L, "print");
|
||||
static int errhandler_aux (lua_State *L) {
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "onerror");
|
||||
if (!lua_isfunction(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
lua_getglobal(L, "print");
|
||||
}
|
||||
lua_pushvalue(L, lua_upvalueindex(1));
|
||||
lua_call(L, 1, 0); /* Using an error handler would cause an infinite loop! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Catch all error handler for CB calls. This uses debug.traceback() to
|
||||
** generate a full Lua traceback.
|
||||
** Error handler for luaL_pcallx(), called from the lua_pcall() with a single
|
||||
** argument -- the thrown error. This plus depth=2 is passed to debug.traceback()
|
||||
** to convert into an error message which it handles in a separate posted task.
|
||||
*/
|
||||
LUALIB_API int luaL_traceback (lua_State *L) {
|
||||
if (lua_isstring(L, 1)) {
|
||||
lua_getglobal(L, "debug");
|
||||
lua_getfield(L, -1, "traceback");
|
||||
lua_remove(L, -2);
|
||||
lua_pushvalue(L, 1); /* pass error message */
|
||||
static int errhandler (lua_State *L) {
|
||||
lua_getglobal(L, "debug");
|
||||
lua_getfield(L, -1, "traceback");
|
||||
if (lua_isfunction(L, -1)) {
|
||||
lua_insert(L, 1); /* insert tracback function above error */
|
||||
lua_pop(L, 1); /* dump the debug table entry */
|
||||
lua_pushinteger(L, 2); /* skip this function and traceback */
|
||||
lua_call(L, 2, 1); /* call debug.traceback and return it as a string */
|
||||
lua_pushcclosure(L, report_traceback, 1); /* report with str as upval */
|
||||
lua_pushcclosure(L, errhandler_aux, 1); /* report with str as upval */
|
||||
luaL_posttask(L, LUA_TASK_HIGH);
|
||||
}
|
||||
return 0;
|
||||
|
@ -60,12 +64,16 @@ LUALIB_API int luaL_traceback (lua_State *L) {
|
|||
LUALIB_API int luaL_pcallx (lua_State *L, int narg, int nres) { // [-narg, +0, v]
|
||||
int status;
|
||||
int base = lua_gettop(L) - narg;
|
||||
lua_pushcfunction(L, luaL_traceback);
|
||||
lua_pushcfunction(L, errhandler);
|
||||
lua_insert(L, base); /* put under args */
|
||||
status = lua_pcall(L, narg, (nres < 0 ? LUA_MULTRET : nres), base);
|
||||
status = lua_pcall(L, narg, nres, base);
|
||||
lua_remove(L, base); /* remove traceback function */
|
||||
if (status && nres >=0)
|
||||
lua_settop(L, base + nres); /* balance the stack on error */
|
||||
if (status != LUA_OK && status != LUA_ERRRUN) {
|
||||
lua_gc(L, LUA_GCCOLLECT, 0); /* call onerror directly if handler failed */
|
||||
lua_pushliteral(L, "out of memory");
|
||||
lua_pushcclosure(L, errhandler_aux, 1); /* report EOM as upval */
|
||||
luaL_posttask(L, LUA_TASK_HIGH);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* Read-only tables for Lua */
|
||||
|
||||
/*
|
||||
* NodeMCU extensions to Lua 5.1 for readonly Flash memory support
|
||||
*/
|
||||
#ifndef lnodemcu_h
|
||||
#define lnodemcu_h
|
||||
|
||||
|
@ -16,7 +17,8 @@
|
|||
#define LOCK_IN_SECTION(s) __attribute__((used,unused,section(".lua_" #s)))
|
||||
#endif
|
||||
|
||||
/* Macros one can use to define rotable entries */
|
||||
/* Macros used to declare rotable entries */
|
||||
|
||||
#define LRO_FUNCVAL(v) {{.p = v}, LUA_TLIGHTFUNCTION}
|
||||
#define LRO_LUDATA(v) {{.p = cast(void*,v)}, LUA_TLIGHTUSERDATA}
|
||||
#define LRO_NILVAL {{.p = NULL}, LUA_TNIL}
|
||||
|
@ -25,7 +27,7 @@
|
|||
#define LRO_FLOATVAL(v) LRO_NUMVAL(v)
|
||||
#define LRO_ROVAL(v) {{.gc = cast(GCObject *, &(v ## _ROTable))}, LUA_TROTABLE}
|
||||
|
||||
#define LROT_MARKED 0 //<<<<<<<<<<*** TBD *** >>>>>>>>>>>
|
||||
#define LROT_MARKED 0 //<<<<<<<<<< *** TBD *** >>>>>>>>>>>
|
||||
|
||||
#define LROT_FUNCENTRY(n,f) {LRO_STRKEY(#n), LRO_FUNCVAL(f)},
|
||||
#define LROT_LUDENTRY(n,x) {LRO_STRKEY(#n), LRO_LUDATA(x)},
|
||||
|
@ -38,9 +40,9 @@
|
|||
#define LROT_ENTRYREF(rt) (rt ##_entries)
|
||||
#define LROT_TABLEREF(rt) (&rt ##_ROTable)
|
||||
#define LROT_BEGIN(rt,mt,f) LROT_TABLE(rt); \
|
||||
static const ROTable_entry rt ## _entries[] = {
|
||||
static ROTable_entry rt ## _entries[] = {
|
||||
#define LROT_ENTRIES_IN_SECTION(rt,s) \
|
||||
static const ROTable_entry LOCK_IN_SECTION(s) rt ## _entries[] = {
|
||||
static ROTable_entry LOCK_IN_SECTION(s) rt ## _entries[] = {
|
||||
#define LROT_END(rt,mt,f) {NULL, LRO_NILVAL} }; \
|
||||
const ROTable rt ## _ROTable = { \
|
||||
(GCObject *)1, LUA_TROTABLE, LROT_MARKED, \
|
||||
|
@ -64,4 +66,9 @@
|
|||
#define LROT_MASK_GC_INDEX (LROT_MASK_GC | LROT_MASK_INDEX)
|
||||
|
||||
/* Maximum length of a rotable name and of a string key*/
|
||||
|
||||
#ifdef LUA_CORE
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -410,7 +410,7 @@ typedef struct Table {
|
|||
GET_BYTE_FN(flags,Table,4,16)
|
||||
GET_BYTE_FN(lsizenode,Table,4,24)
|
||||
|
||||
typedef struct ROTable_entry {
|
||||
typedef const struct ROTable_entry {
|
||||
const char *key;
|
||||
const TValue value;
|
||||
} ROTable_entry;
|
||||
|
|
|
@ -383,10 +383,13 @@ struct lua_Debug {
|
|||
/* }====================================================================== */
|
||||
|
||||
typedef struct ROTable ROTable;
|
||||
typedef struct ROTable_entry ROTable_entry;
|
||||
typedef const struct ROTable_entry ROTable_entry;
|
||||
|
||||
LUA_API void (lua_pushrotable) (lua_State *L, const ROTable *p);
|
||||
LUA_API void (lua_createrotable) (lua_State *L, ROTable *t, const ROTable_entry *e, ROTable *mt);
|
||||
LUA_API void (lua_pushrotable) (lua_State *L, const ROTable *p);
|
||||
LUA_API void (lua_createrotable) (lua_State *L, ROTable *t, ROTable_entry *e, ROTable *mt);
|
||||
|
||||
LUAI_FUNC int lua_lfsreload (lua_State *L);
|
||||
LUAI_FUNC int lua_lfsindex (lua_State *L);
|
||||
|
||||
#define EGC_NOT_ACTIVE 0 // EGC disabled
|
||||
#define EGC_ON_ALLOC_FAILURE 1 // run EGC on allocation failure
|
||||
|
@ -413,7 +416,12 @@ LUA_API void lua_setegcmode(lua_State *L, int mode, int limit);
|
|||
#define dbg_printf printf
|
||||
|
||||
#endif
|
||||
extern void lua_debugbreak(void);
|
||||
|
||||
#ifdef DEVELOPMENT_USE_GDB
|
||||
LUALIB_API void (lua_debugbreak)(void);
|
||||
#else
|
||||
#define lua_debugbreak() (void)(0)
|
||||
#endif
|
||||
|
||||
// EGC operations modes
|
||||
#define EGC_NOT_ACTIVE 0 // EGC disabled
|
||||
|
|
|
@ -649,6 +649,28 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref) {
|
||||
int reft;
|
||||
/*
|
||||
* If the ref is positive and the entry in table t exists then
|
||||
* overwrite the value otherwise fall through to luaL_ref()
|
||||
*/
|
||||
if (ref) {
|
||||
if (*ref >= 0) {
|
||||
t = lua_absindex(L, t);
|
||||
lua_rawgeti(L, t, *ref);
|
||||
reft = lua_type(L, -1);
|
||||
lua_pop(L, 1);
|
||||
if (reft != LUA_TNIL) {
|
||||
lua_rawseti(L, t, *ref);
|
||||
return;
|
||||
}
|
||||
}
|
||||
*ref = luaL_ref(L, t);
|
||||
}
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
|
@ -1127,26 +1149,23 @@ static int errhandler_aux (lua_State *L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Error handler for luaL_pcallx()
|
||||
** Error handler for luaL_pcallx(), called from the lua_pcall() with a single
|
||||
** argument -- the thrown error. This plus depth=2 is passed to debug.traceback()
|
||||
** to convert into an error message which it handles in a separate posted task.
|
||||
*/
|
||||
static int errhandler (lua_State *L) {
|
||||
if (lua_isnil(L, -1))
|
||||
return 0;
|
||||
if (lua_type(L, -1) != LUA_TSTRING) { /* is error object not a string? */
|
||||
if (luaL_callmeta(L, 1, "__tostring") && /* does it have a metamethod */
|
||||
lua_type(L, -1) == LUA_TSTRING) { /* that produces a string? */
|
||||
lua_remove(L, 1); /* replace ToS with this */
|
||||
} else if (!lua_isnil(L,-1)) {
|
||||
lua_pushfstring(L, "(error object is a %s value)", luaL_typename(L, 1));
|
||||
lua_remove(L, 1); /* replace ToS with error object is type value */
|
||||
}
|
||||
lua_getglobal(L, "debug");
|
||||
lua_getfield(L, -1, "traceback");
|
||||
if (lua_isfunction(L, -1)) {
|
||||
lua_insert(L, 1); /* insert tracback function above error */
|
||||
lua_pop(L, 1); /* dump the debug table entry */
|
||||
lua_pushinteger(L, 2); /* skip this function and traceback */
|
||||
lua_call(L, 2, 1); /* call debug.traceback and return it as a string */
|
||||
lua_pushcclosure(L, errhandler_aux, 1); /* report with str as upval */
|
||||
luaL_posttask(L, LUA_TASK_HIGH);
|
||||
}
|
||||
luaL_traceback(L, L, lua_tostring(L, 1), 1); /* append a standard traceback */
|
||||
lua_pushcclosure(L, errhandler_aux, 1); /* report with str as upval */
|
||||
luaL_posttask(L, LUA_TASK_HIGH);
|
||||
return 1; /* return the traceback */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1155,11 +1174,17 @@ static int errhandler (lua_State *L) {
|
|||
*/
|
||||
LUALIB_API int luaL_pcallx (lua_State *L, int narg, int nres) {
|
||||
int status;
|
||||
int base = lua_gettop(L) - narg; /* function index */
|
||||
lua_pushcfunction(L, errhandler); /* push message handler */
|
||||
lua_insert(L, base); /* put it under function and args */
|
||||
int base = lua_gettop(L) - narg; /* function index */
|
||||
lua_pushcfunction(L, errhandler); /* push message handler */
|
||||
lua_insert(L, base); /* put it under function and args */
|
||||
status = lua_pcall(L, narg, nres, base);
|
||||
lua_remove(L, base); /* remove message handler from the stack */
|
||||
lua_remove(L, base); /* remove message handler from the stack */
|
||||
if (status != LUA_OK && status != LUA_ERRRUN) {
|
||||
lua_gc(L, LUA_GCCOLLECT, 0); /* call onerror directly if handler failed */
|
||||
lua_pushliteral(L, "out of memory");
|
||||
lua_pushcclosure(L, errhandler_aux, 1); /* report EOM as upval */
|
||||
luaL_posttask(L, LUA_TASK_HIGH);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1180,7 +1205,7 @@ static void do_task (platform_task_param_t task_fn_ref, uint8_t prio) {
|
|||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, (int) task_fn_ref);
|
||||
lua_pushinteger(L, prio);
|
||||
luaL_pcallx (L, 1, 0);
|
||||
luaL_pcallx(L, 1, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -79,6 +79,8 @@ LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
|
|||
|
||||
LUALIB_API int (luaL_ref) (lua_State *L, int t);
|
||||
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
|
||||
#define luaL_unref2(l,t,r) luaL_unref(L, (t), (r)); r = LUA_NOREF
|
||||
LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref);
|
||||
|
||||
LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
|
||||
const char *mode);
|
||||
|
|
|
@ -83,7 +83,6 @@ typedef LUAI_UACNUMBER l_uacNumber;
|
|||
typedef LUAI_UACINT l_uacInt;
|
||||
|
||||
#if defined(DEVELOPMENT_USE_GDB) && !defined(lua_assert)
|
||||
extern void (lua_debugbreak)(void);
|
||||
# define lua_assert(c) ((c) ? (void) 0 : lua_debugbreak())
|
||||
#endif
|
||||
|
||||
|
|
|
@ -202,8 +202,6 @@ LUALIB_API void lua_debugbreak(void) {
|
|||
asm("break 0,0" ::);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
#define lua_debugbreak() (void)(0)
|
||||
#endif
|
||||
|
||||
//== NodeMCU lua.h API extensions ============================================//
|
||||
|
@ -567,7 +565,7 @@ LUAI_FUNC int luaN_init (lua_State *L) {
|
|||
#define getfield(L,t,f) \
|
||||
lua_getglobal(L, #t); luaL_getmetafield( L, 1, #f ); lua_remove(L, -2);
|
||||
|
||||
LUAI_FUNC int luaN_reload_reboot (lua_State *L) {
|
||||
LUAI_FUNC int lua_lfsreload (lua_State *L) {
|
||||
int n = 0;
|
||||
#ifdef LUA_USE_ESP
|
||||
size_t l;
|
||||
|
@ -579,6 +577,10 @@ LUAI_FUNC int luaN_reload_reboot (lua_State *L) {
|
|||
#endif
|
||||
lua_settop(L, 1);
|
||||
lua_getglobal(L, "file");
|
||||
if (lua_isnil(L, 2)) {
|
||||
lua_pushstring(L, "No file system mounted");
|
||||
return 1;
|
||||
}
|
||||
lua_getfield(L, 2, "exists");
|
||||
lua_pushstring(L, img + off);
|
||||
lua_call(L, 1, 1);
|
||||
|
@ -594,7 +596,7 @@ LUAI_FUNC int luaN_reload_reboot (lua_State *L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
LUAI_FUNC int luaN_index (lua_State *L) {
|
||||
LUAI_FUNC int lua_lfsindex (lua_State *L) {
|
||||
lua_settop(L,1);
|
||||
if (lua_isstring(L, 1)){
|
||||
lua_getglobal(L, "LFS");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* NodeMCU extensions to Lua for readonly Flash memory support
|
||||
* NodeMCU extensions to Lua 5.3 for readonly Flash memory support
|
||||
*/
|
||||
#ifndef lnodemcu_h
|
||||
#define lnodemcu_h
|
||||
|
@ -27,7 +27,7 @@
|
|||
#define LRO_FLOATVAL(v) {{.n = v}, LUA_TNUMFLT}
|
||||
#define LRO_ROVAL(v) {{.gc = cast(GCObject *, &(v ## _ROTable))}, LUA_TTBLROF}
|
||||
|
||||
#define LROT_MARKED 0 //<<<<<<<<<<*** TBD *** >>>>>>>>>>>
|
||||
#define LROT_MARKED 0 //<<<<<<<<<< *** TBD *** >>>>>>>>>>>
|
||||
|
||||
#define LROT_FUNCENTRY(n,f) {LRO_STRKEY(#n), LRO_FUNCVAL(f)},
|
||||
#define LROT_LUDENTRY(n,x) {LRO_STRKEY(#n), LRO_LUDATA(x)},
|
||||
|
@ -65,65 +65,18 @@
|
|||
#define LROT_MASK_NEWINDEX LROT_MASK(NEWINDEX)
|
||||
#define LROT_MASK_GC_INDEX (LROT_MASK_GC | LROT_MASK_INDEX)
|
||||
|
||||
/* Maximum length of a rotable name and of a string key*/
|
||||
#define LUA_MAX_ROTABLE_NAME 32
|
||||
|
||||
#define LUA_MAX_ROTABLE_NAME 32 /* Maximum length of a rotable name and of a string key*/
|
||||
|
||||
#ifdef LUA_CORE
|
||||
|
||||
#include "lstate.h"
|
||||
#include "lzio.h"
|
||||
|
||||
typedef struct FlashHeader LFSHeader;
|
||||
/*
|
||||
** The LFSHeader uses offsets rather than pointers to avoid 32 vs 64 bit issues
|
||||
** during host compilation. The offsets are in units of lu_int32's and NOT
|
||||
** size_t, though clearly any internal pointers are of the size_t for the
|
||||
** executing architectures: 4 or 8 byte. Likewise recources are size_t aligned
|
||||
** so LFS regions built for 64-bit execution will have 4-byte alignment packing
|
||||
** between resources.
|
||||
*/
|
||||
struct FlashHeader{
|
||||
lu_int32 flash_sig; /* a standard fingerprint identifying an LFS image */
|
||||
lu_int32 flash_size; /* Size of LFS image in bytes */
|
||||
lu_int32 seed; /* random number seed used in LFS */
|
||||
lu_int32 timestamp; /* timestamp of LFS build */
|
||||
lu_int32 nROuse; /* number of elements in ROstrt */
|
||||
lu_int32 nROsize; /* size of ROstrt */
|
||||
lu_int32 oROhash; /* offset of TString ** ROstrt hash */
|
||||
lu_int32 protoROTable; /* offset of master ROTable for proto lookup */
|
||||
lu_int32 protoHead; /* offset of linked list of Protos in LFS */
|
||||
lu_int32 shortTShead; /* offset of linked list of short TStrings in LFS */
|
||||
lu_int32 longTShead; /* offset of linked list of long TStrings in LFS */
|
||||
lu_int32 reserved;
|
||||
};
|
||||
|
||||
#ifdef LUA_USE_HOST
|
||||
extern void *LFSregion;
|
||||
LUAI_FUNC void luaN_setabsolute(lu_int32 addr);
|
||||
#endif
|
||||
|
||||
#define FLASH_FORMAT_VERSION ( 2 << 8)
|
||||
#define FLASH_SIG_B1 0x06
|
||||
#define FLASH_SIG_B2 0x02
|
||||
#define FLASH_SIG_PASS2 0x0F
|
||||
#define FLASH_FORMAT_MASK 0xF00
|
||||
#define FLASH_SIG_B2_MASK 0x04
|
||||
#define FLASH_SIG_ABSOLUTE 0x01
|
||||
#define FLASH_SIG_IN_PROGRESS 0x08
|
||||
#define FLASH_SIG (0xfafaa050 | FLASH_FORMAT_VERSION)
|
||||
|
||||
#define FLASH_FORMAT_MASK 0xF00
|
||||
|
||||
LUAI_FUNC int luaN_init (lua_State *L);
|
||||
LUAI_FUNC int luaN_flashSetup (lua_State *L);
|
||||
|
||||
LUAI_FUNC int luaN_reload_reboot (lua_State *L);
|
||||
LUAI_FUNC int luaN_index (lua_State *L);
|
||||
|
||||
LUAI_FUNC void *luaN_writeFlash (void *data, const void *rec, size_t n);
|
||||
LUAI_FUNC void luaN_flushFlash (void *);
|
||||
LUAI_FUNC void luaN_setFlash (void *, unsigned int o);
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -64,9 +64,10 @@ static void l_print (lua_State *L, int n) {
|
|||
luaL_checkstack(L, LUA_MINSTACK, "too many results to print");
|
||||
lua_getglobal(L, "print");
|
||||
lua_insert(L, -n-1);
|
||||
if (lua_pcall(L, n, 0, 0) != LUA_OK)
|
||||
lua_writestringerror( "error calling 'print' (%s)\n",
|
||||
lua_tostring(L, -1));
|
||||
if (lua_pcall(L, n, 0, 0) != LUA_OK) {
|
||||
lua_writestringerror("error calling 'print' (%s)\n", lua_tostring(L, -1));
|
||||
lua_settop(L, -n-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,52 +76,43 @@ static void l_print (lua_State *L, int n) {
|
|||
** Message handler is used with all chunks calls. Returns the traceback on ToS
|
||||
*/
|
||||
static int msghandler (lua_State *L) {
|
||||
const char *msg = lua_tostring(L, 1);
|
||||
if (msg == NULL) { /* is error object not a string? */
|
||||
if (luaL_callmeta(L, 1, "__tostring") && /* does it have a metamethod */
|
||||
lua_type(L, -1) == LUA_TSTRING) /* that produces a string? */
|
||||
return 1; /* that is the message */
|
||||
msg = lua_pushfstring(L, "(error object is a %s value)",
|
||||
luaL_typename(L, 1));
|
||||
lua_remove(L, -2); /* otherwise swap with printable error */
|
||||
lua_getglobal(L, "debug");
|
||||
lua_getfield(L, -1, "traceback");
|
||||
if (lua_isfunction(L, -1)) {
|
||||
lua_insert(L, 1); /* insert tracback function above error */
|
||||
lua_pop(L, 1); /* dump the debug table entry */
|
||||
lua_pushinteger(L, 2); /* skip this function and traceback */
|
||||
lua_call(L, 2, 1); /* call debug.traceback and return it as a string */
|
||||
}
|
||||
#ifdef LUA_VERSION_51
|
||||
lua_getglobal(L,"debug");
|
||||
lua_getfield(L, -1,"traceback");
|
||||
lua_insert(L, 1); /* pass error message */
|
||||
lua_pop(L, 1);
|
||||
lua_pushinteger(L, 2); /* skip this function and traceback */
|
||||
lua_call(L, 2, 1); /* call debug.traceback */
|
||||
#else /* LUA_VERSION_53 */
|
||||
luaL_traceback(L, L, msg, 1); /* append a standard traceback */
|
||||
#endif
|
||||
return 1; /* return the traceback */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Interface to 'lua_pcall', which sets appropriate message function
|
||||
** and error handler. Used to run all chunks.
|
||||
** Interface to 'lua_pcall', which sets appropriate message function and error
|
||||
** handler. Used to run all chunks. Results or error traceback left on stack.
|
||||
** This function is interactive so unlike lua_pcallx(), the error is sent direct
|
||||
** to the print function and erroring does not trigger an on error restart.
|
||||
*/
|
||||
static int docall (lua_State *L, int narg, int nres) {
|
||||
static int docall (lua_State *L, int narg) {
|
||||
int status;
|
||||
int base = lua_gettop(L) - narg; /* function index */
|
||||
lua_pushcfunction(L, msghandler); /* push message handler */
|
||||
lua_insert(L, base); /* put it under chunk and args */
|
||||
status = lua_pcall(L, narg, (nres ? 0 : LUA_MULTRET), base);
|
||||
status = lua_pcall(L, narg, LUA_MULTRET, base);
|
||||
lua_remove(L, base); /* remove message handler from the stack */
|
||||
/* force a complete garbage collection in case of errors */
|
||||
if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
#ifndef DISABLE_STARTUP_BANNER
|
||||
static void print_version (lua_State *L) {
|
||||
#ifndef DISABLE_STARTUP_BANNER
|
||||
lua_writestringerror( "\n" NODE_VERSION " build " BUILD_DATE
|
||||
" powered by " LUA_RELEASE " on SDK %s\n", SDK_VERSION);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Returns the string to be used as a prompt by the interpreter.
|
||||
|
@ -164,7 +156,6 @@ static void l_create_stdin (lua_State *L);
|
|||
** other C API and Lua functions might be executed as tasks between lines in
|
||||
** a multiline, so a standard luaL_ref() registry entry is used instead.
|
||||
*/
|
||||
//// TODO SHOLD this have an boot return false if pipe empty else nil
|
||||
static void dojob (lua_State *L) {
|
||||
static int MLref = LUA_NOREF; /* Lua Reg entry for cached multi-line */
|
||||
int status;
|
||||
|
@ -204,21 +195,18 @@ static void dojob (lua_State *L) {
|
|||
}
|
||||
/* Execute the compiled chunk of successful */
|
||||
if (status == 0)
|
||||
status = docall(L, 0, 0);
|
||||
status = docall(L, 0);
|
||||
/* print any returned results or error message */
|
||||
if (status && !lua_isnil(L, -1))
|
||||
lua_writestringerror("Lua error: %s\n", lua_tostring(L, -1));
|
||||
if (status == 0 && lua_gettop(L) - 1)
|
||||
l_print(L, lua_gettop(L) - 1);
|
||||
|
||||
lua_settop(L, 2);
|
||||
if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
|
||||
if (status && !lua_isnil(L, -1)) {
|
||||
lua_pushliteral(L, "Lua error: ");
|
||||
lua_insert(L , -2);
|
||||
}
|
||||
l_print(L, lua_gettop(L) - 1); /* print error or results one stack */
|
||||
}
|
||||
|
||||
prompt = get_prompt(L, MLref!= LUA_NOREF ? 0 : 1);
|
||||
input_setprompt(prompt);
|
||||
lua_writestring(prompt,strlen(prompt));
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
|
||||
|
@ -241,7 +229,9 @@ static int pmain (lua_State *L) {
|
|||
input_setup(LUA_MAXINPUT, get_prompt(L, 1));
|
||||
lua_input_string(" \n", 2); /* queue CR to issue first prompt */
|
||||
|
||||
#ifndef DISABLE_STARTUP_BANNER
|
||||
print_version(L);
|
||||
#endif
|
||||
/*
|
||||
* And last of all, kick off application initialisation. Note that if
|
||||
* LUA_INIT_STRING is a file reference and the file system is uninitialised
|
||||
|
@ -252,7 +242,7 @@ static int pmain (lua_State *L) {
|
|||
luaL_loadfile(L, init+1) :
|
||||
luaL_loadbuffer(L, init, strlen(init), "=INIT");
|
||||
if (status == LUA_OK)
|
||||
status = docall(L, 0, 0);
|
||||
status = docall(L, 0);
|
||||
if (status != LUA_OK)
|
||||
l_print (L, 1);
|
||||
return 0;
|
||||
|
@ -274,7 +264,7 @@ int lua_main (void) {
|
|||
}
|
||||
globalL = L;
|
||||
lua_pushcfunction(L, pmain);
|
||||
if (docall(L, 0, 0) != LUA_OK) {
|
||||
if (docall(L, 0) != LUA_OK) {
|
||||
if (strstr(lua_tostring(L, -1),"!LFSrestart!")) {
|
||||
lua_close(L);
|
||||
return 1; /* non-zero return to flag LFS reload */
|
||||
|
@ -337,7 +327,7 @@ static int l_read_stdin (lua_State *L) {
|
|||
/* likewise if not CR terminated, then unread and ditto */
|
||||
lua_insert(L, 1); /* insert false return above the pipe */
|
||||
lua_getfield(L, 2, "unread");
|
||||
lua_insert(L, 1); /* insert pipe.unread above the pipe */
|
||||
lua_insert(L, 2); /* insert pipe.unread above the pipe */
|
||||
lua_call(L, 2, 0); /* pobj:unread(line) */
|
||||
return 1; /* return false */
|
||||
}
|
||||
|
|
|
@ -467,16 +467,15 @@ typedef struct ROTable ROTable;
|
|||
typedef const struct ROTable_entry ROTable_entry;
|
||||
typedef size_t KeyCache;
|
||||
|
||||
LUA_API void (lua_pushrotable) (lua_State *L, const ROTable *p);
|
||||
LUA_API void (lua_pushrotable) (lua_State *L, const ROTable *p);
|
||||
LUA_API void (lua_createrotable) (lua_State *L, ROTable *t, const ROTable_entry *e, ROTable *mt);
|
||||
LUA_API lua_State *(lua_getstate) (void);
|
||||
LUA_API KeyCache *(lua_getcache) (int cl);
|
||||
LUA_API int (lua_getstrings) (lua_State *L, int opt);
|
||||
LUA_API int (lua_freeheap) (void);
|
||||
|
||||
LUAI_FUNC int luaN_flashSetup (lua_State *L);
|
||||
LUAI_FUNC int luaN_reload_reboot (lua_State *L);
|
||||
LUAI_FUNC int luaN_index (lua_State *L);
|
||||
LUAI_FUNC int lua_lfsreload (lua_State *L);
|
||||
LUAI_FUNC int lua_lfsindex (lua_State *L);
|
||||
|
||||
#define luaN_freearray(L,a,l) luaM_freearray(L,a,l)
|
||||
|
||||
|
@ -487,10 +486,11 @@ LUAI_FUNC int luaN_index (lua_State *L);
|
|||
typedef struct Proto Proto;
|
||||
|
||||
#ifdef DEVELOPMENT_USE_GDB
|
||||
LUALIB_API void lua_debugbreak(void);
|
||||
#define ASSERT(s) if (!(s)) {();}
|
||||
LUALIB_API void (lua_debugbreak)(void);
|
||||
#define ASSERT(s) if (!(s)) {lua_debugbreak();}
|
||||
#else
|
||||
#define ASSERT(s)
|
||||
#define lua_debugbreak() (void)(0)
|
||||
#define ASSERT(s) (void)(0)
|
||||
#endif
|
||||
|
||||
LUAI_FUNC int luaG_stripdebug (lua_State *L, Proto *f, int level, int recv);
|
||||
|
|
|
@ -48,4 +48,46 @@ LUAI_FUNC int luaU_DumpAllProtos(lua_State *L, const Proto *m, lua_Writer w,
|
|||
void *data, int strip);
|
||||
|
||||
LUAI_FUNC int luaU_undumpLFS(lua_State *L, ZIO *Z, int isabs);
|
||||
|
||||
typedef struct FlashHeader LFSHeader;
|
||||
/*
|
||||
** The LFSHeader uses offsets rather than pointers to avoid 32 vs 64 bit issues
|
||||
** during host compilation. The offsets are in units of lu_int32's and NOT
|
||||
** size_t, though clearly any internal pointers are of the size_t for the
|
||||
** executing architectures: 4 or 8 byte. Likewise recources are size_t aligned
|
||||
** so LFS regions built for 64-bit execution will have 4-byte alignment packing
|
||||
** between resources.
|
||||
*/
|
||||
struct FlashHeader{
|
||||
lu_int32 flash_sig; /* a standard fingerprint identifying an LFS image */
|
||||
lu_int32 flash_size; /* Size of LFS image in bytes */
|
||||
lu_int32 seed; /* random number seed used in LFS */
|
||||
lu_int32 timestamp; /* timestamp of LFS build */
|
||||
lu_int32 nROuse; /* number of elements in ROstrt */
|
||||
lu_int32 nROsize; /* size of ROstrt */
|
||||
lu_int32 oROhash; /* offset of TString ** ROstrt hash */
|
||||
lu_int32 protoROTable; /* offset of master ROTable for proto lookup */
|
||||
lu_int32 protoHead; /* offset of linked list of Protos in LFS */
|
||||
lu_int32 shortTShead; /* offset of linked list of short TStrings in LFS */
|
||||
lu_int32 longTShead; /* offset of linked list of long TStrings in LFS */
|
||||
lu_int32 reserved;
|
||||
};
|
||||
|
||||
#ifdef LUA_USE_HOST
|
||||
extern void *LFSregion;
|
||||
LUAI_FUNC void luaN_setabsolute(lu_int32 addr);
|
||||
#endif
|
||||
|
||||
#define FLASH_FORMAT_VERSION ( 2 << 8)
|
||||
#define FLASH_SIG_B1 0x06
|
||||
#define FLASH_SIG_B2 0x02
|
||||
#define FLASH_SIG_PASS2 0x0F
|
||||
#define FLASH_FORMAT_MASK 0xF00
|
||||
#define FLASH_SIG_B2_MASK 0x04
|
||||
#define FLASH_SIG_ABSOLUTE 0x01
|
||||
#define FLASH_SIG_IN_PROGRESS 0x08
|
||||
#define FLASH_SIG (0xfafaa050 | FLASH_FORMAT_VERSION)
|
||||
|
||||
#define FLASH_FORMAT_MASK 0xF00
|
||||
|
||||
#endif
|
||||
|
|
|
@ -499,7 +499,7 @@ static int ads1115_lua_readoutdone(void * param) {
|
|||
luaL_unref(L, LUA_REGISTRYINDEX, ads_ctrl->timer_ref);
|
||||
ads_ctrl->timer_ref = LUA_NOREF;
|
||||
read_common(ads_ctrl, raw, L);
|
||||
lua_call(L, 4, 0);
|
||||
luaL_pcallx(L, 4, 0);
|
||||
}
|
||||
|
||||
// Read the conversion register from the ADC device
|
||||
|
|
|
@ -320,9 +320,9 @@ static void bme280_readoutdone (void *arg)
|
|||
NODE_DBG("timer out\n");
|
||||
lua_State *L = lua_getstate();
|
||||
lua_rawgeti (L, LUA_REGISTRYINDEX, lua_connected_readout_ref);
|
||||
lua_call (L, 0, 0);
|
||||
luaL_unref (L, LUA_REGISTRYINDEX, lua_connected_readout_ref);
|
||||
os_timer_disarm (&bme280_timer);
|
||||
luaL_pcallx (L, 0, 0);
|
||||
}
|
||||
|
||||
static int bme280_lua_startreadout(lua_State* L) {
|
||||
|
|
|
@ -430,9 +430,9 @@ static void bme280_readoutdone (void *arg)
|
|||
NODE_DBG("timer out\n");
|
||||
lua_State *L = lua_getstate();
|
||||
lua_rawgeti (L, LUA_REGISTRYINDEX, lua_connected_readout_ref);
|
||||
lua_call (L, 0, 0);
|
||||
luaL_unref (L, LUA_REGISTRYINDEX, lua_connected_readout_ref);
|
||||
os_timer_disarm (&bme680_timer);
|
||||
luaL_pcallx (L, 0, 0);
|
||||
}
|
||||
|
||||
static int bme680_lua_startreadout(lua_State* L) {
|
||||
|
|
|
@ -200,7 +200,7 @@ static void cron_handle_time(uint8_t mon, uint8_t dom, uint8_t dow, uint8_t hour
|
|||
if ((ent->desc.min & desc.min ) == 0) continue;
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, ent->cb_ref);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, cronent_list[i]);
|
||||
lua_call(L, 1, 0);
|
||||
luaL_pcallx(L, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,8 @@ static int call_encoder( lua_State* L, const char *function ) {
|
|||
lua_getfield(L, -1, function);
|
||||
lua_insert(L, 1); //move function below the argument
|
||||
lua_pop(L, 1); //and dump the encoder rotable from stack.
|
||||
lua_call(L,1,1); // call encoder.xxx(string)
|
||||
lua_call(L,1,1); // Normal call encoder.xxx(string)
|
||||
// (errors thrown back to caller)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,13 +53,13 @@ void notifyDccReset(uint8_t hardReset ) {
|
|||
lua_State* L = lua_getstate();
|
||||
cbInit(L, DCC_RESET);
|
||||
cbAddFieldInteger(L, hardReset, "hardReset");
|
||||
lua_call(L, 2, 0);
|
||||
luaL_pcallx(L, 2, 0);
|
||||
}
|
||||
|
||||
void notifyDccIdle(void) {
|
||||
lua_State* L = lua_getstate();
|
||||
cbInit(L, DCC_IDLE);
|
||||
lua_call(L, 2, 0);
|
||||
luaL_pcallx(L, 2, 0);
|
||||
}
|
||||
|
||||
void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION Dir, DCC_SPEED_STEPS SpeedSteps ) {
|
||||
|
@ -70,7 +70,7 @@ void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_D
|
|||
cbAddFieldInteger(L, Speed, "Speed");
|
||||
cbAddFieldInteger(L, Dir, "Dir");
|
||||
cbAddFieldInteger(L, SpeedSteps, "SpeedSteps");
|
||||
lua_call(L, 2, 0);
|
||||
luaL_pcallx(L, 2, 0);
|
||||
}
|
||||
|
||||
void notifyDccSpeedRaw( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Raw) {
|
||||
|
@ -79,7 +79,7 @@ void notifyDccSpeedRaw( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Raw) {
|
|||
cbAddFieldInteger(L, Addr, "Addr");
|
||||
cbAddFieldInteger(L, AddrType, "AddrType");
|
||||
cbAddFieldInteger(L, Raw, "Raw");
|
||||
lua_call(L, 2, 0);
|
||||
luaL_pcallx(L, 2, 0);
|
||||
}
|
||||
|
||||
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
|
||||
|
@ -89,7 +89,7 @@ void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uin
|
|||
cbAddFieldInteger(L, AddrType, "AddrType");
|
||||
cbAddFieldInteger(L, FuncGrp, "FuncGrp");
|
||||
cbAddFieldInteger(L, FuncState, "FuncState");
|
||||
lua_call(L, 2, 0);
|
||||
luaL_pcallx(L, 2, 0);
|
||||
}
|
||||
|
||||
void notifyDccAccTurnoutBoard( uint16_t BoardAddr, uint8_t OutputPair, uint8_t Direction, uint8_t OutputPower ) {
|
||||
|
@ -99,7 +99,7 @@ void notifyDccAccTurnoutBoard( uint16_t BoardAddr, uint8_t OutputPair, uint8_t D
|
|||
cbAddFieldInteger(L, OutputPair, "OutputPair");
|
||||
cbAddFieldInteger(L, Direction, "Direction");
|
||||
cbAddFieldInteger(L, OutputPower, "OutputPower");
|
||||
lua_call(L, 2, 0);
|
||||
luaL_pcallx(L, 2, 0);
|
||||
}
|
||||
|
||||
void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t OutputPower ) {
|
||||
|
@ -108,28 +108,28 @@ void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t Output
|
|||
cbAddFieldInteger(L, Addr, "Addr");
|
||||
cbAddFieldInteger(L, Direction, "Direction");
|
||||
cbAddFieldInteger(L, OutputPower, "OutputPower");
|
||||
lua_call(L, 2, 0);
|
||||
luaL_pcallx(L, 2, 0);
|
||||
}
|
||||
|
||||
void notifyDccAccBoardAddrSet( uint16_t BoardAddr) {
|
||||
lua_State* L = lua_getstate();
|
||||
cbInit(L, DCC_ACCESSORY);
|
||||
cbAddFieldInteger(L, BoardAddr, "BoardAddr");
|
||||
lua_call(L, 2, 0);
|
||||
luaL_pcallx(L, 2, 0);
|
||||
}
|
||||
|
||||
void notifyDccAccOutputAddrSet( uint16_t Addr) {
|
||||
lua_State* L = lua_getstate();
|
||||
cbInit(L, DCC_ACCESSORY);
|
||||
cbAddFieldInteger(L, Addr, "Addr");
|
||||
lua_call(L, 2, 0);
|
||||
luaL_pcallx(L, 2, 0);
|
||||
}
|
||||
|
||||
void notifyDccSigOutputState( uint16_t Addr, uint8_t State) {
|
||||
lua_State* L = lua_getstate();
|
||||
cbInit(L, DCC_ACCESSORY);
|
||||
cbAddFieldInteger(L, State, "State");
|
||||
lua_call(L, 2, 0);
|
||||
luaL_pcallx(L, 2, 0);
|
||||
}
|
||||
|
||||
void notifyDccMsg( DCC_MSG * Msg ) {
|
||||
|
@ -142,14 +142,14 @@ void notifyDccMsg( DCC_MSG * Msg ) {
|
|||
ets_sprintf(field, "Data%d", i);
|
||||
cbAddFieldInteger(L, Msg->Data[i], field);
|
||||
}
|
||||
lua_call(L, 2, 0);
|
||||
luaL_pcallx(L, 2, 0);
|
||||
}
|
||||
|
||||
void notifyServiceMode(bool InServiceMode){
|
||||
lua_State* L = lua_getstate();
|
||||
cbInit(L, DCC_SERVICEMODE);
|
||||
cbAddFieldInteger(L, InServiceMode, "InServiceMode");
|
||||
lua_call(L, 2, 0);
|
||||
luaL_pcallx(L, 2, 0);
|
||||
}
|
||||
|
||||
// CV handling
|
||||
|
@ -163,7 +163,8 @@ uint8_t notifyCVValid( uint16_t CV, uint8_t Writable ) {
|
|||
lua_newtable(L);
|
||||
cbAddFieldInteger(L, CV, "CV");
|
||||
cbAddFieldInteger(L, Writable, "Writable");
|
||||
lua_call(L, 2, 1);
|
||||
if (luaL_pcallx(L, 2, 1) != LUA_OK)
|
||||
return 0;
|
||||
uint8 result = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return result;
|
||||
|
@ -177,7 +178,8 @@ uint8_t notifyCVRead( uint16_t CV) {
|
|||
lua_pushinteger(L, CV_READ);
|
||||
lua_newtable(L);
|
||||
cbAddFieldInteger(L, CV, "CV");
|
||||
lua_call(L, 2, 1);
|
||||
if (luaL_pcallx(L, 2, 1) != LUA_OK)
|
||||
return 0;;
|
||||
uint8 result = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return result;
|
||||
|
@ -192,7 +194,7 @@ uint8_t notifyCVWrite( uint16_t CV, uint8_t Value) {
|
|||
lua_newtable(L);
|
||||
cbAddFieldInteger(L, CV, "CV");
|
||||
cbAddFieldInteger(L, Value, "Value");
|
||||
lua_call(L, 2, 0);
|
||||
luaL_pcallx(L, 2, 0);
|
||||
return Value;
|
||||
}
|
||||
|
||||
|
@ -202,7 +204,7 @@ void notifyCVResetFactoryDefault(void) {
|
|||
return;
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, CV_cb);
|
||||
lua_pushinteger(L, CV_RESET);
|
||||
lua_call(L, 1, 0);
|
||||
luaL_pcallx(L, 1, 0);
|
||||
}
|
||||
|
||||
static int dcc_lua_setup(lua_State* L) {
|
||||
|
|
|
@ -181,7 +181,7 @@ static void enduser_setup_debug(int line, const char *str)
|
|||
{
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, state->lua_dbg_cb_ref);
|
||||
lua_pushfstring(L, "%d: \t%s", line, str);
|
||||
lua_call(L, 1, 0);
|
||||
luaL_pcallx(L, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,7 +196,7 @@ static void enduser_setup_error(int line, const char *str, int err)
|
|||
lua_rawgeti (L, LUA_REGISTRYINDEX, state->lua_err_cb_ref);
|
||||
lua_pushnumber(L, err);
|
||||
lua_pushfstring(L, "%d: \t%s", line, str);
|
||||
lua_call (L, 2, 0);
|
||||
luaL_pcallx (L, 2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,7 @@ static void enduser_setup_connected_callback()
|
|||
if (state != NULL && state->lua_connected_cb_ref != LUA_NOREF)
|
||||
{
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, state->lua_connected_cb_ref);
|
||||
lua_call(L, 0, 0);
|
||||
luaL_pcallx(L, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,8 @@ static sint32_t file_rtc_cb( vfs_time *tm )
|
|||
lua_State *L = lua_getstate();
|
||||
|
||||
lua_rawgeti( L, LUA_REGISTRYINDEX, rtc_cb_ref );
|
||||
lua_call( L, 0, 1 );
|
||||
if (luaL_pcallx( L, 0, 1 ) != LUA_OK)
|
||||
return res;
|
||||
|
||||
if (lua_type( L, lua_gettop( L ) ) == LUA_TTABLE) {
|
||||
table2tm( L, tm );
|
||||
|
|
|
@ -77,7 +77,8 @@ static void gpio_intr_callback_task (task_param_t param, uint8 priority)
|
|||
then = system_get_time() & 0x7fffffff;
|
||||
}
|
||||
|
||||
lua_call(L, 3, 0);
|
||||
if(luaL_pcallx(L, 3, 0) != LUA_OK)
|
||||
return;
|
||||
}
|
||||
|
||||
if (INTERRUPT_TYPE_IS_LEVEL(pin_int_type[pin])) {
|
||||
|
@ -237,10 +238,7 @@ static void seroutasync_done (task_param_t arg)
|
|||
lua_rawgeti (L, LUA_REGISTRYINDEX, serout.lua_done_ref);
|
||||
luaL_unref (L, LUA_REGISTRYINDEX, serout.lua_done_ref);
|
||||
serout.lua_done_ref = LUA_NOREF;
|
||||
if (lua_pcall(L, 0, 0, 0)) {
|
||||
// Uncaught Error. Print instead of sudden reset
|
||||
luaL_error(L, "error: %s", lua_tostring(L, -1));
|
||||
}
|
||||
luaL_pcallx(L, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -463,7 +463,7 @@ static void gpio_pulse_task(os_param_t param, uint8_t prio)
|
|||
active_pulser_ref = LUA_NOREF;
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, pulser_ref);
|
||||
|
||||
lua_call(L, rc, 0);
|
||||
luaL_pcallx(L, rc, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ static void http_callback( char * response, int http_status, char ** full_respon
|
|||
luaL_unref(L, LUA_REGISTRYINDEX, http_callback_registry);
|
||||
http_callback_registry = LUA_NOREF;
|
||||
|
||||
lua_call(L, 3, 0); // With 3 arguments and 0 result
|
||||
luaL_pcallx(L, 3, 0); // With 3 arguments and 0 result
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -258,7 +258,7 @@ static void hx711_task(platform_task_param_t param, uint8_t prio)
|
|||
|
||||
control->freed = param;
|
||||
|
||||
lua_call(L, 3, 0);
|
||||
luaL_pcallx(L, 3, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,39 @@
|
|||
#define CPU80MHZ 80
|
||||
#define CPU160MHZ 160
|
||||
|
||||
#define DELAY2SEC 2000
|
||||
|
||||
static void restart_callback(void *arg) {
|
||||
UNUSED(arg);
|
||||
system_restart();
|
||||
}
|
||||
static int default_onerror(lua_State *L) {
|
||||
static os_timer_t restart_timer = {0};
|
||||
/* Use Lua print to print the ToS */
|
||||
lua_settop(L, 1);
|
||||
lua_getglobal(L, "print");
|
||||
lua_insert(L, 1);
|
||||
lua_pcall(L, 1, 0, 0);
|
||||
/* One first time through set automatic restart after 2s delay */
|
||||
if (!restart_timer.timer_func) {
|
||||
os_timer_setfn(&restart_timer, restart_callback, NULL);
|
||||
os_timer_arm(&restart_timer, DELAY2SEC, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: setonerror([function])
|
||||
static int node_setonerror( lua_State* L ) {
|
||||
lua_settop(L, 1);
|
||||
if (!lua_isfunction(L, 1)) {
|
||||
lua_pop(L, 1);
|
||||
lua_pushcfunction(L, default_onerror);
|
||||
}
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "onerror");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Lua: startupcommand(string)
|
||||
static int node_startupcommand( lua_State* L ) {
|
||||
size_t l, lrcr;
|
||||
|
@ -229,12 +262,17 @@ static int node_input( lua_State* L ) {
|
|||
lua_rawgeti(L, -1, 1); /* get the pipe_write func from stdin[1] */
|
||||
lua_insert(L, -2); /* and move above the pipe ref */
|
||||
lua_pushvalue(L, 1);
|
||||
lua_call(L, 2, 0); /* stdin:write(line) */
|
||||
lua_call(L, 2, 0); /* stdin:write(line); errors are thrown to caller */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int serial_debug = 1;
|
||||
|
||||
/*
|
||||
** Output redirector. Note that panics in the output callback cannot be processed
|
||||
** using luaL_pcallx() as this would create an infinite error loop, so they are
|
||||
** reported direct to the UART.
|
||||
*/
|
||||
void output_redirect(const char *str, size_t l) {
|
||||
lua_State *L = lua_getstate();
|
||||
int n = lua_gettop(L);
|
||||
|
@ -247,8 +285,10 @@ void output_redirect(const char *str, size_t l) {
|
|||
lua_rawgeti(L, -1, 1); /* get the pipe_write func from stdout[1] */
|
||||
lua_insert(L, -2); /* and move above the pipe ref */
|
||||
lua_pushlstring(L, str, l);
|
||||
lua_call(L, 2, 0); /* Reg.stdout:write(str) */
|
||||
|
||||
if (lua_pcall(L, 2, 0, 0) != LUA_OK) { /* Reg.stdout:write(str) */
|
||||
lua_writestringerror("error calling stdout:write(%s)\n", lua_tostring(L, -1));
|
||||
system_restart();
|
||||
}
|
||||
} else { /* reg.stdout == nil */
|
||||
uart0_sendStrn(str, l);
|
||||
}
|
||||
|
@ -266,7 +306,7 @@ static int node_output( lua_State* L )
|
|||
lua_pushcfunction(L, pipe_create);
|
||||
lua_insert(L, 1);
|
||||
lua_pushinteger(L, LUA_TASK_MEDIUM);
|
||||
lua_call(L, 2, 1); /* T[1] = pipe.create(CB, medium_priority) */
|
||||
lua_call(L, 2, 1); /* Any pipe.create() errors thrown back to caller */
|
||||
} else { // remove the stdout pipe
|
||||
lua_pop(L,1);
|
||||
lua_pushnil(L); /* T[1] = nil */
|
||||
|
@ -786,8 +826,9 @@ LROT_BEGIN(node, NULL, 0)
|
|||
LROT_FUNCENTRY( heap, node_heap )
|
||||
LROT_FUNCENTRY( info, node_info )
|
||||
LROT_TABENTRY( task, node_task )
|
||||
LROT_FUNCENTRY( flashreload, luaN_reload_reboot )
|
||||
LROT_FUNCENTRY( flashindex, luaN_index )
|
||||
LROT_FUNCENTRY( flashreload, lua_lfsreload )
|
||||
LROT_FUNCENTRY( flashindex, lua_lfsindex )
|
||||
LROT_FUNCENTRY( setonerror, node_setonerror )
|
||||
LROT_FUNCENTRY( startupcommand, node_startupcommand )
|
||||
LROT_FUNCENTRY( restart, node_restart )
|
||||
LROT_FUNCENTRY( dsleep, node_deepsleep )
|
||||
|
@ -831,5 +872,9 @@ LROT_BEGIN(node, NULL, 0)
|
|||
// LROT_FUNCENTRY( dsleepsetoption, node_deepsleep_setoption )
|
||||
LROT_END(node, NULL, 0)
|
||||
|
||||
int luaopen_node( lua_State *L ) {
|
||||
lua_settop(L, 0);
|
||||
return node_setonerror(L); /* set default onerror action */
|
||||
}
|
||||
|
||||
NODEMCU_MODULE(NODE, "node", node, NULL);
|
||||
NODEMCU_MODULE(NODE, "node", node, luaopen_node);
|
||||
|
|
|
@ -27,7 +27,7 @@ static void dispatch_callback( lua_State *L, int self_ref, int cb_ref, int retur
|
|||
if (cb_ref != LUA_NOREF) {
|
||||
lua_rawgeti( L, LUA_REGISTRYINDEX, cb_ref );
|
||||
lua_rawgeti( L, LUA_REGISTRYINDEX, self_ref );
|
||||
lua_call( L, 1, returns );
|
||||
luaL_pcallx( L, 1, returns );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -185,7 +185,7 @@ static int pipe_write_and_read_poster (lua_State *L) {
|
|||
lua_replace(L, UVstate);
|
||||
lua_pushvalue(L, UVfunc); /* Lua CB function */
|
||||
lua_pushvalue(L, UVpipe); /* pipe table */
|
||||
lua_call(L, 1, 1);
|
||||
lua_call(L, 1, 1); /* Errors are thrown back to caller */
|
||||
/*
|
||||
* On return from the Lua CB, the task is never reposted if the pipe is empty.
|
||||
* If it is not empty then the Lua CB return status determines when reposting
|
||||
|
|
|
@ -114,7 +114,7 @@ static void callback_callOne(lua_State* L, int cb, int mask, int arg, uint32_t t
|
|||
lua_pushinteger(L, arg);
|
||||
lua_pushinteger(L, time);
|
||||
|
||||
lua_call(L, 3, 0);
|
||||
luaL_pcallx(L, 3, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ static void handle_error (lua_State *L, ntp_err_t err, const char *msg)
|
|||
lua_pushinteger (L, err);
|
||||
lua_pushstring (L, msg);
|
||||
cleanup (L);
|
||||
lua_call (L, 2, 0);
|
||||
luaL_pcallx (L, 2, 0);
|
||||
}
|
||||
else
|
||||
cleanup (L);
|
||||
|
@ -319,7 +319,7 @@ static void sntp_handle_result(lua_State *L) {
|
|||
|
||||
if (have_cb)
|
||||
{
|
||||
lua_call (L, 4, 0);
|
||||
luaL_pcallx (L, 4, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -287,7 +287,7 @@ static void softuart_rx_callback(task_param_t arg)
|
|||
}
|
||||
lua_pushlstring(L, softuart_rx_buffer, buffer_lenght);
|
||||
softuart->armed = 1;
|
||||
lua_call(L, 1, 0);
|
||||
luaL_pcallx(L, 1, 0);
|
||||
}
|
||||
|
||||
// Arguments: event name, minimum buffer filled to run callback, callback function
|
||||
|
|
|
@ -92,7 +92,7 @@ static void somfy_transmissionDone (task_param_t arg)
|
|||
lua_rawgeti (L, LUA_REGISTRYINDEX, lua_done_ref);
|
||||
luaL_unref (L, LUA_REGISTRYINDEX, lua_done_ref);
|
||||
lua_done_ref = LUA_NOREF;
|
||||
lua_call (L, 0, 0);
|
||||
luaL_pcallx (L, 0, 0);
|
||||
}
|
||||
|
||||
static void ICACHE_RAM_ATTR sendCommand(os_param_t p) {
|
||||
|
|
|
@ -47,7 +47,7 @@ static void callback_execute(lua_State* L, unsigned int id)
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, callback);
|
||||
callback_free(L, id);
|
||||
|
||||
lua_call(L, 0, 0);
|
||||
luaL_pcallx(L, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -188,7 +188,7 @@ uint8_t tcs34725EnableDone()
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, cb_tcs_en); // Get the callback to call
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, cb_tcs_en); // Unregister the callback to avoid leak
|
||||
cb_tcs_en = LUA_NOREF;
|
||||
lua_call(L, 0, 0);
|
||||
luaL_pcallx(L, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -10,8 +10,9 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "mem.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "espconn.h"
|
||||
|
@ -463,12 +464,11 @@ static const char *fill_page_with_pem(lua_State *L, const unsigned char *flash_m
|
|||
static int tls_cert_auth(lua_State *L)
|
||||
{
|
||||
if (ssl_client_options.cert_auth_callback != LUA_NOREF) {
|
||||
lua_unref(L, ssl_client_options.cert_auth_callback);
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, ssl_client_options.cert_auth_callback);
|
||||
ssl_client_options.cert_auth_callback = LUA_NOREF;
|
||||
}
|
||||
if ((lua_type(L, 1) == LUA_TFUNCTION)
|
||||
|| (lua_type(L, 1) == LUA_TLIGHTFUNCTION)) {
|
||||
ssl_client_options.cert_auth_callback = lua_ref(L, 1);
|
||||
if (lua_type(L, 1) == LUA_TFUNCTION) {
|
||||
ssl_client_options.cert_auth_callback = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
}
|
||||
|
@ -518,12 +518,11 @@ static int tls_cert_auth(lua_State *L)
|
|||
static int tls_cert_verify(lua_State *L)
|
||||
{
|
||||
if (ssl_client_options.cert_verify_callback != LUA_NOREF) {
|
||||
lua_unref(L, ssl_client_options.cert_verify_callback);
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, ssl_client_options.cert_verify_callback);
|
||||
ssl_client_options.cert_verify_callback = LUA_NOREF;
|
||||
}
|
||||
if ((lua_type(L, 1) == LUA_TFUNCTION)
|
||||
|| (lua_type(L, 1) == LUA_TLIGHTFUNCTION)) {
|
||||
ssl_client_options.cert_verify_callback = lua_ref(L, 1);
|
||||
if (lua_type(L, 1) == LUA_TFUNCTION) {
|
||||
ssl_client_options.cert_verify_callback = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -5,48 +5,7 @@
|
|||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#endif
|
||||
|
||||
/*-------------------------------------
|
||||
NEW TIMER API
|
||||
---------------------------------------
|
||||
|
||||
tmr.wdclr() -- not changed
|
||||
tmr.now() -- not changed
|
||||
tmr.time() -- not changed
|
||||
tmr.delay() -- not changed
|
||||
tmr.alarm() -- not changed
|
||||
tmr.stop() -- changed, see below. use tmr.unregister for old functionality
|
||||
|
||||
tmr.register(ref, interval, mode, function)
|
||||
bind function with timer and set the interval in ms
|
||||
the mode can be:
|
||||
tmr.ALARM_SINGLE for a single run alarm
|
||||
tmr.ALARM_SEMI for a multiple single run alarm
|
||||
tmr.ALARM_AUTO for a repating alarm
|
||||
tmr.register does NOT start the timer
|
||||
tmr.alarm is a tmr.register & tmr.start macro
|
||||
tmr.unregister(ref)
|
||||
stop alarm, unbind function and clean up memory
|
||||
not needed for ALARM_SINGLE, as it unregisters itself
|
||||
tmr.start(ref)
|
||||
ret: bool
|
||||
start a alarm, returns true on success
|
||||
tmr.stop(ref)
|
||||
ret: bool
|
||||
stops a alarm, returns true on success
|
||||
this call dose not free any memory, to do so use tmr.unregister
|
||||
stopped alarms can be started with start
|
||||
tmr.interval(ref, interval)
|
||||
set alarm interval, running alarm will be restarted
|
||||
tmr.state(ref)
|
||||
ret: (bool, int) or nil
|
||||
returns alarm status (true=started/false=stopped) and mode
|
||||
nil if timer is unregistered
|
||||
tmr.softwd(int)
|
||||
set a negative value to stop the timer
|
||||
any other value starts the timer, when the
|
||||
countdown reaches zero, the device restarts
|
||||
the timer units are seconds
|
||||
*/
|
||||
/* See docs/modules/tmr.md for documentaiton o current API */
|
||||
|
||||
#include "module.h"
|
||||
#include "lauxlib.h"
|
||||
|
@ -55,40 +14,40 @@ tmr.softwd(int)
|
|||
#include "user_interface.h"
|
||||
#include "pm/swtimer.h"
|
||||
|
||||
#define TIMER_MODE_OFF 3
|
||||
#define TIMER_MODE_SINGLE 0
|
||||
#define TIMER_MODE_SEMI 2
|
||||
#define TIMER_MODE_AUTO 1
|
||||
#define TIMER_MODE_AUTO 1
|
||||
#define TIMER_MODE_SEMI 2
|
||||
#define TIMER_MODE_OFF 3
|
||||
#define TIMER_IDLE_FLAG (1<<7)
|
||||
|
||||
|
||||
#define STRINGIFY_VAL(x) #x
|
||||
#define STRINGIFY(x) STRINGIFY_VAL(x)
|
||||
|
||||
// assuming system_timer_reinit() has *not* been called
|
||||
#define MAX_TIMEOUT_DEF 6870947 //SDK 1.5.3 limit (0x68D7A3)
|
||||
#define MAX_TIMEOUT_DEF 0x68D7A3 // SDK specfied limit
|
||||
|
||||
static const uint32 MAX_TIMEOUT=MAX_TIMEOUT_DEF;
|
||||
static const char* MAX_TIMEOUT_ERR_STR = "Range: 1-"STRINGIFY(MAX_TIMEOUT_DEF);
|
||||
|
||||
typedef struct{
|
||||
os_timer_t os;
|
||||
sint32_t lua_ref; /* Reference to the callback function */
|
||||
sint32_t self_ref; /* Reference to this structure as userdata */
|
||||
sint32_t lua_ref; /* Reference to registered callback function */
|
||||
sint32_t self_ref; /* Reference to UD registered slot */
|
||||
uint32_t interval;
|
||||
uint8_t mode;
|
||||
}timer_struct_t;
|
||||
typedef timer_struct_t* tmr_t;
|
||||
} tmr_t;
|
||||
|
||||
// The previous implementation extended the rtc counter to 64 bits, and then
|
||||
// applied rtc2sec with the current calibration value to that 64 bit value.
|
||||
// This means that *ALL* clock ticks since bootup are counted with the *current*
|
||||
// clock period. In extreme cases (long uptime, sudden temperature change), this
|
||||
// could result in tmr.time() going backwards....
|
||||
// This implementation instead applies rtc2usec to short time intervals only (the
|
||||
// longest being around 1 second), and then accumulates the resulting microseconds
|
||||
// in a 64 bit counter. That's guaranteed to be monotonic, and should be a lot closer
|
||||
// to representing an actual uptime.
|
||||
// This means that *ALL* clock ticks since bootup are counted with the
|
||||
// *current* clock period. In extreme cases (long uptime, sudden temperature
|
||||
// change), this could result in tmr.time() going backwards....
|
||||
//
|
||||
// This implementation instead applies rtc2usec to short time intervals only
|
||||
// (the longest being around 1 second), and then accumulates the resulting
|
||||
// microseconds in a 64 bit counter. That's guaranteed to be monotonic, and
|
||||
// should be a lot closer to representing an actual uptime.
|
||||
|
||||
static uint32_t rtc_time_cali=0;
|
||||
static uint32_t last_rtc_time=0;
|
||||
static uint64_t last_rtc_time_us=0;
|
||||
|
@ -97,180 +56,137 @@ static sint32_t soft_watchdog = -1;
|
|||
static os_timer_t rtc_timer;
|
||||
|
||||
static void alarm_timer_common(void* arg){
|
||||
tmr_t tmr = (tmr_t)arg;
|
||||
lua_State* L = lua_getstate();
|
||||
if(tmr->lua_ref == LUA_NOREF)
|
||||
return;
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, tmr->lua_ref);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, tmr->self_ref);
|
||||
//if the timer was set to single run we clean up after it
|
||||
if(tmr->mode == TIMER_MODE_SINGLE){
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, tmr->lua_ref);
|
||||
tmr->lua_ref = LUA_NOREF;
|
||||
tmr->mode = TIMER_MODE_OFF;
|
||||
}else if(tmr->mode == TIMER_MODE_SEMI){
|
||||
tmr->mode |= TIMER_IDLE_FLAG;
|
||||
}
|
||||
if (tmr->mode != TIMER_MODE_AUTO && tmr->self_ref != LUA_REFNIL) {
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, tmr->self_ref);
|
||||
tmr->self_ref = LUA_NOREF;
|
||||
}
|
||||
lua_call(L, 1, 0);
|
||||
tmr_t *tmr = (tmr_t *) arg;
|
||||
if(tmr->lua_ref > 0) {
|
||||
lua_State* L = lua_getstate();
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, tmr->lua_ref);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, tmr->self_ref);
|
||||
if (tmr->mode != TIMER_MODE_AUTO) {
|
||||
if(tmr->mode == TIMER_MODE_SINGLE) {
|
||||
luaL_unref2(L, LUA_REGISTRYINDEX, tmr->lua_ref);
|
||||
luaL_unref2(L, LUA_REGISTRYINDEX, tmr->self_ref);
|
||||
tmr->mode = TIMER_MODE_OFF;
|
||||
} else if (tmr->mode == TIMER_MODE_SEMI) {
|
||||
tmr->mode |= TIMER_IDLE_FLAG;
|
||||
luaL_unref2(L, LUA_REGISTRYINDEX, tmr->self_ref);
|
||||
}
|
||||
}
|
||||
luaL_pcallx(L, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Lua: tmr.delay( us )
|
||||
static int tmr_delay( lua_State* L ){
|
||||
sint32_t us = luaL_checkinteger(L, 1);
|
||||
if(us <= 0)
|
||||
return luaL_error(L, "wrong arg range");
|
||||
while(us >= 1000000){
|
||||
us -= 1000000;
|
||||
os_delay_us(1000000);
|
||||
system_soft_wdt_feed ();
|
||||
luaL_argcheck(L, us>0, 1, "wrong arg range");
|
||||
while(us > 0){
|
||||
os_delay_us(us >= 1000000 ? 1000000 : us);
|
||||
system_soft_wdt_feed ();
|
||||
us -= 1000000;
|
||||
}
|
||||
if(us>0){
|
||||
os_delay_us(us);
|
||||
system_soft_wdt_feed ();
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: tmr.now() , return system timer in us
|
||||
static int tmr_now(lua_State* L){
|
||||
uint32_t now = 0x7FFFFFFF & system_get_time();
|
||||
lua_pushinteger(L, now);
|
||||
lua_pushinteger(L, (uint32_t) (0x7FFFFFFF & system_get_time()));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Lua: tmr.ccount() , returns CCOUNT register
|
||||
static int tmr_ccount( lua_State* L )
|
||||
{
|
||||
static int tmr_ccount(lua_State* L){
|
||||
lua_pushinteger(L, CCOUNT_REG);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static tmr_t tmr_get( lua_State *L, int stack ) {
|
||||
tmr_t t = (tmr_t)luaL_checkudata(L, stack, "tmr.timer");
|
||||
if (t == NULL)
|
||||
return (tmr_t)luaL_error(L, "timer object expected");
|
||||
return t;
|
||||
}
|
||||
|
||||
// Lua: tmr.register( ref, interval, mode, function )
|
||||
static int tmr_register(lua_State* L){
|
||||
tmr_t tmr = tmr_get(L, 1);
|
||||
/*
|
||||
** Health warning: this is also called DIRECTLY from alarm() which assumes that the Lua
|
||||
** stack is preserved for the following start(), so the stack MUST be balanced here.
|
||||
*/
|
||||
|
||||
// Lua: t:register( interval, mode, function )
|
||||
static int tmr_register(lua_State* L) {
|
||||
tmr_t *tmr = (tmr_t *) luaL_checkudata(L, 1, "tmr.timer");
|
||||
uint32_t interval = luaL_checkinteger(L, 2);
|
||||
uint8_t mode = luaL_checkinteger(L, 3);
|
||||
|
||||
luaL_argcheck(L, (interval > 0 && interval <= MAX_TIMEOUT), 2, MAX_TIMEOUT_ERR_STR);
|
||||
luaL_argcheck(L, (mode == TIMER_MODE_SINGLE || mode == TIMER_MODE_SEMI || mode == TIMER_MODE_AUTO), 3, "Invalid mode");
|
||||
luaL_argcheck(L, lua_isfunction(L, 4), 4, "Must be function");
|
||||
|
||||
//get the lua function reference
|
||||
lua_pushvalue(L, 4);
|
||||
sint32_t ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
if(!(tmr->mode & TIMER_IDLE_FLAG) && tmr->mode != TIMER_MODE_OFF)
|
||||
os_timer_disarm(&tmr->os);
|
||||
//there was a bug in this part, the second part of the following condition was missing
|
||||
if(tmr->lua_ref != LUA_NOREF && tmr->lua_ref != ref)
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, tmr->lua_ref);
|
||||
tmr->lua_ref = ref;
|
||||
luaL_reref(L, LUA_REGISTRYINDEX, &tmr->lua_ref);
|
||||
tmr->mode = mode|TIMER_IDLE_FLAG;
|
||||
tmr->interval = interval;
|
||||
os_timer_setfn(&tmr->os, alarm_timer_common, tmr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: tmr.start( id / ref )
|
||||
// Lua: t:start()
|
||||
static int tmr_start(lua_State* L){
|
||||
tmr_t tmr = tmr_get(L, 1);
|
||||
tmr_t *tmr = (tmr_t *) luaL_checkudata(L, 1, "tmr.timer");
|
||||
int idle = tmr->mode & TIMER_IDLE_FLAG;
|
||||
|
||||
if (tmr->self_ref == LUA_NOREF) {
|
||||
lua_pushvalue(L, 1);
|
||||
lua_settop(L, 1); /* ignore any args after the userdata */
|
||||
if (tmr->self_ref == LUA_NOREF)
|
||||
tmr->self_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
//we return false if the timer is not idle
|
||||
if(!(tmr->mode&TIMER_IDLE_FLAG)){
|
||||
lua_pushboolean(L, 0);
|
||||
}else{
|
||||
tmr->mode &= ~TIMER_IDLE_FLAG;
|
||||
if(idle) {
|
||||
tmr->mode &= ~TIMER_IDLE_FLAG;
|
||||
os_timer_arm(&tmr->os, tmr->interval, tmr->mode==TIMER_MODE_AUTO);
|
||||
lua_pushboolean(L, 1);
|
||||
}
|
||||
}
|
||||
lua_pushboolean(L, !idle); /* false if the timer is not idle */
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Lua: tmr.alarm( id / ref, interval, repeat, function )
|
||||
// Lua: t:alarm( interval, repeat, function )
|
||||
static int tmr_alarm(lua_State* L){
|
||||
tmr_register(L);
|
||||
return tmr_start(L);
|
||||
}
|
||||
|
||||
// Lua: tmr.stop( id / ref )
|
||||
// Lua: t:stop()
|
||||
static int tmr_stop(lua_State* L){
|
||||
tmr_t tmr = tmr_get(L, 1);
|
||||
tmr_t *tmr = (tmr_t *) luaL_checkudata(L, 1, "tmr.timer");
|
||||
int idle = tmr->mode == TIMER_MODE_OFF || (tmr->mode & TIMER_IDLE_FLAG);
|
||||
luaL_unref2(L, LUA_REGISTRYINDEX, tmr->self_ref);
|
||||
|
||||
if (tmr->self_ref != LUA_REFNIL) {
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, tmr->self_ref);
|
||||
tmr->self_ref = LUA_NOREF;
|
||||
}
|
||||
|
||||
//we return false if the timer is idle (of not registered)
|
||||
if(!(tmr->mode & TIMER_IDLE_FLAG) && tmr->mode != TIMER_MODE_OFF){
|
||||
tmr->mode |= TIMER_IDLE_FLAG;
|
||||
if(!idle)
|
||||
os_timer_disarm(&tmr->os);
|
||||
lua_pushboolean(L, 1);
|
||||
}else{
|
||||
lua_pushboolean(L, 0);
|
||||
}
|
||||
tmr->mode |= TIMER_IDLE_FLAG;
|
||||
lua_pushboolean(L, !idle); /* return false if the timer is idle (or not registered) */
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef TIMER_SUSPEND_ENABLE
|
||||
|
||||
#define TMR_SUSPEND_REMOVED_MSG "This feature has been removed, we apologize for any inconvenience this may have caused."
|
||||
static int tmr_suspend(lua_State* L){
|
||||
#define tmr_suspend tmr_suspend_removed
|
||||
#define tmr_resume tmr_suspend_removed
|
||||
#define tmr_suspend_all tmr_suspend_removed
|
||||
#define tmr_resume_all tmr_suspend_removed
|
||||
static int tmr_suspend_removed(lua_State* L){
|
||||
return luaL_error(L, TMR_SUSPEND_REMOVED_MSG);
|
||||
}
|
||||
|
||||
static int tmr_resume(lua_State* L){
|
||||
return luaL_error(L, TMR_SUSPEND_REMOVED_MSG);
|
||||
}
|
||||
|
||||
static int tmr_suspend_all (lua_State *L){
|
||||
return luaL_error(L, TMR_SUSPEND_REMOVED_MSG);
|
||||
}
|
||||
|
||||
static int tmr_resume_all (lua_State *L){
|
||||
return luaL_error(L, TMR_SUSPEND_REMOVED_MSG);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// Lua: tmr.unregister( id / ref )
|
||||
// Lua: t:unregister()
|
||||
static int tmr_unregister(lua_State* L){
|
||||
tmr_t tmr = tmr_get(L, 1);
|
||||
|
||||
if (tmr->self_ref != LUA_REFNIL) {
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, tmr->self_ref);
|
||||
tmr->self_ref = LUA_NOREF;
|
||||
}
|
||||
|
||||
tmr_t *tmr = (tmr_t *) luaL_checkudata(L, 1, "tmr.timer");
|
||||
luaL_unref2(L, LUA_REGISTRYINDEX, tmr->self_ref);
|
||||
luaL_unref2(L, LUA_REGISTRYINDEX, tmr->lua_ref);
|
||||
if(!(tmr->mode & TIMER_IDLE_FLAG) && tmr->mode != TIMER_MODE_OFF)
|
||||
os_timer_disarm(&tmr->os);
|
||||
if(tmr->lua_ref != LUA_NOREF)
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, tmr->lua_ref);
|
||||
tmr->lua_ref = LUA_NOREF;
|
||||
tmr->mode = TIMER_MODE_OFF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: tmr.interval( id / ref, interval )
|
||||
// Lua: t:interval( interval )
|
||||
static int tmr_interval(lua_State* L){
|
||||
tmr_t tmr = tmr_get(L, 1);
|
||||
|
||||
tmr_t *tmr = (tmr_t *) luaL_checkudata(L, 1, "tmr.timer");
|
||||
uint32_t interval = luaL_checkinteger(L, 2);
|
||||
luaL_argcheck(L, (interval > 0 && interval <= MAX_TIMEOUT), 2, MAX_TIMEOUT_ERR_STR);
|
||||
if(tmr->mode != TIMER_MODE_OFF){
|
||||
|
@ -283,10 +199,9 @@ static int tmr_interval(lua_State* L){
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Lua: tmr.state( id / ref )
|
||||
// Lua: t:state()
|
||||
static int tmr_state(lua_State* L){
|
||||
tmr_t tmr = tmr_get(L, 1);
|
||||
|
||||
tmr_t *tmr = (tmr_t *) luaL_checkudata(L, 1, "tmr.timer");
|
||||
if(tmr->mode == TIMER_MODE_OFF){
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
|
@ -297,28 +212,21 @@ static int tmr_state(lua_State* L){
|
|||
return 2;
|
||||
}
|
||||
|
||||
/*I left the led comments 'couse I don't know
|
||||
why they are here*/
|
||||
|
||||
// extern void update_key_led();
|
||||
// Lua: tmr.wdclr()
|
||||
static int tmr_wdclr( lua_State* L ){
|
||||
system_soft_wdt_feed ();
|
||||
// update_key_led();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//system_rtc_clock_cali_proc() returns
|
||||
//a fixed point value (12 bit fraction part)
|
||||
//it tells how many rtc clock ticks represent 1us.
|
||||
//the high 64 bits of the uint64_t multiplication
|
||||
//are unnedded (I did the math)
|
||||
// The on ESP8266 system_rtc_clock_cali_proc() returns a fixed point value
|
||||
// (12 bit fraction part), giving how many rtc clock ticks represent 1us.
|
||||
// The high 64 bits of the uint64_t multiplication are not needed)
|
||||
static uint32_t rtc2usec(uint64_t rtc){
|
||||
return (rtc*rtc_time_cali)>>12;
|
||||
}
|
||||
|
||||
// This returns the number of microseconds uptime. Note that it relies on the rtc clock,
|
||||
// which is notoriously temperature dependent
|
||||
// This returns the number of microseconds uptime. Note that it relies on
|
||||
// the rtc clock, which is notoriously temperature dependent
|
||||
inline static uint64_t rtc_timer_update(bool do_calibration){
|
||||
if (do_calibration || rtc_time_cali==0)
|
||||
rtc_time_cali=system_rtc_clock_cali_proc();
|
||||
|
@ -330,8 +238,7 @@ inline static uint64_t rtc_timer_update(bool do_calibration){
|
|||
|
||||
// Only update if at least 100ms has passed since we last updated.
|
||||
// This prevents the rounding errors in rtc2usec from accumulating
|
||||
if (us_since_last>=100000)
|
||||
{
|
||||
if (us_since_last>=100000){
|
||||
last_rtc_time=current;
|
||||
last_rtc_time_us=now;
|
||||
}
|
||||
|
@ -356,20 +263,18 @@ static int tmr_time( lua_State* L ){
|
|||
|
||||
// Lua: tmr.softwd( value )
|
||||
static int tmr_softwd( lua_State* L ){
|
||||
soft_watchdog = luaL_checkinteger(L, 1);
|
||||
int t = luaL_checkinteger(L, 1);
|
||||
luaL_argcheck(L, t>0 , 2, "invalid time");
|
||||
soft_watchdog = t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: tmr.create()
|
||||
static int tmr_create( lua_State *L ) {
|
||||
tmr_t ud = (tmr_t)lua_newuserdata(L, sizeof(timer_struct_t));
|
||||
if (!ud) return luaL_error(L, "not enough memory");
|
||||
tmr_t *ud = (tmr_t *)lua_newuserdata(L, sizeof(*ud));
|
||||
luaL_getmetatable(L, "tmr.timer");
|
||||
lua_setmetatable(L, -2);
|
||||
ud->lua_ref = LUA_NOREF;
|
||||
ud->self_ref = LUA_NOREF;
|
||||
ud->mode = TIMER_MODE_OFF;
|
||||
os_timer_disarm(&ud->os);
|
||||
*ud = (tmr_t) {{0}, LUA_NOREF, LUA_NOREF, 0, TIMER_MODE_OFF};
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -422,13 +327,14 @@ int luaopen_tmr( lua_State *L ){
|
|||
os_timer_setfn(&rtc_timer, rtc_callback, NULL);
|
||||
os_timer_arm(&rtc_timer, 1000, 1);
|
||||
|
||||
// The function rtc_callback calls the a function that calibrates the SoftRTC
|
||||
// for drift in the esp8266's clock. My guess: after the duration of light_sleep
|
||||
// there is bound to be some drift in the clock, so a calibration is due.
|
||||
SWTIMER_REG_CB(rtc_callback, SWTIMER_RESUME);
|
||||
//The function rtc_callback calls the a function that calibrates the SoftRTC for drift in the esp8266's clock.
|
||||
//My guess: after the duration of light_sleep there's bound to be some drift in the clock, so a calibration is due.
|
||||
SWTIMER_REG_CB(alarm_timer_common, SWTIMER_RESUME);
|
||||
//The function alarm_timer_common handles timers created by the developer via tmr.create().
|
||||
//No reason not to resume the timers, so resume em'.
|
||||
|
||||
// The function alarm_timer_common handles timers created by the developer via
|
||||
// tmr.create(). No reason not to resume the timers, so resume em'.
|
||||
SWTIMER_REG_CB(alarm_timer_common, SWTIMER_RESUME);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ static void websocketclient_onConnectionCallback(ws_info *ws) {
|
|||
if (data->onConnection != LUA_NOREF) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, data->onConnection); // load the callback function
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref); // pass itself, #1 callback argument
|
||||
lua_call(L, 1, 0);
|
||||
luaL_pcallx(L, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ static void websocketclient_onReceiveCallback(ws_info *ws, int len, char *messag
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref); // pass itself, #1 callback argument
|
||||
lua_pushlstring(L, message, len); // #2 callback argument
|
||||
lua_pushnumber(L, opCode); // #3 callback argument
|
||||
lua_call(L, 3, 0);
|
||||
luaL_pcallx(L, 3, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ static void websocketclient_onCloseCallback(ws_info *ws, int errorCode) {
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, data->onClose); // load the callback function
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref); // pass itself, #1 callback argument
|
||||
lua_pushnumber(L, errorCode); // pass the error code, #2 callback argument
|
||||
lua_call(L, 2, 0);
|
||||
luaL_pcallx(L, 2, 0);
|
||||
}
|
||||
|
||||
// free self-reference to allow gc (no futher callback will be called until next ws:connect())
|
||||
|
@ -285,7 +285,7 @@ static int websocketclient_gc(lua_State *L) {
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, data->onClose);
|
||||
|
||||
lua_pushnumber(L, -100);
|
||||
lua_call(L, 1, 0);
|
||||
luaL_pcallx(L, 1, 0);
|
||||
}
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, data->onClose);
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ static void wifi_smart_succeed_cb(sc_status status, void *pdata){
|
|||
|
||||
lua_State* L = (lua_State *)arg;
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, wifi_smart_succeed);
|
||||
lua_call(L, 0, 0);
|
||||
luaL_pcallx(L, 0, 0);
|
||||
|
||||
#else
|
||||
|
||||
|
@ -64,9 +64,8 @@ static void wifi_smart_succeed_cb(sc_status status, void *pdata){
|
|||
|
||||
lua_pushstring(L, sta_conf->ssid);
|
||||
lua_pushstring(L, sta_conf->password);
|
||||
lua_call(L, 2, 0);
|
||||
|
||||
unregister_lua_cb(L, &wifi_smart_succeed);
|
||||
luaL_pcallx(L, 2, 0);
|
||||
}
|
||||
|
||||
#endif // defined( NODE_SMART_OLDSTYLE )
|
||||
|
@ -125,8 +124,8 @@ static void wifi_scan_done(void *arg, STATUS status)
|
|||
{
|
||||
lua_newtable( L );
|
||||
}
|
||||
lua_call(L, 1, 0);
|
||||
unregister_lua_cb(L, &wifi_scan_succeed);
|
||||
luaL_pcallx(L, 1, 0);
|
||||
}
|
||||
|
||||
#ifdef WIFI_SMART_ENABLE
|
||||
|
@ -438,9 +437,9 @@ void wifi_pmSleep_suspend_CB(void)
|
|||
{
|
||||
lua_State* L = lua_getstate(); // Get main Lua thread pointer
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, wifi_suspend_cb_ref); // Push suspend callback onto stack
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, wifi_suspend_cb_ref); // remove suspend callback from LUA_REGISTRY
|
||||
luaL_unref(L, wifi_suspend_cb_ref); // remove suspend callback from LUA_REGISTRY
|
||||
wifi_suspend_cb_ref = LUA_NOREF; // Update variable since reference is no longer valid
|
||||
lua_call(L, 0, 0); // Execute suspend callback
|
||||
luaL_pcallx(L, 0, 0); // Execute suspend callback
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -242,7 +242,7 @@ static void wifi_event_monitor_process_event_queue(task_param_t param, uint8 pri
|
|||
luaL_unref(L, LUA_REGISTRYINDEX, event_ref); //the userdata containing event info is no longer needed
|
||||
event_ref = LUA_NOREF;
|
||||
|
||||
lua_call(L, 1, 0); //execute user's callback and pass Lua table
|
||||
luaL_pcallx(L, 1, 0); //execute user's callback and pass Lua table
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -321,7 +321,7 @@ static void monitor_task(os_param_t param, uint8_t prio)
|
|||
|
||||
free(input);
|
||||
|
||||
lua_call(L, 1, 0);
|
||||
luaL_pcallx(L, 1, 0);
|
||||
} else {
|
||||
free(input);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ LOCAL void ICACHE_FLASH_ATTR user_wps_status_cb(int status)
|
|||
if (wps_callback_ref != LUA_NOREF) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, wps_callback_ref);
|
||||
lua_pushinteger(L, status);
|
||||
lua_call(L, 1, 0);
|
||||
luaL_pcallx(L, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,13 +18,14 @@
|
|||
|
||||
#include "pcm.h"
|
||||
|
||||
static void dispatch_callback( lua_State *L, int self_ref, int cb_ref, int returns )
|
||||
static int dispatch_callback( lua_State *L, int self_ref, int cb_ref, int returns )
|
||||
{
|
||||
if (cb_ref != LUA_NOREF) {
|
||||
lua_rawgeti( L, LUA_REGISTRYINDEX, cb_ref );
|
||||
lua_rawgeti( L, LUA_REGISTRYINDEX, self_ref );
|
||||
lua_call( L, 1, returns );
|
||||
return luaL_pcallx( L, 1, returns );
|
||||
}
|
||||
return LUA_OK;
|
||||
}
|
||||
|
||||
void pcm_data_vu( task_param_t param, uint8 prio )
|
||||
|
@ -36,7 +37,7 @@ void pcm_data_vu( task_param_t param, uint8 prio )
|
|||
lua_rawgeti( L, LUA_REGISTRYINDEX, cfg->cb_vu_ref );
|
||||
lua_rawgeti( L, LUA_REGISTRYINDEX, cfg->self_ref );
|
||||
lua_pushnumber( L, (LUA_NUMBER)(cfg->vu_peak) );
|
||||
lua_call( L, 2, 0 );
|
||||
luaL_pcallx( L, 2, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +53,8 @@ void pcm_data_play( task_param_t param, uint8 prio )
|
|||
// retrieve new data from callback
|
||||
if ((cfg->isr_throttled >= 0) &&
|
||||
(cfg->cb_data_ref != LUA_NOREF)) {
|
||||
dispatch_callback( L, cfg->self_ref, cfg->cb_data_ref, 1 );
|
||||
if(dispatch_callback( L, cfg->self_ref, cfg->cb_data_ref, 1 ) != LUA_OK)
|
||||
return;
|
||||
need_pop = TRUE;
|
||||
|
||||
if (lua_type( L, -1 ) == LUA_TSTRING) {
|
||||
|
|
|
@ -26,12 +26,12 @@ struct gpio_hook_entry {
|
|||
uint32_t bits;
|
||||
};
|
||||
struct gpio_hook {
|
||||
struct gpio_hook_entry *entry;
|
||||
uint32_t all_bits;
|
||||
uint32_t count;
|
||||
struct gpio_hook_entry entry[1];
|
||||
};
|
||||
|
||||
static struct gpio_hook platform_gpio_hook;
|
||||
static struct gpio_hook *platform_gpio_hook;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -218,10 +218,10 @@ static void ICACHE_RAM_ATTR platform_gpio_intr_dispatcher (void *dummy){
|
|||
UNUSED(dummy);
|
||||
|
||||
#ifdef GPIO_INTERRUPT_HOOK_ENABLE
|
||||
if (gpio_status & platform_gpio_hook.all_bits) {
|
||||
for (j = 0; j < platform_gpio_hook.count; j++) {
|
||||
if (gpio_status & platform_gpio_hook.entry[j].bits)
|
||||
gpio_status = (platform_gpio_hook.entry[j].func)(gpio_status);
|
||||
if (gpio_status & platform_gpio_hook->all_bits) {
|
||||
for (j = 0; j < platform_gpio_hook->count; j++) {
|
||||
if (gpio_status & platform_gpio_hook->entry[j].bits)
|
||||
gpio_status = (platform_gpio_hook->entry[j].func)(gpio_status);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -266,7 +266,8 @@ static void ICACHE_RAM_ATTR platform_gpio_intr_dispatcher (void *dummy){
|
|||
void platform_gpio_init( platform_task_handle_t gpio_task )
|
||||
{
|
||||
gpio_task_handle = gpio_task;
|
||||
|
||||
// No error handling but this is called at startup when there is a lot of free RAM
|
||||
platform_gpio_hook = calloc (1, sizeof(*platform_gpio_hook) - sizeof(struct gpio_hook_entry));
|
||||
ETS_GPIO_INTR_ATTACH(platform_gpio_intr_dispatcher, NULL);
|
||||
}
|
||||
|
||||
|
@ -281,78 +282,53 @@ void platform_gpio_init( platform_task_handle_t gpio_task )
|
|||
*/
|
||||
int platform_gpio_register_intr_hook(uint32_t bits, platform_hook_function hook)
|
||||
{
|
||||
struct gpio_hook nh, oh = platform_gpio_hook;
|
||||
int i, j;
|
||||
struct gpio_hook *oh = platform_gpio_hook;
|
||||
int i, j, cur = -1;
|
||||
|
||||
if (!hook) {
|
||||
// Cannot register or unregister null hook
|
||||
if (!hook) // Cannot register or unregister null hook
|
||||
return 0;
|
||||
}
|
||||
|
||||
int delete_slot = -1;
|
||||
|
||||
// If hook already registered, just update the bits
|
||||
for (i=0; i<oh.count; i++) {
|
||||
if (hook == oh.entry[i].func) {
|
||||
if (!bits) {
|
||||
// Unregister if move to zero bits
|
||||
delete_slot = i;
|
||||
break;
|
||||
}
|
||||
if (bits & (oh.all_bits & ~oh.entry[i].bits)) {
|
||||
// Attempt to hook an already hooked bit
|
||||
return 0;
|
||||
}
|
||||
// Update the hooked bits (in the right order)
|
||||
uint32_t old_bits = oh.entry[i].bits;
|
||||
*(volatile uint32_t *) &oh.entry[i].bits = bits;
|
||||
*(volatile uint32_t *) &oh.all_bits = (oh.all_bits & ~old_bits) | bits;
|
||||
ETS_GPIO_INTR_DISABLE();
|
||||
// This is a structure copy, so interrupts need to be disabled
|
||||
platform_gpio_hook = oh;
|
||||
ETS_GPIO_INTR_ENABLE();
|
||||
return 1;
|
||||
// Is the hook already registered?
|
||||
for (i=0; i<oh->count; i++) {
|
||||
if (hook == oh->entry[i].func) {
|
||||
cur = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// This must be the register new hook / delete old hook
|
||||
// return error status if there is a bits clash
|
||||
if (oh->all_bits & ~(cur < 0 ? 0 : oh->entry[cur].bits) & bits)
|
||||
return 0;
|
||||
|
||||
if (delete_slot < 0) {
|
||||
if (bits & oh.all_bits) {
|
||||
return 0; // Attempt to hook already hooked bits
|
||||
}
|
||||
nh.count = oh.count + 1; // register a new hook
|
||||
} else {
|
||||
nh.count = oh.count - 1; // unregister an old hook
|
||||
// Allocate replacement hook block and return 0 on alloc failure
|
||||
int count = oh->count + (cur < 0 ? 1 : (bits == 0 ? -1 : 0));
|
||||
struct gpio_hook *nh = malloc (sizeof *oh + (count -1)*sizeof(struct gpio_hook_entry));
|
||||
if (!oh)
|
||||
return 0;
|
||||
|
||||
nh->all_bits = 0;
|
||||
nh->count = count;
|
||||
|
||||
for (i=0, j=0; i<oh->count; i++) {
|
||||
if (i == cur && !bits)
|
||||
continue; /* unregister entry is a no-op */
|
||||
nh->entry[j] = oh->entry[i]; /* copy existing entry */
|
||||
if (i == cur)
|
||||
nh->entry[j].bits = bits; /* update bits if this is a replacement */
|
||||
nh->all_bits |= nh->entry[j++].bits;
|
||||
}
|
||||
|
||||
// These return NULL if the count = 0 so only error check if > 0)
|
||||
nh.entry = malloc( nh.count * sizeof(*(nh.entry)) );
|
||||
if (nh.count && !(nh.entry)) {
|
||||
return 0; // Allocation failure
|
||||
}
|
||||
|
||||
for (i=0, j=0; i<oh.count; i++) {
|
||||
// Don't copy if this is the entry to delete
|
||||
if (i != delete_slot) {
|
||||
nh.entry[j++] = oh.entry[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (delete_slot < 0) { // for a register add the hook to the tail and set the all bits
|
||||
nh.entry[j].bits = bits;
|
||||
nh.entry[j].func = hook;
|
||||
nh.all_bits = oh.all_bits | bits;
|
||||
} else { // for an unregister clear the matching all bits
|
||||
nh.all_bits = oh.all_bits & (~oh.entry[delete_slot].bits);
|
||||
}
|
||||
|
||||
|
||||
if (cur < 0) { /* append new hook entry */
|
||||
nh->entry[j].func = hook;
|
||||
nh->entry[j].bits = bits;
|
||||
nh->all_bits |= bits;
|
||||
}
|
||||
|
||||
ETS_GPIO_INTR_DISABLE();
|
||||
// This is a structure copy, so interrupts need to be disabled
|
||||
platform_gpio_hook = nh;
|
||||
ETS_GPIO_INTR_ENABLE();
|
||||
|
||||
free(oh.entry);
|
||||
free(oh);
|
||||
return 1;
|
||||
}
|
||||
#endif // GPIO_INTERRUPT_HOOK_ENABLE
|
||||
|
|
|
@ -162,7 +162,7 @@ void pmSleep_execute_lua_cb(int* cb_ref){
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, *cb_ref); // Push resume callback onto the stack
|
||||
lua_unref(L, *cb_ref); // Remove resume callback from registry
|
||||
*cb_ref = LUA_NOREF; // Update variable since reference is no longer valid
|
||||
lua_call(L, 0, 0); // Execute resume callback
|
||||
luaL_pcallx(L, 0, 0); // Execute resume callback
|
||||
}
|
||||
|
||||
}
|
||||
|
|
174
app/pm/swtimer.c
174
app/pm/swtimer.c
|
@ -8,33 +8,33 @@
|
|||
* The SDK software timer API executes in a task. The priority of this task in relation to the
|
||||
* application level tasks is unknown (at time of writing).
|
||||
*
|
||||
*
|
||||
* To determine when a timer's callback should be executed, the respective timer's `timer_expire`
|
||||
* variable is compared to the hardware counter(FRC2), then, if the timer's `timer_expire` is
|
||||
* less than the current FRC2 count, the timer's callback is fired.
|
||||
* variable is compared to the hardware counter(FRC2), then, if the timer's `timer_expire` is
|
||||
* less than the current FRC2 count, the timer's callback is fired.
|
||||
*
|
||||
* The timers in this list are organized in an ascending order starting with the timer
|
||||
* with the lowest timer_expire.
|
||||
*
|
||||
* When a timer expires that has a timer_period greater than 0, timer_expire is changed to
|
||||
* current FRC2 + timer_period, then the timer is inserted back in to the list in the correct position.
|
||||
* When a timer expires that has a timer_period greater than 0, timer_expire is changed to current
|
||||
* FRC2 + timer_period, then the timer is inserted back in to the list in the correct position.
|
||||
*
|
||||
* when using millisecond(default) timers, FRC2 resolution is 312.5 ticks per millisecond.
|
||||
* When using millisecond(default) timers, FRC2 resolution is 312.5 ticks per millisecond.
|
||||
*
|
||||
*
|
||||
* TIMER SUSPEND API INFO:
|
||||
*
|
||||
* Timer suspension is achieved by first finding any non-SDK timers by comparing the timer function callback pointer
|
||||
* of each timer in "timer_list" to a list of registered timer callback pointers stored in the Lua registry.
|
||||
* If a timer with a corresponding registered callback pointer is found, the timer's timer_expire field is is compared
|
||||
* to the current FRC2 count and the difference is saved along with the other timer parameters to temporary variables.
|
||||
* The timer is then disarmed and the parameters are copied back, the timer pointer is then
|
||||
* added to a separate linked list of which the head pointer is stored as a lightuserdata in the lua registry.
|
||||
* Timer suspension is achieved by first finding any non-SDK timers by comparing the timer function
|
||||
* callback pointer of each timer in "timer_list" to a list of registered timer callback pointers
|
||||
* stored in the Lua registry. If a timer with a corresponding registered callback pointer is found,
|
||||
* the timer's timer_expire field is is compared to the current FRC2 count and the difference is
|
||||
* saved along with the other timer parameters to temporary variables. The timer is then disarmed
|
||||
* and the parameters are copied back, the timer pointer is then added to a separate linked list of
|
||||
* which the head pointer is stored as a lightuserdata in the lua registry.
|
||||
*
|
||||
* Resuming the timers is achieved by first retrieving the lightuserdata holding the suspended timer list head pointer.
|
||||
* Then, starting with the beginning of the list the current FRC2 count is added back to the timer's timer_expire, then
|
||||
* the timer is manually added back to "timer_list" in an ascending order.
|
||||
* Once there are no more suspended timers, the function returns
|
||||
* Resuming the timers is achieved by first retrieving the lightuserdata holding the suspended timer
|
||||
* list head pointer. Then, starting with the beginning of the list the current FRC2 count is added
|
||||
* back to the timer's timer_expire, then the timer is manually added back to "timer_list" in an
|
||||
* ascending order. Once there are no more suspended timers, the function returns.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
@ -57,17 +57,24 @@
|
|||
#define SWTMR_DEBUG
|
||||
#endif
|
||||
|
||||
//this section specifies which lua registry to use. LUA_GLOBALSINDEX or LUA_REGISTRYINDEX
|
||||
// The SWTMR table is either normally stored in the Lua registry, but at _G.SWTMR_registry_key
|
||||
// when in debug. THe CB and suspend lists have different names depending of debugging mode.
|
||||
// Also
|
||||
#ifdef SWTMR_DEBUG
|
||||
#define SWTMR_DBG(fmt, ...) dbg_printf("\n SWTMR_DBG(%s): "fmt"\n", __FUNCTION__, ##__VA_ARGS__)
|
||||
#define L_REGISTRY LUA_GLOBALSINDEX
|
||||
#define CB_LIST_STR "timer_cb_ptrs"
|
||||
#define SUSP_LIST_STR "suspended_tmr_LL_head"
|
||||
#define get_swtmr_registry(L) lua_getglobal(L, "SWTMR_registry_key")
|
||||
#define set_swtmr_registry(L) lua_setglobal(L, "SWTMR_registry_key")
|
||||
#else
|
||||
#define SWTMR_DBG(...)
|
||||
#define L_REGISTRY LUA_REGISTRYINDEX
|
||||
#define CB_LIST_STR "cb"
|
||||
#define SUSP_LIST_STR "st"
|
||||
#define get_swtmr_registry(L) lua_pushlightuserdata(L, ®ister_queue); \
|
||||
lua_rawget(L, LUA_REGISTRYINDEX)
|
||||
#define set_swtmr_registry(L) lua_pushlightuserdata(L, ®ister_queue); \
|
||||
lua_insert(L, -2); \
|
||||
lua_rawset(L, LUA_REGISTRYINDEX)
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -92,32 +99,21 @@ static task_handle_t cb_register_task_id = 0; //variable to hold task id for tas
|
|||
static void add_to_reg_queue(void* timer_cb_ptr, uint8 suspend_policy);
|
||||
static void process_cb_register_queue(task_param_t param, uint8 priority);
|
||||
|
||||
|
||||
#ifdef SWTMR_DEBUG
|
||||
#define push_swtmr_registry_key(L) lua_pushstring(L, "SWTMR_registry_key")
|
||||
#else
|
||||
#define push_swtmr_registry_key(L) lua_pushlightuserdata(L, ®ister_queue);
|
||||
#endif
|
||||
|
||||
#include <pm/swtimer.h>
|
||||
|
||||
void swtmr_suspend_timers(){
|
||||
lua_State* L = lua_getstate();
|
||||
|
||||
//get swtimer table
|
||||
push_swtmr_registry_key(L);
|
||||
lua_rawget(L, L_REGISTRY);
|
||||
get_swtmr_registry(L);
|
||||
if(!lua_istable(L, -1)) {lua_pop(L, 1); return;}
|
||||
|
||||
//get cb_list table
|
||||
lua_pushstring(L, CB_LIST_STR);
|
||||
lua_rawget(L, -2);
|
||||
|
||||
//check for existence of the swtimer table and the cb_list table, return if not found
|
||||
if(!lua_istable(L, -2) || !lua_istable(L, -1)){
|
||||
// not necessarily an error maybe there are legitimately no timers to suspend
|
||||
lua_pop(L, 2);
|
||||
return;
|
||||
}
|
||||
//check for existence of the cb_list table, return if not found
|
||||
if(!lua_istable(L, -1)) {lua_pop(L, 2); return;}
|
||||
|
||||
os_timer_t* suspended_timer_list_head = NULL;
|
||||
os_timer_t* suspended_timer_list_tail = NULL;
|
||||
|
@ -168,10 +164,10 @@ void swtmr_suspend_timers(){
|
|||
uint32 period_temp = 0;
|
||||
void* arg_temp = NULL;
|
||||
|
||||
/* In this section, the SDK's timer_list is traversed to find any timers that have a registered callback pointer.
|
||||
* If a registered callback is found, the timer is suspended by saving the difference
|
||||
* between frc2_count and timer_expire then the timer is disarmed and placed into suspended_timer_list
|
||||
* so it can later be resumed.
|
||||
/* In this section, the SDK's timer_list is traversed to find any timers that have a registered
|
||||
* callback pointer. If a registered callback is found, the timer is suspended by saving the
|
||||
* difference between frc2_count and timer_expire then the timer is disarmed and placed into
|
||||
* suspended_timer_list so it can later be resumed.
|
||||
*/
|
||||
while(timer_ptr != NULL){
|
||||
os_timer_t* next_timer = (os_timer_t*)0xffffffff;
|
||||
|
@ -190,7 +186,8 @@ void swtmr_suspend_timers(){
|
|||
arg_temp = timer_ptr->timer_arg;
|
||||
|
||||
if(timer_ptr->timer_period == 0 && cb_reg_array[i]->suspend_policy == SWTIMER_RESTART){
|
||||
SWTMR_DBG("Warning: suspend_policy(RESTART) is not compatible with single-shot timer(%p), changing suspend_policy to (RESUME)", timer_ptr);
|
||||
SWTMR_DBG("Warning: suspend_policy(RESTART) is not compatible with single-shot timer(%p), "
|
||||
"changing suspend_policy to (RESUME)", timer_ptr);
|
||||
cb_reg_array[i]->suspend_policy = SWTIMER_RESUME;
|
||||
}
|
||||
|
||||
|
@ -260,19 +257,15 @@ void swtmr_resume_timers(){
|
|||
lua_State* L = lua_getstate();
|
||||
|
||||
//get swtimer table
|
||||
push_swtmr_registry_key(L);
|
||||
lua_rawget(L, L_REGISTRY);
|
||||
get_swtmr_registry(L);
|
||||
if(!lua_istable(L, -1)) {lua_pop(L, 1); return;}
|
||||
|
||||
//get suspended_timer_list lightuserdata
|
||||
lua_pushstring(L, SUSP_LIST_STR);
|
||||
lua_rawget(L, -2);
|
||||
|
||||
//check for existence of swtimer table and the suspended_timer_list pointer userdata, return if not found
|
||||
if(!lua_istable(L, -2) || !lua_isuserdata(L, -1)){
|
||||
// not necessarily an error maybe there are legitimately no timers to resume
|
||||
lua_pop(L, 2);
|
||||
return;
|
||||
}
|
||||
//check for existence of the suspended_timer_list pointer userdata, return if not found
|
||||
if(!lua_isuserdata(L, -1)) {lua_pop(L, 2); return;}
|
||||
|
||||
os_timer_t* suspended_timer_list_ptr = lua_touserdata(L, -1);
|
||||
lua_pop(L, 1); //pop suspended timer list userdata from stack
|
||||
|
@ -339,25 +332,21 @@ void swtmr_resume_timers(){
|
|||
void swtmr_cb_register(void* timer_cb_ptr, uint8 suspend_policy){
|
||||
lua_State* L = lua_getstate();
|
||||
if(!L){
|
||||
//Lua has not started yet, therefore L_REGISTRY is not available.
|
||||
//add timer cb to queue for later processing after Lua has started
|
||||
// If Lua has not started yet, then add timer cb to queue for later processing after Lua has started
|
||||
add_to_reg_queue(timer_cb_ptr, suspend_policy);
|
||||
return;
|
||||
}
|
||||
if(timer_cb_ptr){
|
||||
size_t cb_list_last_idx = 0;
|
||||
|
||||
push_swtmr_registry_key(L);
|
||||
lua_rawget(L, L_REGISTRY);
|
||||
get_swtmr_registry(L);
|
||||
|
||||
if(!lua_istable(L, -1)){
|
||||
//swtmr does not exist, create and add to registry
|
||||
//swtmr does not exist, create and add to registry and leave table as ToS
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L);//push new table for swtmr.timer_cb_list
|
||||
// add swtimer table to L_REGISTRY
|
||||
push_swtmr_registry_key(L);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_rawset(L, L_REGISTRY);
|
||||
lua_newtable(L);
|
||||
lua_pushvalue(L, -1);
|
||||
set_swtmr_registry(L);
|
||||
}
|
||||
|
||||
lua_pushstring(L, CB_LIST_STR);
|
||||
|
@ -439,41 +428,40 @@ static void process_cb_register_queue(task_param_t param, uint8 priority)
|
|||
|
||||
#ifdef SWTMR_DEBUG
|
||||
int print_timer_list(lua_State* L){
|
||||
push_swtmr_registry_key(L);
|
||||
lua_rawget(L, L_REGISTRY);
|
||||
lua_pushstring(L, CB_LIST_STR);
|
||||
lua_rawget(L, -2);
|
||||
if(!lua_istable(L, -2) || !lua_istable(L, -1)){
|
||||
lua_pop(L, 2);
|
||||
return 0;
|
||||
get_swtmr_registry(L);
|
||||
if(!lua_istable(L, -1)) {lua_pop(L, 1); return 0;}
|
||||
|
||||
lua_pushstring(L, CB_LIST_STR);
|
||||
lua_rawget(L, -2);
|
||||
if(!lua_istable(L, -1)) {lua_pop(L, 2); return 0;}
|
||||
|
||||
os_timer_t* suspended_timer_list_head = NULL;
|
||||
os_timer_t* suspended_timer_list_tail = NULL;
|
||||
lua_pushstring(L, SUSP_LIST_STR);
|
||||
lua_rawget(L, -3);
|
||||
if(lua_isuserdata(L, -1)){
|
||||
suspended_timer_list_head = suspended_timer_list_tail = lua_touserdata(L, -1);
|
||||
while(suspended_timer_list_tail->timer_next != NULL){
|
||||
suspended_timer_list_tail = suspended_timer_list_tail->timer_next;
|
||||
}
|
||||
os_timer_t* suspended_timer_list_head = NULL;
|
||||
os_timer_t* suspended_timer_list_tail = NULL;
|
||||
lua_pushstring(L, SUSP_LIST_STR);
|
||||
lua_rawget(L, -3);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
size_t registered_cb_qty = lua_objlen(L, -1);
|
||||
cb_registry_item_t** cb_reg_array = calloc(1,sizeof(cb_registry_item_t*)*registered_cb_qty);
|
||||
if(!cb_reg_array){
|
||||
luaL_error(L, "%s: unable to suspend timers, out of memory!", __func__);
|
||||
return 0;
|
||||
}
|
||||
uint8 index = 0;
|
||||
lua_pushnil(L);
|
||||
while(lua_next(L, -2) != 0){
|
||||
if(lua_isuserdata(L, -1)){
|
||||
suspended_timer_list_head = suspended_timer_list_tail = lua_touserdata(L, -1);
|
||||
while(suspended_timer_list_tail->timer_next != NULL){
|
||||
suspended_timer_list_tail = suspended_timer_list_tail->timer_next;
|
||||
}
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
size_t registered_cb_qty = lua_objlen(L, -1);
|
||||
cb_registry_item_t** cb_reg_array = calloc(1,sizeof(cb_registry_item_t*)*registered_cb_qty);
|
||||
if(!cb_reg_array){
|
||||
luaL_error(L, "%s: unable to suspend timers, out of memory!", __func__);
|
||||
return 0;
|
||||
}
|
||||
uint8 index = 0;
|
||||
lua_pushnil(L);
|
||||
while(lua_next(L, -2) != 0){
|
||||
if(lua_isuserdata(L, -1)){
|
||||
cb_reg_array[index] = lua_touserdata(L, -1);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
index++;
|
||||
cb_reg_array[index] = lua_touserdata(L, -1);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
index++;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
|
||||
os_timer_t* timer_list_ptr = timer_list;
|
||||
|
@ -499,9 +487,7 @@ int print_timer_list(lua_State* L){
|
|||
}
|
||||
|
||||
int print_susp_timer_list(lua_State* L){
|
||||
push_swtmr_registry_key(L);
|
||||
lua_rawget(L, L_REGISTRY);
|
||||
|
||||
get_swtmr_registry(L);
|
||||
if(!lua_istable(L, -1)){
|
||||
return luaL_error(L, "swtmr table not found!");
|
||||
}
|
||||
|
@ -516,7 +502,9 @@ int print_susp_timer_list(lua_State* L){
|
|||
os_timer_t* susp_timer_list_ptr = lua_touserdata(L, -1);
|
||||
dbg_printf("\n\tsuspended_timer_list:\n");
|
||||
while(susp_timer_list_ptr != NULL){
|
||||
dbg_printf("\tptr:%p\tcb:%p\texpire:%8u\tperiod:%8u\tnext:%p\n",susp_timer_list_ptr, susp_timer_list_ptr->timer_func, susp_timer_list_ptr->timer_expire, susp_timer_list_ptr->timer_period, susp_timer_list_ptr->timer_next);
|
||||
dbg_printf("\tptr:%p\tcb:%p\texpire:%8u\tperiod:%8u\tnext:%p\n",susp_timer_list_ptr,
|
||||
susp_timer_list_ptr->timer_func, susp_timer_list_ptr->timer_expire,
|
||||
susp_timer_list_ptr->timer_period, susp_timer_list_ptr->timer_next);
|
||||
susp_timer_list_ptr = susp_timer_list_ptr->timer_next;
|
||||
}
|
||||
return 0;
|
||||
|
@ -542,5 +530,5 @@ LROT_END(test_swtimer_debug, NULL, 0)
|
|||
|
||||
NODEMCU_MODULE(SWTMR_DBG, "SWTMR_DBG", test_swtimer_debug, NULL);
|
||||
|
||||
#endif
|
||||
#endif /* SWTMR_DEBUG */
|
||||
|
||||
|
|
|
@ -22,4 +22,5 @@
|
|||
// Reduce the chance of returning disk full
|
||||
#define SPIFFS_GC_MAX_RUNS 256
|
||||
|
||||
#define SPIFFS_SECURE_ERASE 0
|
||||
#endif
|
||||
|
|
|
@ -93,7 +93,7 @@ static bool myspiffs_set_cfg(spiffs_config *cfg, bool force_create) {
|
|||
|
||||
if (cfg->phys_size < MIN_BLOCKS_FS * LOG_BLOCK_SIZE_SMALL_FS) {
|
||||
return FALSE;
|
||||
} else if (cfg->phys_size < MIN_BLOCKS_FS * LOG_BLOCK_SIZE_SMALL_FS) {
|
||||
} else if (cfg->phys_size < MIN_BLOCKS_FS * LOG_BLOCK_SIZE) {
|
||||
cfg->log_block_size = LOG_BLOCK_SIZE_SMALL_FS;
|
||||
} else {
|
||||
cfg->log_block_size = LOG_BLOCK_SIZE;
|
||||
|
|
|
@ -889,6 +889,16 @@ s32_t spiffs_page_delete(
|
|||
fs->stats_p_deleted++;
|
||||
fs->stats_p_allocated--;
|
||||
|
||||
#if SPIFFS_SECURE_ERASE
|
||||
// Secure erase
|
||||
unsigned char data[SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header)];
|
||||
bzero(data, sizeof(data));
|
||||
res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_DELE,
|
||||
0,
|
||||
SPIFFS_PAGE_TO_PADDR(fs, pix) + sizeof(spiffs_page_header), sizeof(data), data);
|
||||
SPIFFS_CHECK_RES(res);
|
||||
#endif
|
||||
|
||||
// mark deleted in source page
|
||||
u8_t flags = 0xff;
|
||||
#if SPIFFS_NO_BLIND_WRITES
|
||||
|
@ -2030,7 +2040,7 @@ s32_t spiffs_object_read(
|
|||
// remaining data in page
|
||||
len_to_read = MIN(len_to_read, SPIFFS_DATA_PAGE_SIZE(fs) - (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs)));
|
||||
// remaining data in file
|
||||
len_to_read = MIN(len_to_read, fd->size);
|
||||
len_to_read = MIN(len_to_read, fd->size - cur_offset);
|
||||
SPIFFS_DBG("read: offset:"_SPIPRIi" rd:"_SPIPRIi" data spix:"_SPIPRIsp" is data_pix:"_SPIPRIpg" addr:"_SPIPRIad"\n", cur_offset, len_to_read, data_spix, data_pix,
|
||||
(u32_t)(SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs))));
|
||||
if (len_to_read <= 0) {
|
||||
|
|
|
@ -262,8 +262,8 @@
|
|||
#define SPIFFS_FH_OFFS(fs, fh) ((fh) != 0 ? ((fh) + (fs)->cfg.fh_ix_offset) : 0)
|
||||
#define SPIFFS_FH_UNOFFS(fs, fh) ((fh) != 0 ? ((fh) - (fs)->cfg.fh_ix_offset) : 0)
|
||||
#else
|
||||
#define SPIFFS_FH_OFFS(fs, fh) (fh)
|
||||
#define SPIFFS_FH_UNOFFS(fs, fh) (fh)
|
||||
#define SPIFFS_FH_OFFS(fs, fh) ((spiffs_file)(fh))
|
||||
#define SPIFFS_FH_UNOFFS(fs, fh) ((spiffs_file)(fh))
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -476,9 +476,6 @@ typedef struct {
|
|||
|
||||
|
||||
// object structs
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack ( push, 1 )
|
||||
#endif
|
||||
|
||||
// page header, part of each page except object lookup pages
|
||||
// NB: this is always aligned when the data page is an object index,
|
||||
|
@ -496,10 +493,9 @@ typedef struct SPIFFS_PACKED {
|
|||
typedef struct SPIFFS_PACKED
|
||||
#if SPIFFS_ALIGNED_OBJECT_INDEX_TABLES
|
||||
#ifdef _MSC_VER
|
||||
//Note: the following needs to track the sizeof(spiffs_page_ix), which is defined in spiffs_config.h
|
||||
__declspec( align( 2 ) )
|
||||
__declspec( align( 2 ) ) // must track sizeof(spiffs_page_ix) in spiffs_config.h
|
||||
#else
|
||||
__attribute(( aligned(sizeof(spiffs_page_ix)) ))
|
||||
__attribute(( aligned(sizeof(spiffs_page_ix)) ))
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
|
@ -525,10 +521,6 @@ typedef struct SPIFFS_PACKED {
|
|||
u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))];
|
||||
} spiffs_page_object_ix;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack ( pop )
|
||||
#endif
|
||||
|
||||
// callback func for object lookup visitor
|
||||
typedef s32_t (*spiffs_visitor_f)(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry,
|
||||
const void *user_const_p, void *user_var_p);
|
||||
|
|
|
@ -86,7 +86,7 @@ static uint8_t u8x8_d_fbrle(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *ar
|
|||
lua_State *L = lua_getstate();
|
||||
lua_rawgeti( L, LUA_REGISTRYINDEX, ext_u8g2->overlay.rfb_cb_ref );
|
||||
lua_pushnil( L );
|
||||
lua_call( L, 1, 0 );
|
||||
luaL_pcallx( L, 1, 0 );
|
||||
}
|
||||
// and note ongoing framebuffer update
|
||||
ext_u8g2->overlay.fb_update_ongoing = 1;
|
||||
|
@ -143,7 +143,7 @@ static uint8_t u8x8_d_fbrle(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *ar
|
|||
|
||||
lua_rawgeti( L, LUA_REGISTRYINDEX, ext_u8g2->overlay.rfb_cb_ref );
|
||||
lua_pushlstring( L, (const char *)fbrle_line, fbrle_line_size );
|
||||
lua_call( L, 1, 0 );
|
||||
luaL_pcallx( L, 1, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
local gpio, bit = gpio, bit
|
||||
local gpio, bit = gpio, bit --luacheck: read globals gpio bit
|
||||
|
||||
return function(bus_args)
|
||||
local rs = bus_args.rs or 0
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
local gpio, bit = gpio, bit
|
||||
local gpio, bit = gpio, bit --luacheck: read globals gpio bit
|
||||
|
||||
return function(bus_args)
|
||||
local rs = bus_args.rs or 0
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
local i2c, bit = i2c, bit
|
||||
local i2c, bit = i2c, bit --luacheck: read globals i2c bit
|
||||
|
||||
return function(bus_args)
|
||||
local busid = bus_args.id or 0
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
local bit = bit
|
||||
local bit = bit --luacheck: read globals bit
|
||||
-- metatable
|
||||
local LiquidCrystal = {}
|
||||
LiquidCrystal.__index = LiquidCrystal
|
||||
|
|
Loading…
Reference in New Issue