Skip to content

Commit

Permalink
Add wifi.suspend() and node.sleep() (nodemcu#1231)
Browse files Browse the repository at this point in the history
* Exposed forced sleep API and more
Added timer suspend functionality
* wifi.suspend
* wifi.resume
* node.sleep 
* tmr.suspend
* tmr.suspend_all
* tmr.resume
* tmr.resume_all
* Implement timer suspend functionality
* Fix for uart TX glitch
* Made some modifications to the error reporting
  • Loading branch information
dnc40085 authored and Konrad Eisele committed Jan 7, 2018
1 parent c71f130 commit 8f5bb97
Show file tree
Hide file tree
Showing 22 changed files with 2,022 additions and 80 deletions.
10 changes: 9 additions & 1 deletion app/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ SUBDIRS= \
http \
fatfs \
esp-gdbstub \
websocket
websocket \
swTimer \
misc \
pm \


endif # } PDIR

Expand Down Expand Up @@ -90,11 +94,15 @@ COMPONENTS_eagle.app.v6 = \
dhtlib/libdhtlib.a \
tsl2561/tsl2561lib.a \
http/libhttp.a \
pm/libpm.a \
websocket/libwebsocket.a \
esp-gdbstub/libgdbstub.a \
net/libnodemcu_net.a \
mbedtls/libmbedtls.a \
modules/libmodules.a \
swTimer/libswtimer.a \
misc/libmisc.a \


# Inspect the modules library and work out which modules need to be linked.
# For each enabled module, a symbol name of the form XYZ_module_selected is
Expand Down
40 changes: 40 additions & 0 deletions app/include/misc/dynarr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef __DYNARR_H__
#define __DYNARR_H__
#include "user_interface.h"
#include "c_stdio.h"
#include "c_stdlib.h"

//#define DYNARR_DEBUG
//#define DYNARR_ERROR


typedef struct _dynarr{
void* data_ptr;
size_t used;
size_t array_size;
size_t data_size;
} dynarr_t;

bool dynarr_init(dynarr_t* array_ptr, size_t array_size, size_t data_size);
bool dynarr_resize(dynarr_t* array_ptr, size_t elements_to_add);
bool dynarr_remove(dynarr_t* array_ptr, void* element_ptr);
bool dynarr_add(dynarr_t* array_ptr, void* data_ptr, size_t data_size);
bool dynarr_boundaryCheck(dynarr_t* array_ptr, void* element_ptr);
bool dynarr_free(dynarr_t* array_ptr);


#if 0 || defined(DYNARR_DEBUG) || defined(NODE_DEBUG)
#define DYNARR_DBG(fmt, ...) c_printf("\n DYNARR_DBG(%s): "fmt"\n", __FUNCTION__, ##__VA_ARGS__)
#else
#define DYNARR_DBG(...)

#endif

#if 0 || defined(DYNARR_ERROR) || defined(NODE_ERROR)
#define DYNARR_ERR(fmt, ...) c_printf("\n DYNARR: "fmt"\n", ##__VA_ARGS__)
#else
#define DYNARR_ERR(...)

#endif

#endif // __DYNARR_H__
53 changes: 53 additions & 0 deletions app/include/swTimer/swTimer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#ifndef __SW_TIMER_H__
#define __SW_TIMER_H__
#include "user_interface.h"
//#define SWTMR_DEBUG
#define USE_SWTMR_ERROR_STRINGS

#if defined(DEVELOP_VERSION)
#define SWTMR_DEBUG
#endif

#if defined(SWTMR_DEBUG)
#define SWTMR_DBG(fmt, ...) dbg_printf("\tSWTIMER(%s):"fmt"\n", __FUNCTION__, ##__VA_ARGS__)
#else
#define SWTMR_DBG(...)
#endif

#if defined(NODE_ERROR)
#define SWTMR_ERR(fmt, ...) NODE_ERR("%s"fmt"\n", "SWTIMER:", ##__VA_ARGS__)
#else
#define SWTMR_ERR(...)
#endif

enum SWTMR_STATUS{
SWTMR_FAIL = 0,
SWTMR_OK = 1,

SWTMR_MALLOC_FAIL = 10,
SWTMR_TIMER_NOT_ARMED,
// SWTMR_NULL_PTR,

SWTMR_REGISTRY_NO_REGISTERED_TIMERS,

// SWTMR_SUSPEND_ARRAY_INITIALIZATION_FAILED,
// SWTMR_SUSPEND_ARRAY_ADD_FAILED,
// SWTMR_SUSPEND_ARRAY_REMOVE_FAILED,
SWTMR_SUSPEND_TIMER_ALREADY_SUSPENDED,
SWTMR_SUSPEND_TIMER_ALREADY_REARMED,
SWTMR_SUSPEND_NO_SUSPENDED_TIMERS,
SWTMR_SUSPEND_TIMER_NOT_SUSPENDED,

};

/* Global Function Declarations */
void swtmr_register(void* timer_ptr);
void swtmr_unregister(void* timer_ptr);
int swtmr_suspend(os_timer_t* timer_ptr);
int swtmr_resume(os_timer_t* timer_ptr);
void swtmr_print_registry(void);
void swtmr_print_suspended(void);
void swtmr_print_timer_list(void);
const char* swtmr_errorcode2str(int error_value);
bool swtmr_suspended_test(os_timer_t* timer_ptr);
#endif // __SW_TIMER_H__
4 changes: 4 additions & 0 deletions app/include/user_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ extern void luaL_assertfail(const char *file, int line, const char *message);
#define WIFI_SDK_EVENT_MONITOR_ENABLE
#define WIFI_EVENT_MONITOR_DISCONNECT_REASON_LIST_ENABLE

#define ENABLE_TIMER_SUSPEND
#define PMSLEEP_ENABLE


#define STRBUF_DEFAULT_INCREMENT 32

#endif /* __USER_CONFIG_H__ */
52 changes: 52 additions & 0 deletions app/misc/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
GEN_LIBS = libmisc.a
endif

STD_CFLAGS=-std=gnu11 -Wimplicit

#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=

#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#

INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ./include
INCLUDES += -I ../include
INCLUDES += -I ../../include
INCLUDES += -I ../lua
INCLUDES += -I ../platform
INCLUDES += -I ../libc

PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile

131 changes: 131 additions & 0 deletions app/misc/dyn_arr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#include "misc/dynarr.h"

#define ARRAY_PTR_CHECK if(array_ptr == NULL || array_ptr->data_ptr == NULL){\
/**/DYNARR_DBG("array not initialized");\
return false; \
}

