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:
parent
7596ed0742
commit
f3f500936d
@ -1,4 +1,5 @@
|
|||||||
XTENSA_TOOLCHAIN ?=
|
XTENSA_TOOLCHAIN ?= ../../tools/xtensa-lx106-elf/bin/
|
||||||
|
ESPTOOL ?= ../../tools/esptool
|
||||||
|
|
||||||
BIN_DIR := ./
|
BIN_DIR := ./
|
||||||
TARGET_DIR := ./
|
TARGET_DIR := ./
|
||||||
|
@ -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.
@ -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;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user