From 108a40acfd3af5fd703b049c9b28dc9dd1a7d131 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 16 May 2015 22:40:53 +0200 Subject: [PATCH 1/9] add support for list of AP connections - auto select ssid with best signal - for debugging enable DEBUG_WIFI_MULTI macro and call Serial.setDebugOutput(true); change ESP8266WiFiClass::status() return type to wl_status_t --- libraries/ESP8266WiFi/src/ESP8266WiFi.cpp | 2 +- libraries/ESP8266WiFi/src/ESP8266WiFi.h | 2 +- .../ESP8266WiFi/src/ESP8266WiFiMulti.cpp | 167 ++++++++++++++++++ libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h | 59 +++++++ .../ESP8266WiFi/src/include/wl_definitions.h | 16 +- 5 files changed, 236 insertions(+), 10 deletions(-) create mode 100644 libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp create mode 100644 libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp index caf63982c..9915d1bd6 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp @@ -336,7 +336,7 @@ uint8_t ESP8266WiFiClass::encryptionType(uint8_t i) return -1; } -uint8_t ESP8266WiFiClass::status() +wl_status_t ESP8266WiFiClass::status() { int status = wifi_station_get_connect_status(); diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFi.h b/libraries/ESP8266WiFi/src/ESP8266WiFi.h index c98f32b8b..be257d152 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFi.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFi.h @@ -195,7 +195,7 @@ public: * * return: one of the value defined in wl_status_t */ - uint8_t status(); + wl_status_t status(); /* * Resolve the given hostname to an IP address. diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp new file mode 100644 index 000000000..a284be754 --- /dev/null +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp @@ -0,0 +1,167 @@ +/** + * + * @file ESP8266WiFiMulti.cpp + * @date 16.05.2015 + * @author Markus Sattler + * + * Copyright (c) 2015 Markus Sattler. All rights reserved. + * This file is part of the esp8266 core for Arduino environment. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "ESP8266WiFi.h" +#include "ESP8266WiFiMulti.h" +#include + +ESP8266WiFiMulti::ESP8266WiFiMulti() { +} + +ESP8266WiFiMulti::~ESP8266WiFiMulti() { + APlistClean(); +} + +bool ESP8266WiFiMulti::addAP(const char* ssid, const char *passphrase) { + return APlistAdd(ssid, passphrase); +} + +wl_status_t ESP8266WiFiMulti::run(void) { + + wl_status_t status = WiFi.status(); + if(status == WL_DISCONNECTED || status == WL_NO_SSID_AVAIL || status == WL_IDLE_STATUS || status == WL_CONNECT_FAILED) { + + WifiAPlist_t bestNetwork { NULL, NULL }; + int bestNetworkDb = INT_MIN; + + // WiFi.scanNetworks will return the number of networks found + int8_t n = WiFi.scanNetworks(); + + DEBUG_WIFI_MULTI("[WIFI] scan done\n"); + delay(0); + + if(n <= 0) { + DEBUG_WIFI_MULTI("[WIFI] no networks found\n"); + } else { + DEBUG_WIFI_MULTI("[WIFI] %d networks found\n", n); + for(int8_t i = 0; i < n; ++i) { + const char * ssid_scan = WiFi.SSID(i); + int32_t rssi_scan = WiFi.RSSI(i); + uint8_t sec_scan = WiFi.encryptionType(i); + + bool known = false; + for(uint32_t x = 0; x < APlist.size(); x++) { + WifiAPlist_t entry = APlist[x]; + + if(strcmp(entry.ssid, ssid_scan) == 0) { // SSID match + known = true; + if(rssi_scan > bestNetworkDb) { // best network + if(sec_scan == ENC_TYPE_NONE || entry.passphrase) { // check for passphrase if not open wlan + bestNetworkDb = rssi_scan; + memcpy((void*) &bestNetwork, (void*) &entry, sizeof(bestNetwork)); + } + } + break; + } + } + if(known) { + DEBUG_WIFI_MULTI(" ---> "); + } else { + DEBUG_WIFI_MULTI(" "); + } + + DEBUG_WIFI_MULTI(" %d: %s (%d) %c\n", i, ssid_scan, rssi_scan, (sec_scan == ENC_TYPE_NONE) ? ' ' : '*'); + delay(0); + } + } + + DEBUG_WIFI_MULTI("\n\n"); + delay(0); + + if(bestNetwork.ssid) { + DEBUG_WIFI_MULTI("[WIFI] Connecting SSID: %s (%d)\n", bestNetwork.ssid, bestNetworkDb); + + WiFi.begin(bestNetwork.ssid, bestNetwork.passphrase); + status = WiFi.status(); + + // wait for connection or fail + while(status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED) { + delay(10); + status = WiFi.status(); + } + + switch(status) { + case WL_CONNECTED: + DEBUG_WIFI_MULTI("[WIFI] Connecting Done.\n"); + break; + case WL_NO_SSID_AVAIL: + DEBUG_WIFI_MULTI("[WIFI] Connecting Faild AP not found.\n"); + break; + case WL_CONNECT_FAILED: + DEBUG_WIFI_MULTI("[WIFI] Connecting Faild.\n"); + break; + default: + DEBUG_WIFI_MULTI("[WIFI] Connecting Faild (%d).\n", status); + break; + } + } else { + DEBUG_WIFI_MULTI("[WIFI] no matching wifi found!\n"); + } + } + return status; +} + +// ################################################################################## + +bool ESP8266WiFiMulti::APlistAdd(const char* ssid, const char *passphrase) { + + WifiAPlist_t newAP; + + newAP.ssid = (char*) malloc(strlen(ssid)); + + if(!newAP.ssid) { + return false; + } + + strcpy(newAP.ssid, ssid); + + if(passphrase && *passphrase != 0x00) { + newAP.passphrase = (char*) malloc(strlen(passphrase)); + } + + if(!newAP.passphrase) { + free(newAP.ssid); + return false; + } + + strcpy(newAP.passphrase, passphrase); + + APlist.push_back(newAP); + return true; +} + +void ESP8266WiFiMulti::APlistClean(void) { + for(uint32_t i = 0; i < APlist.size(); i++) { + WifiAPlist_t entry = APlist[i]; + if(entry.ssid) { + free(entry.ssid); + } + if(entry.passphrase) { + free(entry.passphrase); + } + } + APlist.clear(); +} + diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h new file mode 100644 index 000000000..285fca755 --- /dev/null +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h @@ -0,0 +1,59 @@ +/** + * + * @file ESP8266WiFiMulti.h + * @date 16.05.2015 + * @author Markus Sattler + * + * Copyright (c) 2015 Markus Sattler. All rights reserved. + * This file is part of the esp8266 core for Arduino environment. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +#ifndef WIFICLIENTMULTI_H_ +#define WIFICLIENTMULTI_H_ + +#include + +//#define DEBUG_WIFI_MULTI(...) os_printf( __VA_ARGS__ ) + +#ifndef DEBUG_WIFI_MULTI +#define DEBUG_WIFI_MULTI(...) +#endif + +typedef struct { + char * ssid; + char * passphrase; +} WifiAPlist_t; + +class ESP8266WiFiMulti { + public: + ESP8266WiFiMulti(); + ~ESP8266WiFiMulti(); + + bool addAP(const char* ssid, const char *passphrase = NULL); + + wl_status_t run(void); + + private: + std::vector APlist; + bool APlistAdd(const char* ssid, const char *passphrase = NULL); + void APlistClean(void); + +}; + +#endif /* WIFICLIENTMULTI_H_ */ diff --git a/libraries/ESP8266WiFi/src/include/wl_definitions.h b/libraries/ESP8266WiFi/src/include/wl_definitions.h index a32ba45b2..45bee6764 100644 --- a/libraries/ESP8266WiFi/src/include/wl_definitions.h +++ b/libraries/ESP8266WiFi/src/include/wl_definitions.h @@ -48,14 +48,14 @@ #define WL_MAX_ATTEMPT_CONNECTION 10 typedef enum { - WL_NO_SHIELD = 255, // for compatibility with WiFi Shield library - WL_IDLE_STATUS = 0, - WL_NO_SSID_AVAIL, - WL_SCAN_COMPLETED, - WL_CONNECTED, - WL_CONNECT_FAILED, - WL_CONNECTION_LOST, - WL_DISCONNECTED + WL_NO_SHIELD = 255, // for compatibility with WiFi Shield library + WL_IDLE_STATUS = 0, + WL_NO_SSID_AVAIL = 1, + WL_SCAN_COMPLETED = 2, + WL_CONNECTED = 3, + WL_CONNECT_FAILED = 4, + WL_CONNECTION_LOST = 5, + WL_DISCONNECTED = 6 } wl_status_t; /* Encryption modes */ From 508f0802d5232929ccf88e542ae03a33c2928ce1 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 16 May 2015 22:47:29 +0200 Subject: [PATCH 2/9] add examples/WiFiMulti/WiFiMulti.ino --- .../examples/WiFiMulti/WiFiMulti.ino | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino diff --git a/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino b/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino new file mode 100644 index 000000000..5a1057893 --- /dev/null +++ b/libraries/ESP8266WiFi/examples/WiFiMulti/WiFiMulti.ino @@ -0,0 +1,33 @@ +/* + * This sketch trys to Connect to the best AP based on a given list + * + */ + +#include +#include + +ESP8266WiFiMulti WiFiMulti = ESP8266WiFiMulti(); + +void setup() { + Serial.begin(115200); + delay(10); + + WiFiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1"); + WiFiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); + WiFiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); + + Serial.println("Connecting Wifi..."); + if(wifiMulti.run() == WL_CONNECTED) { + Serial.println(""); + Serial.println("WiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + } +} + +void loop() { + if(wifiMulti.run() != WL_CONNECTED) { + Serial.println("WiFi not connected!"); + delay(1000); + } +} \ No newline at end of file From 03da6393d57c005af786fd7a16224694fcb614e3 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 16 May 2015 22:56:15 +0200 Subject: [PATCH 3/9] improve includes add ssid and ip to debug out --- libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp | 8 ++++++-- libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp index a284be754..3b878020f 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp @@ -23,7 +23,6 @@ * */ -#include "ESP8266WiFi.h" #include "ESP8266WiFiMulti.h" #include @@ -76,6 +75,7 @@ wl_status_t ESP8266WiFiMulti::run(void) { break; } } + if(known) { DEBUG_WIFI_MULTI(" ---> "); } else { @@ -102,9 +102,13 @@ wl_status_t ESP8266WiFiMulti::run(void) { status = WiFi.status(); } + IPAddress ip; switch(status) { case WL_CONNECTED: - DEBUG_WIFI_MULTI("[WIFI] Connecting Done.\n"); + ip = WiFi.localIP(); + DEBUG_WIFI_MULTI("[WIFI] Connecting done.\n"); + DEBUG_WIFI_MULTI("[WIFI] SSID: %s\n", WiFi.SSID()); + DEBUG_WIFI_MULTI("[WIFI] IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); break; case WL_NO_SSID_AVAIL: DEBUG_WIFI_MULTI("[WIFI] Connecting Faild AP not found.\n"); diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h index 285fca755..a3926a406 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h @@ -27,6 +27,7 @@ #ifndef WIFICLIENTMULTI_H_ #define WIFICLIENTMULTI_H_ +#include "ESP8266WiFi.h" #include //#define DEBUG_WIFI_MULTI(...) os_printf( __VA_ARGS__ ) From e50fc0fef8dd46e58483a66889f821c1d5fa3e7e Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 16 May 2015 23:10:06 +0200 Subject: [PATCH 4/9] fix possible problems in EEPROM regarding interrupt handling and SPI flash blocking --- libraries/EEPROM/EEPROM.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libraries/EEPROM/EEPROM.cpp b/libraries/EEPROM/EEPROM.cpp index 74e7f3b0f..2e1eb4fca 100644 --- a/libraries/EEPROM/EEPROM.cpp +++ b/libraries/EEPROM/EEPROM.cpp @@ -49,7 +49,9 @@ void EEPROMClass::begin(size_t size) _data = new uint8_t[size]; _size = size; + noInterrupts(); spi_flash_read(CONFIG_ADDR, reinterpret_cast(_data), _size); + interrupts(); } void EEPROMClass::end() @@ -90,19 +92,21 @@ bool EEPROMClass::commit() if(!_dirty) return true; - ETS_UART_INTR_DISABLE(); + noInterrupts(); if(spi_flash_erase_sector(CONFIG_SECTOR) == SPI_FLASH_RESULT_OK) { if(spi_flash_write(CONFIG_ADDR, reinterpret_cast(_data), _size) == SPI_FLASH_RESULT_OK) { _dirty = false; ret = true; } } - ETS_UART_INTR_ENABLE(); + interrupts(); + return ret; } uint8_t * EEPROMClass::getDataPtr() { + _dirty = true; return &_data[0]; } From e0f9a4173eac7450758d02deac1d65857d2d2966 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sun, 17 May 2015 13:33:10 +0200 Subject: [PATCH 5/9] force all os_malloc calls to request a aligned size. - this fix Fatal exception (9) by unaligned class memory --- cores/esp8266/abi.cpp | 2 ++ cores/esp8266/libc_replacements.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/cores/esp8266/abi.cpp b/cores/esp8266/abi.cpp index add40bcb1..b863997a3 100644 --- a/cores/esp8266/abi.cpp +++ b/cores/esp8266/abi.cpp @@ -26,10 +26,12 @@ extern "C" { } void *operator new(size_t size) { + size = ((size + 3) & ~((size_t)0x3)); return os_malloc(size); } void *operator new[](size_t size) { + size = ((size + 3) & ~((size_t)0x3)); return os_malloc(size); } diff --git a/cores/esp8266/libc_replacements.c b/cores/esp8266/libc_replacements.c index 64efd94ab..519ea233a 100644 --- a/cores/esp8266/libc_replacements.c +++ b/cores/esp8266/libc_replacements.c @@ -38,6 +38,7 @@ #include "user_interface.h" void* malloc(size_t size) { + size = ((size + 3) & ~((size_t)0x3)); return os_malloc(size); } @@ -46,6 +47,7 @@ void free(void* ptr) { } void* realloc(void* ptr, size_t size) { + size = ((size + 3) & ~((size_t)0x3)); return os_realloc(ptr, size); } From 5b5deb5a7784702b0c71a5bea1cfa15bac9b7256 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sun, 17 May 2015 13:43:49 +0200 Subject: [PATCH 6/9] improve os_printf handling when buffer full. - wait for free buffer in hw fifo --- cores/esp8266/HardwareSerial.cpp | 46 +++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/cores/esp8266/HardwareSerial.cpp b/cores/esp8266/HardwareSerial.cpp index bdcd45716..ac56919ca 100644 --- a/cores/esp8266/HardwareSerial.cpp +++ b/cores/esp8266/HardwareSerial.cpp @@ -42,12 +42,12 @@ extern "C" { #define UART_TX_FIFO_SIZE 0x80 struct uart_ { - int uart_nr; + int uart_nr; int baud_rate; bool rxEnabled; bool txEnabled; - uint8_t rxPin; - uint8_t txPin; + uint8_t rxPin; + uint8_t txPin; }; static const int UART0 = 0; @@ -120,7 +120,7 @@ void ICACHE_RAM_ATTR uart_interrupt_handler(uart_t* uart) { // -------------- UART 0 -------------- if(Serial.isRxEnabled()) { while(U0IS & (1 << UIFF)) { - Serial._rx_complete_irq((char)(U0F & 0xff)); + Serial._rx_complete_irq((char) (U0F & 0xff)); U0IC = (1 << UIFF); } } @@ -135,7 +135,7 @@ void ICACHE_RAM_ATTR uart_interrupt_handler(uart_t* uart) { if(Serial1.isRxEnabled()) { while(U1IS & (1 << UIFF)) { - Serial1._rx_complete_irq((char)(U1F & 0xff)); + Serial1._rx_complete_irq((char) (U1F & 0xff)); U1IC = (1 << UIFF); } } @@ -357,19 +357,19 @@ void uart_swap(uart_t* uart) { switch(uart->uart_nr) { case UART0: if(uart->txPin == 1 && uart->rxPin == 3) { - pinMode(15, FUNCTION_4);//TX - pinMode(13, FUNCTION_4);//RX + pinMode(15, FUNCTION_4); //TX + pinMode(13, FUNCTION_4); //RX USWAP |= (1 << USWAP0); - pinMode(1, INPUT);//TX - pinMode(3, INPUT);//RX + pinMode(1, INPUT); //TX + pinMode(3, INPUT); //RX uart->rxPin = 13; uart->txPin = 15; } else { - pinMode(1, SPECIAL);//TX - pinMode(3, SPECIAL);//RX + pinMode(1, SPECIAL); //TX + pinMode(3, SPECIAL); //RX USWAP &= ~(1 << USWAP0); - pinMode(15, INPUT);//TX - pinMode(13, INPUT);//RX + pinMode(15, INPUT); //TX + pinMode(13, INPUT); //RX uart->rxPin = 3; uart->txPin = 1; } @@ -400,6 +400,14 @@ void uart0_write_char(char c) { return; } } + + // wait for the Hardware FIFO + while(true) { + if(((USS(0) >> USTXC) & 0xff) <= (UART_TX_FIFO_SIZE - 2)) { + break; + } + } + if(c == '\n') { USF(0) = '\r'; } @@ -416,6 +424,14 @@ void uart1_write_char(char c) { return; } } + + // wait for the Hardware FIFO + while(true) { + if(((USS(1) >> USTXC) & 0xff) <= (UART_TX_FIFO_SIZE - 2)) { + break; + } + } + if(c == '\n') { USF(1) = '\r'; } @@ -469,11 +485,11 @@ void HardwareSerial::begin(unsigned long baud, byte config) { } if(_uart->rxEnabled) { - if (!_rx_buffer) + if(!_rx_buffer) _rx_buffer = new cbuf(SERIAL_RX_BUFFER_SIZE); } if(_uart->txEnabled) { - if (!_tx_buffer) + if(!_tx_buffer) _tx_buffer = new cbuf(SERIAL_TX_BUFFER_SIZE); } _written = false; From d15225430e0ecd419ee56c564e93381d58e7c80b Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sun, 17 May 2015 13:53:31 +0200 Subject: [PATCH 7/9] Align the start of functions to the next power-of-two greater than 4, skipping up to 3 bytes. --- platform.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform.txt b/platform.txt index cd09aff98..9c197a832 100644 --- a/platform.txt +++ b/platform.txt @@ -15,7 +15,7 @@ compiler.sdk.path={compiler.tools.path}sdk/ compiler.cpreprocessor.flags=-D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-I{compiler.sdk.path}/include" compiler.c.cmd=xtensa-lx106-elf-gcc -compiler.c.flags=-c -Os -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -MMD -std=c99 +compiler.c.flags=-c -Os -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -falign-functions=4 -MMD -std=c99 compiler.S.cmd=xtensa-lx106-elf-gcc compiler.S.flags=-c -g -x assembler-with-cpp -MMD @@ -26,7 +26,7 @@ compiler.c.elf.cmd=xtensa-lx106-elf-gcc compiler.c.elf.libs=-lm -lgcc -lhal -lphy -lnet80211 -llwip -lwpa -lmain -lpp -lsmartconfig compiler.cpp.cmd=xtensa-lx106-elf-g++ -compiler.cpp.flags=-c -Os -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -std=c++11 -MMD +compiler.cpp.flags=-c -Os -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -std=c++11 -MMD compiler.as.cmd=xtensa-lx106-elf-as From a4adfab517a47eaa3e74f3ec28558eb5b2a40b9b Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sun, 17 May 2015 13:54:03 +0200 Subject: [PATCH 8/9] fix possible null ptr in EEPROM.cpp --- libraries/EEPROM/EEPROM.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/libraries/EEPROM/EEPROM.cpp b/libraries/EEPROM/EEPROM.cpp index 2e1eb4fca..d0699c92e 100644 --- a/libraries/EEPROM/EEPROM.cpp +++ b/libraries/EEPROM/EEPROM.cpp @@ -41,7 +41,7 @@ EEPROMClass::EEPROMClass() void EEPROMClass::begin(size_t size) { - if (size < 0) + if (size <= 0) return; if (size > SPI_FLASH_SEC_SIZE) size = SPI_FLASH_SEC_SIZE; @@ -60,8 +60,9 @@ void EEPROMClass::end() return; commit(); - - delete[] _data; + if(_data) { + delete[] _data; + } _data = 0; _size = 0; } @@ -71,6 +72,8 @@ uint8_t EEPROMClass::read(int address) { if (address < 0 || (size_t)address >= _size) return 0; + if(!_data) + return 0; return _data[address]; } @@ -79,6 +82,8 @@ void EEPROMClass::write(int address, uint8_t value) { if (address < 0 || (size_t)address >= _size) return; + if(!_data) + return; _data[address] = value; _dirty = true; @@ -91,6 +96,8 @@ bool EEPROMClass::commit() return false; if(!_dirty) return true; + if(!_data) + return false; noInterrupts(); if(spi_flash_erase_sector(CONFIG_SECTOR) == SPI_FLASH_RESULT_OK) { From 0be310f5b0b2042e0024e1ac500420c4efc08958 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sun, 17 May 2015 14:55:11 +0200 Subject: [PATCH 9/9] add Exception Causes (EXCCAUSE) docu --- doc/exception_causes.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 doc/exception_causes.md diff --git a/doc/exception_causes.md b/doc/exception_causes.md new file mode 100644 index 000000000..4b11bdb13 --- /dev/null +++ b/doc/exception_causes.md @@ -0,0 +1,38 @@ +Exception Causes (EXCCAUSE) +=========================================== + +| EXC-CAUSE Code | Cause Name | Cause Description | Required Option | EXC-VADDR Loaded | +|:--------------:|:---------------------------|:------------------------------------------------------------------------------------------------------------|:-------------------------|:----------------:| +| 0 | IllegalInstructionCause | Illegal instruction | Exception | No | +| 1 | SyscallCause | SYSCALL instruction | Exception | No | +| 2 | InstructionFetchErrorCause | Processor internal physical address or data error during instruction fetch | Exception | Yes | +| 3 | LoadStoreErrorCause | Processor internal physical address or data error during load or store | Exception | Yes | +| 4 | Level1InterruptCause | Level-1 interrupt as indicated by set level-1 bits in the INTERRUPT register | Interrupt | No | +| 5 | AllocaCause | MOVSP instruction, if caller’s registers are not in the register file | Windowed Register | No | +| 6 | IntegerDivideByZeroCause | QUOS, QUOU, REMS, or REMU divisor operand is zero | 32-bit Integer Divide | No | +| 7 | Reserved for Tensilica | | | | +| 8 | PrivilegedCause | Attempt to execute a privileged operation when CRING ? 0 | MMU | No | +| 9 | LoadStoreAlignmentCause | Load or store to an unaligned address | Unaligned Exception | Yes | +| 10..11 | Reserved for Tensilica | | | | +| 12 | InstrPIFDataErrorCause | PIF data error during instruction fetch | Processor Interface | Yes | +| 13 | LoadStorePIFDataErrorCause | Synchronous PIF data error during LoadStore access | Processor Interface | Yes | +| 14 | InstrPIFAddrErrorCause | PIF address error during instruction fetch | Processor Interface | Yes | +| 15 | LoadStorePIFAddrErrorCause | Synchronous PIF address error during LoadStore access | Processor Interface | Yes | +| 16 | InstTLBMissCause | Error during Instruction TLB refill | MMU | Yes | +| 17 | InstTLBMultiHitCause | Multiple instruction TLB entries matched | MMU | Yes | +| 18 | InstFetchPrivilegeCause | An instruction fetch referenced a virtual address at a ring level less than CRING | MMU | Yes | +| 19 | Reserved for Tensilica | | | | +| 20 | InstFetchProhibitedCause | An instruction fetch referenced a page mapped with an attribute that does not permit instruction fetch | Region Protection or MMU | Yes | +| 21..23 | Reserved for Tensilica | | | | +| 24 | LoadStoreTLBMissCause | Error during TLB refill for a load or store | MMU | Yes | +| 25 | LoadStoreTLBMultiHitCause | Multiple TLB entries matched for a load or store | MMU | Yes | +| 26 | LoadStorePrivilegeCause | A load or store referenced a virtual address at a ring level less than CRING | MMU | Yes | +| 27 | Reserved for Tensilica | | | | +| 28 | LoadProhibitedCause | A load referenced a page mapped with an attribute that does not permit loads | Region Protection or MMU | Yes | +| 29 | StoreProhibitedCause | A store referenced a page mapped with an attribute that does not permit stores | Region Protection or MMU | Yes | +| 30..31 | Reserved for Tensilica | | | | +| 32..39 | CoprocessornDisabled | Coprocessor n instruction when cpn disabled. n varies 0..7 as the cause varies 32..39 | Coprocessor | No | +| 40..63 | Reserved | | | | + + +Infos from Xtensa Instruction Set Architecture (ISA) Reference Manual \ No newline at end of file