bool dynarr_init(dynarr_t* array_ptr, size_t array_size, size_t data_size){
if(array_ptr == NULL || data_size == 0 || array_size == 0){
/**/DYNARR_DBG("Invalid parameter: array_ptr(%p) data_size(%u) array_size(%u)", array_ptr, data_size, array_size);
return false;
}
if(array_ptr->data_ptr != NULL ){
/**/DYNARR_DBG("Array already initialized: array_ptr->data_ptr=%p", array_ptr->data_ptr);
return false;
}
/**/DYNARR_DBG("Array parameters:\n\t\t\tarray_size(%u)\n\t\t\tdata_size(%u)\n\t\t\ttotal size(bytes):%u", array_size, data_size, (array_size * data_size));

void* temp_array = c_zalloc(array_size * data_size);
if(temp_array == NULL){
/**/DYNARR_ERR("malloc FAIL! req:%u free:%u", (array_size * data_size), system_get_free_heap_size());
return false;
}

array_ptr->data_ptr = temp_array;
array_ptr->array_size = array_size;
array_ptr->data_size = data_size;
array_ptr->used = 0;

return true;
}

bool dynarr_resize(dynarr_t* array_ptr, size_t elements_to_add){
ARRAY_PTR_CHECK;

if(elements_to_add <= 0){
/**/DYNARR_DBG("Invalid qty: elements_to_add=%u", elements_to_add);
return false;
}

size_t new_array_size = array_ptr->array_size + elements_to_add;

/**/DYNARR_DBG("old size=%u\tnew size=%u\tmem used=%u",
array_ptr->array_size, new_array_size, (new_array_size * array_ptr->data_size));

void* temp_array_p = c_realloc(array_ptr->data_ptr, new_array_size * array_ptr->data_size);
if(temp_array_p == NULL){
/**/DYNARR_ERR("malloc FAIL! req:%u free:%u", (new_array_size * array_ptr->data_size), system_get_free_heap_size());
return false;
}

array_ptr->data_ptr = temp_array_p;

size_t prev_size = array_ptr->array_size;

array_ptr->array_size = new_array_size;

//set memory to 0 for newly added array elements
memset((uint8*) array_ptr->data_ptr + (prev_size * array_ptr->data_size), 0, (elements_to_add * array_ptr->data_size));

/**/DYNARR_DBG("Array successfully resized");
return true;
}

