From a1e02fc6a898475316d18a27f61092eabcefccb0 Mon Sep 17 00:00:00 2001 From: petur Date: Sun, 25 Mar 2018 22:56:01 +0200 Subject: [PATCH 01/15] fix for ds18b20 negative decimals ds18b20 decimals do not take into account the sign bit. Since the original calculation was not so readable, rewritten in readable way that also fixes the bug. Same code as PR against master. --- app/modules/ds18b20.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/modules/ds18b20.c b/app/modules/ds18b20.c index b07bc173..a9df0ab1 100644 --- a/app/modules/ds18b20.c +++ b/app/modules/ds18b20.c @@ -192,6 +192,7 @@ static int ds18b20_lua_read(lua_State *L) { static int ds18b20_read_device(uint8_t *ds18b20_device_rom) { lua_State *L = lua_getstate(); + int16_t ds18b20_raw_temp; if (onewire_crc8(ds18b20_device_rom,7) == ds18b20_device_rom[7]) { @@ -216,8 +217,9 @@ static int ds18b20_read_device(uint8_t *ds18b20_device_rom) { lua_pushfstring(L, "%d:%d:%d:%d:%d:%d:%d:%d", ds18b20_device_rom[0], ds18b20_device_rom[1], ds18b20_device_rom[2], ds18b20_device_rom[3], ds18b20_device_rom[4], ds18b20_device_rom[5], ds18b20_device_rom[6], ds18b20_device_rom[7]); ds18b20_device_scratchpad_conf = (ds18b20_device_scratchpad[4] >> 5) + 9; - ds18b20_device_scratchpad_temp = ((int8_t)(ds18b20_device_scratchpad[1] << 4) + (ds18b20_device_scratchpad[0] >> 4) + ((double)(ds18b20_device_scratchpad[0] & 0x0F) / 16)); - ds18b20_device_scratchpad_temp_dec = ((double)(ds18b20_device_scratchpad[0] & 0x0F) / 16 * 1000); + ds18b20_raw_temp = ((ds18b20_device_scratchpad[1] << 8) | ds18b20_device_scratchpad[0]); + ds18b20_device_scratchpad_temp = (double)ds18b20_raw_temp / 16; + ds18b20_device_scratchpad_temp_dec = (ds18b20_raw_temp - (ds18b20_raw_temp / 16 * 16)) * 1000 / 16; if (ds18b20_device_scratchpad_conf >= ds18b20_device_res) { ds18b20_device_res = ds18b20_device_scratchpad_conf; From 2e201cd8357425c8c801d82da198683330f3dc63 Mon Sep 17 00:00:00 2001 From: dnc40085 Date: Sun, 22 Apr 2018 18:36:23 -0700 Subject: [PATCH 02/15] Fixed coding errors in app/pm/swtimer.c --- app/pm/swtimer.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/app/pm/swtimer.c b/app/pm/swtimer.c index bedbf954..43c1ae5a 100644 --- a/app/pm/swtimer.c +++ b/app/pm/swtimer.c @@ -1,3 +1,9 @@ +#if defined(__GNUC__) +#pragma GCC diagnostic warning "-Wall" +#pragma GCC diagnostic warning "-Wextra" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + /* swTimer.c SDK timer suspend API * * SDK software timer API info: @@ -57,7 +63,7 @@ //this section specifies which lua registry to use. LUA_GLOBALSINDEX or LUA_REGISTRYINDEX #ifdef SWTMR_DEBUG -#define SWTMR_DBG(fmt, ...) c_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 SUSP_LIST_STR "suspended_tmr_LL_head" @@ -83,7 +89,7 @@ typedef struct cb_registry_item{ /* Internal variables */ static tmr_cb_queue_t* register_queue = NULL; -static task_handle_t cb_register_task_id = NULL; //variable to hold task id for task handler(process_cb_register_queue) +static task_handle_t cb_register_task_id = 0; //variable to hold task id for task handler(process_cb_register_queue) /* Function declarations */ //void swtmr_cb_register(void* timer_cb_ptr, uint8 resume_policy); @@ -173,7 +179,7 @@ void swtmr_suspend_timers(){ */ while(timer_ptr != NULL){ os_timer_t* next_timer = (os_timer_t*)0xffffffff; - for(int i = 0; i < registered_cb_qty; i++){ + for(size_t i = 0; i < registered_cb_qty; i++){ if(timer_ptr->timer_func == cb_reg_array[i]->tmr_cb_ptr){ //current timer will be suspended, next timer's pointer will be needed to continue processing timer_list @@ -394,7 +400,7 @@ static void add_to_reg_queue(void* timer_cb_ptr, uint8 suspend_policy){ tmr_cb_queue_t* queue_temp = c_zalloc(sizeof(tmr_cb_queue_t)); if(!queue_temp){ //it's boot time currently and we're already out of memory, something is very wrong... - c_printf("\n\t%s:out of memory, system halted!\n", __FUNCTION__); + dbg_printf("\n\t%s:out of memory, system halted!\n", __FUNCTION__); while(1) system_soft_wdt_feed(); } @@ -476,8 +482,8 @@ int print_timer_list(lua_State* L){ os_timer_t* timer_list_ptr = timer_list; - c_printf("\n\tCurrent FRC2: %u\n", RTC_REG_READ(FRC2_COUNT_ADDRESS)); - c_printf("\ttimer_list:\n"); + dbg_printf("\n\tCurrent FRC2: %u\n", RTC_REG_READ(FRC2_COUNT_ADDRESS)); + dbg_printf("\ttimer_list:\n"); while(timer_list_ptr != NULL){ bool registered_flag = FALSE; for(int i=0; i < registered_cb_qty; i++){ @@ -486,7 +492,7 @@ int print_timer_list(lua_State* L){ break; } } - c_printf("\tptr:%p\tcb:%p\texpire:%8u\tperiod:%8u\tnext:%p\t%s\n", + dbg_printf("\tptr:%p\tcb:%p\texpire:%8u\tperiod:%8u\tnext:%p\t%s\n", timer_list_ptr, timer_list_ptr->timer_func, timer_list_ptr->timer_expire, timer_list_ptr->timer_period, timer_list_ptr->timer_next, registered_flag ? "Registered" : ""); timer_list_ptr = timer_list_ptr->timer_next; } @@ -513,9 +519,9 @@ int print_susp_timer_list(lua_State* L){ } os_timer_t* susp_timer_list_ptr = lua_touserdata(L, -1); - c_printf("\n\tsuspended_timer_list:\n"); + dbg_printf("\n\tsuspended_timer_list:\n"); while(susp_timer_list_ptr != NULL){ - c_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; } return 0; From 2735426fc0cd838caea44411163a2cc02b3c9652 Mon Sep 17 00:00:00 2001 From: dnc40085 Date: Sun, 22 Apr 2018 22:02:55 -0700 Subject: [PATCH 03/15] Removed pragma defines that were mistakenly left in --- app/pm/swtimer.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/pm/swtimer.c b/app/pm/swtimer.c index 43c1ae5a..802a2ee4 100644 --- a/app/pm/swtimer.c +++ b/app/pm/swtimer.c @@ -1,9 +1,3 @@ -#if defined(__GNUC__) -#pragma GCC diagnostic warning "-Wall" -#pragma GCC diagnostic warning "-Wextra" -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif - /* swTimer.c SDK timer suspend API * * SDK software timer API info: From da2bc7395d70a909b037a7a60073e019713b47dd Mon Sep 17 00:00:00 2001 From: dnc40085 Date: Sun, 22 Apr 2018 22:18:36 -0700 Subject: [PATCH 04/15] Changed out of memory response from system halt to system restart --- app/pm/swtimer.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/pm/swtimer.c b/app/pm/swtimer.c index 802a2ee4..9042b3b1 100644 --- a/app/pm/swtimer.c +++ b/app/pm/swtimer.c @@ -394,9 +394,8 @@ static void add_to_reg_queue(void* timer_cb_ptr, uint8 suspend_policy){ tmr_cb_queue_t* queue_temp = c_zalloc(sizeof(tmr_cb_queue_t)); if(!queue_temp){ //it's boot time currently and we're already out of memory, something is very wrong... - dbg_printf("\n\t%s:out of memory, system halted!\n", __FUNCTION__); - while(1) - system_soft_wdt_feed(); + dbg_printf("\n\t%s:out of memory, rebooting.", __FUNCTION__); + system_restart(); } queue_temp->tmr_cb_ptr = timer_cb_ptr; queue_temp->suspend_policy = suspend_policy; From 5e1ca234cce36f251edd78dc3d5a5ce4d4c76a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Tue, 24 Apr 2018 13:58:10 +0200 Subject: [PATCH 05/15] Fix config reference --- docs/en/modules/sqlite3.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/modules/sqlite3.md b/docs/en/modules/sqlite3.md index a18f382e..bba6647c 100644 --- a/docs/en/modules/sqlite3.md +++ b/docs/en/modules/sqlite3.md @@ -9,7 +9,7 @@ This module depens on [SQLite3](http://www.sqlite.org/) library developed by Dwa For instruction on how to use this module or further documentation, please, refer to [LuaSQLite3 Documentation](http://lua.sqlite.org/index.cgi/doc/tip/doc/lsqlite3.wiki). -This module is a stripped down version of SQLite, with every possible OMIT_\* configuration enable. The enabled OMIT_\* directives are available in the module's [Makefile](../../../app/sqlite3/Makefile). +This module is a stripped down version of SQLite, with every possible OMIT_\* configuration enable. The enabled OMIT_\* directives are available in the module's [config file](../../../app/sqlite3/config_ext.h). The SQLite3 module vfs layer integration with NodeMCU was developed by me. From 6069ebdc9090b0e16bcfacedde4c359bdef6d702 Mon Sep 17 00:00:00 2001 From: dnc40085 Date: Thu, 26 Apr 2018 13:45:24 -0700 Subject: [PATCH 06/15] Update node.dsleep() to support longer deep sleep duration. (#2358) * Update node.dsleep() to support longer deep sleep duration. * Updated documentation for node.dsleepMax() --- app/modules/node.c | 12 +++++++++--- docs/en/modules/node.md | 42 ++++++++++++++++++++++++++++++++++------- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/app/modules/node.c b/app/modules/node.c index 10e7a639..efdf9491 100644 --- a/app/modules/node.c +++ b/app/modules/node.c @@ -38,10 +38,15 @@ static int node_restart( lua_State* L ) return 0; } +static int dsleepMax( lua_State *L ) { + lua_pushnumber(L, (uint64_t)system_rtc_clock_cali_proc()*(0x80000000-1)/(0x1000)); + return 1; +} + // Lua: dsleep( us, option ) static int node_deepsleep( lua_State* L ) { - uint32 us; + uint64 us; uint8 option; //us = luaL_checkinteger( L, 1 ); // Set deleep option, skip if nil @@ -592,8 +597,9 @@ static const LUA_REG_TYPE node_task_map[] = { static const LUA_REG_TYPE node_map[] = { - { LSTRKEY( "restart" ), LFUNCVAL( node_restart ) }, - { LSTRKEY( "dsleep" ), LFUNCVAL( node_deepsleep ) }, + { LSTRKEY( "restart" ), LFUNCVAL( node_restart ) }, + { LSTRKEY( "dsleep" ), LFUNCVAL( node_deepsleep ) }, + { LSTRKEY( "dsleepMax" ), LFUNCVAL( dsleepMax ) }, #ifdef PMSLEEP_ENABLE { LSTRKEY( "sleep" ), LFUNCVAL( node_sleep ) }, PMSLEEP_INT_MAP, diff --git a/docs/en/modules/node.md b/docs/en/modules/node.md index c2979a9c..39efc83c 100644 --- a/docs/en/modules/node.md +++ b/docs/en/modules/node.md @@ -87,9 +87,8 @@ dofile("hello.lc") Enters deep sleep mode, wakes up when timed out. -The maximum sleep time is 4294967295us, ~71 minutes. This is an SDK limitation. -Firmware from before 05 Jan 2016 have a maximum sleeptime of ~35 minutes. - +Theoretical maximum deep sleep duration can be found with [`node.dsleepMax()`](#nodedsleepmax) + !!! caution This function can only be used in the condition that esp8266 PIN32(RST) and PIN8(XPD_DCDC aka GPIO16) are connected together. Using sleep(0) will set no wake up timer, connect a GPIO to pin RST, the chip will wake up by a falling-edge on pin RST. @@ -107,10 +106,7 @@ Firmware from before 05 Jan 2016 have a maximum sleeptime of ~35 minutes. - 1, RF_CAL after deep-sleep wake up, there will be large current - 2, no RF_CAL after deep-sleep wake up, there will only be small current - 4, disable RF after deep-sleep wake up, just like modem sleep, there will be the smallest current - - `instant` number (integer) or `nil`. If present and non-zero, do not use - the normal grace time before entering deep sleep. This is a largely - undocumented feature, and is only briefly mentioned in Espressif's - [low power solutions](https://espressif.com/sites/default/files/documentation/9b-esp8266_low_power_solutions_en.pdf#page=10) document (chapter 4.5). + - `instant` number (integer) or `nil`. If present and non-zero, the chip will enter Deep-sleep immediately and will not wait for the Wi-Fi core to be shutdown. #### Returns `nil` @@ -131,6 +127,38 @@ node.dsleep(nil,4) - [`wifi.suspend()`](wifi.md#wifisuspend) - [`wifi.resume()`](wifi.md#wifiresume) - [`node.sleep()`](#nodesleep) +- [`node.dsleepMax()`](#nodedsleepmax) + +## node.dsleepMax() + +Returns the current theoretical maximum deep sleep duration. + +!!! caution + + While it is possible to specify a longer sleep time than the theoretical maximum sleep duration, it is not recommended to exceed this maximum. + + +!!! note + + This theoretical maximum is dependent on ambient temperature. + (lower temp = shorter sleep duration, higher temp = longer sleep duration) + +#### Syntax +`node.dsleepMax()` + +#### Parameters + none + +#### Returns +`max_duration` + +#### Example +```lua +node.dsleep(node.dsleepMax()) +``` + +#### See also +- [`node.dsleep()`](#nodedsleep) ## node.flashid() From 53e44d5ecee74b14d5125037fac9e971cc55a362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Thu, 26 Apr 2018 22:56:43 +0200 Subject: [PATCH 07/15] Add reference to deep sleep post for details --- docs/en/modules/node.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/en/modules/node.md b/docs/en/modules/node.md index 39efc83c..d8176ff9 100644 --- a/docs/en/modules/node.md +++ b/docs/en/modules/node.md @@ -87,7 +87,7 @@ dofile("hello.lc") Enters deep sleep mode, wakes up when timed out. -Theoretical maximum deep sleep duration can be found with [`node.dsleepMax()`](#nodedsleepmax) +Theoretical maximum deep sleep duration can be found with [`node.dsleepMax()`](#nodedsleepmax). ["Max deep sleep for ESP8266"](https://thingpulse.com/max-deep-sleep-for-esp8266/) claims the realistic maximum be around 3.5h. !!! caution @@ -135,13 +135,12 @@ Returns the current theoretical maximum deep sleep duration. !!! caution - While it is possible to specify a longer sleep time than the theoretical maximum sleep duration, it is not recommended to exceed this maximum. + While it is possible to specify a longer sleep time than the theoretical maximum sleep duration, it is not recommended to exceed this maximum. In tests documented at ["Max deep sleep for ESP8266"](https://thingpulse.com/max-deep-sleep-for-esp8266/) the device never woke up again if the specified sleep time was beyond `dsleepMax()`. !!! note - This theoretical maximum is dependent on ambient temperature. - (lower temp = shorter sleep duration, higher temp = longer sleep duration) + This theoretical maximum is dependent on ambient temperature: lower temp = shorter sleep duration, higher temp = longer sleep duration #### Syntax `node.dsleepMax()` From 6a261aecdbdb172aa9b2b0c059d070a9f120a6c7 Mon Sep 17 00:00:00 2001 From: dnc40085 Date: Mon, 7 May 2018 04:55:59 -0700 Subject: [PATCH 08/15] Fixed bug that caused crash when printing wifi.suspend disabled msg (#2365) --- app/modules/wifi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/modules/wifi.c b/app/modules/wifi.c index 8ff1db39..3eb68194 100644 --- a/app/modules/wifi.c +++ b/app/modules/wifi.c @@ -512,16 +512,16 @@ static int wifi_resume(lua_State* L) /* End WiFi suspend functions*/ #else -static char *susp_note_str = "\n The option \"pmsleep_enable\" in \"app/include/user_config.h\" was disabled during FW build!\n"; +static char *susp_note_str = "\n The option \"PMSLEEP_ENABLE\" in \"app/include/user_config.h\" was disabled during FW build!\n"; static char *susp_unavailable_str = "wifi.suspend is unavailable"; static int wifi_suspend(lua_State* L){ - c_sprintf("%s", susp_note_str); + dbg_printf("%s", susp_note_str); return luaL_error(L, susp_unavailable_str); } static int wifi_resume(lua_State* L){ - c_sprintf("%s", susp_note_str); + dbg_printf("%s", susp_note_str); return luaL_error(L, susp_unavailable_str); } #endif From 106841c26c5a7cbfcb5977f287d386e4b7832b6a Mon Sep 17 00:00:00 2001 From: dnc40085 Date: Tue, 8 May 2018 13:43:12 -0700 Subject: [PATCH 09/15] Add message indicating that node.sleep() was disabled during build. (#2367) --- app/modules/node.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/modules/node.c b/app/modules/node.c index efdf9491..a00bafd7 100644 --- a/app/modules/node.c +++ b/app/modules/node.c @@ -108,13 +108,18 @@ static int node_sleep( lua_State* L ) cfg.resume_cb_ptr = &node_sleep_resume_cb; pmSleep_suspend(&cfg); #else - c_printf("\n The option \"timer_suspend_enable\" in \"app/include/user_config.h\" was disabled during FW build!\n"); - return luaL_error(L, "light sleep is unavailable"); + dbg_printf("\n The option \"TIMER_SUSPEND_ENABLE\" in \"app/include/user_config.h\" was disabled during FW build!\n"); + return luaL_error(L, "node.sleep() is unavailable"); #endif return 0; } +#else +static int node_sleep( lua_State* L ) +{ + dbg_printf("\n The options \"TIMER_SUSPEND_ENABLE\" and \"PMSLEEP_ENABLE\" in \"app/include/user_config.h\" were disabled during FW build!\n"); + return luaL_error(L, "node.sleep() is unavailable"); +} #endif //PMSLEEP_ENABLE - static int node_info( lua_State* L ) { lua_pushinteger(L, NODE_VERSION_MAJOR); @@ -600,8 +605,8 @@ static const LUA_REG_TYPE node_map[] = { LSTRKEY( "restart" ), LFUNCVAL( node_restart ) }, { LSTRKEY( "dsleep" ), LFUNCVAL( node_deepsleep ) }, { LSTRKEY( "dsleepMax" ), LFUNCVAL( dsleepMax ) }, -#ifdef PMSLEEP_ENABLE { LSTRKEY( "sleep" ), LFUNCVAL( node_sleep ) }, +#ifdef PMSLEEP_ENABLE PMSLEEP_INT_MAP, #endif { LSTRKEY( "info" ), LFUNCVAL( node_info ) }, From 914a4afc96136311db8ab923b8a6942f429d266f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnim=20L=C3=A4uger?= Date: Tue, 15 May 2018 20:55:31 +0200 Subject: [PATCH 10/15] Fix MQTT connect leak (#2368) * fix application of patch 0018-feat-espconn-Modification-for-espconn.patch in #2269 espconn_tcp_reconnect() was removed instead of espconn_list_delete() --- app/lwip/app/espconn_tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lwip/app/espconn_tcp.c b/app/lwip/app/espconn_tcp.c index 49942e4e..b1ebfde4 100644 --- a/app/lwip/app/espconn_tcp.c +++ b/app/lwip/app/espconn_tcp.c @@ -434,9 +434,9 @@ espconn_Task(os_event_t *events) break; case SIG_ESPCONN_ERRER: /*remove the node from the client's active connection list*/ - espconn_list_delete(&plink_active, task_msg); if (espconn_manual_recv_enabled(task_msg)) espconn_list_delete(&plink_active, task_msg); + espconn_tcp_reconnect(task_msg); break; case SIG_ESPCONN_CLOSE: /*remove the node from the client's active connection list*/ From cbcb1b1a9ff9203869eb5458dc2d4b09f3f21ebb Mon Sep 17 00:00:00 2001 From: dnc40085 Date: Fri, 18 May 2018 22:08:42 -0700 Subject: [PATCH 11/15] Fixed lack of nil return in file.read() when EOF is reached --- app/modules/file.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/modules/file.c b/app/modules/file.c index 670fab89..26a91d94 100644 --- a/app/modules/file.c +++ b/app/modules/file.c @@ -432,7 +432,8 @@ static int file_g_read( lua_State* L, int n, int16_t end_char, int fd ) luaM_free(L, heap_mem); heap_mem = NULL; } - return 0; + lua_pushnil(L); + return 1; } vfs_lseek(fd, -(n - i), VFS_SEEK_CUR); From dd02faef273a73f31fa172c266ab01b322e39f7e Mon Sep 17 00:00:00 2001 From: dnc40085 Date: Sun, 20 May 2018 00:38:33 -0700 Subject: [PATCH 12/15] Add function node.getcpufreq() (#2375) --- app/modules/node.c | 8 ++++++++ docs/en/modules/node.md | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/app/modules/node.c b/app/modules/node.c index a00bafd7..3df88b8c 100644 --- a/app/modules/node.c +++ b/app/modules/node.c @@ -386,6 +386,13 @@ static int node_setcpufreq(lua_State* L) return 1; } +// Lua: freq = node.getcpufreq() +static int node_getcpufreq(lua_State* L) +{ + lua_pushinteger(L, system_get_cpu_freq()); + return 1; +} + // Lua: code, reason [, exccause, epc1, epc2, epc3, excvaddr, depc ] = bootreason() static int node_bootreason (lua_State *L) { @@ -622,6 +629,7 @@ static const LUA_REG_TYPE node_map[] = { LSTRKEY( "CPU80MHZ" ), LNUMVAL( CPU80MHZ ) }, { LSTRKEY( "CPU160MHZ" ), LNUMVAL( CPU160MHZ ) }, { LSTRKEY( "setcpufreq" ), LFUNCVAL( node_setcpufreq) }, + { LSTRKEY( "getcpufreq" ), LFUNCVAL( node_getcpufreq) }, { LSTRKEY( "bootreason" ), LFUNCVAL( node_bootreason) }, { LSTRKEY( "restore" ), LFUNCVAL( node_restore) }, { LSTRKEY( "random" ), LFUNCVAL( node_random) }, diff --git a/docs/en/modules/node.md b/docs/en/modules/node.md index d8176ff9..823e7650 100644 --- a/docs/en/modules/node.md +++ b/docs/en/modules/node.md @@ -185,6 +185,27 @@ none #### Returns flash size in bytes (integer) +## node.getcpufreq() + +Get the current CPU Frequency. + +#### Syntax +`node.getcpufreq()` + +#### Parameters +none + +#### Returns +Current CPU frequency (number) + +#### Example +```lua +do + local cpuFreq = node.getcpufreq() + print("The current CPU frequency is " .. cpuFreq .. " MHz") +end +``` + ## node.heap() Returns the current available heap size in bytes. Note that due to fragmentation, actual allocations of this size may not be possible. From 07ced6396969d13e17047e86bf30135ed4c8a3ff Mon Sep 17 00:00:00 2001 From: dnc40085 Date: Sun, 20 May 2018 00:46:04 -0700 Subject: [PATCH 13/15] Dev wifi/wifi_eventmon malloc/free update (#2318) * updated wifi_eventmon to store events in LUA_REGISTRYINDEX * updated wifi_eventmon debug comments * Updated wifi.c to remove c_free() In wifi_ap_listclient(app/modules/wifi.c), c_free() was replaced with wifi_softap_free_station_info() * Removed unnecessary line of code from app/modules/wifi_eventmon.c --- app/modules/wifi.c | 7 +- app/modules/wifi_common.h | 22 +++--- app/modules/wifi_eventmon.c | 139 ++++++++++++++++++++---------------- 3 files changed, 88 insertions(+), 80 deletions(-) diff --git a/app/modules/wifi.c b/app/modules/wifi.c index 3eb68194..e0460c13 100644 --- a/app/modules/wifi.c +++ b/app/modules/wifi.c @@ -1787,7 +1787,7 @@ static int wifi_ap_listclient( lua_State* L ) { if (wifi_get_opmode() == STATION_MODE) { - return luaL_error( L, "Can't list client in STATION_MODE mode" ); + return luaL_error( L, "Can't list clients in STATION mode" ); } char temp[64]; @@ -1800,10 +1800,9 @@ static int wifi_ap_listclient( lua_State* L ) { c_sprintf(temp, MACSTR, MAC2STR(station->bssid)); wifi_add_sprintf_field(L, temp, IPSTR, IP2STR(&station->ip)); - next_station = STAILQ_NEXT(station, next); - c_free(station); - station = next_station; + station = STAILQ_NEXT(station, next); } + wifi_softap_free_station_info(); return 1; } diff --git a/app/modules/wifi_common.h b/app/modules/wifi_common.h index 122e4615..789633a3 100644 --- a/app/modules/wifi_common.h +++ b/app/modules/wifi_common.h @@ -19,21 +19,17 @@ void wifi_add_sprintf_field(lua_State* L, char* name, char* string, ...); void wifi_add_int_field(lua_State* L, char* name, lua_Integer integer); -static inline void register_lua_cb(lua_State* L,int* cb_ref) -{ +static inline void register_lua_cb(lua_State* L,int* cb_ref){ int ref=luaL_ref(L, LUA_REGISTRYINDEX); - if( *cb_ref != LUA_NOREF) - { - luaL_unref(L, LUA_REGISTRYINDEX, *cb_ref); + if( *cb_ref != LUA_NOREF){ + luaL_unref(L, LUA_REGISTRYINDEX, *cb_ref); } *cb_ref = ref; } -static inline void unregister_lua_cb(lua_State* L, int* cb_ref) -{ - if(*cb_ref != LUA_NOREF) - { - luaL_unref(L, LUA_REGISTRYINDEX, *cb_ref); +static inline void unregister_lua_cb(lua_State* L, int* cb_ref){ + if(*cb_ref != LUA_NOREF){ + luaL_unref(L, LUA_REGISTRYINDEX, *cb_ref); *cb_ref = LUA_NOREF; } } @@ -47,13 +43,13 @@ void wifi_change_default_host_name(void); #endif #if defined(EVENT_DEBUG) || defined(NODE_DEBUG) -#define EVENT_DBG(...) c_printf(__VA_ARGS__) +#define EVENT_DBG(fmt, ...) c_printf("\n EVENT_DBG(%s): "fmt"\n", __FUNCTION__, ##__VA_ARGS__) + #else #define EVENT_DBG(...) //c_printf(__VA_ARGS__) #endif -enum wifi_suspension_state -{ +enum wifi_suspension_state{ WIFI_AWAKE = 0, WIFI_SUSPENSION_PENDING = 1, WIFI_SUSPENDED = 2 diff --git a/app/modules/wifi_eventmon.c b/app/modules/wifi_eventmon.c index 66bd9827..06bce2a3 100644 --- a/app/modules/wifi_eventmon.c +++ b/app/modules/wifi_eventmon.c @@ -22,13 +22,6 @@ //variables for wifi event monitor static task_handle_t wifi_event_monitor_task_id; //variable to hold task id for task handler(process_event_queue) -typedef struct evt_queue{ - System_Event_t *evt; - struct evt_queue * next; -}evt_queue_t; //structure to hold pointers to event info and next item in queue - -static evt_queue_t *wifi_event_queue_head; //pointer to beginning of queue -static evt_queue_t *wifi_event_queue_tail; //pointer to end of queue static int wifi_event_cb_ref[EVENT_MAX+1] = { [0 ... EVENT_MAX] = LUA_NOREF}; //holds references to registered Lua callbacks #ifdef LUA_USE_MODULES_WIFI_MONITOR @@ -62,9 +55,11 @@ int wifi_event_monitor_register(lua_State* L) } } +static sint32_t event_queue_ref = LUA_NOREF; + static void wifi_event_monitor_handle_event_cb(System_Event_t *evt) { - EVENT_DBG("\n\twifi_event_monitor_handle_event_cb is called\n"); + EVENT_DBG("was called (Event:%d)", evt->event); #ifdef LUA_USE_MODULES_WIFI_MONITOR if (hook_fn && hook_fn(evt)) { @@ -79,38 +74,66 @@ static void wifi_event_monitor_handle_event_cb(System_Event_t *evt) evt->event == EVENT_SOFTAPMODE_STADISCONNECTED || evt->event == EVENT_SOFTAPMODE_PROBEREQRECVED || evt->event == EVENT_OPMODE_CHANGED))) { - evt_queue_t *temp = (evt_queue_t*)c_malloc(sizeof(evt_queue_t)); //allocate memory for new queue item - temp->evt = (System_Event_t*)c_malloc(sizeof(System_Event_t)); //allocate memory to hold event structure - if(!temp || !temp->evt) - { - luaL_error(lua_getstate(), "wifi.eventmon malloc: out of memory"); - return; + lua_State* L = lua_getstate(); + if(event_queue_ref == LUA_NOREF){ //if event queue has not been created, create it now + lua_newtable(L); + event_queue_ref = luaL_ref(L, LUA_REGISTRYINDEX); } - c_memcpy(temp->evt, evt, sizeof(System_Event_t)); //copy event data to new struct + lua_rawgeti(L, LUA_REGISTRYINDEX, event_queue_ref); - if(wifi_event_queue_head == NULL && wifi_event_queue_tail == NULL)// if queue is empty add item to queue - { - wifi_event_queue_head = wifi_event_queue_tail = temp; - EVENT_DBG("\n\tqueue empty, adding event and posting task\n"); + System_Event_t* evt_tmp = lua_newuserdata(L, sizeof(System_Event_t)); + c_memcpy(evt_tmp, evt, sizeof(System_Event_t)); //copy event data to new struct + sint32_t evt_ud_ref = luaL_ref(L, LUA_REGISTRYINDEX); + size_t queue_len = lua_objlen(L, -1); + + //add event to queue + lua_pushnumber(L, queue_len+1); + lua_pushnumber(L, evt_ud_ref); + lua_rawset(L, -3); + + if(queue_len == 0){ //if queue was empty, post task + EVENT_DBG("Posting task"); task_post_low(wifi_event_monitor_task_id, false); } - else //if queue is not empty append item to end of queue - { - wifi_event_queue_tail->next=temp; - wifi_event_queue_tail=temp; - EVENT_DBG("\n\tqueue not empty, appending queue\n"); - } - } -} + else{ + EVENT_DBG("Appending queue, items in queue: %d", lua_objlen(L, -1)); + } + lua_pop(L, 1); + } //else{} //there are no callbacks registered, so the event can't be processed +} static void wifi_event_monitor_process_event_queue(task_param_t param, uint8 priority) { lua_State* L = lua_getstate(); - evt_queue_t *temp = wifi_event_queue_head; //copy event_queue_head pointer to temporary pointer - System_Event_t *evt = temp->evt; //copy event data pointer to temporary pointer + lua_rawgeti(L, LUA_REGISTRYINDEX, event_queue_ref); + int index = 1; + lua_rawgeti(L, 1, index); + sint32 event_ref = lua_tonumber(L, -1); + lua_pop(L, 1); - EVENT_DBG("\t\tevent %u\n", evt->event); + //remove event reference from queue + int queue_length = lua_objlen(L, 1); + lua_rawgeti(L, 1, index); + for(; index0){ + task_post_low(wifi_event_monitor_task_id, false); //post task to process next item in queue + EVENT_DBG("%d events left in queue, posting task", queue_length); + } + lua_pop(L, 1); //pop event queue from stack if(wifi_event_cb_ref[evt->event] != LUA_NOREF) // check if user has registered a callback { @@ -130,107 +153,97 @@ static void wifi_event_monitor_process_event_queue(task_param_t param, uint8 pri switch (evt->event) { case EVENT_STAMODE_CONNECTED: - EVENT_DBG("\n\tSTAMODE_CONNECTED\n"); + EVENT_DBG("Event: %d (STAMODE_CONNECTED)", EVENT_STAMODE_CONNECTED); wifi_add_sprintf_field(L, "SSID", (char*)evt->event_info.connected.ssid); wifi_add_sprintf_field(L, "BSSID", MACSTR, MAC2STR(evt->event_info.connected.bssid)); wifi_add_int_field(L, "channel", evt->event_info.connected.channel); - EVENT_DBG("\tConnected to SSID %s, Channel %d\n", + EVENT_DBG("Connected to SSID %s, Channel %d", evt->event_info.connected.ssid, evt->event_info.connected.channel); break; case EVENT_STAMODE_DISCONNECTED: - EVENT_DBG("\n\tSTAMODE_DISCONNECTED\n"); + EVENT_DBG("Event: %d (STAMODE_DISCONNECTED)", EVENT_STAMODE_DISCONNECTED); wifi_add_sprintf_field(L, "SSID", (char*)evt->event_info.disconnected.ssid); wifi_add_int_field(L, "reason", evt->event_info.disconnected.reason); wifi_add_sprintf_field(L, "BSSID", MACSTR, MAC2STR(evt->event_info.disconnected.bssid)); - EVENT_DBG("\tDisconnect from SSID %s, reason %d\n", + EVENT_DBG("Disconnect from SSID %s, reason %d", evt->event_info.disconnected.ssid, evt->event_info.disconnected.reason); break; case EVENT_STAMODE_AUTHMODE_CHANGE: - EVENT_DBG("\n\tSTAMODE_AUTHMODE_CHANGE\n"); + EVENT_DBG("Event: %d (STAMODE_AUTHMODE_CHANGE)", EVENT_STAMODE_AUTHMODE_CHANGE); wifi_add_int_field(L, "old_auth_mode", evt->event_info.auth_change.old_mode); wifi_add_int_field(L, "new_auth_mode", evt->event_info.auth_change.new_mode); - EVENT_DBG("\tAuthmode: %u -> %u\n", + EVENT_DBG("Authmode: %u -> %u", evt->event_info.auth_change.old_mode, evt->event_info.auth_change.new_mode); break; case EVENT_STAMODE_GOT_IP: - EVENT_DBG("\n\tGOT_IP\n"); + EVENT_DBG("Event: %d (STAMODE_GOT_IP)", EVENT_STAMODE_GOT_IP); wifi_add_sprintf_field(L, "IP", IPSTR, IP2STR(&evt->event_info.got_ip.ip)); wifi_add_sprintf_field(L, "netmask", IPSTR, IP2STR(&evt->event_info.got_ip.mask)); wifi_add_sprintf_field(L, "gateway", IPSTR, IP2STR(&evt->event_info.got_ip.gw)); - EVENT_DBG("\tIP:" IPSTR ",Mask:" IPSTR ",GW:" IPSTR "\n", + EVENT_DBG("IP:" IPSTR ",Mask:" IPSTR ",GW:" IPSTR "", IP2STR(&evt->event_info.got_ip.ip), IP2STR(&evt->event_info.got_ip.mask), IP2STR(&evt->event_info.got_ip.gw)); break; case EVENT_STAMODE_DHCP_TIMEOUT: - EVENT_DBG("\n\tSTAMODE_DHCP_TIMEOUT\n"); + EVENT_DBG("Event: %d (STAMODE_DHCP_TIMEOUT)", EVENT_STAMODE_DHCP_TIMEOUT); break; case EVENT_SOFTAPMODE_STACONNECTED: - EVENT_DBG("\n\tSOFTAPMODE_STACONNECTED\n"); + EVENT_DBG("Event: %d (SOFTAPMODE_STACONNECTED)", EVENT_SOFTAPMODE_STACONNECTED); wifi_add_sprintf_field(L, "MAC", MACSTR, MAC2STR(evt->event_info.sta_connected.mac)); wifi_add_int_field(L, "AID", evt->event_info.sta_connected.aid); - EVENT_DBG("\tStation: " MACSTR "join, AID = %d\n", + EVENT_DBG("Station: " MACSTR "join, AID = %d", MAC2STR(evt->event_info.sta_connected.mac), evt->event_info.sta_connected.aid); break; case EVENT_SOFTAPMODE_STADISCONNECTED: - EVENT_DBG("\n\tSOFTAPMODE_STADISCONNECTED\n"); + EVENT_DBG("Event: %d (SOFTAPMODE_STADISCONNECTED)", EVENT_SOFTAPMODE_STADISCONNECTED); wifi_add_sprintf_field(L, "MAC", MACSTR, MAC2STR(evt->event_info.sta_disconnected.mac)); wifi_add_int_field(L, "AID", evt->event_info.sta_disconnected.aid); - EVENT_DBG("\tstation: " MACSTR "leave, AID = %d\n", + EVENT_DBG("station: " MACSTR "leave, AID = %d", MAC2STR(evt->event_info.sta_disconnected.mac), evt->event_info.sta_disconnected.aid); break; case EVENT_SOFTAPMODE_PROBEREQRECVED: - EVENT_DBG("\n\tSOFTAPMODE_PROBEREQRECVED\n"); + EVENT_DBG("Event: %d (SOFTAPMODE_PROBEREQRECVED)", EVENT_SOFTAPMODE_PROBEREQRECVED); wifi_add_sprintf_field(L, "MAC", MACSTR, MAC2STR(evt->event_info.ap_probereqrecved.mac)); wifi_add_int_field(L, "RSSI", evt->event_info.ap_probereqrecved.rssi); - EVENT_DBG("Station PROBEREQ: " MACSTR " RSSI = %d\n", + EVENT_DBG("Station PROBEREQ: " MACSTR " RSSI = %d", MAC2STR(evt->event_info.ap_probereqrecved.mac), evt->event_info.ap_probereqrecved.rssi); break; case EVENT_OPMODE_CHANGED: - EVENT_DBG("\n\tOPMODE_CHANGED\n"); + EVENT_DBG("Event: %d (OPMODE_CHANGED)", EVENT_OPMODE_CHANGED); wifi_add_int_field(L, "old_mode", evt->event_info.opmode_changed.old_opmode); wifi_add_int_field(L, "new_mode", evt->event_info.opmode_changed.new_opmode); - EVENT_DBG("\topmode: %u -> %u\n", + EVENT_DBG("opmode: %u -> %u", evt->event_info.opmode_changed.old_opmode, evt->event_info.opmode_changed.new_opmode); break; default://if event is not implemented, return event id - EVENT_DBG("\n\tswitch/case default\n"); + EVENT_DBG("Event: %d (switch/case default)", evt->event); wifi_add_sprintf_field(L, "info", "event %u not implemented", evt->event); break; } + + luaL_unref(L, LUA_REGISTRYINDEX, event_ref); //the userdata containing event info is no longer needed + event_ref = LUA_NOREF; + lua_call(L, 1, 0); //execute user's callback and pass Lua table - - if (wifi_event_queue_head == wifi_event_queue_tail) //if queue is empty.. - { - wifi_event_queue_head = wifi_event_queue_tail = NULL; //set queue pointers to NULL - EVENT_DBG("\n\tQueue empty\n"); - } - else //if queue is not empty... - { - wifi_event_queue_head = wifi_event_queue_head->next; //append item to end of queue - EVENT_DBG("\n\tmore in queue, posting task...\n"); - task_post_low(wifi_event_monitor_task_id, false); //post task to process next item in queue - } - - c_free(evt); //free memory used by event structure - c_free(temp); //free memory used by queue structure + return; } #ifdef WIFI_EVENT_MONITOR_DISCONNECT_REASON_LIST_ENABLE From 7a54ae06c7cb570777e0cfa1c1b6df7981693703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnim=20L=C3=A4uger?= Date: Tue, 22 May 2018 14:55:14 +0200 Subject: [PATCH 14/15] Set safe defaults for scan config (#2378) --- app/modules/wifi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/modules/wifi.c b/app/modules/wifi.c index e0460c13..1e701547 100644 --- a/app/modules/wifi.c +++ b/app/modules/wifi.c @@ -1158,8 +1158,9 @@ static int wifi_station_listap( lua_State* L ) { return luaL_error( L, "Can't list ap in SOFTAP mode" ); } - struct scan_config scan_cfg; - memset(&scan_cfg, 0, sizeof(scan_cfg)); + // set safe defaults for scan time, all other members are initialized with 0 + // source: https://github.com/espressif/ESP8266_NONOS_SDK/issues/103 + struct scan_config scan_cfg = {.scan_time = {.passive=120, .active = {.max=120, .min=60}}}; getap_output_format=0; From 2cc195d5c9781677123d98f5dd3d43c36321503b Mon Sep 17 00:00:00 2001 From: Gergo Huszty Date: Mon, 4 Jun 2018 13:16:20 +0200 Subject: [PATCH 15/15] webap_toggle_pin.lua HTML warnings and typos fixed (#2394) --- lua_examples/webap_toggle_pin.lua | 56 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/lua_examples/webap_toggle_pin.lua b/lua_examples/webap_toggle_pin.lua index 7d5a558d..60de70a6 100644 --- a/lua_examples/webap_toggle_pin.lua +++ b/lua_examples/webap_toggle_pin.lua @@ -1,31 +1,31 @@ wifi.setmode(wifi.SOFTAP) -wifi.ap.config({ssid="test",pwd="12345678"}) +wifi.ap.config({ ssid = "test", pwd = "12345678" }) gpio.mode(1, gpio.OUTPUT) -srv=net.createServer(net.TCP) -srv:listen(80,function(conn) - conn:on("receive", function(client,request) - local buf = "" - local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP") - if(method == nil)then - _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP") - end - local _GET = {} - if (vars ~= nil)then - for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do - _GET[k] = v - end - end - buf = buf.."

Hello, NodeMcu.

Turn PIN1
" - client:send(buf) - end) - conn:on("sent", function (c) c:close() end) +srv = net.createServer(net.TCP) +srv:listen(80, function(conn) + conn:on("receive", function(client, request) + local buf = "" + local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP") + if (method == nil) then + _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP") + end + local _GET = {} + if (vars ~= nil) then + for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do + _GET[k] = v + end + end + buf = buf .. "

Hello, this is NodeMCU.

Turn PIN1
" + client:send(buf) + end) + conn:on("sent", function(c) c:close() end) end)