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

Related