1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

make eboot erase/read/write sector by sector

that makes possible having sketches with size up to the free size
This commit is contained in:
John Doe 2015-07-04 00:27:13 +03:00 committed by Ivan Grokhotkov
parent 7596ed0742
commit f3f500936d
7 changed files with 49 additions and 52 deletions

View File

@ -1,4 +1,5 @@
XTENSA_TOOLCHAIN ?= XTENSA_TOOLCHAIN ?= ../../tools/xtensa-lx106-elf/bin/
ESPTOOL ?= ../../tools/esptool
BIN_DIR := ./ BIN_DIR := ./
TARGET_DIR := ./ TARGET_DIR := ./

View File

@ -76,38 +76,31 @@ int copy_raw(const uint32_t src_addr,
const uint32_t dst_addr, const uint32_t dst_addr,
const uint32_t size) const uint32_t size)
{ {
ets_putc('\n');
ets_putc('c');
ets_putc('p');
ets_putc('\n');
// require regions to be aligned // require regions to be aligned
if (src_addr & 0xfff != 0 || if (src_addr & 0xfff != 0 ||
dst_addr & 0xfff != 0) { dst_addr & 0xfff != 0) {
return 1; return 1;
} }
if (SPIEraseAreaEx(dst_addr, size)) { const uint32_t buffer_size = FLASH_SECTOR_SIZE;
return 2;
}
const uint32_t buffer_size = 4096;
uint8_t buffer[buffer_size]; uint8_t buffer[buffer_size];
uint32_t left = ((size+buffer_size-1) & ~(buffer_size-1));
const uint32_t end = src_addr + size;
uint32_t saddr = src_addr; uint32_t saddr = src_addr;
uint32_t daddr = dst_addr; uint32_t daddr = dst_addr;
uint32_t left = size;
while (saddr < end) { while (left) {
uint32_t will_copy = (left < buffer_size) ? left : buffer_size; if (SPIEraseSector(daddr/buffer_size)) {
if (SPIRead(saddr, buffer, will_copy)) { return 2;
return 3; }
} if (SPIRead(saddr, buffer, buffer_size)) {
if (SPIWrite(daddr, buffer, will_copy)) { return 3;
return 4; }
} if (SPIWrite(daddr, buffer, buffer_size)) {
saddr += will_copy; return 4;
daddr += will_copy; }
left -= will_copy; saddr += buffer_size;
daddr += buffer_size;
left -= buffer_size;
} }
return 0; return 0;
@ -123,14 +116,16 @@ void main()
if (eboot_command_read(&cmd)) { if (eboot_command_read(&cmd)) {
cmd.action = ACTION_LOAD_APP; cmd.action = ACTION_LOAD_APP;
cmd.args[0] = 0; cmd.args[0] = 0;
ets_putc('e'); ets_putc('~');
} else { } else {
ets_putc('@'); ets_putc('@');
} }
eboot_command_clear(); eboot_command_clear();
if (cmd.action == ACTION_COPY_RAW) { 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]); res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2]);
ets_putc((char)0x30+res); ets_putc('\n');
if (res == 0) { if (res == 0) {
cmd.action = ACTION_LOAD_APP; cmd.action = ACTION_LOAD_APP;
cmd.args[0] = cmd.args[1]; cmd.args[0] = cmd.args[1];
@ -138,15 +133,14 @@ void main()
} }
if (cmd.action == ACTION_LOAD_APP) { 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) { if (res) {
ets_putc('\n'); SWRST;
ets_putc('#');
ets_putc('0' + res);
ets_putc('\n');
SWRST;
} }
while(true){} while(true){}

Binary file not shown.

View File

@ -4,7 +4,7 @@
* Redistribution and use is permitted according to the conditions of the * Redistribution and use is permitted according to the conditions of the
* 3-clause BSD license to be found in the LICENSE file. * 3-clause BSD license to be found in the LICENSE file.
*/ */
/*
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
@ -46,4 +46,4 @@ int SPIEraseAreaEx(const uint32_t start, const uint32_t size)
return 0; return 0;
} }
*/

