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

Update 52840 firmware with aws_iot jobs with 9160 through external flash

Hello,

We're currently trying to update 52840 chip on a similar board such as the 9160dk, that has an external flash in between 9160 and 52840. We want to apply a firmware upgrade to 52840, but through LTE. Currently 9160 can be updated as expected, when we assign it a json job document telling it where to download the .bin file from an S3 bucket. This uses the aws_iot library, which again uses fota_download.

But, what we want to do further is to download another .bin file from the same server, forward it to external flash (we're using spi_nor) and once it's completed, tell 52840 through UART between 91 and 52, that there's a firmware available for 52. 52 then takes control over the external flash and applies the update by copying it from external flash to internal s1, and then reboots which triggers secure boot to validate and check if s1 is valid. If it is, perform a swap and apply the new update.

Based on this, a few questions have come to mind: Is there any examples or documentation that does something like this? I've seen this branch: DFU UART sample: update 52840 from 9160 · plskeggs/sdk-nrf@6baf0e0 · GitHub, but this looks like 9160 just forwards the entire update through UART?

How can we alter the fota_download to instead of writing to 9160 internal flash, send it to external flash with flash_write? Would we have to copy the contents of fota_download and create a fork of the SDK? Maybe there are CONFIG flags where we instead can set file download destination or something similar?

And regarding applying the upgrade to 52840; Which method is easiest and most beneficial to implement, apply the update by just telling MCUBOOT to check in external flash for firmware image, or manually copy the contents from external flash to 52840 internal s1 and perform a reboot and let MCUBOOT handle fw check and swap?

Regards,

EivindTH

Parents
  • Hi,

     

    At this time; we do not have any options to reroute a mcuboot update image from one device to another, unfortunately.

    Such a solution is on a per-application basis at this point, as we do not have any mechanisms to differentiate mcuboot generated images in our dfu support libraries.

     

    Kind regards,

    Håkon

  • Hi,

    Ok, I see. We know which mcuboot generated image we are sending, this can easily be added as a field in the JSON job document, telling 9160 what to do with the image. Whether it's supposed to apply it to itself (using dfu libraries), or reroute the fragments to an external flash address partition and further notify 52840 that a firmware image is available in the external flash. Now when 52840 gets this status flag from 9160, it can apply dfu from external flash to itself.


    But what you are saying is that there are no examples of this? Would we have to create a fork of our own of the /net/ source code? This would start by adding support in this function to accept a new job flag, where we can check if we want to apply it to 9160 or reroute it to external flash. This means we would have to pass the argument further down the chain to fota_download.c to prevent us from calling dfu related functions such as


    int dfu_target_write(const void *const buf, size_t len)
    {
    	if (current_target == NULL || buf == NULL) {
    		return -EACCES;
    	}
    
    	return current_target->write(buf, len);
    }

    and inevitably,

    /**
     * @brief  Process input buffers to be written to flash device in single blocks.
     * Will store remainder between calls.
     *
     * A final call to this function with flush set to true
     * will write out the remaining block buffer to flash.
     *
     * @param ctx context
     * @param data data to write
     * @param len Number of bytes to write
     * @param flush when true this forces any buffered data to be written to flash
     *        A flush write should be the last write operation in a sequence of
     *        write operations for given context (although this is not mandatory
     *        if the total data size is a multiple of the buffer size).
     *
     * @return non-negative on success, negative errno code on fail
     */
    int stream_flash_buffered_write(struct stream_flash_ctx *ctx, const uint8_t *data,
    				size_t len, bool flush);


    It's most likely to use these functions on 52840 instead, (setting up dfu_target to external flash), and on 9160 we'd instead modify from this line in fota_download.c, based on the flag we acquired from the JSON job document. From that line we can instead use event->fragment.buf if job document is set to 52840 dfu, to our "flash_write" spi_nor command, as such:

    flash_write(current_offset, event->fragment.buf, event->fragment.len);
    current_offset += event->fragment.len;

    and wait for the download to continue until we know the fragment has been written to external flash. Wouldn't this be possible, and just remove dfu dependent functionality below that line, such as dfu_target_img_type or dfu_target_init? These functions should be applied on 52840's side once 9160 is finished.

    1. Would this be a theoretical approach, or is the .bin file split up in such a way that we NEED to put the pieces correctly? It shouldn't really matter though, since 52840 would just use the dfu functions to apply the .bin file either way, as 9160 just forwarded the file, correct?

    2. Does dfu or download libraries perform CRC on the file at any time? In this scenario, it's probably wise to check on 52840 after the file has been downloaded to external flash.

    Kind regards,

    Eivind

  • Hi Eivind,

     

    EivindTH said:
    Whether it's supposed to apply it to itself (using dfu libraries), or reroute the fragments to an external flash address partition and further notify 52840 that a firmware image is available in the external flash. Now when 52840 gets this status flag from 9160, it can apply dfu from external flash to itself.
    EivindTH said:
    1. Would this be a theoretical approach, or is the .bin file split up in such a way that we NEED to put the pieces correctly? It shouldn't really matter though, since 52840 would just use the dfu functions to apply the .bin file either way, as 9160 just forwarded the file, correct?

    As long as the .bin is kept intact when it reaches the nRF52-device, there no issues.

    Splitting the logic on the application side is the way to go in this case (ie. not on dfu_targ level), and as long as you ensure that only one device is accessing the ext flash; I see no deal-breakers in this setup.

    EivindTH said:
    2. Does dfu or download libraries perform CRC on the file at any time? In this scenario, it's probably wise to check on 52840 after the file has been downloaded to external flash.

     No, this is done by mcuboot when it verifies the whole binary. If it does not verify properly, it will not be accepted and application boots the only verified image (ie. the "old" firmware)

    Kind regards,

    Håkon 

  • Hello,

    Thanks for the answer. I've looked some more at it, and I don't think the big issue is with downloading and rerouting to external flash (here we can just use download_client.h), but rather parse the job json to determine what to do with the file.

    Ultimately, what I'm asking is what's the most practical approach? Should we use aws_iot libraries (aws_fota_json, aws_fota, aws_jobs etc...), or would it be easier to create own mqtt job subscriber and job parser callback? It would be nice to use aws_fota sample if we want to apply upgrade to 9160, and custom use of download_client.h if its 52840 upgrade..

    Regards and thanks again,

    EivindTH

  • Hi Eivind,

     

    EivindTH said:
    Thanks for the answer. I've looked some more at it, and I don't think the big issue is with downloading and rerouting to external flash (here we can just use download_client.h), but rather parse the job json to determine what to do with the file.

    Ultimately, what I'm asking is what's the most practical approach? Should we use aws_iot libraries (aws_fota_json, aws_fota, aws_jobs etc...), or would it be easier to create own mqtt job subscriber and job parser callback? It would be nice to use aws_fota sample if we want to apply upgrade to 9160, and custom use of download_client.h if its 52840 upgrade..

     This depends on your preference, and if you're using that specific backend (AWS in this case).

    If you plan to use one specific cloud vendor for this platform (and future products/projects), it makes sense to evaluate the supporting libraries that we have in-place in the ncs sdk.

     

    Kind regards,

    Håkon

  • Hi Håkon,

    Thanks for helpful advice. I successfully made FOTA for both 91 and 52 work, by utilizing download_client library. I managed to download to external flash and forward each fragment using callback for each fragment. I applied the same logic on 52840, and was able create a function built on top of spi_nor driver (called flash_read_file). This triggers a callback every time fragment size was reached during flash_read, where in this scenario on 52840, I used dfu_target library (and mcuboot as target) to send the fragments and apply the update.

    Just wanted to mention this and will mark this as verified answer, as the solution mentioned earlier does indeed work if anyone plans to do this themselves! Just keep in mind to handle how 9160 and 52840 both use the external flash ;)

    Kind Regards,

    EivindTH

Reply
  • Hi Håkon,

    Thanks for helpful advice. I successfully made FOTA for both 91 and 52 work, by utilizing download_client library. I managed to download to external flash and forward each fragment using callback for each fragment. I applied the same logic on 52840, and was able create a function built on top of spi_nor driver (called flash_read_file). This triggers a callback every time fragment size was reached during flash_read, where in this scenario on 52840, I used dfu_target library (and mcuboot as target) to send the fragments and apply the update.

    Just wanted to mention this and will mark this as verified answer, as the solution mentioned earlier does indeed work if anyone plans to do this themselves! Just keep in mind to handle how 9160 and 52840 both use the external flash ;)

    Kind Regards,

    EivindTH

Children
No Data
Related