From 43b4946252e4668f0263a2db92212f6d959e3612 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 30 Sep 2018 15:08:00 +0200 Subject: [PATCH 1/4] timing improvements (separate mutexes for IRQ; Loraloop higher prio) --- platformio.ini | 2 +- src/button.cpp | 8 ++++---- src/cyclic.cpp | 8 ++++---- src/cyclic.h | 2 +- src/display.cpp | 8 ++++---- src/display.h | 2 +- src/globals.h | 2 +- src/hash.cpp | 4 ++-- src/hash.h | 7 +++++-- src/main.cpp | 22 ++++++++++++---------- src/ota.cpp | 7 +++++-- src/ota.h | 5 ++++- src/senddata.cpp | 8 ++++---- src/senddata.h | 2 +- src/statemachine.cpp | 1 + src/wifiscan.cpp | 3 ++- src/wifiscan.h | 2 +- 17 files changed, 53 insertions(+), 40 deletions(-) diff --git a/platformio.ini b/platformio.ini index 014772e3..936d5fa7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -26,7 +26,7 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng [common] ; for release_version use max. 10 chars total, use any decimal format like "a.b.c" -release_version = 1.5.8 +release_version = 1.5.9 ; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running! ; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose debug_level = 0 diff --git a/src/button.cpp b/src/button.cpp index 1cca9f4e..42f4180f 100644 --- a/src/button.cpp +++ b/src/button.cpp @@ -7,15 +7,15 @@ static const char TAG[] = "main"; void IRAM_ATTR ButtonIRQ() { - portENTER_CRITICAL(&timerMux); + portENTER_CRITICAL(&mutexButton); ButtonPressedIRQ++; - portEXIT_CRITICAL(&timerMux); + portEXIT_CRITICAL(&mutexButton); } void readButton() { - portENTER_CRITICAL(&timerMux); + portENTER_CRITICAL(&mutexButton); ButtonPressedIRQ = 0; - portEXIT_CRITICAL(&timerMux); + portEXIT_CRITICAL(&mutexButton); ESP_LOGI(TAG, "Button pressed"); payload.reset(); payload.addButton(0x01); diff --git a/src/cyclic.cpp b/src/cyclic.cpp index 756c1a42..0e49726a 100644 --- a/src/cyclic.cpp +++ b/src/cyclic.cpp @@ -12,9 +12,9 @@ static const char TAG[] = "main"; // do all housekeeping void doHousekeeping() { - portENTER_CRITICAL(&timerMux); + portENTER_CRITICAL(&mutexHomeCycle); HomeCycleIRQ = 0; - portEXIT_CRITICAL(&timerMux); + portEXIT_CRITICAL(&mutexHomeCycle); // update uptime counter uptime(); @@ -69,9 +69,9 @@ void doHousekeeping() { } // doHousekeeping() void IRAM_ATTR homeCycleIRQ() { - portENTER_CRITICAL(&timerMux); + portENTER_CRITICAL(&mutexHomeCycle); HomeCycleIRQ++; - portEXIT_CRITICAL(&timerMux); + portEXIT_CRITICAL(&mutexHomeCycle); } // uptime counter 64bit to prevent millis() rollover after 49 days diff --git a/src/cyclic.h b/src/cyclic.h index 0a169e4e..a006f137 100644 --- a/src/cyclic.h +++ b/src/cyclic.h @@ -2,7 +2,7 @@ #define _CYCLIC_H void doHousekeeping(void); -void homeCycleIRQ(void); +void IRAM_ATTR homeCycleIRQ(void); uint64_t uptime(void); void reset_counters(void); int redirect_log(const char *fmt, va_list args); diff --git a/src/display.cpp b/src/display.cpp index e7c168bb..9e2ffcb2 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -91,9 +91,9 @@ void init_display(const char *Productname, const char *Version) { void refreshtheDisplay() { - portENTER_CRITICAL(&timerMux); + portENTER_CRITICAL(&mutexDisplay); DisplayTimerIRQ = 0; - portEXIT_CRITICAL(&timerMux); + portEXIT_CRITICAL(&mutexDisplay); // set display on/off according to current device configuration if (DisplayState != cfg.screenon) { @@ -191,9 +191,9 @@ void refreshtheDisplay() { } // refreshDisplay() void IRAM_ATTR DisplayIRQ() { - portENTER_CRITICAL_ISR(&timerMux); + portENTER_CRITICAL_ISR(&mutexDisplay); DisplayTimerIRQ++; - portEXIT_CRITICAL_ISR(&timerMux); + portEXIT_CRITICAL_ISR(&mutexDisplay); } #endif // HAS_DISPLAY \ No newline at end of file diff --git a/src/display.h b/src/display.h index 39a3128a..84ff9b7a 100644 --- a/src/display.h +++ b/src/display.h @@ -9,6 +9,6 @@ extern HAS_DISPLAY u8x8; void init_display(const char *Productname, const char *Version); void refreshtheDisplay(void); void DisplayKey(const uint8_t *key, uint8_t len, bool lsb); -void DisplayIRQ(void); +void IRAM_ATTR DisplayIRQ(void); #endif \ No newline at end of file diff --git a/src/globals.h b/src/globals.h index a63859e1..a4fffd4d 100644 --- a/src/globals.h +++ b/src/globals.h @@ -46,7 +46,7 @@ extern uint16_t volatile macs_total, macs_wifi, macs_ble, batt_voltage; // display values extern std::set macs; // temp storage for MACs extern hw_timer_t *channelSwitch, *sendCycle; -extern portMUX_TYPE timerMux; +extern portMUX_TYPE mutexButton, mutexDisplay, mutexHomeCycle, mutexSendCycle; extern volatile uint8_t SendCycleTimerIRQ, HomeCycleIRQ, DisplayTimerIRQ, ChannelTimerIRQ, ButtonPressedIRQ; diff --git a/src/hash.cpp b/src/hash.cpp index 62e12656..e5d268f9 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -34,9 +34,9 @@ * SOFTWARE. */ -#include +#include "hash.h" -uint32_t rokkit(const char *data, int len) { +uint32_t IRAM_ATTR rokkit(const char *data, int len) { uint32_t hash, tmp; int rem; diff --git a/src/hash.h b/src/hash.h index 010fd6b8..b86e7b2e 100644 --- a/src/hash.h +++ b/src/hash.h @@ -1,6 +1,9 @@ #ifndef _HASH_H #define _HASH_H -uint32_t rokkit(const char *data, int len); +#include +#include -#endif +uint32_t IRAM_ATTR rokkit(const char *data, int len); + +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 15363f54..d150928a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,12 +26,12 @@ licenses. Refer to LICENSE.txt file in repository for more details. Uused tasks and timers: Task Core Prio Purpose -==================================================================== -IDLE 0 0 ESP32 arduino scheduler +==================================================================================== +IDLE 0 0 ESP32 arduino scheduler -> runs wifi sniffer task gpsloop 0 2 read data from GPS over serial or i2c IDLE 1 0 Arduino loop() -> used for LED switching -loraloop 1 1 runs the LMIC stack -statemachine 1 3 switches application process logic +loraloop 1 3 runs the LMIC stack +statemachine 1 1 switches application process logic wifiloop 0 4 rotates wifi channels ESP32 hardware timers @@ -77,9 +77,11 @@ QueueHandle_t SPISendQueue; TaskHandle_t GpsTask = NULL; #endif -portMUX_TYPE timerMux = - portMUX_INITIALIZER_UNLOCKED; // sync main loop and ISR when modifying IRQ - // handler shared variables +// sync main loop and ISR when modifying IRQ handler shared variables +portMUX_TYPE mutexButton = portMUX_INITIALIZER_UNLOCKED; +portMUX_TYPE mutexDisplay = portMUX_INITIALIZER_UNLOCKED; +portMUX_TYPE mutexHomeCycle = portMUX_INITIALIZER_UNLOCKED; +portMUX_TYPE mutexSendCycle = portMUX_INITIALIZER_UNLOCKED; std::set macs; // container holding unique MAC adress hashes @@ -312,7 +314,7 @@ void setup() { "loraloop", /* name of task */ 2560, /* stack size of task */ (void *)1, /* parameter of the task */ - 1, /* priority of the task */ + 3, /* priority of the task */ &LoraTask, /* task handle*/ 1); /* CPU core */ #endif @@ -350,7 +352,7 @@ void setup() { // start wifi channel rotation task xTaskCreatePinnedToCore(switchWifiChannel, /* task function */ "wifiloop", /* name of task */ - 1024, /* stack size of task */ + 1536, /* stack size of task */ NULL, /* parameter of the task */ 4, /* priority of the task */ &wifiSwitchTask, /* task handle*/ @@ -362,7 +364,7 @@ void setup() { "stateloop", /* name of task */ 2048, /* stack size of task */ (void *)1, /* parameter of the task */ - 3, /* priority of the task */ + 1, /* priority of the task */ &stateMachineTask, /* task handle */ 1); /* CPU core */ diff --git a/src/ota.cpp b/src/ota.cpp index bf826953..5e123dff 100644 --- a/src/ota.cpp +++ b/src/ota.cpp @@ -314,7 +314,8 @@ void do_ota_update() { client.stop(); } // do_ota_update -void display(const uint8_t row, const std::string status, const std::string msg) { +void display(const uint8_t row, const std::string status, + const std::string msg) { #ifdef HAS_DISPLAY u8x8.setCursor(14, row); u8x8.print((status.substr(0, 2)).c_str()); @@ -323,15 +324,17 @@ void display(const uint8_t row, const std::string status, const std::string msg) u8x8.setCursor(0, 7); u8x8.print(msg.substr(0, 16).c_str()); } +#endif } +#ifdef HAS_DISPLAY // callback function to show download progress while streaming data void show_progress(size_t current, size_t size) { char buf[17]; snprintf(buf, 17, "%-9lu (%3lu%%)", current, current * 100 / size); display(4, "**", buf); -#endif } +#endif // helper function to compare two versions. Returns 1 if v2 is // smaller, -1 if v1 is smaller, 0 if equal diff --git a/src/ota.h b/src/ota.h index 135591ea..560ee144 100644 --- a/src/ota.h +++ b/src/ota.h @@ -14,8 +14,11 @@ void do_ota_update(); void start_ota_update(); int version_compare(const String v1, const String v2); +void display(const uint8_t row, const std::string status, + const std::string msg); +#ifdef HAS_DISPLAY void show_progress(size_t current, size_t size); -void display(const uint8_t row, const std::string status, const std::string msg); +#endif #endif // USE_OTA diff --git a/src/senddata.cpp b/src/senddata.cpp index 2ca7973a..616df8fb 100644 --- a/src/senddata.cpp +++ b/src/senddata.cpp @@ -37,9 +37,9 @@ void SendData(uint8_t port) { // interrupt triggered function to prepare payload to send void sendPayload() { - portENTER_CRITICAL(&timerMux); + portENTER_CRITICAL(&mutexSendCycle); SendCycleTimerIRQ = 0; - portEXIT_CRITICAL(&timerMux); + portEXIT_CRITICAL(&mutexSendCycle); // append counter data to payload payload.reset(); @@ -68,9 +68,9 @@ void sendPayload() { // interrupt handler used for payload send cycle timer void IRAM_ATTR SendCycleIRQ() { - portENTER_CRITICAL(&timerMux); + portENTER_CRITICAL(&mutexSendCycle); SendCycleTimerIRQ++; - portEXIT_CRITICAL(&timerMux); + portEXIT_CRITICAL(&mutexSendCycle); } // interrupt triggered function to eat data from send queues and transmit it diff --git a/src/senddata.h b/src/senddata.h index df7b53f5..fc236b5f 100644 --- a/src/senddata.h +++ b/src/senddata.h @@ -3,7 +3,7 @@ void SendData(uint8_t port); void sendPayload(void); -void SendCycleIRQ(void); +void IRAM_ATTR SendCycleIRQ(void); void checkSendQueues(void); void flushQueues(); diff --git a/src/statemachine.cpp b/src/statemachine.cpp index c9c5ed07..76d02801 100644 --- a/src/statemachine.cpp +++ b/src/statemachine.cpp @@ -31,4 +31,5 @@ void stateMachine(void *pvParameters) { // give yield to CPU vTaskDelay(2 / portTICK_PERIOD_MS); } + vTaskDelete(NULL); // shoud never be reached } \ No newline at end of file diff --git a/src/wifiscan.cpp b/src/wifiscan.cpp index 21a5a95e..fca54e2a 100644 --- a/src/wifiscan.cpp +++ b/src/wifiscan.cpp @@ -28,6 +28,7 @@ IRAM_ATTR void wifi_sniffer_packet_handler(void *buff, void wifi_sniffer_init(void) { wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); cfg.nvs_enable = 0; // we don't need any wifi settings from NVRAM + cfg.wifi_task_core_id = 0; // we want wifi task running on core 0 wifi_promiscuous_filter_t filter = { .filter_mask = WIFI_PROMIS_FILTER_MASK_MGMT}; // we need only MGMT frames @@ -64,5 +65,5 @@ void switchWifiChannel(void * parameter) { esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE); ESP_LOGD(TAG, "Wifi set channel %d", channel); } - vTaskDelete(NULL); + vTaskDelete(NULL); // shoud never be reached } diff --git a/src/wifiscan.h b/src/wifiscan.h index 930178f2..ea507cd7 100644 --- a/src/wifiscan.h +++ b/src/wifiscan.h @@ -26,7 +26,7 @@ typedef struct { } wifi_ieee80211_packet_t; void wifi_sniffer_init(void); -void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); +void IRAM_ATTR wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); void ChannelSwitchIRQ(void); void switchWifiChannel(void * parameter); From afc464d3f7711a7d8c4aa9f94a8b75cc83a3c436 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 30 Sep 2018 15:54:17 +0200 Subject: [PATCH 2/4] improved wifi sniffing (use all frames not only mgmt) --- src/wifiscan.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/wifiscan.cpp b/src/wifiscan.cpp index fca54e2a..621c8494 100644 --- a/src/wifiscan.cpp +++ b/src/wifiscan.cpp @@ -27,10 +27,11 @@ IRAM_ATTR void wifi_sniffer_packet_handler(void *buff, void wifi_sniffer_init(void) { wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - cfg.nvs_enable = 0; // we don't need any wifi settings from NVRAM + cfg.nvs_enable = 0; // we don't need any wifi settings from NVRAM cfg.wifi_task_core_id = 0; // we want wifi task running on core 0 wifi_promiscuous_filter_t filter = { - .filter_mask = WIFI_PROMIS_FILTER_MASK_MGMT}; // we need only MGMT frames + // .filter_mask = WIFI_PROMIS_FILTER_MASK_MGMT}; // only MGMT frames + .filter_mask = WIFI_PROMIS_FILTER_MASK_ALL}; // we use all frames // esp_event_loop_init(NULL, NULL); // ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); @@ -56,9 +57,10 @@ void ChannelSwitchIRQ() { } // Wifi channel rotation task -void switchWifiChannel(void * parameter) { +void switchWifiChannel(void *parameter) { while (1) { - // task is remaining in block state waiting for channel switch timer interrupt event + // task is remaining in block state waiting for channel switch timer + // interrupt event xSemaphoreTake(xWifiChannelSwitchSemaphore, portMAX_DELAY); // rotates variable channel 1..WIFI_CHANNEL_MAX channel = (channel % WIFI_CHANNEL_MAX) + 1; From 4b80667f036222b5b40ca084248a00bbfcf75501 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 30 Sep 2018 16:20:19 +0200 Subject: [PATCH 3/4] edit HAL ttgo21old.h (removied display flip) --- src/hal/ttgov21old.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hal/ttgov21old.h b/src/hal/ttgov21old.h index c423ca67..ebb76e4d 100644 --- a/src/hal/ttgov21old.h +++ b/src/hal/ttgov21old.h @@ -9,7 +9,7 @@ #define HAS_LED NOT_A_PIN // no usable LED on board #define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C -#define DISPLAY_FLIP 1 // rotated display +//#define DISPLAY_FLIP 1 // rotated display #define HAS_BATTERY_PROBE ADC1_GPIO35_CHANNEL // uses GPIO7 #define BATT_FACTOR 2 // voltage divider 100k/100k on board From 240212afb9afe6c7ba1f29ea5a2d2fdeef71ecc7 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 30 Sep 2018 16:49:31 +0200 Subject: [PATCH 4/4] edit HAL file ttgov21old.h --- src/hal/ttgov21old.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hal/ttgov21old.h b/src/hal/ttgov21old.h index ebb76e4d..ce92a8a4 100644 --- a/src/hal/ttgov21old.h +++ b/src/hal/ttgov21old.h @@ -10,8 +10,8 @@ #define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C //#define DISPLAY_FLIP 1 // rotated display -#define HAS_BATTERY_PROBE ADC1_GPIO35_CHANNEL // uses GPIO7 -#define BATT_FACTOR 2 // voltage divider 100k/100k on board +//#define HAS_BATTERY_PROBE ADC1_GPIO35_CHANNEL // uses GPIO7 +//#define BATT_FACTOR 2 // voltage divider 100k/100k on board // re-define pin definitions of pins_arduino.h #define PIN_SPI_SS GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select Input