Skip to content

Commit

Permalink
Implement timer suspend functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
dnc40085 committed Jan 25, 2017
1 parent 87e1abf commit 4e3560d
Show file tree
Hide file tree
Showing 11 changed files with 1,037 additions and 18 deletions.
8 changes: 7 additions & 1 deletion app/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ SUBDIRS= \
http \
fatfs \
esp-gdbstub \
websocket
websocket \
swTimer \
misc \


endif # } PDIR

Expand Down Expand Up @@ -97,6 +100,9 @@ COMPONENTS_eagle.app.v6 = \
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__
55 changes: 55 additions & 0 deletions app/include/swTimer/swTimer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#ifndef __SW_TIMER_H__
#define __SW_TIMER_H__
#include "user_interface.h"
//#define SWTMR_DEBUG
#define USE_SWTMR_ERROR_STRINGS

#if defined(SWTMR_DEBUG) || defined(NODE_DEBUG)
#ifndef SWTMR_DEBUG
#define SWTMR_DEBUG
#endif


#define SWTMR_DBG(fmt, ...) c_printf("\n SWTMR_DBG(%s):"fmt"\n", __FUNCTION__, ##__VA_ARGS__)
#else
#define SWTMR_DBG(...)
#endif

#if defined(SWTMR_ERROR) || defined(NODE_ERROR)
#define SWTMR_ERR(fmt, ...) c_printf("\n SWTMR:"fmt"\n", ##__VA_ARGS__)
#else
#define SWTMR_DBG(...)
#endif

enum SWTMR_STATUS{
SWTMR_OK = 0,

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 sw_timer_register(void* timer_ptr);
void sw_timer_unregister(void* timer_ptr);
int sw_timer_suspend(os_timer_t* timer_ptr);
int sw_timer_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__
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;
}

17 changes: 17 additions & 0 deletions app/modules/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,21 @@ static int node_restore (lua_State *L)
return 0;
}

#include "swTimer/swTimer.h"

static int node_suspend_timers (lua_State *L)
{
lua_pushnumber(L, sw_timer_suspend(NULL));
return 1;
}

static int node_resume_timers (lua_State *L)
{
lua_pushnumber(L, sw_timer_resume(NULL));
return 1;
}


#ifdef LUA_OPTIMIZE_DEBUG
/* node.stripdebug([level[, function]]). 
* level: 1 don't discard debug
Expand Down Expand Up @@ -577,6 +592,8 @@ static const LUA_REG_TYPE node_map[] =
{ LSTRKEY( "setcpufreq" ), LFUNCVAL( node_setcpufreq) },
{ LSTRKEY( "bootreason" ), LFUNCVAL( node_bootreason) },
{ LSTRKEY( "restore" ), LFUNCVAL( node_restore) },
{ LSTRKEY( "suspendTimers" ), LFUNCVAL( node_suspend_timers ) },
{ LSTRKEY( "resumeTimers" ), LFUNCVAL( node_resume_timers ) },
{ LSTRKEY( "random" ), LFUNCVAL( node_random) },
#ifdef LUA_OPTIMIZE_DEBUG
{ LSTRKEY( "stripdebug" ), LFUNCVAL( node_stripdebug ) },
Expand Down
Loading

0 comments on commit 4e3560d

Please sign in to comment.