From 8e50cdb190c295c611d5757ba0b0ef83b72a1be3 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 29 Aug 2015 13:45:58 +0200 Subject: [PATCH 1/4] Updater.cpp: - use new AutoInterruptLock - add delay to give the RTOS some time to handle TCP WiFiClient.cpp - add stopAllexcepted to cancel all TCP excepted one ClientContext.h - add getLocalPort() ESP8266HTTPUpdate.cpp - close all not needed TCP and UDP osapi.h - missing commit from SDK --- cores/esp8266/Updater.cpp | 49 +++++++++++-------- cores/esp8266/Updater.h | 2 + cores/esp8266/debug.h | 5 +- libraries/ESP8266WiFi/src/WiFiClient.cpp | 24 +++++++++ libraries/ESP8266WiFi/src/WiFiClient.h | 1 + .../ESP8266WiFi/src/include/ClientContext.h | 6 +++ .../src/ESP8266httpUpdate.cpp | 11 ++++- .../ESP8266httpUpdate/src/ESP8266httpUpdate.h | 2 + tools/sdk/include/osapi.h | 2 +- 9 files changed, 78 insertions(+), 24 deletions(-) diff --git a/cores/esp8266/Updater.cpp b/cores/esp8266/Updater.cpp index cfce272a8..a91ce3938 100644 --- a/cores/esp8266/Updater.cpp +++ b/cores/esp8266/Updater.cpp @@ -1,6 +1,7 @@ #include "Updater.h" #include "Arduino.h" #include "eboot_command.h" +#include "interrupts.h" //#define DEBUG_UPDATER Serial @@ -111,28 +112,36 @@ bool UpdaterClass::end(bool evenIfRemaining){ return true; } -bool UpdaterClass::_writeBuffer(){ - noInterrupts(); - int rc = SPIEraseSector(_currentAddress/FLASH_SECTOR_SIZE); - interrupts(); - yield(); - if(!rc){ - noInterrupts(); - rc = SPIWrite(_currentAddress, _buffer, _bufferLen); - interrupts(); - } - interrupts(); - if (rc) { - _error = UPDATE_ERROR_WRITE; - _currentAddress = (_startAddress + _size); +bool UpdaterClass::_writeBuffer() { + int rc = 0; + delay(2); // give the rtos some time to handle TCP + { + AutoInterruptLock(15); + rc = SPIEraseSector(_currentAddress / FLASH_SECTOR_SIZE); + } + + delay(2); // give the rtos some time to handle TCP + + if(!rc) { + { + AutoInterruptLock(15); + rc = SPIWrite(_currentAddress, _buffer, _bufferLen); + } + } + + delay(2); // give the rtos some time to handle TCP + + if(rc) { + _error = UPDATE_ERROR_WRITE; + _currentAddress = (_startAddress + _size); #ifdef DEBUG_UPDATER - printError(DEBUG_UPDATER); + printError(DEBUG_UPDATER); #endif - return false; - } - _currentAddress += _bufferLen; - _bufferLen = 0; - return true; + return false; + } + _currentAddress += _bufferLen; + _bufferLen = 0; + return true; } size_t UpdaterClass::write(uint8_t *data, size_t len) { diff --git a/cores/esp8266/Updater.h b/cores/esp8266/Updater.h index eac84f466..aecf52163 100644 --- a/cores/esp8266/Updater.h +++ b/cores/esp8266/Updater.h @@ -11,6 +11,8 @@ #define UPDATE_ERROR_SIZE 4 #define UPDATE_ERROR_STREAM 5 +#define DEBUG_UPDATER Serial1 + class UpdaterClass { public: UpdaterClass(); diff --git a/cores/esp8266/debug.h b/cores/esp8266/debug.h index 7bdc247bd..fe389bb2d 100644 --- a/cores/esp8266/debug.h +++ b/cores/esp8266/debug.h @@ -2,8 +2,11 @@ #define ARD_DEBUG_H #include -// #define DEBUGV(...) ets_printf(__VA_ARGS__) +//#define DEBUGV(...) ets_printf(__VA_ARGS__) + +#ifndef DEBUGV #define DEBUGV(...) +#endif #ifdef __cplusplus void hexdump(uint8_t *mem, uint32_t len, uint8_t cols = 16); diff --git a/libraries/ESP8266WiFi/src/WiFiClient.cpp b/libraries/ESP8266WiFi/src/WiFiClient.cpp index 50e8d1123..a7e7f593d 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -284,3 +284,27 @@ void WiFiClient::stopAll() } } } + + +void WiFiClient::stopAllexcepted(WiFiClient * exC) { + for (WiFiClient* it = _s_first; it; it = it->_next) { + ClientContext* c = it->_client; + + if(c && exC->_client) { + if(exC->_client->getRemoteAddress() == c->getRemoteAddress()) { + if(exC->_client->getRemotePort() == c->getRemotePort()) { + if(exC->_client->getLocalPort() == c->getLocalPort()) { + // ignore this + c = NULL; + } + } + } + } + + if (c) { + c->abort(); + c->unref(); + it->_client = 0; + } + } +} diff --git a/libraries/ESP8266WiFi/src/WiFiClient.h b/libraries/ESP8266WiFi/src/WiFiClient.h index 161ca0be1..ed0a09f8b 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.h +++ b/libraries/ESP8266WiFi/src/WiFiClient.h @@ -91,6 +91,7 @@ public: using Print::write; static void stopAll(); + static void stopAllexcepted(WiFiClient * c); private: diff --git a/libraries/ESP8266WiFi/src/include/ClientContext.h b/libraries/ESP8266WiFi/src/include/ClientContext.h index 619356862..db8157e6b 100644 --- a/libraries/ESP8266WiFi/src/include/ClientContext.h +++ b/libraries/ESP8266WiFi/src/include/ClientContext.h @@ -125,6 +125,12 @@ class ClientContext { return _pcb->remote_port; } + uint16_t getLocalPort() { + if(!_pcb) return 0; + + return _pcb->local_port; + } + size_t getSize() const { if(!_rx_buf) return 0; diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp index 8c42afffc..3964415ba 100644 --- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp +++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp @@ -128,10 +128,17 @@ t_httpUpdate_return ESP8266HTTPUpdate::update(const char * host, uint16_t port, ret = HTTP_UPDATE_FAILD; DEBUG_HTTP_UPDATE("[httpUpdate] FreeSketchSpace to low (%d) needed: %d\n", ESP.getFreeSketchSpace(), len); } else { - if(ESP.updateSketch(tcp, len)) { - // may never reached! + + WiFiUDP::stopAll(); + WiFiClient::stopAllexcepted(&tcp); + + delay(100); + + if(ESP.updateSketch(tcp, len, false, false)) { ret = HTTP_UPDATE_OK; DEBUG_HTTP_UPDATE("[httpUpdate] Update ok\n"); + tcp.stop(); + ESP.restart(); } else { ret = HTTP_UPDATE_FAILD; DEBUG_HTTP_UPDATE("[httpUpdate] Update failed\n"); diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h index 911a6a565..a167f9fe4 100644 --- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h +++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h @@ -28,6 +28,8 @@ #include #include +#include +#include //#define DEBUG_HTTP_UPDATE(...) Serial1.printf( __VA_ARGS__ ) diff --git a/tools/sdk/include/osapi.h b/tools/sdk/include/osapi.h index 404efb855..1169e5406 100644 --- a/tools/sdk/include/osapi.h +++ b/tools/sdk/include/osapi.h @@ -46,7 +46,7 @@ #ifdef USE_OPTIMIZE_PRINTF #define os_printf(fmt, ...) do { \ - static const char flash_str[] ICACHE_RODATA_ATTR = fmt; \ + static const char flash_str[] ICACHE_RODATA_ATTR __attribute__((aligned(4))) = fmt; \ os_printf_plus(flash_str, ##__VA_ARGS__); \ } while(0) #else From a3bc0e924b3f3f179bc8d399afe4a0ad69922a3d Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 29 Aug 2015 13:56:03 +0200 Subject: [PATCH 2/4] revert some space auto formatting --- cores/esp8266/Updater.cpp | 44 +++++++++++++++++++-------------------- cores/esp8266/Updater.h | 2 +- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/cores/esp8266/Updater.cpp b/cores/esp8266/Updater.cpp index 95bf341bd..c4ec4b00b 100644 --- a/cores/esp8266/Updater.cpp +++ b/cores/esp8266/Updater.cpp @@ -12,13 +12,13 @@ extern "C" { extern "C" uint32_t _SPIFFS_start; -UpdaterClass::UpdaterClass() +UpdaterClass::UpdaterClass() : _error(0) , _buffer(0) , _bufferLen(0) , _size(0) , _startAddress(0) -, _currentAddress(0) +, _currentAddress(0) { } @@ -39,7 +39,7 @@ bool UpdaterClass::begin(size_t size){ #endif return false; } - + if(size == 0){ _error = UPDATE_ERROR_SIZE; #ifdef DEBUG_UPDATER @@ -47,10 +47,10 @@ bool UpdaterClass::begin(size_t size){ #endif return false; } - + _reset(); _error = 0; - + //size of current sketch rounded to a sector uint32_t currentSketchSize = (ESP.getSketchSize() + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1)); //address of the end of the space available for sketch and update @@ -59,7 +59,7 @@ bool UpdaterClass::begin(size_t size){ uint32_t roundedSize = (size + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1)); //address where we will start writing the update uint32_t updateStartAddress = updateEndAddress - roundedSize; - + //make sure that the size of both sketches is less than the total space (updateEndAddress) if(updateStartAddress < currentSketchSize){ _error = UPDATE_ERROR_SPACE; @@ -68,13 +68,13 @@ bool UpdaterClass::begin(size_t size){ #endif return false; } - + //initialize _startAddress = updateStartAddress; _currentAddress = _startAddress; _size = size; _buffer = new uint8_t[FLASH_SECTOR_SIZE]; - + return true; } @@ -85,30 +85,30 @@ bool UpdaterClass::end(bool evenIfRemaining){ #endif return false; } - + if(hasError() || (!isFinished() && !evenIfRemaining)){ #ifdef DEBUG_UPDATER DEBUG_UPDATER.printf("premature end: res:%u, pos:%u/%u\n", getError(), progress(), _size); #endif - + _reset(); return false; } - + if(evenIfRemaining){ if(_bufferLen > 0){ _writeBuffer(); } _size = progress(); } - + eboot_command ebcmd; ebcmd.action = ACTION_COPY_RAW; ebcmd.args[0] = _startAddress; ebcmd.args[1] = 0x00000; ebcmd.args[2] = _size; eboot_command_write(&ebcmd); - + #ifdef DEBUG_UPDATER DEBUG_UPDATER.printf("Staged: address:0x%08X, size:0x%08X\n", _startAddress, _size); #endif @@ -126,23 +126,23 @@ bool UpdaterClass::_writeBuffer(){ _error = UPDATE_ERROR_WRITE; _currentAddress = (_startAddress + _size); #ifdef DEBUG_UPDATER - printError(DEBUG_UPDATER); + printError(DEBUG_UPDATER); #endif - return false; - } - _currentAddress += _bufferLen; - _bufferLen = 0; - return true; + return false; + } + _currentAddress += _bufferLen; + _bufferLen = 0; + return true; } size_t UpdaterClass::write(uint8_t *data, size_t len) { size_t left = len; if(hasError() || !isRunning()) return 0; - + if(len > remaining()) len = remaining(); - + while((_bufferLen + left) > FLASH_SECTOR_SIZE) { size_t toBuff = FLASH_SECTOR_SIZE - _bufferLen; memcpy(_buffer + _bufferLen, data + (len - left), toBuff); @@ -170,7 +170,7 @@ size_t UpdaterClass::writeStream(Stream &data) { size_t toRead = 0; if(hasError() || !isRunning()) return 0; - + while(remaining()) { toRead = FLASH_SECTOR_SIZE - _bufferLen; toRead = data.readBytes(_buffer + _bufferLen, toRead); diff --git a/cores/esp8266/Updater.h b/cores/esp8266/Updater.h index aecf52163..c8b4e81f1 100644 --- a/cores/esp8266/Updater.h +++ b/cores/esp8266/Updater.h @@ -11,7 +11,7 @@ #define UPDATE_ERROR_SIZE 4 #define UPDATE_ERROR_STREAM 5 -#define DEBUG_UPDATER Serial1 +//#define DEBUG_UPDATER Serial1 class UpdaterClass { public: From 966bf45b350bb3a4f2bc5838eae83fcefd79ea0e Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 29 Aug 2015 15:33:41 +0200 Subject: [PATCH 3/4] rename stopAllexcepted to stopAllExcept and simplify the compare --- libraries/ESP8266WiFi/src/WiFiClient.cpp | 15 ++------------- libraries/ESP8266WiFi/src/WiFiClient.h | 2 +- .../ESP8266httpUpdate/src/ESP8266httpUpdate.cpp | 2 +- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/libraries/ESP8266WiFi/src/WiFiClient.cpp b/libraries/ESP8266WiFi/src/WiFiClient.cpp index dd97cdd02..354103a7e 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -302,22 +302,11 @@ void WiFiClient::stopAll() } -void WiFiClient::stopAllexcepted(WiFiClient * exC) { +void WiFiClient::stopAllExcept(WiFiClient * exC) { for (WiFiClient* it = _s_first; it; it = it->_next) { ClientContext* c = it->_client; - if(c && exC->_client) { - if(exC->_client->getRemoteAddress() == c->getRemoteAddress()) { - if(exC->_client->getRemotePort() == c->getRemotePort()) { - if(exC->_client->getLocalPort() == c->getLocalPort()) { - // ignore this - c = NULL; - } - } - } - } - - if (c) { + if (c && c != exC->_client) { c->abort(); c->unref(); it->_client = 0; diff --git a/libraries/ESP8266WiFi/src/WiFiClient.h b/libraries/ESP8266WiFi/src/WiFiClient.h index 542b05d31..8d8cab10f 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.h +++ b/libraries/ESP8266WiFi/src/WiFiClient.h @@ -93,7 +93,7 @@ public: using Print::write; static void stopAll(); - static void stopAllexcepted(WiFiClient * c); + static void stopAllExcept(WiFiClient * c); private: diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp index 3964415ba..e4e062ff0 100644 --- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp +++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp @@ -130,7 +130,7 @@ t_httpUpdate_return ESP8266HTTPUpdate::update(const char * host, uint16_t port, } else { WiFiUDP::stopAll(); - WiFiClient::stopAllexcepted(&tcp); + WiFiClient::stopAllExcept(&tcp); delay(100); From f96ea403ddb9e9083999f85295da2c074f2c0622 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 29 Aug 2015 15:39:12 +0200 Subject: [PATCH 4/4] port stopAllExcept to WiFiUDP to keep the interface the same --- libraries/ESP8266WiFi/src/WiFiUdp.cpp | 9 +++++++++ libraries/ESP8266WiFi/src/WiFiUdp.h | 1 + 2 files changed, 10 insertions(+) diff --git a/libraries/ESP8266WiFi/src/WiFiUdp.cpp b/libraries/ESP8266WiFi/src/WiFiUdp.cpp index 733ba3ff8..50734d1dd 100644 --- a/libraries/ESP8266WiFi/src/WiFiUdp.cpp +++ b/libraries/ESP8266WiFi/src/WiFiUdp.cpp @@ -290,3 +290,12 @@ void WiFiUDP::stopAll() it->stop(); } } + +void WiFiUDP::stopAllExcept(WiFiUDP * exC) { + for (WiFiUDP* it = _s_first; it; it = it->_next) { + if (it->_ctx != exC->_ctx) { + DEBUGV("%s %08x %08x\n", __func__, (uint32_t) it, (uint32_t) _s_first); + it->stop(); + } + } +} diff --git a/libraries/ESP8266WiFi/src/WiFiUdp.h b/libraries/ESP8266WiFi/src/WiFiUdp.h index 16aa0a3be..011de2e64 100644 --- a/libraries/ESP8266WiFi/src/WiFiUdp.h +++ b/libraries/ESP8266WiFi/src/WiFiUdp.h @@ -105,6 +105,7 @@ public: uint16_t localPort(); static void stopAll(); + static void stopAllExcept(WiFiUDP * exC); };