Unverified Commit 1f2e5bba authored by Terry Ellison's avatar Terry Ellison Committed by GitHub
Browse files

Implement panic call handling for all modules (#3163)

parent 4e689e98
...@@ -41,7 +41,7 @@ static void websocketclient_onConnectionCallback(ws_info *ws) { ...@@ -41,7 +41,7 @@ static void websocketclient_onConnectionCallback(ws_info *ws) {
if (data->onConnection != LUA_NOREF) { if (data->onConnection != LUA_NOREF) {
lua_rawgeti(L, LUA_REGISTRYINDEX, data->onConnection); // load the callback function 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_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 ...@@ -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_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref); // pass itself, #1 callback argument
lua_pushlstring(L, message, len); // #2 callback argument lua_pushlstring(L, message, len); // #2 callback argument
lua_pushnumber(L, opCode); // #3 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) { ...@@ -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->onClose); // load the callback function
lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref); // pass itself, #1 callback argument 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_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()) // 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) { ...@@ -285,7 +285,7 @@ static int websocketclient_gc(lua_State *L) {
lua_rawgeti(L, LUA_REGISTRYINDEX, data->onClose); lua_rawgeti(L, LUA_REGISTRYINDEX, data->onClose);
lua_pushnumber(L, -100); lua_pushnumber(L, -100);
lua_call(L, 1, 0); luaL_pcallx(L, 1, 0);
} }
luaL_unref(L, LUA_REGISTRYINDEX, data->onClose); luaL_unref(L, LUA_REGISTRYINDEX, data->onClose);
} }
......
...@@ -46,7 +46,7 @@ static void wifi_smart_succeed_cb(sc_status status, void *pdata){ ...@@ -46,7 +46,7 @@ static void wifi_smart_succeed_cb(sc_status status, void *pdata){
lua_State* L = (lua_State *)arg; lua_State* L = (lua_State *)arg;
lua_rawgeti(L, LUA_REGISTRYINDEX, wifi_smart_succeed); lua_rawgeti(L, LUA_REGISTRYINDEX, wifi_smart_succeed);
lua_call(L, 0, 0); luaL_pcallx(L, 0, 0);
#else #else
...@@ -64,9 +64,8 @@ static void wifi_smart_succeed_cb(sc_status status, void *pdata){ ...@@ -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->ssid);
lua_pushstring(L, sta_conf->password); lua_pushstring(L, sta_conf->password);
lua_call(L, 2, 0);
unregister_lua_cb(L, &wifi_smart_succeed); unregister_lua_cb(L, &wifi_smart_succeed);
luaL_pcallx(L, 2, 0);
} }
#endif // defined( NODE_SMART_OLDSTYLE ) #endif // defined( NODE_SMART_OLDSTYLE )
...@@ -125,8 +124,8 @@ static void wifi_scan_done(void *arg, STATUS status) ...@@ -125,8 +124,8 @@ static void wifi_scan_done(void *arg, STATUS status)
{ {
lua_newtable( L ); lua_newtable( L );
} }
lua_call(L, 1, 0);
unregister_lua_cb(L, &wifi_scan_succeed); unregister_lua_cb(L, &wifi_scan_succeed);
luaL_pcallx(L, 1, 0);
} }
#ifdef WIFI_SMART_ENABLE #ifdef WIFI_SMART_ENABLE
...@@ -438,9 +437,9 @@ void wifi_pmSleep_suspend_CB(void) ...@@ -438,9 +437,9 @@ void wifi_pmSleep_suspend_CB(void)
{ {
lua_State* L = lua_getstate(); // Get main Lua thread pointer lua_State* L = lua_getstate(); // Get main Lua thread pointer
lua_rawgeti(L, LUA_REGISTRYINDEX, wifi_suspend_cb_ref); // Push suspend callback onto stack 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 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 else
{ {
......
...@@ -242,7 +242,7 @@ static void wifi_event_monitor_process_event_queue(task_param_t param, uint8 pri ...@@ -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 luaL_unref(L, LUA_REGISTRYINDEX, event_ref); //the userdata containing event info is no longer needed
event_ref = LUA_NOREF; 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; return;
} }
......
...@@ -321,7 +321,7 @@ static void monitor_task(os_param_t param, uint8_t prio) ...@@ -321,7 +321,7 @@ static void monitor_task(os_param_t param, uint8_t prio)
free(input); free(input);
lua_call(L, 1, 0); luaL_pcallx(L, 1, 0);
} else { } else {
free(input); free(input);
} }
......
...@@ -30,7 +30,7 @@ LOCAL void ICACHE_FLASH_ATTR user_wps_status_cb(int status) ...@@ -30,7 +30,7 @@ LOCAL void ICACHE_FLASH_ATTR user_wps_status_cb(int status)
if (wps_callback_ref != LUA_NOREF) { if (wps_callback_ref != LUA_NOREF) {
lua_rawgeti(L, LUA_REGISTRYINDEX, wps_callback_ref); lua_rawgeti(L, LUA_REGISTRYINDEX, wps_callback_ref);
lua_pushinteger(L, status); lua_pushinteger(L, status);
lua_call(L, 1, 0); luaL_pcallx(L, 1, 0);
} }
} }
......
...@@ -18,13 +18,14 @@ ...@@ -18,13 +18,14 @@
#include "pcm.h" #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) { if (cb_ref != LUA_NOREF) {
lua_rawgeti( L, LUA_REGISTRYINDEX, cb_ref ); lua_rawgeti( L, LUA_REGISTRYINDEX, cb_ref );
lua_rawgeti( L, LUA_REGISTRYINDEX, self_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 ) void pcm_data_vu( task_param_t param, uint8 prio )
...@@ -36,7 +37,7 @@ 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->cb_vu_ref );
lua_rawgeti( L, LUA_REGISTRYINDEX, cfg->self_ref ); lua_rawgeti( L, LUA_REGISTRYINDEX, cfg->self_ref );
lua_pushnumber( L, (LUA_NUMBER)(cfg->vu_peak) ); 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 ) ...@@ -52,7 +53,8 @@ void pcm_data_play( task_param_t param, uint8 prio )
// retrieve new data from callback // retrieve new data from callback
if ((cfg->isr_throttled >= 0) && if ((cfg->isr_throttled >= 0) &&
(cfg->cb_data_ref != LUA_NOREF)) { (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; need_pop = TRUE;
if (lua_type( L, -1 ) == LUA_TSTRING) { if (lua_type( L, -1 ) == LUA_TSTRING) {
......
...@@ -26,12 +26,12 @@ struct gpio_hook_entry { ...@@ -26,12 +26,12 @@ struct gpio_hook_entry {
uint32_t bits; uint32_t bits;
}; };
struct gpio_hook { struct gpio_hook {
struct gpio_hook_entry *entry;
uint32_t all_bits; uint32_t all_bits;
uint32_t count; 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
#endif #endif
...@@ -218,10 +218,10 @@ static void ICACHE_RAM_ATTR platform_gpio_intr_dispatcher (void *dummy){ ...@@ -218,10 +218,10 @@ static void ICACHE_RAM_ATTR platform_gpio_intr_dispatcher (void *dummy){
UNUSED(dummy); UNUSED(dummy);
#ifdef GPIO_INTERRUPT_HOOK_ENABLE #ifdef GPIO_INTERRUPT_HOOK_ENABLE
if (gpio_status & platform_gpio_hook.all_bits) { if (gpio_status & platform_gpio_hook->all_bits) {
for (j = 0; j < platform_gpio_hook.count; j++) { for (j = 0; j < platform_gpio_hook->count; j++) {
if (gpio_status & platform_gpio_hook.entry[j].bits) if (gpio_status & platform_gpio_hook->entry[j].bits)
gpio_status = (platform_gpio_hook.entry[j].func)(gpio_status); gpio_status = (platform_gpio_hook->entry[j].func)(gpio_status);
} }
} }
#endif #endif
...@@ -266,7 +266,8 @@ static void ICACHE_RAM_ATTR platform_gpio_intr_dispatcher (void *dummy){ ...@@ -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 ) void platform_gpio_init( platform_task_handle_t gpio_task )
{ {
gpio_task_handle = 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); ETS_GPIO_INTR_ATTACH(platform_gpio_intr_dispatcher, NULL);
} }
...@@ -281,78 +282,53 @@ void platform_gpio_init( platform_task_handle_t gpio_task ) ...@@ -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) int platform_gpio_register_intr_hook(uint32_t bits, platform_hook_function hook)
{ {
struct gpio_hook nh, oh = platform_gpio_hook; struct gpio_hook *oh = platform_gpio_hook;
int i, j; int i, j, cur = -1;
if (!hook) { if (!hook) // Cannot register or unregister null hook
// Cannot register or unregister null hook
return 0; return 0;
}
int delete_slot = -1; // Is the hook already registered?
for (i=0; i<oh->count; i++) {
// If hook already registered, just update the bits if (hook == oh->entry[i].func) {
for (i=0; i<oh.count; i++) { cur = i;
if (hook == oh.entry[i].func) { break;
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;
} }
} }
// 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)
if (delete_slot < 0) { return 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
}
// These return NULL if the count = 0 so only error check if > 0) // Allocate replacement hook block and return 0 on alloc failure
nh.entry = malloc( nh.count * sizeof(*(nh.entry)) ); int count = oh->count + (cur < 0 ? 1 : (bits == 0 ? -1 : 0));
if (nh.count && !(nh.entry)) { struct gpio_hook *nh = malloc (sizeof *oh + (count -1)*sizeof(struct gpio_hook_entry));
return 0; // Allocation failure if (!oh)
} return 0;
for (i=0, j=0; i<oh.count; i++) { nh->all_bits = 0;
// Don't copy if this is the entry to delete nh->count = count;
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 for (i=0, j=0; i<oh->count; i++) {
nh.entry[j].bits = bits; if (i == cur && !bits)
nh.entry[j].func = hook; continue; /* unregister entry is a no-op */
nh.all_bits = oh.all_bits | bits; nh->entry[j] = oh->entry[i]; /* copy existing entry */
} else { // for an unregister clear the matching all bits if (i == cur)
nh.all_bits = oh.all_bits & (~oh.entry[delete_slot].bits); nh->entry[j].bits = bits; /* update bits if this is a replacement */
nh->all_bits |= nh->entry[j++].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(); ETS_GPIO_INTR_DISABLE();
// This is a structure copy, so interrupts need to be disabled
platform_gpio_hook = nh; platform_gpio_hook = nh;
ETS_GPIO_INTR_ENABLE(); ETS_GPIO_INTR_ENABLE();
free(oh.entry); free(oh);
return 1; return 1;
} }
#endif // GPIO_INTERRUPT_HOOK_ENABLE #endif // GPIO_INTERRUPT_HOOK_ENABLE
......
...@@ -162,7 +162,7 @@ void pmSleep_execute_lua_cb(int* cb_ref){ ...@@ -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_rawgeti(L, LUA_REGISTRYINDEX, *cb_ref); // Push resume callback onto the stack
lua_unref(L, *cb_ref); // Remove resume callback from registry lua_unref(L, *cb_ref); // Remove resume callback from registry
*cb_ref = LUA_NOREF; // Update variable since reference is no longer valid *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
} }
} }
......
...@@ -8,33 +8,33 @@ ...@@ -8,33 +8,33 @@
* The SDK software timer API executes in a task. The priority of this task in relation to the * 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). * 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` * 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 * 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. * 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 * The timers in this list are organized in an ascending order starting with the timer
* with the lowest timer_expire. * with the lowest timer_expire.
* *
* When a timer expires that has a timer_period greater than 0, timer_expire is changed to * When a timer expires that has a timer_period greater than 0, timer_expire is changed to current
* current FRC2 + timer_period, then the timer is inserted back in to the list in the correct position. * 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 SUSPEND API INFO:
* *
* Timer suspension is achieved by first finding any non-SDK timers by comparing the timer function callback pointer * Timer suspension is achieved by first finding any non-SDK timers by comparing the timer function
* of each timer in "timer_list" to a list of registered timer callback pointers stored in the Lua registry. * callback pointer of each timer in "timer_list" to a list of registered timer callback pointers
* If a timer with a corresponding registered callback pointer is found, the timer's timer_expire field is is compared * stored in the Lua registry. If a timer with a corresponding registered callback pointer is found,
* to the current FRC2 count and the difference is saved along with the other timer parameters to temporary variables. * the timer's timer_expire field is is compared to the current FRC2 count and the difference is
* The timer is then disarmed and the parameters are copied back, the timer pointer is then * saved along with the other timer parameters to temporary variables. The timer is then disarmed
* added to a separate linked list of which the head pointer is stored as a lightuserdata in the lua registry. * 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. * Resuming the timers is achieved by first retrieving the lightuserdata holding the suspended timer
* Then, starting with the beginning of the list the current FRC2 count is added back to the timer's timer_expire, then * list head pointer. Then, starting with the beginning of the list the current FRC2 count is added
* the timer is manually added back to "timer_list" in an ascending order. * back to the timer's timer_expire, then the timer is manually added back to "timer_list" in an
* Once there are no more suspended timers, the function returns * ascending order. Once there are no more suspended timers, the function returns.
* *
* *
*/ */
...@@ -57,17 +57,24 @@ ...@@ -57,17 +57,24 @@
#define SWTMR_DEBUG #define SWTMR_DEBUG
#endif #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 #ifdef SWTMR_DEBUG
#define SWTMR_DBG(fmt, ...) dbg_printf("\n SWTMR_DBG(%s): "fmt"\n", __FUNCTION__, ##__VA_ARGS__) #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 CB_LIST_STR "timer_cb_ptrs"
#define SUSP_LIST_STR "suspended_tmr_LL_head" #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 #else
#define SWTMR_DBG(...) #define SWTMR_DBG(...)
#define L_REGISTRY LUA_REGISTRYINDEX
#define CB_LIST_STR "cb" #define CB_LIST_STR "cb"
#define SUSP_LIST_STR "st" #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 #endif
...@@ -92,32 +99,21 @@ static task_handle_t cb_register_task_id = 0; //variable to hold task id for tas ...@@ -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 add_to_reg_queue(void* timer_cb_ptr, uint8 suspend_policy);
static void process_cb_register_queue(task_param_t param, uint8 priority); 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> #include <pm/swtimer.h>
void swtmr_suspend_timers(){ void swtmr_suspend_timers(){
lua_State* L = lua_getstate(); lua_State* L = lua_getstate();
//get swtimer table //get swtimer table
push_swtmr_registry_key(L); get_swtmr_registry(L);
lua_rawget(L, L_REGISTRY); if(!lua_istable(L, -1)) {lua_pop(L, 1); return;}
//get cb_list table //get cb_list table
lua_pushstring(L, CB_LIST_STR); lua_pushstring(L, CB_LIST_STR);
lua_rawget(L, -2); lua_rawget(L, -2);
//check for existence of the swtimer table and the cb_list table, return if not found //check for existence of the cb_list table, return if not found
if(!lua_istable(L, -2) || !lua_istable(L, -1)){ if(!lua_istable(L, -1)) {lua_pop(L, 2); return;}
// not necessarily an error maybe there are legitimately no timers to suspend
lua_pop(L, 2);
return;
}
os_timer_t* suspended_timer_list_head = NULL; os_timer_t* suspended_timer_list_head = NULL;
os_timer_t* suspended_timer_list_tail = NULL; os_timer_t* suspended_timer_list_tail = NULL;
...@@ -168,10 +164,10 @@ void swtmr_suspend_timers(){ ...@@ -168,10 +164,10 @@ void swtmr_suspend_timers(){
uint32 period_temp = 0; uint32 period_temp = 0;
void* arg_temp = NULL; void* arg_temp = NULL;
/* In this section, the SDK's timer_list is traversed to find any timers that have a registered callback pointer. /* In this section, the SDK's timer_list is traversed to find any timers that have a registered
* If a registered callback is found, the timer is suspended by saving the difference * callback pointer. If a registered callback is found, the timer is suspended by saving the
* between frc2_count and timer_expire then the timer is disarmed and placed into suspended_timer_list * difference between frc2_count and timer_expire then the timer is disarmed and placed into
* so it can later be resumed. * suspended_timer_list so it can later be resumed.
*/ */
while(timer_ptr != NULL){ while(timer_ptr != NULL){
os_timer_t* next_timer = (os_timer_t*)0xffffffff; os_timer_t* next_timer = (os_timer_t*)0xffffffff;
...@@ -190,7 +186,8 @@ void swtmr_suspend_timers(){ ...@@ -190,7 +186,8 @@ void swtmr_suspend_timers(){
arg_temp = timer_ptr->timer_arg; arg_temp = timer_ptr->timer_arg;
if(timer_ptr->timer_period == 0 && cb_reg_array[i]->suspend_policy == SWTIMER_RESTART){ 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; cb_reg_array[i]->suspend_policy = SWTIMER_RESUME;
} }
...@@ -260,19 +257,15 @@ void swtmr_resume_timers(){ ...@@ -260,19 +257,15 @@ void swtmr_resume_timers(){
lua_State* L = lua_getstate(); lua_State* L = lua_getstate();
//get swtimer table //get swtimer table
push_swtmr_registry_key(L); get_swtmr_registry(L);
lua_rawget(L, L_REGISTRY); if(!lua_istable(L, -1)) {lua_pop(L, 1); return;}
//get suspended_timer_list lightuserdata //get suspended_timer_list lightuserdata
lua_pushstring(L, SUSP_LIST_STR); lua_pushstring(L, SUSP_LIST_STR);
lua_rawget(L, -2); lua_rawget(L, -2);
//check for existence of swtimer table and the suspended_timer_list pointer userdata, return if not found //check for existence of the suspended_timer_list pointer userdata, return if not found
if(!lua_istable(L, -2) || !lua_isuserdata(L, -1)){ if(!lua_isuserdata(L, -1)) {lua_pop(L, 2); return;}
// not necessarily an error maybe there are legitimately no timers to resume
lua_pop(L, 2);
return;
}
os_timer_t* suspended_timer_list_ptr = lua_touserdata(L, -1); os_timer_t* suspended_timer_list_ptr = lua_touserdata(L, -1);
lua_pop(L, 1); //pop suspended timer list userdata from stack lua_pop(L, 1); //pop suspended timer list userdata from stack
...@@ -339,25 +332,21 @@ void swtmr_resume_timers(){ ...@@ -339,25 +332,21 @@ void swtmr_resume_timers(){
void swtmr_cb_register(void* timer_cb_ptr, uint8 suspend_policy){ void swtmr_cb_register(void* timer_cb_ptr, uint8 suspend_policy){
lua_State* L = lua_getstate(); lua_State* L = lua_getstate();
if(!L){ if(!L){
//Lua has not started yet, therefore L_REGISTRY is not available. // If Lua has not started yet, then add timer cb to queue for later processing after Lua has started
//add timer cb to queue for later processing after Lua has started
add_to_reg_queue(timer_cb_ptr, suspend_policy); add_to_reg_queue(timer_cb_ptr, suspend_policy);
return; return;
} }
if(timer_cb_ptr){ if(timer_cb_ptr){
size_t cb_list_last_idx = 0; size_t cb_list_last_idx = 0;
push_swtmr_registry_key(L); get_swtmr_registry(L);
lua_rawget(L, L_REGISTRY);
if(!lua_istable(L, -1)){ 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_pop(L, 1);
lua_newtable(L);//push new table for swtmr.timer_cb_list lua_newtable(L);
// add swtimer table to L_REGISTRY lua_pushvalue(L, -1);
push_swtmr_registry_key(L); set_swtmr_registry(L);
lua_pushvalue(L, -2);
lua_rawset(L, L_REGISTRY);
} }
lua_pushstring(L, CB_LIST_STR); lua_pushstring(L, CB_LIST_STR);
...@@ -439,41 +428,40 @@ static void process_cb_register_queue(task_param_t param, uint8 priority) ...@@ -439,41 +428,40 @@ static void process_cb_register_queue(task_param_t param, uint8 priority)
#ifdef SWTMR_DEBUG #ifdef SWTMR_DEBUG
int print_timer_list(lua_State* L){ int print_timer_list(lua_State* L){
push_swtmr_registry_key(L); get_swtmr_registry(L);
lua_rawget(L, L_REGISTRY); if(!lua_istable(L, -1)) {lua_pop(L, 1); return 0;}
lua_pushstring(L, CB_LIST_STR);
lua_rawget(L, -2); lua_pushstring(L, CB_LIST_STR);
if(!lua_istable(L, -2) || !lua_istable(L, -1)){ lua_rawget(L, -2);
lua_pop(L, 2); if(!lua_istable(L, -1)) {lua_pop(L, 2); return 0;}
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_pop(L, 1);
lua_pushstring(L, SUSP_LIST_STR); size_t registered_cb_qty = lua_objlen(L, -1);
lua_rawget(L, -3); 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)){ if(lua_isuserdata(L, -1)){
suspended_timer_list_head = suspended_timer_list_tail = lua_touserdata(L, -1); cb_reg_array[index] = 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++;
} }
lua_pop(L, 1); lua_pop(L, 1);
index++;
}
lua_pop(L, 1);
os_timer_t* timer_list_ptr = timer_list; os_timer_t* timer_list_ptr = timer_list;
...@@ -499,9 +487,7 @@ int print_timer_list(lua_State* L){ ...@@ -499,9 +487,7 @@ int print_timer_list(lua_State* L){
} }
int print_susp_timer_list(lua_State* L){ int print_susp_timer_list(lua_State* L){
push_swtmr_registry_key(L); get_swtmr_registry(L);
lua_rawget(L, L_REGISTRY);
if(!lua_istable(L, -1)){ if(!lua_istable(L, -1)){
return luaL_error(L, "swtmr table not found!"); return luaL_error(L, "swtmr table not found!");
} }
...@@ -516,7 +502,9 @@ int print_susp_timer_list(lua_State* L){ ...@@ -516,7 +502,9 @@ int print_susp_timer_list(lua_State* L){
os_timer_t* susp_timer_list_ptr = lua_touserdata(L, -1); os_timer_t* susp_timer_list_ptr = lua_touserdata(L, -1);
dbg_printf("\n\tsuspended_timer_list:\n"); dbg_printf("\n\tsuspended_timer_list:\n");
while(susp_timer_list_ptr != NULL){ 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; susp_timer_list_ptr = susp_timer_list_ptr->timer_next;
} }
return 0; return 0;
...@@ -542,5 +530,5 @@ LROT_END(test_swtimer_debug, NULL, 0) ...@@ -542,5 +530,5 @@ LROT_END(test_swtimer_debug, NULL, 0)
NODEMCU_MODULE(SWTMR_DBG, "SWTMR_DBG", test_swtimer_debug, NULL); NODEMCU_MODULE(SWTMR_DBG, "SWTMR_DBG", test_swtimer_debug, NULL);
#endif #endif /* SWTMR_DEBUG */
...@@ -22,4 +22,5 @@ ...@@ -22,4 +22,5 @@
// Reduce the chance of returning disk full // Reduce the chance of returning disk full
#define SPIFFS_GC_MAX_RUNS 256 #define SPIFFS_GC_MAX_RUNS 256
#define SPIFFS_SECURE_ERASE 0
#endif #endif
...@@ -93,7 +93,7 @@ static bool myspiffs_set_cfg(spiffs_config *cfg, bool force_create) { ...@@ -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) { if (cfg->phys_size < MIN_BLOCKS_FS * LOG_BLOCK_SIZE_SMALL_FS) {
return FALSE; 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; cfg->log_block_size = LOG_BLOCK_SIZE_SMALL_FS;
} else { } else {
cfg->log_block_size = LOG_BLOCK_SIZE; cfg->log_block_size = LOG_BLOCK_SIZE;
......
...@@ -889,6 +889,16 @@ s32_t spiffs_page_delete( ...@@ -889,6 +889,16 @@ s32_t spiffs_page_delete(
fs->stats_p_deleted++; fs->stats_p_deleted++;
fs->stats_p_allocated--; 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 // mark deleted in source page
u8_t flags = 0xff; u8_t flags = 0xff;
#if SPIFFS_NO_BLIND_WRITES #if SPIFFS_NO_BLIND_WRITES
...@@ -2030,7 +2040,7 @@ s32_t spiffs_object_read( ...@@ -2030,7 +2040,7 @@ s32_t spiffs_object_read(
// remaining data in page // remaining data in page
len_to_read = MIN(len_to_read, SPIFFS_DATA_PAGE_SIZE(fs) - (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs))); len_to_read = MIN(len_to_read, SPIFFS_DATA_PAGE_SIZE(fs) - (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs)));
// remaining data in file // 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, 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)))); (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) { if (len_to_read <= 0) {
......
...@@ -262,8 +262,8 @@ ...@@ -262,8 +262,8 @@
#define SPIFFS_FH_OFFS(fs, fh) ((fh) != 0 ? ((fh) + (fs)->cfg.fh_ix_offset) : 0) #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) #define SPIFFS_FH_UNOFFS(fs, fh) ((fh) != 0 ? ((fh) - (fs)->cfg.fh_ix_offset) : 0)
#else #else
#define SPIFFS_FH_OFFS(fs, fh) (fh) #define SPIFFS_FH_OFFS(fs, fh) ((spiffs_file)(fh))
#define SPIFFS_FH_UNOFFS(fs, fh) (fh) #define SPIFFS_FH_UNOFFS(fs, fh) ((spiffs_file)(fh))
#endif #endif
...@@ -476,9 +476,6 @@ typedef struct { ...@@ -476,9 +476,6 @@ typedef struct {
// object structs // object structs
#ifdef _MSC_VER
#pragma pack ( push, 1 )
#endif
// page header, part of each page except object lookup pages // page header, part of each page except object lookup pages
// NB: this is always aligned when the data page is an object index, // NB: this is always aligned when the data page is an object index,
...@@ -496,10 +493,9 @@ typedef struct SPIFFS_PACKED { ...@@ -496,10 +493,9 @@ typedef struct SPIFFS_PACKED {
typedef struct SPIFFS_PACKED typedef struct SPIFFS_PACKED
#if SPIFFS_ALIGNED_OBJECT_INDEX_TABLES #if SPIFFS_ALIGNED_OBJECT_INDEX_TABLES
#ifdef _MSC_VER #ifdef _MSC_VER
//Note: the following needs to track the sizeof(spiffs_page_ix), which is defined in spiffs_config.h __declspec( align( 2 ) ) // must track sizeof(spiffs_page_ix) in spiffs_config.h
__declspec( align( 2 ) )
#else #else
__attribute(( aligned(sizeof(spiffs_page_ix)) )) __attribute(( aligned(sizeof(spiffs_page_ix)) ))
#endif #endif
#endif #endif
{ {
...@@ -525,10 +521,6 @@ typedef struct SPIFFS_PACKED { ...@@ -525,10 +521,6 @@ typedef struct SPIFFS_PACKED {
u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))]; u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))];
} spiffs_page_object_ix; } spiffs_page_object_ix;
#ifdef _MSC_VER
#pragma pack ( pop )
#endif
// callback func for object lookup visitor // 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, 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); 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 ...@@ -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_State *L = lua_getstate();
lua_rawgeti( L, LUA_REGISTRYINDEX, ext_u8g2->overlay.rfb_cb_ref ); lua_rawgeti( L, LUA_REGISTRYINDEX, ext_u8g2->overlay.rfb_cb_ref );
lua_pushnil( L ); lua_pushnil( L );
lua_call( L, 1, 0 ); luaL_pcallx( L, 1, 0 );
} }
// and note ongoing framebuffer update // and note ongoing framebuffer update
ext_u8g2->overlay.fb_update_ongoing = 1; 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 ...@@ -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_rawgeti( L, LUA_REGISTRYINDEX, ext_u8g2->overlay.rfb_cb_ref );
lua_pushlstring( L, (const char *)fbrle_line, fbrle_line_size ); lua_pushlstring( L, (const char *)fbrle_line, fbrle_line_size );
lua_call( L, 1, 0 ); luaL_pcallx( L, 1, 0 );
} }
} }
......
local gpio, bit = gpio, bit local gpio, bit = gpio, bit --luacheck: read globals gpio bit
return function(bus_args) return function(bus_args)
local rs = bus_args.rs or 0 local rs = bus_args.rs or 0
......
local gpio, bit = gpio, bit local gpio, bit = gpio, bit --luacheck: read globals gpio bit
return function(bus_args) return function(bus_args)
local rs = bus_args.rs or 0 local rs = bus_args.rs or 0
......
local i2c, bit = i2c, bit local i2c, bit = i2c, bit --luacheck: read globals i2c bit
return function(bus_args) return function(bus_args)
local busid = bus_args.id or 0 local busid = bus_args.id or 0
......
local bit = bit local bit = bit --luacheck: read globals bit
-- metatable -- metatable
local LiquidCrystal = {} local LiquidCrystal = {}
LiquidCrystal.__index = LiquidCrystal LiquidCrystal.__index = LiquidCrystal
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment