From f3f500936d831be890a62a959e21ceff4fd246ef Mon Sep 17 00:00:00 2001 From: John Doe Date: Sat, 4 Jul 2015 00:27:13 +0300 Subject: [PATCH] make eboot erase/read/write sector by sector that makes possible having sketches with size up to the free size --- bootloaders/eboot/Makefile | 3 +- bootloaders/eboot/eboot.c | 56 ++++++++++++++++-------------------- bootloaders/eboot/eboot.elf | Bin 11233 -> 10064 bytes bootloaders/eboot/flash.c | 4 +-- bootloaders/eboot/flash.h | 2 +- cores/esp8266/Updater.cpp | 25 +++++++++------- tools/espota.py | 11 +++---- 7 files changed, 49 insertions(+), 52 deletions(-) diff --git a/bootloaders/eboot/Makefile b/bootloaders/eboot/Makefile index 0872ee35f..a465a76f6 100644 --- a/bootloaders/eboot/Makefile +++ b/bootloaders/eboot/Makefile @@ -1,4 +1,5 @@ -XTENSA_TOOLCHAIN ?= +XTENSA_TOOLCHAIN ?= ../../tools/xtensa-lx106-elf/bin/ +ESPTOOL ?= ../../tools/esptool BIN_DIR := ./ TARGET_DIR := ./ diff --git a/bootloaders/eboot/eboot.c b/bootloaders/eboot/eboot.c index 0b74fcdf0..ffa1238b3 100644 --- a/bootloaders/eboot/eboot.c +++ b/bootloaders/eboot/eboot.c @@ -76,38 +76,31 @@ int copy_raw(const uint32_t src_addr, const uint32_t dst_addr, const uint32_t size) { - ets_putc('\n'); - ets_putc('c'); - ets_putc('p'); - ets_putc('\n'); // require regions to be aligned if (src_addr & 0xfff != 0 || dst_addr & 0xfff != 0) { return 1; } - if (SPIEraseAreaEx(dst_addr, size)) { - return 2; - } - - const uint32_t buffer_size = 4096; + const uint32_t buffer_size = FLASH_SECTOR_SIZE; uint8_t buffer[buffer_size]; - - const uint32_t end = src_addr + size; + uint32_t left = ((size+buffer_size-1) & ~(buffer_size-1)); uint32_t saddr = src_addr; uint32_t daddr = dst_addr; - uint32_t left = size; - while (saddr < end) { - uint32_t will_copy = (left < buffer_size) ? left : buffer_size; - if (SPIRead(saddr, buffer, will_copy)) { - return 3; - } - if (SPIWrite(daddr, buffer, will_copy)) { - return 4; - } - saddr += will_copy; - daddr += will_copy; - left -= will_copy; + + while (left) { + if (SPIEraseSector(daddr/buffer_size)) { + return 2; + } + if (SPIRead(saddr, buffer, buffer_size)) { + return 3; + } + if (SPIWrite(daddr, buffer, buffer_size)) { + return 4; + } + saddr += buffer_size; + daddr += buffer_size; + left -= buffer_size; } return 0; @@ -123,14 +116,16 @@ void main() if (eboot_command_read(&cmd)) { cmd.action = ACTION_LOAD_APP; cmd.args[0] = 0; - ets_putc('e'); + ets_putc('~'); } else { ets_putc('@'); } eboot_command_clear(); - + if (cmd.action == ACTION_COPY_RAW) { + ets_putc('c'); ets_putc('p'); ets_putc(':'); res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2]); + ets_putc((char)0x30+res); ets_putc('\n'); if (res == 0) { cmd.action = ACTION_LOAD_APP; cmd.args[0] = cmd.args[1]; @@ -138,15 +133,14 @@ void main() } if (cmd.action == ACTION_LOAD_APP) { - res = load_app_from_flash_raw(cmd.args[0]); + ets_putc('l'); ets_putc('d'); ets_putc('\n'); + res = load_app_from_flash_raw(cmd.args[0]); + //we will get to this only on load fail + ets_putc('e'); ets_putc(':'); ets_putc((char)0x30+res); ets_putc('\n'); } if (res) { - ets_putc('\n'); - ets_putc('#'); - ets_putc('0' + res); - ets_putc('\n'); - SWRST; + SWRST; } while(true){} diff --git a/bootloaders/eboot/eboot.elf b/bootloaders/eboot/eboot.elf index 97e25c14616a9f6e768711b46c6cafa6f62df21e..2a46a359c2621a4115be7aa19e2268a8659dbc78 100755 GIT binary patch delta 4192 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 J{k1>f{{z3*d8YsX literal 11233 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 #include #include @@ -46,4 +46,4 @@ int SPIEraseAreaEx(const uint32_t start, const uint32_t size) return 0; } - +*/ diff --git a/bootloaders/eboot/flash.h b/bootloaders/eboot/flash.h index ea8b65c1f..f762296cf 100644 --- a/bootloaders/eboot/flash.h +++ b/bootloaders/eboot/flash.h @@ -12,7 +12,7 @@ int SPIEraseBlock(uint32_t block); int SPIEraseSector(uint32_t sector); int SPIRead(uint32_t addr, void *dest, size_t size); int SPIWrite(uint32_t addr, void *src, size_t size); -int SPIEraseAreaEx(const uint32_t start, const uint32_t size); +//int SPIEraseAreaEx(const uint32_t start, const uint32_t size); #define FLASH_SECTOR_SIZE 0x1000 #define FLASH_BLOCK_SIZE 0x10000 diff --git a/cores/esp8266/Updater.cpp b/cores/esp8266/Updater.cpp index 194a21e9b..aba181fe7 100644 --- a/cores/esp8266/Updater.cpp +++ b/cores/esp8266/Updater.cpp @@ -27,30 +27,33 @@ bool UpdaterClass::begin(size_t size){ } if(_buffer) os_free(_buffer); - _bufferLen = 0; _startAddress = 0; _currentAddress = 0; _size = 0; _error = 0; - uint32_t usedSize = ESP.getSketchSize(); - uint32_t freeSpaceEnd = (uint32_t)&_SPIFFS_start - 0x40200000 - (5 * FLASH_SECTOR_SIZE); + //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 (5 sectors are for EEPROM and init data) + uint32_t updateEndAddress = (uint32_t)&_SPIFFS_start - 0x40200000 - (5 * FLASH_SECTOR_SIZE); + //size of the update rounded to a sector uint32_t roundedSize = (size + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1)); - uint32_t freeSpaceStart = freeSpaceEnd - roundedSize; + //address where we will start writing the update + uint32_t updateStartAddress = updateEndAddress - roundedSize; - //new sketch can not be more then half the size or more than the free space - //this means that max sketch size is (1MB - 20KB) / 2 for flash 2MB and above - //and the current sketch should not be more than that either - if(freeSpaceStart < usedSize || roundedSize > (freeSpaceEnd/2)){ + //make sure that the size of both sketches is less than the total space (updateEndAddress) + if(updateStartAddress < currentSketchSize){ _error = UPDATE_ERROR_SPACE; #ifdef DEBUG_UPDATER printError(DEBUG_UPDATER); #endif return false; } + + //erase the neede space noInterrupts(); - int rc = SPIEraseAreaEx(freeSpaceStart, roundedSize); + int rc = SPIEraseAreaEx(updateStartAddress, roundedSize); interrupts(); if (rc){ _error = UPDATE_ERROR_ERASE; @@ -59,7 +62,9 @@ bool UpdaterClass::begin(size_t size){ #endif return false; } - _startAddress = freeSpaceStart; + + //initialize + _startAddress = updateStartAddress; _currentAddress = _startAddress; _size = size; _buffer = (uint8_t*)os_malloc(FLASH_SECTOR_SIZE); diff --git a/tools/espota.py b/tools/espota.py index 52ef3e95a..dbd22eb45 100755 --- a/tools/espota.py +++ b/tools/espota.py @@ -1,11 +1,7 @@ #!/usr/bin/env python # # this script will push an OTA update to the ESP -# -# use it like: python ota_server.py -# -# on the ESP side you need code like this: https://gist.github.com/igrr/43d5c52328e955bb6b09 to handle the update -# +# use it like: python espota.py from __future__ import print_function import socket @@ -22,7 +18,7 @@ def serve(remoteAddr, remotePort, filename): sock.bind(server_address) sock.listen(1) except: - print('Socket Failed', file=sys.stderr) + print('Listen Failed', file=sys.stderr) return 1 content_size = os.path.getsize(filename) @@ -80,10 +76,11 @@ def serve(remoteAddr, remotePort, filename): f.close() sock.close() return 1 - + finally: connection.close() f.close() + sock.close() return 1