nRF52840 : update from a LTEM modem

Hello,

My device is already implementing DFU over BLE and all is working fine. But now, I want to add the update over LTEM (Quectel BG77).

I want to proceed like this : 

 ('ko" means kilobyte (KB))

Step 1 => First, the current application on my host CPU (nRF52840) is dowloading the ".bin" and the ".dat" file from the last package availble by using FTP protocol and storing them into the bank2.

Step 2 => Then, the current application checks the checksum of the downloaded binary

Step 3 => Finally, if everything is ok, the application reboots and indicate to the bootloader to copy .bin into bank1 and then execute it.

Is it something that could work ? From what i understand, this is the easiest way to proceed.

Regarding step 1 and step 2, i'm not worried, it is more about step 3 where i have some questions : do I need to update the settings in the bootloader by myself ? How can i proceed ? 

Feel free to help if you have any suggestion ? 

Configuration : 

- SDK17.0.2

- nRF52840

- Soft device : S140

Regards,

Aurélien

Parents
  • Hello Aurélien,

    The bootloader supports activation of application updates which have been downloaded by the application.  To enable this, you can build the bootloader with NRF_BL_DFU_ALLOW_UPDATE_FROM_APP==1 and application with NRF_DFU_IN_APP==1. This will also allow you to import and use the same DFU modules in your application as you already use in the Bootloader. I included an example of that in this post:  RE: Background DFU application source code . 

    Regarding step 1 and step 2, i'm not worried, it is more about step 3 where i have some questions : do I need to update the settings in the bootloader by myself ? How can i proceed ? 

    Yes, the application will be responsible for updating the following elements in the settings struct: bank_current, write_offset, progress, and init_command. This will allow the bootloader to activate the image you have stored in bank 1 after you reboot.

    Regards,

    Vidar

  • Hello Vidar,


    Thank you so much for the reply.In your example, you make the upgrade in the application with the serial interface, so you are using an existing transport layer of the DFU. But according to the readme file, if I want to use an other transport layer, I need to re-write the code of nrf_dfu_serial_uart so that i can interface with the DFU stack. To do so, I need to understand the DFU transport layer in order to write new one. 

    At first glance, I was thinking of copying the binaries (.bin + .dat file) myself directly into the internal flash (bank 1) so not using any transport layer, and then rebooting so that the bootloader could finalize the update, but that's not possible, isn't it?

    Best regards,

    Aurélien

  • Hello Vidar,

    Ok good, that's very interesting and it should be easier. So, in summary, I just need to do it like this : 

    - Activate NRF_BL_DFU_ALLOW_UPDATE_FROM_APP and NRF_DFU_IN_APP flag

    - Copy ".bin" file in bank1 (first 32 bits aligned address after the end of firmware)

    - Copy ".dat" file in init_command[INIT_COMMAND_MAX_SIZE] buffer + call nrf_dfu_settings_write (I guess i just need to add a few DFU file in the app to be able to retrieve the settings structure from the app firmware)

    - Then reboot and the bootloader should be able to make the update in standalone.

    I try this and I ll keep you updated.

    Best regards,

    Aurélien 

  • Hello Aurélien,

    Yes, this should work. In addition, you need to set .bank_current == NRF_DFU_CURRENT_BANK_1 to inform the bootloader that there is an image in bank 1 to be validated, and .write_offset+.progress for the app_activate() routine.

    Best regards,

    Vidar

  • Hello Vidar,

    I have good news. Indeed, it seems it is working now :) 

    I started with copying the .bin into bank 1 (i'm using nrf_dfu_bank1_start_addr() to get the start address)

    Then, once i retrieve the .dat file, I had to add the following lines : 

            if (m_data_file_read_len < INIT_COMMAND_MAX_SIZE) {
                memcpy(s_dfu_settings.init_command, m_data_file_read, m_data_file_read_len);
            }
            s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_1;
            s_dfu_settings.progress.command_size = ctx->file_read_size;
            s_dfu_settings.progress.command_offset = ctx->file_read_size;
            s_dfu_settings.write_offset = m_bank1_addr;
            sd_softdevice_disable();
            uint32_t err_code = nrf_dfu_settings_write(NULL);

    (for example, I needed to disable the softdevice before calling nrf_dfu_settings_write) 

    If you see any corner cases, don't hesitate to tell me.

    By the way i have one question : Since I added nrf_dfu_settings.h in my code, my application is now linking some code into the bootloader memory segments (in particular the dfu settings structure in the end of the flash) but I guess it does not bother the ZIP generation. nrf_utils will take into account only the first memory segment , right and will dump the others ?

    Now, I need to make some cleaning in my code and some tests to check if everything is still working as expected, especially regarding DFU over BLE and FDS ...

  • Hello Aurélien,

    I'm glad to hear it's working now. I don't see any obvious problems with the approach you have described.

    Aurele said:
    Since I added nrf_dfu_settings.h in my code, my application is now linking some code into the bootloader memory segments (in particular the dfu settings structure in the end of the flash) but I guess it does not bother the ZIP generation

    This is fine. The application hex will include address references to the bootloader settings page, but it won't include data outside of its memory range in flash.

  • Hello Vidar,

    Ok that's great, thank you very much !

    I have just noticed that I'm also able to update the bootloader with the same method ! Smiley

    So, everything looks good, 

    thank you again for the help

    Regards

Reply Children
No Data
Related