View File

@ -12,7 +12,7 @@ int SPIEraseBlock(uint32_t block);
int SPIEraseSector(uint32_t sector); int SPIEraseSector(uint32_t sector);
int SPIRead(uint32_t addr, void *dest, size_t size); int SPIRead(uint32_t addr, void *dest, size_t size);
int SPIWrite(uint32_t addr, void *src, 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_SECTOR_SIZE 0x1000
#define FLASH_BLOCK_SIZE 0x10000 #define FLASH_BLOCK_SIZE 0x10000

View File

@ -27,30 +27,33 @@ bool UpdaterClass::begin(size_t size){
} }
if(_buffer) os_free(_buffer); if(_buffer) os_free(_buffer);
_bufferLen = 0; _bufferLen = 0;
_startAddress = 0; _startAddress = 0;
_currentAddress = 0; _currentAddress = 0;
_size = 0; _size = 0;
_error = 0; _error = 0;
uint32_t usedSize = ESP.getSketchSize(); //size of current sketch rounded to a sector
uint32_t freeSpaceEnd = (uint32_t)&_SPIFFS_start - 0x40200000 - (5 * FLASH_SECTOR_SIZE); 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 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 //make sure that the size of both sketches is less than the total space (updateEndAddress)
//this means that max sketch size is (1MB - 20KB) / 2 for flash 2MB and above if(updateStartAddress < currentSketchSize){
//and the current sketch should not be more than that either
if(freeSpaceStart < usedSize || roundedSize > (freeSpaceEnd/2)){
_error = UPDATE_ERROR_SPACE; _error = UPDATE_ERROR_SPACE;
#ifdef DEBUG_UPDATER #ifdef DEBUG_UPDATER
printError(DEBUG_UPDATER); printError(DEBUG_UPDATER);
#endif #endif
return false; return false;
} }
//erase the neede space
noInterrupts(); noInterrupts();
int rc = SPIEraseAreaEx(freeSpaceStart, roundedSize); int rc = SPIEraseAreaEx(updateStartAddress, roundedSize);
interrupts(); interrupts();
if (rc){ if (rc){
_error = UPDATE_ERROR_ERASE; _error = UPDATE_ERROR_ERASE;
@ -59,7 +62,9 @@ bool UpdaterClass::begin(size_t size){
#endif #endif
return false; return false;
} }
_startAddress = freeSpaceStart;
//initialize
_startAddress = updateStartAddress;
_currentAddress = _startAddress; _currentAddress = _startAddress;
_size = size; _size = size;
_buffer = (uint8_t*)os_malloc(FLASH_SECTOR_SIZE); _buffer = (uint8_t*)os_malloc(FLASH_SECTOR_SIZE);

View File

@ -1,11 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# #
# this script will push an OTA update to the ESP # this script will push an OTA update to the ESP
# # use it like: python espota.py <ESP_IP_address> <sketch.bin>
# use it like: python ota_server.py <ESP_IP_address> <sketch.bin>
#
# on the ESP side you need code like this: https://gist.github.com/igrr/43d5c52328e955bb6b09 to handle the update
#
from __future__ import print_function from __future__ import print_function
import socket import socket
@ -22,7 +18,7 @@ def serve(remoteAddr, remotePort, filename):
sock.bind(server_address) sock.bind(server_address)
sock.listen(1) sock.listen(1)
except: except:
print('Socket Failed', file=sys.stderr) print('Listen Failed', file=sys.stderr)
return 1 return 1
content_size = os.path.getsize(filename) content_size = os.path.getsize(filename)
@ -80,10 +76,11 @@ def serve(remoteAddr, remotePort, filename):
f.close() f.close()
sock.close() sock.close()
return 1 return 1
finally: finally:
connection.close() connection.close()
f.close() f.close()
sock.close() sock.close()
return 1 return 1