@@ -23,6 +23,7 @@ extern "C" {
2323}
2424
2525extern " C" uint32_t _FS_start;
26+ extern " C" uint32_t _FS_end;
2627
2728UpdaterClass::UpdaterClass ()
2829: _async(false )
@@ -105,15 +106,17 @@ bool UpdaterClass::begin(size_t size, int command, int ledPin, uint8_t ledOn) {
105106
106107 wifi_set_sleep_type (NONE_SLEEP_T);
107108
109+ // address where we will start writing the update
108110 uintptr_t updateStartAddress = 0 ;
111+ // size of current sketch rounded to a sector
112+ size_t currentSketchSize = (ESP.getSketchSize () + FLASH_SECTOR_SIZE - 1 ) & (~(FLASH_SECTOR_SIZE - 1 ));
113+ // size of the update rounded to a sector
114+ size_t roundedSize = (size + FLASH_SECTOR_SIZE - 1 ) & (~(FLASH_SECTOR_SIZE - 1 ));
115+
109116 if (command == U_FLASH) {
110- // size of current sketch rounded to a sector
111- size_t currentSketchSize = (ESP.getSketchSize () + FLASH_SECTOR_SIZE - 1 ) & (~(FLASH_SECTOR_SIZE - 1 ));
112117 // address of the end of the space available for sketch and update
113118 uintptr_t updateEndAddress = (uintptr_t )&_FS_start - 0x40200000 ;
114- // size of the update rounded to a sector
115- size_t roundedSize = (size + FLASH_SECTOR_SIZE - 1 ) & (~(FLASH_SECTOR_SIZE - 1 ));
116- // address where we will start writing the update
119+
117120 updateStartAddress = (updateEndAddress > roundedSize)? (updateEndAddress - roundedSize) : 0 ;
118121
119122#ifdef DEBUG_UPDATER
@@ -129,7 +132,24 @@ bool UpdaterClass::begin(size_t size, int command, int ledPin, uint8_t ledOn) {
129132 }
130133 }
131134 else if (command == U_FS) {
132- updateStartAddress = (uintptr_t )&_FS_start - 0x40200000 ;
135+ if ((uintptr_t )&_FS_start + roundedSize > (uintptr_t )&_FS_end) {
136+ _setError (UPDATE_ERROR_SPACE);
137+ return false ;
138+ }
139+
140+ #ifdef ATOMIC_FS_UPDATE
141+ // address of the end of the space available for update
142+ uintptr_t updateEndAddress = (uintptr_t )&_FS_start - 0x40200000 ;
143+
144+ updateStartAddress = (updateEndAddress > roundedSize)? (updateEndAddress - roundedSize) : 0 ;
145+
146+ if (updateStartAddress < currentSketchSize) {
147+ _setError (UPDATE_ERROR_SPACE);
148+ return false ;
149+ }
150+ #else
151+ updateStartAddress = (uintptr_t )&_FS_start - 0x40200000 ;
152+ #endif
133153 }
134154 else {
135155 // unknown command
@@ -272,8 +292,19 @@ bool UpdaterClass::end(bool evenIfRemaining){
272292
273293#ifdef DEBUG_UPDATER
274294 DEBUG_UPDATER.printf_P (PSTR (" Staged: address:0x%08X, size:0x%08zX\n " ), _startAddress, _size);
295+ #endif
275296 }
276297 else if (_command == U_FS) {
298+ #ifdef ATOMIC_FS_UPDATE
299+ eboot_command ebcmd;
300+ ebcmd.action = ACTION_COPY_RAW;
301+ ebcmd.args [0 ] = _startAddress;
302+ ebcmd.args [1 ] = (uintptr_t )&_FS_start - 0x40200000 ;
303+ ebcmd.args [2 ] = _size;
304+ eboot_command_write (&ebcmd);
305+ #endif
306+
307+ #ifdef DEBUG_UPDATER
277308 DEBUG_UPDATER.printf_P (PSTR (" Filesystem: address:0x%08X, size:0x%08zX\n " ), _startAddress, _size);
278309#endif
279310 }
@@ -387,7 +418,7 @@ bool UpdaterClass::_verifyHeader(uint8_t data) {
387418 }
388419 return true ;
389420 } else if (_command == U_FS) {
390- // no check of SPIFFS possible with first byte.
421+ // no check of FS possible with first byte.
391422 return true ;
392423 }
393424 return false ;
@@ -421,7 +452,7 @@ bool UpdaterClass::_verifyEnd() {
421452
422453 return true ;
423454 } else if (_command == U_FS) {
424- // SPIFFS is already over written checks make no sense any more.
455+ // FS is already over written checks make no sense any more.
425456 return true ;
426457 }
427458 return false ;
0 commit comments