bool dynarr_remove(dynarr_t* array_ptr, void* element_to_remove){
ARRAY_PTR_CHECK;

uint8* element_ptr = element_to_remove;
uint8* data_ptr = array_ptr->data_ptr;

if(dynarr_boundaryCheck(array_ptr, element_to_remove) == FALSE){
return false;
}

//overwrite element to be removed by shifting all elements to the left
memmove(element_ptr, element_ptr + array_ptr->data_size, (array_ptr->array_size - 1) * array_ptr->data_size - (element_ptr - data_ptr));

//clear newly freed element
memset(data_ptr + ((array_ptr->array_size-1) * array_ptr->data_size), 0, array_ptr->data_size);

//decrement array used since we removed an element
array_ptr->used--;
/**/DYNARR_DBG("element(%p) removed from array", element_ptr);
return true;
}

bool dynarr_add(dynarr_t* array_ptr, void* data_ptr, size_t data_size){
ARRAY_PTR_CHECK;

if(data_size != array_ptr->data_size){
/**/DYNARR_DBG("Invalid data size: data_size(%u) != arr->data_size(%u)", data_size, array_ptr->data_size);
return false;
}

if(array_ptr->array_size == array_ptr->used){
if(!dynarr_resize(array_ptr, (array_ptr->array_size/2))){
return false;
}
}
memcpy(((uint8*)array_ptr->data_ptr + (array_ptr->used * array_ptr->data_size)), data_ptr, array_ptr->data_size);

array_ptr->used++;
return true;
}

bool dynarr_boundaryCheck(dynarr_t* array_ptr, void* element_to_check){
ARRAY_PTR_CHECK;

uint8* data_ptr = array_ptr->data_ptr;
uint8* element_ptr = element_to_check;

if(element_ptr < data_ptr || ((element_ptr - data_ptr) / array_ptr->data_size) > array_ptr->array_size - 1){
/**/DYNARR_DBG("element_ptr(%p) out of bounds: first element ptr:%p last element ptr:%p",
element_ptr, data_ptr, data_ptr + ((array_ptr->array_size - 1) * array_ptr->data_size));
return false;
}
return true;
}

bool dynarr_free(dynarr_t* array_ptr){
ARRAY_PTR_CHECK;

c_free(array_ptr->data_ptr);

array_ptr->data_ptr=NULL;
array_ptr->array_size = array_ptr->used = 0;

/**/DYNARR_DBG("array freed");
return true;
}

1 change: 1 addition & 0 deletions app/modules/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ INCLUDES += -I ../fatfs
INCLUDES += -I ../http
INCLUDES += -I ../sjson
INCLUDES += -I ../websocket
INCLUDES += -I ../pm
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile

47 changes: 34 additions & 13 deletions app/modules/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,36 @@ static int node_deepsleep( lua_State* L )
return 0;
}

// Lua: dsleep_set_options
// Combined to dsleep( us, option )
// static int node_deepsleep_setoption( lua_State* L )
// {
// s32 option;
// option = luaL_checkinteger( L, 1 );
// if ( option < 0 || option > 4)
// return luaL_error( L, "wrong arg range" );
// else
// deep_sleep_set_option( option );
// return 0;
// }
// Lua: info()

#ifdef PMSLEEP_ENABLE
#include "pmSleep.h"

int node_sleep_resume_cb_ref= LUA_NOREF;
void node_sleep_resume_cb(void)
{
PMSLEEP_DBG("START");
pmSleep_execute_lua_cb(&node_sleep_resume_cb_ref);
PMSLEEP_DBG("END");
}

// Lua: node.sleep(table)
static int node_sleep( lua_State* L )
{
pmSleep_INIT_CFG(cfg);
cfg.sleep_mode=LIGHT_SLEEP_T;

if(lua_istable(L, 1)){
pmSleep_parse_table_lua(L, 1, &cfg, NULL, &node_sleep_resume_cb_ref);
}
else{
return luaL_argerror(L, 1, "must be table");
}

cfg.resume_cb_ptr = &node_sleep_resume_cb;
pmSleep_suspend(&cfg);
return 0;
}
#endif //PMSLEEP_ENABLE

static int node_info( lua_State* L )
{
Expand Down Expand Up @@ -570,6 +587,10 @@ static const LUA_REG_TYPE node_map[] =
{
{ LSTRKEY( "restart" ), LFUNCVAL( node_restart ) },
{ LSTRKEY( "dsleep" ), LFUNCVAL( node_deepsleep ) },
#ifdef PMSLEEP_ENABLE
{ LSTRKEY( "sleep" ), LFUNCVAL( node_sleep ) },
PMSLEEP_INT_MAP,
#endif
{ LSTRKEY( "info" ), LFUNCVAL( node_info ) },
{ LSTRKEY( "chipid" ), LFUNCVAL( node_chipid ) },
{ LSTRKEY( "flashid" ), LFUNCVAL( node_flashid ) },
Expand Down
Loading

0 comments on commit 8f5bb97

Please sign in to comment.