Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 063d608

Browse filesBrowse files
committed
Optimize Update class
- add roll back API to switch the running partition - do not write the partition magic until the end to prevent booting into partially written update
1 parent dcdf813 commit 063d608
Copy full SHA for 063d608

File tree

Expand file treeCollapse file tree

2 files changed

+70
-7
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+70
-7
lines changed

‎libraries/Update/src/Update.h

Copy file name to clipboardExpand all lines: libraries/Update/src/Update.h
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,15 @@ class UpdateClass {
137137
return written;
138138
}
139139

140+
/*
141+
check if there is a firmware on the other OTA partition that you can bootinto
142+
*/
143+
bool canRollBack();
144+
/*
145+
set the other OTA partition as bootable (reboot to enable)
146+
*/
147+
bool rollBack();
148+
140149
private:
141150
void _reset();
142151
void _abort(uint8_t err);

‎libraries/Update/src/Updater.cpp

Copy file name to clipboardExpand all lines: libraries/Update/src/Updater.cpp
+61-7Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,34 @@ static const char * _err2str(uint8_t _error){
3535
return ("UNKNOWN");
3636
}
3737

38+
static bool _partitionIsBootable(const esp_partition_t* partition){
39+
uint8_t buf[4];
40+
if(!partition){
41+
return false;
42+
}
43+
if(!ESP.flashRead(partition->address, (uint32_t*)buf, 4)) {
44+
return false;
45+
}
46+
47+
if(buf[0] != ESP_IMAGE_HEADER_MAGIC) {
48+
return false;
49+
}
50+
return true;
51+
}
52+
53+
static bool _enablePartition(const esp_partition_t* partition){
54+
uint8_t buf[4];
55+
if(!partition){
56+
return false;
57+
}
58+
if(!ESP.flashRead(partition->address, (uint32_t*)buf, 4)) {
59+
return false;
60+
}
61+
buf[0] = ESP_IMAGE_HEADER_MAGIC;
62+
63+
return ESP.flashWrite(partition->address, (uint32_t*)buf, 4);
64+
}
65+
3866
UpdateClass::UpdateClass()
3967
: _error(0)
4068
, _buffer(0)
@@ -56,6 +84,22 @@ void UpdateClass::_reset() {
5684
_command = U_FLASH;
5785
}
5886

87+
bool UpdateClass::canRollBack(){
88+
if(_buffer){ //Update is running
89+
return false;
90+
}
91+
const esp_partition_t* partition = esp_ota_get_next_update_partition(NULL);
92+
return _partitionIsBootable(partition);
93+
}
94+
95+
bool UpdateClass::rollBack(){
96+
if(_buffer){ //Update is running
97+
return false;
98+
}
99+
const esp_partition_t* partition = esp_ota_get_next_update_partition(NULL);
100+
return _partitionIsBootable(partition) && !esp_ota_set_boot_partition(partition);
101+
}
102+
59103
bool UpdateClass::begin(size_t size, int command) {
60104
if(_size > 0){
61105
log_w("already running");
@@ -121,6 +165,17 @@ void UpdateClass::abort(){
121165
}
122166

123167
bool UpdateClass::_writeBuffer(){
168+
//first bytes of new firmware
169+
if(!_progress && _command == U_FLASH){
170+
//check magic
171+
if(_buffer[0] != ESP_IMAGE_HEADER_MAGIC){
172+
_abort(UPDATE_ERROR_MAGIC_BYTE);
173+
return false;
174+
}
175+
//remove magic byte from the firmware now and write it upon success
176+
//this ensures that partially written firmware will not be bootable
177+
_buffer[0] = 0xFF;
178+
}
124179
if(!ESP.flashEraseSector((_partition->address + _progress)/SPI_FLASH_SEC_SIZE)){
125180
_abort(UPDATE_ERROR_ERASE);
126181
return false;
@@ -129,6 +184,10 @@ bool UpdateClass::_writeBuffer(){
129184
_abort(UPDATE_ERROR_WRITE);
130185
return false;
131186
}
187+
//restore magic or md5 will fail
188+
if(!_progress && _command == U_FLASH){
189+
_buffer[0] = ESP_IMAGE_HEADER_MAGIC;
190+
}
132191
_md5.add(_buffer, _bufferLen);
133192
_progress += _bufferLen;
134193
_bufferLen = 0;
@@ -150,24 +209,19 @@ bool UpdateClass::_verifyHeader(uint8_t data) {
150209

151210
bool UpdateClass::_verifyEnd() {
152211
if(_command == U_FLASH) {
153-
uint8_t buf[4];
154-
if(!ESP.flashRead(_partition->address, (uint32_t*)buf, 4)) {
212+
if(!_partitionIsBootable(_partition)) {
155213
_abort(UPDATE_ERROR_READ);
156214
return false;
157215
}
158216

159-
if(buf[0] != ESP_IMAGE_HEADER_MAGIC) {
160-
_abort(UPDATE_ERROR_MAGIC_BYTE);
161-
return false;
162-
}
163-
164217
if(esp_ota_set_boot_partition(_partition)){
165218
_abort(UPDATE_ERROR_ACTIVATE);
166219
return false;
167220
}
168221
_reset();
169222
return true;
170223
} else if(_command == U_SPIFFS) {
224+
_reset();
171225
return true;
172226
}
173227
return false;

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.