FOTA update HTTP

Hello,

I am trying to load an application update from a server into external flash, the download itself is working but mcuboot is not:

<err> dfu_target_mcuboot: boot_request_upgrade for image-0 error -14
<err> fota_download: dfu_target_done error: -14

I need to use the external flash because the application is already too big to fit into the internal one (with bootloader, primary & secondary partition).

External flash

	chosen {
		zephyr,flash = &flash0;
		zephyr,sram = &sram0_ns;
		zephyr,code-partition = &slot0_ns_partition;
		nordic,pm-ext-flash = &mx25r64;
	};

flash_spi: &spi1 {
	compatible = "nordic,nrf-spim";
	status = "okay";
	pinctrl-0 = <&spi1_default_alt>;
	pinctrl-1 = <&spi1_sleep_alt>;
	pinctrl-names = "default", "sleep";
	cs-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
	mx25r64: mx25r6435f@0 {
		compatible = "jedec,spi-nor";
		reg = <0>;
		spi-max-frequency = <80000000>;
		label = "MX25R64";
		jedec-id = [c2 28 17];
		size = <67108864>;        // 0x4000000
	};
	
};

This seems to be working, if I exclude the external flash than build fails with the hint that the size is not sufficient.
Also test functions from the spi_flash example are principially working (but not contained in the main application).

MCUboot

prj.conf:

# Image manager
CONFIG_FLASH=y
CONFIG_IMG_MANAGER=y
CONFIG_IMG_ERASE_PROGRESSIVELY=y

# FOTA library
CONFIG_FOTA_DOWNLOAD=y

# Download client
CONFIG_DOWNLOAD_CLIENT=y
CONFIG_DOWNLOAD_CLIENT_STACK_SIZE=4096

# DFU Target
CONFIG_DFU_TARGET=y

# Application Upgrade support
CONFIG_BOOTLOADER_MCUBOOT=y
CONFIG_MCUBOOT_IMG_MANAGER=y



CONFIG_MCUBOOT_SHELL=y

child_image/mcuboot/prj.conf:

# MCUboot requires a large stack size, otherwise an MPU fault will occur
CONFIG_MAIN_STACK_SIZE=10240

CONFIG_DEBUG_OPTIMIZATIONS=y

# Enable flash operations
CONFIG_FLASH=y

# This must be increased to accommodate the bigger images.
CONFIG_BOOT_MAX_IMG_SECTORS=256

# Enable serial recovery
CONFIG_UART_CONSOLE=y
CONFIG_MCUBOOT_SERIAL=n
CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=n

MCUboot seems to be working:

*** Booting Zephyr OS build v3.1.99-ncs1-1  ***

Also the file build/zephyr/app_update.bin is generated.

From the mcuboot command shell I get the same error, although I am not sure if the operation is the same:

mcuboot request_upgrade

failed to request upgrade: -14

I have also tryd to use the application_update example without any modifications, but due to the filesize it is not working:

Requested file too big to fit in flash 577112 > 0x78000

Partitions

My main suspicion is that the partitions are not configured correctly, I have tried several configurations here, for example pm.yml:

 mcuboot_secondary:
  address: 0x0
  device: mx25r6435f
  end_address: 0xf0000
  placement:
    align:
      start: 0x000
  region: external_flash
  size: 0x0f0000

which results in partitions.yml

mcuboot_primary_app:
  address: 0xc200
  end_address: 0xf2000
  orig_span: &id002
  - app
  - tfm
  region: flash_primary
  size: 0xe5e00
  span: *id002
mcuboot_secondary:
  address: 0x0
  device: /soc/peripheral@40000000/spi@9000/mx25r6435f@0
  end_address: 0xe6000
  placement:
    align:
      start: 0x4
  region: external_flash
  share_size:
  - mcuboot_primary
  size: 0xe6000

I found this somewhere but actually it seems if I add nothing at all the result will be the same.

FOTA

The FOTA functions are already strongly reduced (since modem is already set up in main application):

static void update_sample_start(void)
{
	int err;

	err = fota_download_start(HTTPS_URL_FOTA, HTTPS_TARGET_FOTA, -1, 0, 0);   // HTTP
	if (err != 0) {
		printk("fota_download_start() failed, err %d\n", err);
	}
}

static void update_sample_done(void)
{
	lte_lc_deinit();
}


static void fota_dl_handler(const struct fota_download_evt *evt)
{
	switch (evt->id) {
	case FOTA_DOWNLOAD_EVT_ERROR:
		printk("Received error from fota_download\n");
		break;

	case FOTA_DOWNLOAD_EVT_FINISHED:
		update_sample_done();
		printk("Press 'Reset' button or enter 'reset' to apply new firmware\n");
		break;

	default:
		break;
	}
}


void application_update_main(void)
{
	int err;

	err = fota_download_init(fota_dl_handler);
	if(err != 0) {
		printk("fota_download_init() failed, err %d\n", err);
		return;
	}

	update_sample_start();
}

I am grateful for every hint and wish you happy holidays!
Bernhard

Parents Reply Children
  • Bernhard said:
    File size of app_update.bin (size of the application in flash)

    When you try to update, do use code similar to the application_update code?

    Bernhard said:
    Generally I did not change the partitions since the default configuration $BUILD_DIR/partitions.yml seems to be correct, I have also added that file as pm_static.yml as described in your linked article (which makes no difference for my actual problem).

    Just to be sure:
    You use the same pm_static.yml in both the old and the new application, right?

    For external flash with the nRF9160DK, you need to enable it from the nRF52840 on the DK.
    Have you done this?
    See my colleague's example on nRF9160: HTTP application update using the nRF9160DK's external flash.

    Does this help? 

    Regards,
    Sigurd Hellesvik

Related