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?

Parents
  • Hello,

    I have adapted open bootloader to remove all the transports.

    What bootloader, exactly did you start with?

    IT's been a while since I looked into this, but there are ways to make the bootloader use images already stored in flash. You need to store it in flash as if it was uploaded by the bootloader itself, but I am not sure about what you mean by "Open bootloader" Did you disable the security? Or just the transport layers?

    Best regards,

    Edvin

Reply
  • Hello,

    I have adapted open bootloader to remove all the transports.

    What bootloader, exactly did you start with?

    IT's been a while since I looked into this, but there are ways to make the bootloader use images already stored in flash. You need to store it in flash as if it was uploaded by the bootloader itself, but I am not sure about what you mean by "Open bootloader" Did you disable the security? Or just the transport layers?

    Best regards,

    Edvin

Children
  • I started from an example in SDK16 called open_bootloader and disabled all the transports as these are not used in the bootleader, rather the applications places a binary copy of the image in flash using a file sent in ascii format, either hex or srec, and coverts on the fly. This provides information on load address, store address, and size, and could also manage merged hex.

    My questions are:

    1. How does my application pass information to the bootloader that there is an image in flash to be loaded. Is there a preferred method. If not then I can use a common area of flash.

    2. If I have a bootloader, how do I provide information to the bootloader that there is a valid application to run if I load the application using the flash tools provided by an IDE.The problem is that I can't use the app to signal the bootloader as the app is never run.

  • I see. This example bootloader is intended for the nRF52840 Dongle, which has a USB bootloader where the security is taken out, because it should work with the nRF52840 dongle, which doesn't have a bootloader. Hence, the default way to update the application running on it is via nRF Connect for Desktop -> Programmer. Hence it should accept .hex files that are not signed, but part of the magic here happens in nRF Connect for Desktop, which is not open source. Hence, I recommend that you start with the secure_bootloader example.

    So the way this normally works, is to use the ble_app_buttonless_dfu example, and implement this into your custom application. In this example the application only tells the bootloader that it will receive a new image, and that the bootloader should restart in DFU mode. So your task will be to make the application handle the transfer part, and when this is done, and the new image is stored in flash, tell the bootloader to start working on it. You must decide whether you want to implement the "init packet" which contains the signature of the application and the size of it, which is usually used to check that 1: The image is valid, signed with the proper key, and 2: whether it will fit in a second slot or not. In your case, it needs to fit in a second slot, because it is the running application that handles the transfer. 

    To tell the bootloader to enter DFU mode, it uses the GPREGRET register, which is retained during the reset, and checked in the bootloader's:

    nrf_bootloader_init() -> dfu_enter_check() which checks the GPREGRET register. 

    You can also see in the nrf_bootloader_init() that it checks bank 1 whether a new application is present. So if everything is in transferred and stored correctly, then you may be able to just reset, and check if the bootloader picks it up.

    Some other useful functions: on_data_obj_execute_request_sched() and on_data_obj_execute_request() in nrf_dfu_req_handler.c, which are the functions triggered when either the init packet or the entire image is transferred, and the bootloader should take action.

    Best regards,

    Edvin

  • Thank you for the hints. I think I understand how I can use common MBR memory to pass the paramaters to flash the image that is loaded and use GPREGRET to indicate to the bootloader to start the process.

    My remaining question was how an app loaded using IDE can indicate to the bootlloader there is a valid app and so the bootloader runs the app. I am assuming it has to write to bank0?

  • What I tried to say was that you use the GPREGRET to tell the bootloader to do DFU stuff instead of just starting the old application (which is the default behavior). When you do so, the bootloader will start investigating the image present in bank1. If it is valid, it will perform a swap, so that whatever was in bank1 will be moved to bank0, and then it will start the new app which then will be present in bank0. 

    BR,
    Edvin

  • 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.

Related