Skip to content

Commit 41a5736

Browse files
dnc40085marcelstoer
authored andcommitted
Add wifi.suspend() and node.sleep() (#1231)
* 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
1 parent 176443c commit 41a5736

File tree

22 files changed

+2022
-80
lines changed

22 files changed

+2022
-80
lines changed

app/Makefile

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ SUBDIRS= \
4545
http \
4646
fatfs \
4747
esp-gdbstub \
48-
websocket
48+
websocket \
49+
swTimer \
50+
misc \
51+
pm \
52+
4953

5054
endif # } PDIR
5155

@@ -90,11 +94,15 @@ COMPONENTS_eagle.app.v6 = \
9094
dhtlib/libdhtlib.a \
9195
tsl2561/tsl2561lib.a \
9296
http/libhttp.a \
97+
pm/libpm.a \
9398
websocket/libwebsocket.a \
9499
esp-gdbstub/libgdbstub.a \
95100
net/libnodemcu_net.a \
96101
mbedtls/libmbedtls.a \
97102
modules/libmodules.a \
103+
swTimer/libswtimer.a \
104+
misc/libmisc.a \
105+
98106

99107
# Inspect the modules library and work out which modules need to be linked.
100108
# For each enabled module, a symbol name of the form XYZ_module_selected is

app/include/misc/dynarr.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#ifndef __DYNARR_H__
2+
#define __DYNARR_H__
3+
#include "user_interface.h"
4+
#include "c_stdio.h"
5+
#include "c_stdlib.h"
6+
7+
//#define DYNARR_DEBUG
8+
//#define DYNARR_ERROR
9+
10+
11+
typedef struct _dynarr{
12+
void* data_ptr;
13+
size_t used;
14+
size_t array_size;
15+
size_t data_size;
16+
} dynarr_t;
17+
18+
bool dynarr_init(dynarr_t* array_ptr, size_t array_size, size_t data_size);
19+
bool dynarr_resize(dynarr_t* array_ptr, size_t elements_to_add);
20+
bool dynarr_remove(dynarr_t* array_ptr, void* element_ptr);
21+
bool dynarr_add(dynarr_t* array_ptr, void* data_ptr, size_t data_size);
22+
bool dynarr_boundaryCheck(dynarr_t* array_ptr, void* element_ptr);
23+
bool dynarr_free(dynarr_t* array_ptr);
24+
25+
26+
#if 0 || defined(DYNARR_DEBUG) || defined(NODE_DEBUG)
27+
#define DYNARR_DBG(fmt, ...) c_printf("\n DYNARR_DBG(%s): "fmt"\n", __FUNCTION__, ##__VA_ARGS__)
28+
#else
29+
#define DYNARR_DBG(...)
30+
31+
#endif
32+
33+
#if 0 || defined(DYNARR_ERROR) || defined(NODE_ERROR)
34+
#define DYNARR_ERR(fmt, ...) c_printf("\n DYNARR: "fmt"\n", ##__VA_ARGS__)
35+
#else
36+
#define DYNARR_ERR(...)
37+
38+
#endif
39+
40+
#endif // __DYNARR_H__

app/include/swTimer/swTimer.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#ifndef __SW_TIMER_H__
2+
#define __SW_TIMER_H__
3+
#include "user_interface.h"
4+
//#define SWTMR_DEBUG
5+
#define USE_SWTMR_ERROR_STRINGS
6+
7+
#if defined(DEVELOP_VERSION)
8+
#define SWTMR_DEBUG
9+
#endif
10+
11+
#if defined(SWTMR_DEBUG)
12+
#define SWTMR_DBG(fmt, ...) dbg_printf("\tSWTIMER(%s):"fmt"\n", __FUNCTION__, ##__VA_ARGS__)
13+
#else
14+
#define SWTMR_DBG(...)
15+
#endif
16+
17+
#if defined(NODE_ERROR)
18+
#define SWTMR_ERR(fmt, ...) NODE_ERR("%s"fmt"\n", "SWTIMER:", ##__VA_ARGS__)
19+
#else
20+
#define SWTMR_ERR(...)
21+
#endif
22+
23+
enum SWTMR_STATUS{
24+
SWTMR_FAIL = 0,
25+
SWTMR_OK = 1,
26+
27+
SWTMR_MALLOC_FAIL = 10,
28+
SWTMR_TIMER_NOT_ARMED,
29+
// SWTMR_NULL_PTR,
30+
31+
SWTMR_REGISTRY_NO_REGISTERED_TIMERS,
32+
33+
// SWTMR_SUSPEND_ARRAY_INITIALIZATION_FAILED,
34+
// SWTMR_SUSPEND_ARRAY_ADD_FAILED,
35+
// SWTMR_SUSPEND_ARRAY_REMOVE_FAILED,
36+
SWTMR_SUSPEND_TIMER_ALREADY_SUSPENDED,
37+
SWTMR_SUSPEND_TIMER_ALREADY_REARMED,
38+
SWTMR_SUSPEND_NO_SUSPENDED_TIMERS,
39+
SWTMR_SUSPEND_TIMER_NOT_SUSPENDED,
40+
41+
};
42+
43+
/* Global Function Declarations */
44+
void swtmr_register(void* timer_ptr);
45+
void swtmr_unregister(void* timer_ptr);
46+
int swtmr_suspend(os_timer_t* timer_ptr);
47+
int swtmr_resume(os_timer_t* timer_ptr);
48+
void swtmr_print_registry(void);
49+
void swtmr_print_suspended(void);
50+
void swtmr_print_timer_list(void);
51+
const char* swtmr_errorcode2str(int error_value);
52+
bool swtmr_suspended_test(os_timer_t* timer_ptr);
53+
#endif // __SW_TIMER_H__

app/include/user_config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ extern void luaL_assertfail(const char *file, int line, const char *message);
116116
#define WIFI_SDK_EVENT_MONITOR_ENABLE
117117
#define WIFI_EVENT_MONITOR_DISCONNECT_REASON_LIST_ENABLE
118118

119+
#define ENABLE_TIMER_SUSPEND
120+
#define PMSLEEP_ENABLE
121+
122+
119123
#define STRBUF_DEFAULT_INCREMENT 32
120124

121125
#endif /* __USER_CONFIG_H__ */

app/misc/Makefile

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
2+
#############################################################
3+
# Required variables for each makefile
4+
# Discard this section from all parent makefiles
5+
# Expected variables (with automatic defaults):
6+
# CSRCS (all "C" files in the dir)
7+
# SUBDIRS (all subdirs with a Makefile)
8+
# GEN_LIBS - list of libs to be generated ()
9+
# GEN_IMAGES - list of images to be generated ()
10+
# COMPONENTS_xxx - a list of libs/objs in the form
11+
# subdir/lib to be extracted and rolled up into
12+
# a generated lib/image xxx.a ()
13+
#
14+
ifndef PDIR
15+
GEN_LIBS = libmisc.a
16+
endif
17+
18+
STD_CFLAGS=-std=gnu11 -Wimplicit
19+
20+
#############################################################
21+
# Configuration i.e. compile options etc.
22+
# Target specific stuff (defines etc.) goes in here!
23+
# Generally values applying to a tree are captured in the
24+
# makefile at its root level - these are then overridden
25+
# for a subtree within the makefile rooted therein
26+
#
27+
#DEFINES +=
28+
29+
#############################################################
30+
# Recursion Magic - Don't touch this!!
31+
#
32+
# Each subtree potentially has an include directory
33+
# corresponding to the common APIs applicable to modules
34+
# rooted at that subtree. Accordingly, the INCLUDE PATH
35+
# of a module can only contain the include directories up
36+
# its parent path, and not its siblings
37+
#
38+
# Required for each makefile to inherit from the parent
39+
#
40+
41+
INCLUDES := $(INCLUDES) -I $(PDIR)include
42+
INCLUDES += -I ./
43+
INCLUDES += -I ./include
44+
INCLUDES += -I ../include
45+
INCLUDES += -I ../../include
46+
INCLUDES += -I ../lua
47+
INCLUDES += -I ../platform
48+
INCLUDES += -I ../libc
49+
50+
PDIR := ../$(PDIR)
51+
sinclude $(PDIR)Makefile
52+

app/misc/dyn_arr.c

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#include "misc/dynarr.h"
2+
3+
#define ARRAY_PTR_CHECK if(array_ptr == NULL || array_ptr->data_ptr == NULL){\
4+
/**/DYNARR_DBG("array not initialized");\
5+
return false; \
6+
}
7+
8+
bool dynarr_init(dynarr_t* array_ptr, size_t array_size, size_t data_size){
9+
if(array_ptr == NULL || data_size == 0 || array_size == 0){
10+
/**/DYNARR_DBG("Invalid parameter: array_ptr(%p) data_size(%u) array_size(%u)", array_ptr, data_size, array_size);
11+
return false;
12+
}
13+
if(array_ptr->data_ptr != NULL ){
14+
/**/DYNARR_DBG("Array already initialized: array_ptr->data_ptr=%p", array_ptr->data_ptr);
15+
return false;
16+
}
17+
/**/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));
18+
19+
void* temp_array = c_zalloc(array_size * data_size);
20+
if(temp_array == NULL){
21+
/**/DYNARR_ERR("malloc FAIL! req:%u free:%u", (array_size * data_size), system_get_free_heap_size());
22+
return false;
23+
}
24+
25+
array_ptr->data_ptr = temp_array;
26+
array_ptr->array_size = array_size;
27+
array_ptr->data_size = data_size;
28+
array_ptr->used = 0;
29+
30+
return true;
31+
}
32+
33+
bool dynarr_resize(dynarr_t* array_ptr, size_t elements_to_add){
34+
ARRAY_PTR_CHECK;
35+
36+
if(elements_to_add <= 0){
37+
/**/DYNARR_DBG("Invalid qty: elements_to_add=%u", elements_to_add);
38+
return false;
39+
}
40+
41+
size_t new_array_size = array_ptr->array_size + elements_to_add;
42+
43+
/**/DYNARR_DBG("old size=%u\tnew size=%u\tmem used=%u",
44+
array_ptr->array_size, new_array_size, (new_array_size * array_ptr->data_size));
45+
46+
void* temp_array_p = c_realloc(array_ptr->data_ptr, new_array_size * array_ptr->data_size);
47+
if(temp_array_p == NULL){
48+
/**/DYNARR_ERR("malloc FAIL! req:%u free:%u", (new_array_size * array_ptr->data_size), system_get_free_heap_size());
49+
return false;
50+
}
51+
52+
array_ptr->data_ptr = temp_array_p;
53+
54+
size_t prev_size = array_ptr->array_size;
55+
56+
array_ptr->array_size = new_array_size;
57+
58+
//set memory to 0 for newly added array elements
59+
memset((uint8*) array_ptr->data_ptr + (prev_size * array_ptr->data_size), 0, (elements_to_add * array_ptr->data_size));
60+
61+
/**/DYNARR_DBG("Array successfully resized");
62+
return true;
63+
}
64+
65+
bool dynarr_remove(dynarr_t* array_ptr, void* element_to_remove){
66+
ARRAY_PTR_CHECK;
67+
68+
uint8* element_ptr = element_to_remove;
69+
uint8* data_ptr = array_ptr->data_ptr;
70+
71+
if(dynarr_boundaryCheck(array_ptr, element_to_remove) == FALSE){
72+
return false;
73+
}
74+
75+
//overwrite element to be removed by shifting all elements to the left
76+
memmove(element_ptr, element_ptr + array_ptr->data_size, (array_ptr->array_size - 1) * array_ptr->data_size - (element_ptr - data_ptr));
77+
78+
//clear newly freed element
79+
memset(data_ptr + ((array_ptr->array_size-1) * array_ptr->data_size), 0, array_ptr->data_size);
80+
81+
//decrement array used since we removed an element
82+
array_ptr->used--;
83+
/**/DYNARR_DBG("element(%p) removed from array", element_ptr);
84+
return true;
85+
}
86+
87+
bool dynarr_add(dynarr_t* array_ptr, void* data_ptr, size_t data_size){
88+
ARRAY_PTR_CHECK;
89+
90+
if(data_size != array_ptr->data_size){
91+
/**/DYNARR_DBG("Invalid data size: data_size(%u) != arr->data_size(%u)", data_size, array_ptr->data_size);
92+
return false;
93+
}
94+
95+
if(array_ptr->array_size == array_ptr->used){
96+
if(!dynarr_resize(array_ptr, (array_ptr->array_size/2))){
97+
return false;
98+
}
99+
}
100+
memcpy(((uint8*)array_ptr->data_ptr + (array_ptr->used * array_ptr->data_size)), data_ptr, array_ptr->data_size);
101+
102+
array_ptr->used++;
103+
return true;
104+
}
105+
106+
bool dynarr_boundaryCheck(dynarr_t* array_ptr, void* element_to_check){
107+
ARRAY_PTR_CHECK;
108+
109+
uint8* data_ptr = array_ptr->data_ptr;
110+
uint8* element_ptr = element_to_check;
111+
112+
if(element_ptr < data_ptr || ((element_ptr - data_ptr) / array_ptr->data_size) > array_ptr->array_size - 1){
113+
/**/DYNARR_DBG("element_ptr(%p) out of bounds: first element ptr:%p last element ptr:%p",
114+
element_ptr, data_ptr, data_ptr + ((array_ptr->array_size - 1) * array_ptr->data_size));
115+
return false;
116+
}
117+
return true;
118+
}
119+
120+
bool dynarr_free(dynarr_t* array_ptr){
121+
ARRAY_PTR_CHECK;
122+
123+
c_free(array_ptr->data_ptr);
124+
125+
array_ptr->data_ptr=NULL;
126+
array_ptr->array_size = array_ptr->used = 0;
127+
128+
/**/DYNARR_DBG("array freed");
129+
return true;
130+
}
131+

