This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Write firmware to bank 1 from application

Hello.

I would like to know if its possible to preform a firmware update from the application itself like so:

1. Getting the firmware via UART in chunks of 2k (from a GSM modem).

2. Writing each chunk to Bank1.

3. Reset to DFU mode that will check if the data in Bank1 is valid.

4. If so, copy it to Bank0 and start the application.

If its possible, I would like to know how to write directly to bank1 from my application and how to reset to that DFU mode.

We are currently using SDK15.

Thanks and all the best,

Ofer.

  • Hi Vidar,

    I'm note sure I understand what you mean. I didn't programmed the Bootloader setting page yet. I get bank1 address from: 

    uint32_t nrf_dfu_bank1_start_addr(void)
    {
        uint32_t bank0_addr = nrf_dfu_bank0_start_addr();
        return ALIGN_TO_PAGE(bank0_addr + s_dfu_settings.bank_0.image_size);
    }

    Doesn't this already pointing to the start location of bank1?

  • I've added:

     

      <MemorySegment name="bootloader_settings_page" start="0x000FF000" size="0x1000">
    	<ProgramSection alignment="4" keep="Yes" load="No" name=".bootloader_settings_page" address_symbol="__start_bootloader_settings_page" end_symbol="__stop_bootloader_settings_page" start = "0x000FF000" size="0x1000" />
      </MemorySegment>
      <MemorySegment name="mbr_params_page" start="0x000FE000" size="0x1000">
    	<ProgramSection alignment="4" keep="Yes" load="No" name=".mbr_params_page" address_symbol="__start_mbr_params_page" end_symbol="__stop_mbr_params_page" start = "0x000FE000" size="0x1000" />
      </MemorySegment>
      <MemorySegment name="ot_flash_data" start="0xdc000" size="0x4000">
    	<ProgramSection alignment="4" keep="Yes" load="Yes" name=".ot_flash_data" address_symbol="__start_ot_flash_data" end_symbol="__stop_ot_flash_data" start = "0xdc000" size="0x4000" />
      </MemorySegment>
      <MemorySegment name="uicr_bootloader_start_address" start="0x00000FF8" size="0x4">
    	<ProgramSection alignment="4" keep="Yes" load="Yes" name=".uicr_bootloader_start_address" address_symbol="__start_uicr_bootloader_start_address" end_symbol="__stop_uicr_bootloader_start_address" start = "0x00000FF8" size="0x4" />
      </MemorySegment>
      <MemorySegment name="uicr_mbr_params_page" start="0x00000FFC" size="0x4">
    	<ProgramSection alignment="4" keep="Yes" load="Yes" name=".uicr_mbr_params_page" address_symbol="__start_uicr_mbr_params_page" end_symbol="__stop_uicr_mbr_params_page" start = "0x00000FFC" size="0x4" />
      </MemorySegment>
    </Root>
    

    To flash_placement.xml and and bootloader_settings_page RX 0x000FF000 0x1000;uicr_mbr_params_page RX 0x00000FFC 0x4;mbr_params_page RX 0x000FE000 0x1000

    to the Memory segments.

    Now the bank1 address is 0x72000 but the error: <error> app: SOFTDEVICE: INVALID MEMORY ACCESS still appears.

  • Hi Ofer,

    The Softdevice will trigger the INVALID MEMORY ACCESS assert if the application tries to access either memory or peripherals that are reserved to the Softdevice (System on Chip resource requirements). As this is occuring when you try to do flash, I assume the problem is that you try to use the NVMC directly and not through the SD flash API.  Please make sure you have selected the SoftDevice backend for fstorage.

  • Hello all,

    I decided to refresh the topic, as not all problems were solved.

    I have custom board with NRF52832 with SD132, use SDK-16. The bootloader is standard one with BLE transport. Bootloader in dual-bank mode. Everything works properly including DFU over BLE in bootloader.

    My objective is very simirar to Ofer's:

    1. Download new firmware by application.
    2. Burn the new application in internel flash-bank1.
    3. persuade bootlader to accept new app in bank1.
    4. Restart in DFU mode.
    5. Bootloader is expected to copy app from bank1 to bank0 and execute new app.

    I don't want to add whole DFU-transport engine to my application. I've already got a custom transport in the application for other purposes. So it was natural to use it to transfer tne app image to the device.

    The problem lays in point 3. May I get detailed guidelines? What I did is:

    nrf_dfu_settings_init (true);
    dst_addr = nrf_dfu_bank1_start_addr();
    nrf_dfu_flash_erase (dst_addr, pages, NULL);
    //nrf_dfu_flash_store(dst_addr...) whole image 
    //  verify CRC of writem image
    dfu_progress_reset();
    s_dfu_settings.bank_1.image_size = app_size;
    s_dfu_settings.bank_1.image_crc  = app_crc;
    s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_APP ;
    nrf_dfu_settings_write_and_backup(NULL);
    

    Here is the first problem, because the last one says: "Settings write aborted since it tries writing to forbidden settings". Apparently direct modification of bank_1 is firbidden?

    Even after commenting out forbidden-parts-check, the bootloader doesn't reconise new application in bank1. Something is missing. Can you explain?

    Vidar, you said: "... store the init data (*.dat) to the BL settings page before you reset". Very interesting.It would be quiet powerfull. Can you give mode details? I tried writing .dat file to s_dfu_settings.init_command, but with no result. Anything else needed in s_dfu_settings?

    Regards,

    Krzysztof

    PS. There's been quite a few discussions on the same topic, none with useful conclusions. The problem is very popular among the public :-)  If you could provide a simple example how to burn an image in bank1 without bootloader-like transport? Just copy an app from external flash to bank1? Or write arbitrary data to bank1 and make bootloader use the data as valid app? Let https://github.com/jimmywong2003/nrf5-external-spi-flash-bootloader.git be a template solution.

Related