From feab8b220803a6e3c973f5c33df395055ebf6c34 Mon Sep 17 00:00:00 2001 From: Philip Gladstone Date: Sat, 24 Dec 2016 18:45:34 -0500 Subject: [PATCH] Various minor bits of cleanup (#1647) * Check the return code of the read function when doing crypto.fhash so that we don't pass negative lengths to the hashing functions * Fix various assert failures in the LVM arising from rotables. No functional change * Add the gpio interrupt time to the callback (and pass it from the interrupt handler) * Get the PC right in the perf module * Make the headers static in the websocket module * Fix the documentation --- app/crypto/digests.c | 4 +++- app/lua/lapi.c | 1 + app/lua/ltable.c | 3 ++- app/lua/lvm.c | 3 ++- app/modules/gpio.c | 16 +++++++++++++--- app/modules/perf.c | 13 +++++-------- app/platform/platform.c | 3 ++- app/websocket/websocketclient.c | 8 ++++---- docs/en/modules/gpio.md | 11 ++++++----- docs/en/modules/perf.md | 4 +--- 10 files changed, 39 insertions(+), 27 deletions(-) diff --git a/app/crypto/digests.c b/app/crypto/digests.c index a81f8a31..f5429ffd 100644 --- a/app/crypto/digests.c +++ b/app/crypto/digests.c @@ -144,7 +144,9 @@ int ICACHE_FLASH_ATTR crypto_fhash (const digest_mech_info_t *mi, int read_len = 0; do { read_len = read(readarg, buffer, mi->block_size); - mi->update (ctx, buffer, read_len); + if (read_len > 0) { + mi->update (ctx, buffer, read_len); + } } while (read_len == mi->block_size); // Finish up diff --git a/app/lua/lapi.c b/app/lua/lapi.c index e3d04e5b..3f783cba 100644 --- a/app/lua/lapi.c +++ b/app/lua/lapi.c @@ -412,6 +412,7 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) { case LUA_TLIGHTUSERDATA: return lua_touserdata(L, idx); case LUA_TROTABLE: + return rvalue(o); case LUA_TLIGHTFUNCTION: return pvalue(o); default: return NULL; diff --git a/app/lua/ltable.c b/app/lua/ltable.c index 914c03ad..2e486512 100644 --- a/app/lua/ltable.c +++ b/app/lua/ltable.c @@ -105,8 +105,9 @@ static Node *mainposition (const Table *t, const TValue *key) { return hashstr(t, rawtsvalue(key)); case LUA_TBOOLEAN: return hashboolean(t, bvalue(key)); - case LUA_TLIGHTUSERDATA: case LUA_TROTABLE: + return hashpointer(t, rvalue(key)); + case LUA_TLIGHTUSERDATA: case LUA_TLIGHTFUNCTION: return hashpointer(t, pvalue(key)); default: diff --git a/app/lua/lvm.c b/app/lua/lvm.c index 091a5aa0..51cf9f21 100644 --- a/app/lua/lvm.c +++ b/app/lua/lvm.c @@ -292,8 +292,9 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { case LUA_TNIL: return 1; case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ - case LUA_TLIGHTUSERDATA: case LUA_TROTABLE: + return rvalue(t1) == rvalue(t2); + case LUA_TLIGHTUSERDATA: case LUA_TLIGHTFUNCTION: return pvalue(t1) == pvalue(t2); case LUA_TUSERDATA: { diff --git a/app/modules/gpio.c b/app/modules/gpio.c index de2fbd47..1cde1545 100644 --- a/app/modules/gpio.c +++ b/app/modules/gpio.c @@ -34,10 +34,19 @@ static int gpio_cb_ref[GPIO_PIN_NUM]; // It also re-enables the pin interrupt, so that we get another callback queued static void gpio_intr_callback_task (task_param_t param, uint8 priority) { - unsigned pin = param >> 1; - unsigned level = param & 1; + uint32_t then = (param >> 8) & 0xffffff; + uint32_t pin = (param >> 1) & 127; + uint32_t level = param & 1; UNUSED(priority); + uint32_t now = system_get_time(); + + // Now must be >= then . Add the missing bits + if (then > (now & 0xffffff)) { + then += 0x1000000; + } + then = (then + (now & 0x7f000000)) & 0x7fffffff; + NODE_DBG("pin:%d, level:%d \n", pin, level); if(gpio_cb_ref[pin] != LUA_NOREF) { // GPIO callbacks are run in L0 and inlcude the level as a parameter @@ -52,7 +61,8 @@ static void gpio_intr_callback_task (task_param_t param, uint8 priority) // Do the actual callback lua_rawgeti(L, LUA_REGISTRYINDEX, gpio_cb_ref[pin]); lua_pushinteger(L, level); - lua_call(L, 1, 0); + lua_pushinteger(L, then); + lua_call(L, 2, 0); if (INTERRUPT_TYPE_IS_LEVEL(pin_int_type[pin])) { // Level triggered -- re-enable the callback diff --git a/app/modules/perf.c b/app/modules/perf.c index 358d98c3..a99ae99e 100644 --- a/app/modules/perf.c +++ b/app/modules/perf.c @@ -24,7 +24,6 @@ typedef struct { uint32_t bucket_count; uint32_t total_samples; uint32_t outside_samples; - uint32_t pc_offset; uint32_t bucket[1]; } DATA; @@ -39,7 +38,11 @@ static void ICACHE_RAM_ATTR hw_timer_cb(os_param_t p) uint32_t stackaddr; if (data) { - uint32_t pc = *(&stackaddr + data->pc_offset); + uint32_t pc; + asm ( + "rsr %0, EPC1;" /* read out the EPC */ + :"=r"(pc) + ); uint32_t bucket_number = (pc - data->start) >> data->bucket_shift; if (bucket_number < data->bucket_count) { @@ -72,11 +75,6 @@ static int perf_start(lua_State *L) bins = (end - start + (1 << shift) - 1) / (1 << shift); - int pc_offset = 20; // This appears to be correct - if (lua_gettop(L) >= 4) { - pc_offset = luaL_checkinteger(L, 4); - } - size_t data_size = sizeof(DATA) + bins * sizeof(uint32_t); DATA *d = (DATA *) lua_newuserdata(L, data_size); memset(d, 0, data_size); @@ -84,7 +82,6 @@ static int perf_start(lua_State *L) d->start = start; d->bucket_shift = shift; d->bucket_count = bins; - d->pc_offset = pc_offset; if (data) { lua_unref(L, data->ref); diff --git a/app/platform/platform.c b/app/platform/platform.c index 267d541a..d1dbc2d9 100755 --- a/app/platform/platform.c +++ b/app/platform/platform.c @@ -204,6 +204,7 @@ int platform_gpio_read( unsigned pin ) static void ICACHE_RAM_ATTR platform_gpio_intr_dispatcher (void *dummy){ uint32 j=0; uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); + uint32 now = system_get_time(); UNUSED(dummy); #ifdef GPIO_INTERRUPT_HOOK_ENABLE @@ -229,7 +230,7 @@ static void ICACHE_RAM_ATTR platform_gpio_intr_dispatcher (void *dummy){ //clear interrupt status GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(j)); uint32 level = 0x1 & GPIO_INPUT_GET(GPIO_ID_PIN(j)); - task_post_high (gpio_task_handle, (i<<1) + level); + task_post_high (gpio_task_handle, (now << 8) + (i<<1) + level); // We re-enable the interrupt when we execute the callback } } diff --git a/app/websocket/websocketclient.c b/app/websocket/websocketclient.c index 834996e7..4628bf8a 100644 --- a/app/websocket/websocketclient.c +++ b/app/websocket/websocketclient.c @@ -69,12 +69,12 @@ #define WS_OPCODE_PING 0x9 #define WS_OPCODE_PONG 0xA -header_t DEFAULT_HEADERS[] = { +static const header_t DEFAULT_HEADERS[] = { {"User-Agent", "ESP8266"}, {"Sec-WebSocket-Protocol", "chat"}, {0} }; -header_t *EMPTY_HEADERS = DEFAULT_HEADERS + sizeof(DEFAULT_HEADERS) / sizeof(header_t) - 1; +static const header_t *EMPTY_HEADERS = DEFAULT_HEADERS + sizeof(DEFAULT_HEADERS) / sizeof(header_t) - 1; static char *cryptoSha1(char *data, unsigned int len) { SHA1_CTX ctx; @@ -132,7 +132,7 @@ static char *_strcpy(char *dst, char *src) { return dst - 1; } -static int headers_length(header_t *headers) { +static int headers_length(const header_t *headers) { int length = 0; for(; headers->key; headers++) length += strlen(headers->key) + strlen(headers->value) + 4; @@ -595,7 +595,7 @@ static void connect_callback(void *arg) { {0} }; - header_t *extraHeaders = ws->extraHeaders ? ws->extraHeaders : EMPTY_HEADERS; + const header_t *extraHeaders = ws->extraHeaders ? ws->extraHeaders : EMPTY_HEADERS; char buf[WS_INIT_REQUEST_LENGTH + strlen(ws->path) + strlen(ws->hostname) + headers_length(DEFAULT_HEADERS) + headers_length(headers) + headers_length(extraHeaders) + 2]; diff --git a/docs/en/modules/gpio.md b/docs/en/modules/gpio.md index f438b402..ff256040 100644 --- a/docs/en/modules/gpio.md +++ b/docs/en/modules/gpio.md @@ -125,9 +125,11 @@ This function is not available if GPIO_INTERRUPT_ENABLE was undefined at compile - `type` "up", "down", "both", "low", "high", which represent *rising edge*, *falling edge*, *both edges*, *low level*, and *high level* trigger modes respectivey. If the type is "none" or omitted then the callback function is removed and the interrupt is disabled. -- `callback_function(level)` callback function when trigger occurs. The level of the specified pin -at the interrupt passed as the parameter to the callback. The previous callback function will be -used if the function is omitted. +- `callback_function(level, when)` callback function when trigger occurs. The level of the specified pin +at the interrupt passed as the first parameter to the callback. The timestamp of the event is passed +as the second parameter. This is in microseconds and has the same base as for `tmr.now()`. This timestamp +is grabbed at interrupt level and is more consistent than getting the time in the callback function. +The previous callback function will be used if the function is omitted. #### Returns `nil` @@ -139,8 +141,7 @@ do -- use pin 1 as the input pulse width counter local pin, pulse1, du, now, trig = 1, 0, 0, tmr.now, gpio.trig gpio.mode(pin,gpio.INT) - local function pin1cb(level) - local pulse2 = now() + local function pin1cb(level, pulse2) print( level, pulse2 - pulse1 ) pulse1 = pulse2 trig(pin, level == gpio.HIGH and "down" or "up") diff --git a/docs/en/modules/perf.md b/docs/en/modules/perf.md index 768bd0bb..4d774684 100644 --- a/docs/en/modules/perf.md +++ b/docs/en/modules/perf.md @@ -11,15 +11,13 @@ of memory to store the histogram, the user can specify which area of code is of Starts a performance monitoring session. #### Syntax -`perf.start([start[, end[, nbins[, offset]]]])` +`perf.start([start[, end[, nbins]]])` #### Parameters - `start` (optional) The lowest PC address for the histogram. Default is 0x40000000. - `end` (optional) The highest address for the histogram. Default is the end of the used space in the flash memory. - `nbins` (optional) The number of bins in the histogram. Keep this reasonable otherwise you will run out of memory. Default is 1024. -- `offset` (Very optional) This specifies the offset of the saved PC value -on the interrupt stack. It appears that 20 is the correct value. Note that the number of bins is an upper limit. The size of each bin is set to be the smallest power of two such that the number of bins required is less than or equal to the provided number of bins.