Change Bootloader start address

I need to do a DFU via BLE but I do not have enough memory.
For the past few months I have been working on a custom bootloader that would use an external memory to do the DFU.
The problem is that the new bootloader is bigger than the previous one and requires me to change the allocated memory.

Current Memory Layout New Memory Layout
Bootloader Settings Page 0x3F000 to 0x40000 0x3F000 to 0x40000
MBR Params Page 0x3E000 to 0x3F000 0x3E000 to 0x3F000
Bootloader 0x38000 to 0x3E000 0x37000 to 0x3E000

I only have two options:

  • Allocate only 0x500 for the settings page and params page so that they will fit between 0x3F000 and 0x40000.
  • Move the bootloader start address

I know this is not recommended but I have no choice in this case.
I cant change the hardware, I already have tens of thousands of devices with the clients that can only be updated through BLE DFU.

As it was mentioned in another public ticket, for SoftDevice versions beyond 6.1, the bootloader start address is stored in the MBR.
I need to know how can I modify this address correctly.

For now i have disabled the memory flash protection of the MBR, in main.c, so that I can modify the value.
Then in nrf_bootloader_fw_activation.c, i modify that value right before the MBR is called to replace the bootloader by calling this function:

  • nrf_nvmc_write_word(MBR_BOOTLOADER_ADDR, (uint32_t) 0x37000);

However, if I read the value stored in MBR_BOOTLOADER_ADDR, it is not necessarily the value I have written.
How can I change this value?

If this is actually impossible, can I reduce the allocated size for the params and settings pages? they only need  800 bytes each but they allocate 4096 each.

Parents
  • As   says, this cannot be done safely. At least not with tens of thousands of devices. The issue is that to update one word in the flash, you need to erase the entire flash page, which in itself is risky. Some error during this operation, and the device is bricked without a programmer. Depending on what SDK you are using, the bootloader may actually be stored in the UICR, and not the MBR (I believe we went back from storing it in the MBR), but I don't remember the details without looking it up. But it is either way a bad idea to change either of these. You may be able to do it on your desk, but doing that successfully 10000 - 90000 times successfully in the field is probably not a good idea.

    Why do you need to change the bootloader size? Perhaps we can come up with something else, less risky?

    Best regards,

    Edvin

  • Basically, I currently use the s112 softdevice and i want to use the s113 because I need 1kbps transfer speeds.
    Since we do DFUs via BLE, that means that the bootloader depends on the softdevice and thus i need to update both at the same time, in theory.
    My problem is that i dont have enough memory to store the old BL + SD and the new BL + SD inside my nRF52820.

    So, i modified the bootloader so that it can use an external SPI flash memory from our device to temporarily store the new SD + BL and then do the update.
    By adding the SPI implementation to the bootloader, i also increased its size which forces me to change the start address of the bootloader to allocate more space.

    I actually have a question regarding BL/SD compatibility.
    If my BL is meant to work with s112 SD, is it really not compatible with s113?

    because, if i remember correctly,  at some point, when i was testing my custom DFU procedure,  i purposely didnt update the BL and the DFU succeded even though i was expecting it to fail.

    by "the DFU succeded" i mean:
      - i updated the SD
      - i did NOT call the mbr function to replace the old bootloader by the new one
      - the DFU continued to phase 2 and started to update the app (this means that the old BL is using the new SD)

  • I understand.

    Andre N said:
    If my BL is meant to work with s112 SD, is it really not compatible with s113?

    I don't dare to say that this will work. You can test, but that is at your own risk. Without changes to the bootloader (that will not increase the size), it will certainly be rejected, but you can change the bootloader to accept it. However, you risk ending up in a state where you have a bootloader and SD that are incompatible.

    You don't happen to have the possibility to use USB/UART instead of the SPI flash?

    And if the SPI flash is the only option, how about this (since you already seem quite familiar with the DFU process):

    Upload the new SD and BL to the external flash (if there is room for both), and then do nothing with them yet. 

    Then upload a temporary SPI bootloader that is capable of reading out the files manually from the SPI flash. This doesn't need BLE support, so perhaps it is small enough to start at the same start address.

    Then update one thing at the time. E.g. if it sees that it has the old SD, then update the SD from the SPI flash. Then if it has the new SD, update the bootloader from the SPI flash. 

    I don't know, but it may work. 

    Disclaimer: This is obviously not tested from our side, so this is something that you need to do at your own risk, in case you end up with a lot of bricked devices out in the field. 

    So the "official answer" is that it is not possible to update the SoftDevice via BLE DFU on our smalles nRF52 devices, because of the reason you describe. It can't fit 2x SD + 2x BL in flash. But you can see whether you manage it using these tricks. 

    I have not tested on the nRF52820, so I don't know the details. In some nRF52 devices it is possible to change the UICR, at least if readbackprotection is not enabled. It is, however, a bit risky. The typical flow then would be to read out the UICR and store it locally in RAM (or possibly even in flash, in case something bad happens). Then do the changes you need to do, and then write it back. It may be worth investigating, as it probably is less work than the thing I suggested above. But this is also at your own risk. 

    To see how to change the UICR during runtime, please see how it is done in the system_nrf52.c file for enabling the NFCT pins as GPIOs:

        #if defined (CONFIG_NFCT_PINS_AS_GPIOS)
            if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){
                NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
                NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
                NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
                NVIC_SystemReset();
            }

    This will work because it is only changing 1's to 0's. In your case, you probably need to change some 0's to 1's as well, which is why you need to erase the UICR before writing it back.

    Best regards,

    Edvin