app/modules/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ INCLUDES += -I ../fatfs
5555
INCLUDES += -I ../http
5656
INCLUDES += -I ../sjson
5757
INCLUDES += -I ../websocket
58+
INCLUDES += -I ../pm
5859
PDIR := ../$(PDIR)
5960
sinclude $(PDIR)Makefile
6061

app/modules/node.c

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,36 @@ static int node_deepsleep( lua_State* L )
7474
return 0;
7575
}
7676

77-
// Lua: dsleep_set_options
78-
// Combined to dsleep( us, option )
79-
// static int node_deepsleep_setoption( lua_State* L )
80-
// {
81-
// s32 option;
82-
// option = luaL_checkinteger( L, 1 );
83-
// if ( option < 0 || option > 4)
84-
// return luaL_error( L, "wrong arg range" );
85-
// else
86-
// deep_sleep_set_option( option );
87-
// return 0;
88-
// }
89-
// Lua: info()
77+
78+
#ifdef PMSLEEP_ENABLE
79+
#include "pmSleep.h"
80+
81+
int node_sleep_resume_cb_ref= LUA_NOREF;
82+
void node_sleep_resume_cb(void)
83+
{
84+
PMSLEEP_DBG("START");
85+
pmSleep_execute_lua_cb(&node_sleep_resume_cb_ref);
86+
PMSLEEP_DBG("END");
87+
}
88+
89+
// Lua: node.sleep(table)
90+
static int node_sleep( lua_State* L )
91+
{
92+
pmSleep_INIT_CFG(cfg);
93+
cfg.sleep_mode=LIGHT_SLEEP_T;
94+
95+
if(lua_istable(L, 1)){
96+
pmSleep_parse_table_lua(L, 1, &cfg, NULL, &node_sleep_resume_cb_ref);
97+
}
98+
else{
99+
return luaL_argerror(L, 1, "must be table");
100+
}
101+
102+
cfg.resume_cb_ptr = &node_sleep_resume_cb;
103+
pmSleep_suspend(&cfg);
104+
return 0;
105+
}
106+
#endif //PMSLEEP_ENABLE
90107

91108
static int node_info( lua_State* L )
92109
{
@@ -570,6 +587,10 @@ static const LUA_REG_TYPE node_map[] =
570587
{
571588
{ LSTRKEY( "restart" ), LFUNCVAL( node_restart ) },
572589
{ LSTRKEY( "dsleep" ), LFUNCVAL( node_deepsleep ) },
590+
#ifdef PMSLEEP_ENABLE
591+
{ LSTRKEY( "sleep" ), LFUNCVAL( node_sleep ) },
592+
PMSLEEP_INT_MAP,
593+
#endif
573594
{ LSTRKEY( "info" ), LFUNCVAL( node_info ) },
574595
{ LSTRKEY( "chipid" ), LFUNCVAL( node_chipid ) },
575596
{ LSTRKEY( "flashid" ), LFUNCVAL( node_flashid ) },

0 commit comments

Comments
 (0)