@@ -26,15 +26,30 @@ extern MyMessage _msgTmp;
26
26
// local variables
27
27
#ifdef MY_OTA_USE_I2C_EEPROM
28
28
I2CEeprom _flash (MY_OTA_I2C_ADDR);
29
- #else
29
+ #elif !defined(MCUBOOT_PRESENT)
30
30
SPIFlash _flash (MY_OTA_FLASH_SS, MY_OTA_FLASH_JDECID);
31
31
#endif
32
32
33
+ // Map flash functions
34
+ #ifndef MCUBOOT_PRESENT
35
+ #define _flash_initialize () _flash.initialize()
36
+ #define _flash_readByte (addr ) _flash.readByte(addr)
37
+ #define _flash_writeBytes ( dstaddr, data, size ) _flash.writeBytes( dstaddr, data, size)
38
+ #define _flash_blockErase32K (num ) _flash.blockErase32K(num)
39
+ #define _flash_busy () _flash.busy()
40
+ #else
41
+ #define _flash_initialize () true
42
+ #define _flash_readByte (addr ) (*((uint8_t *)(addr)))
43
+ #define _flash_blockErase32K (num ) Flash.erase((uint32_t *)FLASH_AREA_IMAGE_1_OFFSET_0, FLASH_AREA_IMAGE_1_SIZE_0)
44
+ #define _flash_busy () false
45
+ #endif
46
+
33
47
LOCAL nodeFirmwareConfig_t _nodeFirmwareConfig;
34
48
LOCAL bool _firmwareUpdateOngoing = false ;
35
49
LOCAL uint32_t _firmwareLastRequest;
36
50
LOCAL uint16_t _firmwareBlock;
37
51
LOCAL uint8_t _firmwareRetry;
52
+ LOCAL bool _firmwareResponse (uint16_t block, uint8_t *data);
38
53
39
54
LOCAL void readFirmwareSettings (void )
40
55
{
@@ -83,15 +98,15 @@ LOCAL bool firmwareOTAUpdateProcess(void)
83
98
// copy new FW config
84
99
(void )memcpy (&_nodeFirmwareConfig, firmwareConfigResponse, sizeof (nodeFirmwareConfig_t));
85
100
// Init flash
86
- if (!_flash. initialize ()) {
101
+ if (!_flash_initialize ()) {
87
102
setIndication (INDICATION_ERR_FW_FLASH_INIT);
88
103
OTA_DEBUG (PSTR (" !OTA:FWP:FLASH INIT FAIL\n " )); // failed to initialise flash
89
104
_firmwareUpdateOngoing = false ;
90
105
} else {
91
106
// erase lower 32K -> max flash size for ATMEGA328
92
- _flash. blockErase32K (0 );
107
+ _flash_blockErase32K (0 );
93
108
// wait until flash erased
94
- while ( _flash. busy () ) {}
109
+ while ( _flash_busy () ) {}
95
110
_firmwareBlock = _nodeFirmwareConfig.blocks ;
96
111
_firmwareUpdateOngoing = true ;
97
112
// reset flags
@@ -102,68 +117,46 @@ LOCAL bool firmwareOTAUpdateProcess(void)
102
117
}
103
118
OTA_DEBUG (PSTR (" OTA:FWP:UPDATE SKIPPED\n " )); // FW update skipped, no newer version available
104
119
} else if (_msg.type == ST_FIRMWARE_RESPONSE) {
105
- if (_firmwareUpdateOngoing) {
106
- // extract FW block
107
- replyFirmwareBlock_t *firmwareResponse = (replyFirmwareBlock_t *)_msg.data ;
108
-
109
- OTA_DEBUG (PSTR (" OTA:FWP:RECV B=%04" PRIX16 " \n " ), firmwareResponse->block ); // received FW block
110
- if (firmwareResponse->block != _firmwareBlock - 1 ) {
111
- OTA_DEBUG (PSTR (" !OTA:FWP:WRONG FWB\n " )); // received FW block
112
- // wrong firmware block received
113
- setIndication (INDICATION_FW_UPDATE_RX_ERR);
114
- // no further processing required
115
- return true ;
116
- }
117
- setIndication (INDICATION_FW_UPDATE_RX);
118
- // Save block to flash
119
- _flash.writeBytes ( ((_firmwareBlock - 1 ) * FIRMWARE_BLOCK_SIZE) + FIRMWARE_START_OFFSET,
120
- firmwareResponse->data , FIRMWARE_BLOCK_SIZE);
121
- // wait until flash written
122
- while (_flash.busy ()) {}
123
- #ifdef OTA_EXTRA_FLASH_DEBUG
124
- {
125
- char prbuf[8 ];
126
- uint32_t addr = ((_firmwareBlock - 1 ) * FIRMWARE_BLOCK_SIZE) + FIRMWARE_START_OFFSET;
127
- OTA_DEBUG (PSTR (" OTA:FWP:FL DUMP " ));
128
- sprintf_P (prbuf,PSTR (" %04" PRIX16 " :" ), (uint16_t )addr);
129
- MY_SERIALDEVICE.print (prbuf);
130
- for (uint8_t i=0 ; i<FIRMWARE_BLOCK_SIZE; i++) {
131
- uint8_t data = _flash.readByte (addr + i);
132
- sprintf_P (prbuf,PSTR (" %02" PRIX8 " " ), (uint8_t )data);
133
- MY_SERIALDEVICE.print (prbuf);
134
- }
135
- OTA_DEBUG (PSTR (" \n " ));
136
- }
120
+ // extract FW block
121
+ replyFirmwareBlock_t *firmwareResponse = (replyFirmwareBlock_t *)_msg.data ;
122
+ // Proceed firmware data
123
+ return _firmwareResponse (firmwareResponse->block , firmwareResponse->data );
124
+ #ifdef FIRMWARE_PROTOCOL_31
125
+ } else if (_msg.type == ST_FIRMWARE_RESPONSE_RLE) {
126
+ // RLE encoded block
127
+ // extract FW block
128
+ replyFirmwareBlockRLE_t *firmwareResponse = (replyFirmwareBlockRLE_t *)_msg.data ;
129
+ uint8_t data[FIRMWARE_BLOCK_SIZE];
130
+ for (uint8_t i=0 ; i<FIRMWARE_BLOCK_SIZE; i++) {
131
+ data[i]=firmwareResponse->data ;
132
+ }
133
+ while ((_firmwareBlock) && (firmwareResponse->number_of_blocks )) {
134
+ _firmwareResponse (firmwareResponse->block , data);
135
+ firmwareResponse->number_of_blocks --;
136
+ firmwareResponse->block --;
137
+ }
138
+ return true ;
137
139
#endif
138
- _firmwareBlock--;
139
- if (!_firmwareBlock) {
140
- // We're done! Do a checksum and reboot.
141
- OTA_DEBUG (PSTR (" OTA:FWP:FW END\n " )); // received FW block
142
- _firmwareUpdateOngoing = false ;
143
- if (transportIsValidFirmware ()) {
144
- OTA_DEBUG (PSTR (" OTA:FWP:CRC OK\n " )); // FW checksum ok
145
- // Write the new firmware config to eeprom
146
- hwWriteConfigBlock ((void *)&_nodeFirmwareConfig, (void *)EEPROM_FIRMWARE_TYPE_ADDRESS,
147
- sizeof (nodeFirmwareConfig_t));
148
- // All seems ok, write size and signature to flash (DualOptiboot will pick this up and flash it)
149
- const uint16_t firmwareSize = FIRMWARE_BLOCK_SIZE * _nodeFirmwareConfig.blocks ;
150
- const uint8_t OTAbuffer[FIRMWARE_START_OFFSET] = {' F' ,' L' ,' X' ,' I' ,' M' ,' G' ,' :' , (uint8_t )(firmwareSize >> 8 ), (uint8_t )(firmwareSize & 0xff ),' :' };
151
- _flash.writeBytes (0 , OTAbuffer, FIRMWARE_START_OFFSET);
152
- // wait until flash ready
153
- while (_flash.busy ()) {}
154
- hwReboot ();
155
- } else {
156
- setIndication (INDICATION_ERR_FW_CHECKSUM);
157
- OTA_DEBUG (PSTR (" !OTA:FWP:CRC FAIL\n " ));
140
+ } else {
141
+ #ifdef MCUBOOT_PRESENT
142
+ if (_msg.type == ST_FIRMWARE_CONFIRM) {
143
+ if (*(uint16_t *)MCUBOOT_IMAGE_0_MAGIC_ADDR == ((uint16_t )MCUBOOT_IMAGE_MAGIC)) {
144
+ if (*(uint8_t *)(MCUBOOT_IMAGE_0_IMG_OK_ADDR)!=MCUBOOT_IMAGE_0_IMG_OK_BYTE) {
145
+ // Calculate data word to write
146
+ uint32_t *img_ok_base_addr = (uint32_t *)(MCUBOOT_IMAGE_0_IMG_OK_ADDR & ~3 ); // align word wise
147
+ uint32_t img_ok_data = *img_ok_base_addr;
148
+ // Set copy of MCUBOOT_IMAGE_0_IMG_OK_ADDR to MCUBOOT_IMAGE_0_IMG_OK_BYTE (0x01)
149
+ uint8_t * img_ok_array = (uint8_t *)(&img_ok_data);
150
+ img_ok_array[MCUBOOT_IMAGE_0_IMG_OK_ADDR % 4 ] = MCUBOOT_IMAGE_0_IMG_OK_BYTE;
151
+ // Write word back
152
+ Flash.write (img_ok_base_addr, img_ok_data);
158
153
}
154
+ OTA_DEBUG (PSTR (" !OTA:FWP:IMAGE CONFIRMED\n " ));
155
+ } else {
156
+ OTA_DEBUG (PSTR (" !OTA:FWP:INVALID MCUBOOT MAGIC\n " ));
159
157
}
160
- // reset flags
161
- _firmwareRetry = MY_OTA_RETRY + 1 ;
162
- _firmwareLastRequest = 0 ;
163
- } else {
164
- OTA_DEBUG (PSTR (" !OTA:FWP:NO UPDATE\n " ));
165
158
}
166
- return true ;
159
+ # endif
167
160
}
168
161
return false ;
169
162
}
@@ -178,6 +171,18 @@ LOCAL void presentBootloaderInformation(void)
178
171
(void )memcpy (requestFirmwareConfig, &_nodeFirmwareConfig, sizeof (nodeFirmwareConfig_t));
179
172
// add bootloader information
180
173
requestFirmwareConfig->BLVersion = MY_OTA_BOOTLOADER_VERSION;
174
+ #ifdef FIRMWARE_PROTOCOL_31
175
+ requestFirmwareConfig->blockSize = FIRMWARE_BLOCK_SIZE;
176
+ #ifndef MCUBOOT_PRESENT
177
+ requestFirmwareConfig->img_commited = 0x2 ;
178
+ requestFirmwareConfig->img_revision = 0x00 ;
179
+ requestFirmwareConfig->img_build_num = 0x00 ;
180
+ #else
181
+ requestFirmwareConfig->img_commited = *((uint8_t *)(MCUBOOT_IMAGE_0_IMG_OK_ADDR));
182
+ requestFirmwareConfig->img_revision = *((uint16_t *)(MCUBOOT_IMAGE_0_IMG_REVISION_ADDR));
183
+ requestFirmwareConfig->img_build_num = *((uint16_t *)(MCUBOOT_IMAGE_0_IMG_BUILD_NUM_ADDR));
184
+ #endif
185
+ #endif
181
186
_firmwareUpdateOngoing = false ;
182
187
(void )_sendRoute (build (_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_STREAM,
183
188
ST_FIRMWARE_CONFIG_REQUEST, false ));
@@ -192,8 +197,8 @@ LOCAL bool transportIsValidFirmware(void)
192
197
{
193
198
// init crc
194
199
uint16_t crc = ~0 ;
195
- for (uint16_t i = 0 ; i < _nodeFirmwareConfig.blocks * FIRMWARE_BLOCK_SIZE; ++i) {
196
- crc ^= _flash. readByte (i + FIRMWARE_START_OFFSET);
200
+ for (uint32_t i = 0 ; i < _nodeFirmwareConfig.blocks * FIRMWARE_BLOCK_SIZE; ++i) {
201
+ crc ^= _flash_readByte (i + FIRMWARE_START_OFFSET);
197
202
for (int8_t j = 0 ; j < 8 ; ++j) {
198
203
if (crc & 1 ) {
199
204
crc = (crc >> 1 ) ^ 0xA001 ;
@@ -207,3 +212,76 @@ LOCAL bool transportIsValidFirmware(void)
207
212
_nodeFirmwareConfig.crc );
208
213
return crc == _nodeFirmwareConfig.crc ;
209
214
}
215
+
216
+ LOCAL bool _firmwareResponse (uint16_t block, uint8_t *data)
217
+ {
218
+ if (_firmwareUpdateOngoing) {
219
+ OTA_DEBUG (PSTR (" OTA:FWP:RECV B=%04" PRIX16 " \n " ), block); // received FW block
220
+ if (block != _firmwareBlock - 1 ) {
221
+ OTA_DEBUG (PSTR (" !OTA:FWP:WRONG FWB\n " )); // received FW block
222
+ // wrong firmware block received
223
+ setIndication (INDICATION_FW_UPDATE_RX_ERR);
224
+ // no further processing required
225
+ return true ;
226
+ }
227
+ setIndication (INDICATION_FW_UPDATE_RX);
228
+ // Save block to flash
229
+ #ifdef MCUBOOT_PRESENT
230
+ uint32_t addr = ((size_t )(((_firmwareBlock - 1 ) * FIRMWARE_BLOCK_SIZE)) + (size_t )(
231
+ FIRMWARE_START_OFFSET));
232
+ if (addr<FLASH_AREA_IMAGE_SCRATCH_OFFSET_0) {
233
+ Flash.write_block ( (uint32_t *)addr, (uint32_t *)data, FIRMWARE_BLOCK_SIZE>>2 );
234
+ }
235
+ #else
236
+ _flash_writeBytes ( ((_firmwareBlock - 1 ) * FIRMWARE_BLOCK_SIZE) + FIRMWARE_START_OFFSET,
237
+ data, FIRMWARE_BLOCK_SIZE);
238
+ #endif
239
+ // wait until flash written
240
+ while (_flash_busy ()) {}
241
+ #ifdef OTA_EXTRA_FLASH_DEBUG
242
+ {
243
+ char prbuf[8 ];
244
+ uint32_t addr = ((_firmwareBlock - 1 ) * FIRMWARE_BLOCK_SIZE) + FIRMWARE_START_OFFSET;
245
+ OTA_DEBUG (PSTR (" OTA:FWP:FL DUMP " ));
246
+ sprintf_P (prbuf,PSTR (" %04" PRIX16 " :" ), (uint16_t )addr);
247
+ MY_SERIALDEVICE.print (prbuf);
248
+ for (uint8_t i=0 ; i<FIRMWARE_BLOCK_SIZE; i++) {
249
+ uint8_t data = _flash_readByte (addr + i);
250
+ sprintf_P (prbuf,PSTR (" %02" PRIX8 " " ), (uint8_t )data);
251
+ MY_SERIALDEVICE.print (prbuf);
252
+ }
253
+ OTA_DEBUG (PSTR (" \n " ));
254
+ }
255
+ #endif
256
+ _firmwareBlock--;
257
+ if (!_firmwareBlock) {
258
+ // We're done! Do a checksum and reboot.
259
+ OTA_DEBUG (PSTR (" OTA:FWP:FW END\n " )); // received FW block
260
+ _firmwareUpdateOngoing = false ;
261
+ if (transportIsValidFirmware ()) {
262
+ OTA_DEBUG (PSTR (" OTA:FWP:CRC OK\n " )); // FW checksum ok
263
+ // Write the new firmware config to eeprom
264
+ hwWriteConfigBlock ((void *)&_nodeFirmwareConfig, (void *)EEPROM_FIRMWARE_TYPE_ADDRESS,
265
+ sizeof (nodeFirmwareConfig_t));
266
+ #ifndef MCUBOOT_PRESENT
267
+ // All seems ok, write size and signature to flash (DualOptiboot will pick this up and flash it)
268
+ const uint16_t firmwareSize = FIRMWARE_BLOCK_SIZE * _nodeFirmwareConfig.blocks ;
269
+ const uint8_t OTAbuffer[FIRMWARE_START_OFFSET] = {' F' ,' L' ,' X' ,' I' ,' M' ,' G' ,' :' , (uint8_t )(firmwareSize >> 8 ), (uint8_t )(firmwareSize & 0xff ),' :' };
270
+ _flash_writeBytes (0 , OTAbuffer, FIRMWARE_START_OFFSET);
271
+ // wait until flash ready
272
+ while (_flash_busy ()) {}
273
+ #endif
274
+ hwReboot ();
275
+ } else {
276
+ setIndication (INDICATION_ERR_FW_CHECKSUM);
277
+ OTA_DEBUG (PSTR (" !OTA:FWP:CRC FAIL\n " ));
278
+ }
279
+ }
280
+ // reset flags
281
+ _firmwareRetry = MY_OTA_RETRY + 1 ;
282
+ _firmwareLastRequest = 0 ;
283
+ } else {
284
+ OTA_DEBUG (PSTR (" !OTA:FWP:NO UPDATE\n " ));
285
+ }
286
+ return true ;
287
+ }
0 commit comments