Updating the SoftDevice on the nRF52832 from S132 v2.0.x to S132 v3.0 using the Dual Bank Bootloader from SDK v11.0.0 results in the application not starting up after the update is complete.
A readback of the flash after the update shows that a section of the SoftDevice 0x0E000-0x0E7FF (2k) is erased.
This issue does not occur when updating from S132 v2.0.0 to S132 v2.0.1. Why does the update from v2.0.x to v3.0.0 fail?
We have just been made aware of this issue and we have discovered that there is a page alignment issue in the code that copies the SoftDevice from swap to the SoftDevice region.
The bootloader library…
Hi, I just hit this issue with some old SDK11 based device I wanted to upgrade and wonder why the block size was computed in such relatively complex way? What was the original point of computing exactly…
I patched succesfully the dfu_sd_image_swap() code with 0xd000 constant, created legacy DFU package with fixed bootloader and after update I managed to succesfully upload another combined package of SDK12…
The bootloader library for the nRF52 has been inherited from the nRF51 and was designed with a flash page size of 1kB (0x400) in mind. However, on the nRF52 the flash page size is 4kB(0x1000).
Since the new SoftDevice (S132 v3.0.0) is larger than the old(S132 v2.0.0), the new bootloader image is divided into blocks and copied to the SD region one by one. The bootloader verifies that each block is written correctly to the SoftDevice region before moving on to the next block. This way we ensure that new bootloader is correctly written to flash even though we have to overwrite the start of the firmware image.
The block size is determined the following way:
block_size = (boot_settings.sd_image_start –sd_start)/2;
which in our case will result in the following
block_size = (0x1C000 – 0x1000)/2 = 0xD800
The 0xD800 block would have been page aligned on the nRF51, but on the nRF52 it will be 13.5 flash pages. So when the next block is written to 0xE800, then the first half of the flash page from 0xE000 to 0xE800 is erased.
The fix is to set the block size so that the blocks are page aligned, which is done by adding the following line below line 715 in dfu_sd_image_swap() in dfu_dual_bank.c
block_size &= ~(uint32_t)(CODE_PAGE_SIZE - 1);
This sets the block size to 0xD000 which ensures that the blocks are page aligned. I have attached the modified dfu_dual_bank.c file.
Thanks! I belive this is also needed for dfu_single_bank. At least I couldn't get single_bank to update to 3.0.0 without this fix. Best Regards, Erik
This is a very old issue, but we are now needing to update some in field devices containing this bootloader.
Could you comment on whether the same change is necessary further down the file in dfu_sd_image_validate()? This code appears to do nearly the same calculations followed by a dfu_sd_img_block_swap() using the blocksize.
A cursory look suggests that the validation may fail due to this block size issue. Any ideas under what conditions would this happen?
I have confirmed in test, that if the SD copy is interrupted by power loss, then dfu_sd_img_block_swap() is resumed via dfu_sd_image_validate() rather than dfu_sd_image_swap(). Validate still contains the non page aligned block calculation, leading to the same SD corruption as the unfixed code.
Does applying the dfu_sd_image_swap() fix to dfu_sd_image_validate() lead to correct behaviour, i.e. no SD corruption?