Loading Image in app and passing to bootloader

I am using SDK16 and attempting to load images for loading.I have questions and would welcome pointers

1. I need to use the application to load a new image into memory ready for loading. What is preferred method to pass information to the bootloader so that it will load the image on next reboot? I have adapted open bootloader to remove all the transports.

2. When I am developing an application and use an IDE to load a new image, how can the bootloader be informed there is a valid app so that it runs the app?

  • I need to clarify my question. When I am developing code I develop in the IDE and then use the IDE to load directly to flash - I do not use the DFU to load the new image. In this case the bootloader does not find a valid image in bank 0 or bank 1 and so sits in the bootloader.

    I can change the code so that I poke 1 into bank 0 to fool the bootloader and so run the new image, but I wondered if there was a preferred method using a flag.

  • I have a further question. My image contains several separate code sections, normally this is the app and then a section to write to the various registers in upper memory. The hex (srec) file contains the separate address sections where to load. How is the bootloader expected to deal with loading these separate sections?

  • Malcolm said:
    the bootloader does not find a valid image in bank 0 or bank 1 and so sits in the bootloader.

    This is because it is lacking something called the "bootloader settings", which is a chunk in flash containing some information about the bootloader. When you perform a DFU operation, these settings are generated by the bootloader and stored in the settings page. If you flash the application manually, you need to generate these bootloader settings, and flash it together with the application (for simplicity, I recommend flashing using nrfjprog while dealing with bootloaders. Write a .bat file with the commands you want to run, and run it from your command prompt.)

    So after you build your application, you can run something like this:

    nrfutil settings generate ... settings.hex
    nrfjprog --program <path to application hex file> --verify --sectorerase
    nrfjprog --program <path to settings.hex> --verify --sectorerase
    nrfjprog --program <path to bootloader.hex> --verify --sectorerase
    nrfjprog --reset

    you can copy this text into a file called e.g. test_application_and_bootloader.bat, and run it from a cmd line.

    Malcolm said:
    The hex (srec) file contains the separate address sections where to load. How is the bootloader expected to deal with loading these separate sections?

    Does your application.hex actually program these addresses, or are they indirectly written by the application?

    I guess that it is not part of your application hex file, but the application writes to a certain area in the upper flash during runtime, which would also be the case if you are using e.g. the peer manager to store bonding data for Bluetooth connections. 

    In that case, the bootloader will set aside an area in the top of the flash, right before the bootloader itself. The size of this area is determined by a define in the bootloader's sdk_config.h called NRF_DFU_APP_DATA_AREA_SIZE. This is the size (in bytes) that the bootloader will never touch, either for validating the application, or while performing a DFU. By default this is set to 3 flash pages (each flash page is of size 4096 bytes).

    If you are using FDS in addition to some custom data on different flash pages, make sure that they are all in the top of the flash (the FDS pages will automatically be closest to the bootloader), and that the NRF_DFU_APP_DATA_AREA_SIZE is up to date.

    Best regards,

    Edvin

  • My application already does 90% of the work and so I have decided to add code to erase the old image and flash the new image. This is easily done by running the required code from RAM so that it is not erased. This works.

    The hex file contains a value to be written at 10001018 (UICR_PARAM_PAGE_ADDR) and the start address for the application. My question is where to write the start address so that soft device jumps to the correct location to run the application as I do not have a bootloader.

    This approach works if I flash the same image as the start address does not change, but will fail if i change the code in the image.

  • Malcolm said:
    This is easily done by running the required code from RAM so that it is not erased. This works.

    You should consider what would happen if you loose power during this operation. At least if this is an end product, it is not unlikely that someone are to power off the device, not knowing the consequences. 

    Malcolm said:
    The hex file contains a value to be written at 10001018 (UICR_PARAM_PAGE_ADDR) and the start address for the application

    You can't update the UICR on the nRF52840 during runtime. That is, you can write to it if it is 0xFFFFFFFF, but if it is not 0xFFFFFFFF, you can't write to it without erasing it, and you can't erase it from the application on the nRF52840. So if you need to update this register on every DFU, then you can't do that. 

    But why do you need to update the value at UICR_PARAM_PAGE_ADDR? Wouldn't it be the same every time?

    Best regards,

    Edvin

Related