Reply
  • I understand.

    Andre N said:
    If my BL is meant to work with s112 SD, is it really not compatible with s113?

    I don't dare to say that this will work. You can test, but that is at your own risk. Without changes to the bootloader (that will not increase the size), it will certainly be rejected, but you can change the bootloader to accept it. However, you risk ending up in a state where you have a bootloader and SD that are incompatible.

    You don't happen to have the possibility to use USB/UART instead of the SPI flash?

    And if the SPI flash is the only option, how about this (since you already seem quite familiar with the DFU process):

    Upload the new SD and BL to the external flash (if there is room for both), and then do nothing with them yet. 

    Then upload a temporary SPI bootloader that is capable of reading out the files manually from the SPI flash. This doesn't need BLE support, so perhaps it is small enough to start at the same start address.

    Then update one thing at the time. E.g. if it sees that it has the old SD, then update the SD from the SPI flash. Then if it has the new SD, update the bootloader from the SPI flash. 

    I don't know, but it may work. 

    Disclaimer: This is obviously not tested from our side, so this is something that you need to do at your own risk, in case you end up with a lot of bricked devices out in the field. 

    So the "official answer" is that it is not possible to update the SoftDevice via BLE DFU on our smalles nRF52 devices, because of the reason you describe. It can't fit 2x SD + 2x BL in flash. But you can see whether you manage it using these tricks. 

    I have not tested on the nRF52820, so I don't know the details. In some nRF52 devices it is possible to change the UICR, at least if readbackprotection is not enabled. It is, however, a bit risky. The typical flow then would be to read out the UICR and store it locally in RAM (or possibly even in flash, in case something bad happens). Then do the changes you need to do, and then write it back. It may be worth investigating, as it probably is less work than the thing I suggested above. But this is also at your own risk. 

    To see how to change the UICR during runtime, please see how it is done in the system_nrf52.c file for enabling the NFCT pins as GPIOs:

        #if defined (CONFIG_NFCT_PINS_AS_GPIOS)
            if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){
                NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
                NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
                NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
                NVIC_SystemReset();
            }

    This will work because it is only changing 1's to 0's. In your case, you probably need to change some 0's to 1's as well, which is why you need to erase the UICR before writing it back.

    Best regards,

    Edvin

Children
  • Unfortunately that wouldn't work for me.

    We use a mobile app to interact with the device and the DFU can only be done through BLE.
    We need to keep it user friendly because our product is destined to the general public and not necessarily tech savvy users.

    The SPI flash seems to be my best option but if I implement the SPI protocol, the bootloader grows in size.
    And since i cant change the bootloader's start address, i cant use the SPI.
    From what i have seen, the start address is stored both on the UICR and MBR. However the MBR will check if it knows the BL address and it will only check on UICR if he doesnt already have a BL address.

    I am now trying to do as Turbo said and reduce the size of the BL by using size optimisation flags.
    This allows me to have a new BL small enough to fit in the space i have.
    But for some reason the CRC checks fail with this BL version, so i'll new to check why.

    If anything else fails, i will try using incompatible BL/SD to see if it works.
    It seems to me that the only difference between s112 and s113 is "LE Data Packet Length Extension" (that i will need to have better speeds on my application, not my BL) and "L2CAP with LE Credit-based Flow Control".

    If my bootloader used s113 with Data Length Extension, it would probably not be compatible with s112.
    But hopefully in my case i wont have an issue

  • Hi Andre N,

    My apology for the late response.

    I think that whether the DFU solution is complex or not, it is always a good idea to keep your mobile application all its inner working in a black box, opaque to the end users. 

    As for using incompatible BL and SD, our stance remain that we strongly recommend against it. Please be aware that complex and hard-to-find problems might occur, such as the incompatibility causing issues only after significant runtime.

    I think you can test this right away by flashing individually the S113 with MBR and your S112-compatible bootloader on an erased device.

    As for the Data Length Extension feature, the bootloader likely has that enabled by default, but I figure you can update the bootloader to a version that does not use that feature first? This is not to suggest you pursue the mismatch SD-BL idea, but merely technical discussion.

    Please remember that we are discussing updating the bootloader on-field devices, so you need to weigh the risks of those devices bricking.

    Hieu

Related