Implement panic call handling for all modules (#3163)

This commit is contained in:
Terry Ellison 2020-06-16 08:19:55 +01:00 committed by GitHub
parent 4e689e9839
commit 1f2e5bba4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 609 additions and 629 deletions

View File

@ -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

View File

@ -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

View File

@ -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 );

View File

@ -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

View File

@ -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 */

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);
}
/*

View File

@ -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);

View File

@ -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

View File

@ -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");

View File

@ -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

View File

@ -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 */
}

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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 );

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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
}
}

View File

@ -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

View File

@ -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);

View File

@ -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 );
}
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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
{

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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) {

View File

@ -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

View File

@ -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
}
}

View File

@ -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, &register_queue); \
lua_rawget(L, LUA_REGISTRYINDEX)
#define set_swtmr_registry(L) lua_pushlightuserdata(L, &register_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, &register_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 */

View File

@ -22,4 +22,5 @@
// Reduce the chance of returning disk full
#define SPIFFS_GC_MAX_RUNS 256
#define SPIFFS_SECURE_ERASE 0
#endif

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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 );
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,4 +1,4 @@
local bit = bit
local bit = bit --luacheck: read globals bit
-- metatable
local LiquidCrystal = {}
LiquidCrystal.__index = LiquidCrystal