@@ -156,19 +156,14 @@ static inline bool in_app_space (uint32_t addr)
156
156
return USER_FLASH_START <= addr && addr < USER_FLASH_END ;
157
157
}
158
158
159
- static inline bool in_uicr_space (uint32_t addr )
160
- {
161
- return addr == 0x10001000 ;
162
- }
163
-
164
159
static inline bool in_bootloader_space (uint32_t addr )
165
160
{
166
- return USER_FLASH_END <= addr && addr < CFG_UF2_FLASH_SIZE ;
161
+ return CFG_UF2_BOOTLOADER_ADDR_START <= addr && addr < CFG_UF2_BOOTLOADER_ADDR_END ;
167
162
}
168
163
169
- static inline bool in_softdevice_space (uint32_t addr )
164
+ static inline bool in_uicr_space (uint32_t addr )
170
165
{
171
- return addr < USER_FLASH_START ;
166
+ return addr == 0x10001000 ;
172
167
}
173
168
174
169
//--------------------------------------------------------------------+
@@ -183,7 +178,7 @@ static uint32_t current_flash_size(void)
183
178
uint32_t flash_sz = 0 ;
184
179
185
180
// return 1 block of 256 bytes
186
- if ( !bootloader_app_is_valid (DFU_BANK_0_REGION_START ) )
181
+ if ( !bootloader_app_is_valid () )
187
182
{
188
183
flash_sz = 256 ;
189
184
}else
@@ -193,6 +188,9 @@ static uint32_t current_flash_size(void)
193
188
194
189
flash_sz = boot_setting -> bank_0_size ;
195
190
191
+ // Include SoftDevice (excluding MBR) for current.uf2
192
+ if ( is_sd_existed () ) flash_sz += (SD_SIZE_GET (MBR_SIZE ) - MBR_SIZE );
193
+
196
194
// Copy size must be multiple of 256 bytes
197
195
// else we will got an issue copying current.uf2
198
196
if (flash_sz & 0xff )
@@ -344,30 +342,63 @@ int write_block (uint32_t block_no, uint8_t *data, WriteState *state)
344
342
345
343
if ( !is_uf2_block (bl ) ) return -1 ;
346
344
347
- PRINTF ("Addr = 0x%08lX, payloadSize = %ld, Family = 0x%08lX\n" , bl -> targetAddr , bl -> payloadSize , bl -> familyID );
348
- #if 0
349
- uint32_t wr_addr ;
350
-
351
345
switch ( bl -> familyID )
352
346
{
353
347
case CFG_UF2_FAMILY_ID :
354
- // Upgrade application
355
- // Directly write over application -- > Target address is the written address
356
- if ( !in_app_space (bl -> targetAddr ) ) return -1 ;
348
+ /* Upgrading Application
349
+ *
350
+ * Although SoftDevice is considered as part of application and the flashing is the same with/without it.
351
+ * There are still 3 cases with slight differences in finishing procedure:
352
+ * 1. Application with SoftDevice:
353
+ * - starting address 0x0000
354
+ * - since MBR is included in SD Hex file (then uf2 file), we must skip it
355
+ * 2. Application only
356
+ * a. For running with existing SoftDevice on the flash:
357
+ * - starting address is right after SD e.g 0x26000
358
+ * b. For running without SoftDevice e.g using other stack such as nimble or zephyr.
359
+ * - starting address is right after MBR 0x1000
360
+ *
361
+ * ------------- -------------
362
+ * | | | |
363
+ * | Bootloader | | Bootloader |
364
+ * BOOTLOADER_ADDR_START--|-------------| |-------------|
365
+ * | | | |
366
+ * | | | |
367
+ * | Application | ---> | New |
368
+ * | | | Application |
369
+ * | | | |
370
+ * | | | |
371
+ * USER_FLASH_START--|-------------| |-------------|
372
+ * | MBR | | MBR |
373
+ * ------------- -------------
374
+ */
375
+ if ( in_app_space (bl -> targetAddr ) )
376
+ {
377
+ PRINTF ("Write addr = 0x%08lX, block = %ld (%ld of %ld)\r\n" , bl -> targetAddr , bl -> blockNo , state -> numWritten , bl -> numBlocks );
357
378
358
- wr_addr = bl -> targetAddr ;
379
+ // writing to SD Info struct is used as SD detector
380
+ if (bl -> targetAddr == (SOFTDEVICE_INFO_STRUCT_ADDRESS & 0xff ) ) state -> has_sd = true;
381
+
382
+ flash_nrf5x_write (bl -> targetAddr , bl -> data , bl -> payloadSize , true);
383
+ }else if ( bl -> targetAddr < USER_FLASH_START )
384
+ {
385
+ // do nothing if writing to MBR
386
+ // keep going as successful write
387
+ }else
388
+ {
389
+ return -1 ;
390
+ }
359
391
break ;
360
392
361
393
case CFG_UF2_BOOTLOADER_ID :
362
- /* Upgrading SoftDevice + Bootloader combo
394
+ /* Upgrading Bootloader (with/without SoftDevice)
363
395
*
364
396
* To prevent corruption/disconnection while transferring we don't directly write over
365
- * SoftDevice and Bootloader. Instead SD + Bootloader is written to Application region.
366
- * Once everything is received and verified.They are written to their respective address
397
+ * Bootloader. Instead Bootloader is written to Application region.
398
+ * Once everything is received and verified. It is written to its respective address
367
399
*
368
- * Note: to simplify the upgrade process, we ASSUME
369
- * - Bootloader size is fixed and is the same as the old bootloader
370
- * - New SoftDevice can has different size than the old one
400
+ * Note: to simplify the upgrade process, we ASSUME, Bootloader size is fixed and
401
+ * is the same as the old bootloader
371
402
*
372
403
* ------------- ------------- -------------
373
404
* | | | | + | New |
@@ -376,42 +407,41 @@ int write_block (uint32_t block_no, uint8_t *data, WriteState *state)
376
407
* | | | New | + | |
377
408
* | | | Bootloader | + | |
378
409
* | | | ++++++++ | | |
379
- * | Application | ---> | | | Invalid |
380
- * | | | | | Application |
381
- * | | | ++++++++ | | |
382
- * | | | New | | |
383
- * | | | SoftDevice | + |-------------|
384
- * USER_FLASH_START--|-------------| |-------------| + | |
385
- * | | | | + | |
386
- * | | | | + | New |
387
- * | SoftDevice | | SoftDevice | + | SoftDevice |
410
+ * | Application | ---> | | | |
411
+ * | | | | | |
412
+ * | | | ++++++++ | | ++++++++ |
413
+ * | | | New | | New |
414
+ * | | | SoftDevice | | SoftDevice |
415
+ * USER_FLASH_START--|-------------| |-------------| |-------------|
416
+ * | MBR | | MBR | | MBR |
388
417
* ------------- ------------- -------------
389
418
*/
390
-
391
419
if ( in_uicr_space (bl -> targetAddr ) )
392
420
{
393
421
/* UCIR contains bootloader & MBR address as follow:
394
- * - 0x10001014: for bootloader address
395
- * - 0x10001018: for MBR
396
- * Both values are fixed if bootloader size is not change
422
+ * - 0x10001014 bootloader address: only change of bootloader size changes
423
+ * - 0x10001018 MBR Params: mostly fixed
424
+ *
425
+ * WARNING: incorrect value of these UCIR will break device
397
426
*/
398
427
399
428
// Nothing to do since bootloader size is fixed
400
429
return 512 ;
401
430
}
402
- else if ( in_softdevice_space (bl -> targetAddr ) )
431
+ else if ( in_bootloader_space (bl -> targetAddr ) )
403
432
{
404
433
// Right above the old SoftDevice
405
- wr_addr = USER_FLASH_START + bl -> targetAddr ;
406
434
}
407
- else if ( in_bootloader_space (bl -> targetAddr ) )
435
+ else if ( in_app_space (bl -> targetAddr ) )
408
436
{
409
437
// Right below the old Bootloader
410
438
//wr_addr = USER_FLASH_START + bl->targetAddr;
439
+ // writing to SD Info struct is used as SD detector
440
+ // if (bl->targetAddr == SOFTDEVICE_INFO_STRUCT_ADDRESS) state->has_sd = true;
441
+
411
442
}
412
443
else
413
444
{
414
-
415
445
return -1 ;
416
446
}
417
447
break ;
@@ -420,25 +450,10 @@ int write_block (uint32_t block_no, uint8_t *data, WriteState *state)
420
450
default : return -1 ;
421
451
}
422
452
423
- (void ) wr_addr ;
424
- #endif
425
-
426
- // only accept block with same family id
427
- if ( (bl -> familyID != CFG_UF2_FAMILY_ID ) ) return -1 ;
428
-
429
- if ( (bl -> targetAddr < USER_FLASH_START ) || (bl -> targetAddr + bl -> payloadSize > USER_FLASH_END ) )
430
- {
431
-
432
- }
433
- else
434
- {
435
- //PRINTF("Write block at %x", bl->targetAddr);
436
- flash_nrf5x_write (bl -> targetAddr , bl -> data , bl -> payloadSize , true);
437
- }
438
-
439
- if ( state && bl -> numBlocks )
453
+ //------------- Update written blocks -------------//
454
+ if ( bl -> numBlocks )
440
455
{
441
- // Update state num blocks
456
+ // Update state num blocks if needed
442
457
if ( state -> numBlocks != bl -> numBlocks )
443
458
{
444
459
if ( bl -> numBlocks >= MAX_BLOCKS || state -> numBlocks )
@@ -460,13 +475,12 @@ int write_block (uint32_t block_no, uint8_t *data, WriteState *state)
460
475
}
461
476
462
477
// flush last blocks
478
+ // TODO numWritten can be smaller than numBlocks if return early
463
479
if ( state -> numWritten >= state -> numBlocks )
464
480
{
465
481
flash_nrf5x_flush (true);
466
482
}
467
483
}
468
-
469
- //PRINTF("wr %d=%d (of %d)", state->numWritten, bl->blockNo, bl->numBlocks);
470
484
}
471
485
472
486
return 512 ;
0 commit comments