about mcuboot flash dfu image invaild

Hello Sir,

I am currently working with the boards:52840dk and ncs:2.9.1

Regarding the issue of failed mcuboot upgrade after writing the upgrade firmware using flash APIs, where the “zephyr.signed.bin” file is the one written to flash.

(The code in this routine has been modified.)

I first transferred the upgraded firmware to the memory via the serial port or other way.

Then, this is the process of writing to the flash using the flash API

while (offset < length)
{
	size_t write_len = MIN(length - offset, CONFIG_IMG_BLOCK_BUF_SIZE);  //Each time, write in blocks of size blocksize.
	if (write_len < CONFIG_IMG_BLOCK_BUF_SIZE)
		break;
	ret = flash_img_buffered_write(&flash_ctx, &uart_rx_buf[offset],
								   write_len, false);  //During the write process, the data in the last write buffer is less than the block size
	if (ret != 0)
	{
		printk("Flash write failed at offset %zu: %d\n", offset, ret);
		return ret;
	}
	offset += write_len;
}
ret = flash_img_buffered_write(&flash_ctx, NULL, 0, true);	//flush The last written buffer
/*ret = flash_img_buffered_write(&flash_ctx, &uart_rx_buf[offset],
							   (length % 512), true);*/  
if (ret != 0)
{
	printk("Final flush failed: %d\n", ret);
	return ret;
}
bytes_written = flash_img_bytes_written(&flash_ctx); //Buffer for the total number of bytes read and written
printk("Total bytes written: %zu\n", bytes_written);
if (bytes_written % UART_RX_MTU != 0)  //Check if it has been fully written in
{
	ret = boot_request_upgrade(BOOT_UPGRADE_PERMANENT); //If fully written, it will enter the DFU mode and start the update process
	if (ret != 0)
	{
		printk("Failed to request upgrade: %d\n", ret);
		return ret;
	}
	printk("Firmware update completed successfully!\n");
}

However, the update failed continuously. This is the error log reported by mcuboot.

its display secondary slot is not vaild,then I dump flash data

In Flash, the corresponding address contains the content I wrote, and the size and other details are also correct. Then, the part circled in red at the top should be the check bit of the swap_type located at the end of the secondary slot sector.

The specific content and the address where it is located have also been confirmed to be correct.

However, it was never able to be upgraded. Later, after debugging, it was found that the program failed during the hash verification process. it should be the verification of the TLV field. It is located at the end of the image, which is the part circled in the above picture.

Here's the problem: even though the contents in the flash are identical to the zephyr.signed.bin file, the upgrade still fails. Later, I dumped a Zephyr routine that can be upgraded successfully and checked the flash status before upgrading. I found that the TLV fields at the end of this routine's flash are different from the last 69 bytes of the zephyr.signed.bin in this routine.

I have found in many official and unofficial documents that this zephyr.signed.bin is used for DFU/OTA upgrades, and apart from this file, I haven't found any other new files that seem suitable for upgrading.

Then the remaining possibility is that since Zephyr uses west flash for burning, could it be that west flash modifies the signature? Or there might be other issues? What should I do next?

Please forgive my not-so-fluent English

Djangyond Kang,

Embedded Developer

Shenzhen Best of Best Holdings Co.,Ltd

Parents
  • Hi,

    west flash does not modify the signature, or do anythign like that. The image is written as is.

    There are two potential problems that come to mind: 1: did you wrtite the image at an incorrect addres or with an offset, so that validation failes because of that? In wchich address does slot 1 start, and can you doubel check that this is exactly where you copy the newimage (without any offset)? Also, make sure you sign with a valid key?

    Also, testing with CONFIG_MCUBOOT_LOG_LEVEL_DBG=y in the MCUboot configuration may give some more information about that is happening.

  • thanks for your reply,I've double-checked the address offset I set for Slot 1, and it exactly matches the flash addresses I dumped earlier.

    after my verification, in my code, both the size and offset in the flash are correct. On the contrary, in the successfully upgradeable routine, the TLV fields at the end of the image cannot match those of the zephyr.signed.bin. I am very curious about this issue,and it maybe the key of the question?

  • ok ofcourse,really thanks,this is my project, you can west flash directly, and then use serial assistant transmit another files which named "Serial_port_transmission_files" to sram and program will auto use flash api, flashed it into flash,and supplementary instruction i already have used Programmer tools of nRF Connect For Desktop and generated memory_dump.txt,and in the last reply mentioned two image trailer was used it,Once again, thank you for your assistance.serial_for_mcuboot.zipSerial_port_transmission_files.zip

  • Hi,

    Thank you, I will look into this. A few additional things:

    1. How do you transfer the image via UART? Exactly which tools and with which command (step by step) in case I need to test this on my end?

    2. I did not see the memory_dump.txt in the attached zip files. Can you make the dump after you have transfered the new image and upload it here?

  • ok,i will sent to you now,thaks for your help,about transfer the image via uart, You can directly use the serial port to send data after powering on or restarting the device and you can use any GUI serial assistant tools only if it can transmit file to Nordic52840dk from Windows/Linux/mac desktop,i use some opensource Windows desktop software form china,and it usually use chinese,you can use some english software Once again, I would like to express my heartfelt gratitude.dump_flash.zip

  • Hi,

    I see. I will start by looking at the build folder and flash dump, then. For readability, can you try to dump the flash like I suggested, with "nrfjprog --memrd 0 --n 0x100000 > memory_dump.txt"? This is simpler to analyze (If you do not have nrfjprog, that is part of nrf command line tools).

  • Hi,

    I have not tested updating via serial as I need exact insructions no how to do that, but fundamentally your approach works. I modified your main.c like this to call "boot_request_upgrade(BOOT_UPGRADE_PERMANENT)" when pressing button 1:

    #include <stdio.h>
    #include <zephyr/drivers/uart.h>
    #include <zephyr/kernel.h>
    #include <zephyr/device.h>
    #include <zephyr/devicetree.h>
    #include <string.h>
    #include <zephyr/dfu/flash_img.h>
    #include <zephyr/dfu/mcuboot.h>
    #include <zephyr/sys/util.h>
    #include <zephyr/storage/flash_map.h>
    #include <zephyr/drivers/gpio.h>
    
    #define SLOT0_PARTITION slot0_partition
    #define SLOT1_PARTITION slot1_partition
    
    #define SLOT0_PARTITION_ID FIXED_PARTITION_ID(SLOT0_PARTITION)
    
    #define SLOT1_PARTITION_ID FIXED_PARTITION_ID(SLOT1_PARTITION)
    
    #define BUF_SIZE 100000
    #define UART_RX_TIMEOUT_MS 20000
    
    #define UART_RX_MTU	34464
    
    const struct device *uart1 = DEVICE_DT_GET(DT_NODELABEL(uart1));
    int global = 65;
    uint8_t uart_tx_buf[128] = {0};
    uint8_t uart_rx_buf[100000] = {0};
    uint8_t uart_rx_buf2[128];
    // uint8_t new_buf[40000] = {0};
    // uint8_t firmware[40000]
    int flag = 0;
    int length = 0;
    #define TARGET_FLASH_AREA_ID 1
    struct flash_img_context flash_ctx;
    
    /*
     * Get button configuration from the devicetree sw0 alias. This is mandatory.
     */
    #define SW0_NODE	DT_ALIAS(sw0)
    #if !DT_NODE_HAS_STATUS_OKAY(SW0_NODE)
    #error "Unsupported board: sw0 devicetree alias is not defined"
    #endif
    static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios,
    							      {0});
    static struct gpio_callback button_cb_data;
    
    
    void button_pressed(const struct device *dev, struct gpio_callback *cb,
    		    uint32_t pins)
    {
    	int ret;
    
    	printk("Button pressed. Requesting upgrade... (new image must allready be copied into slot 1)\n");
    	ret = boot_request_upgrade(BOOT_UPGRADE_PERMANENT); //If fully written, it will enter the DFU mode and start the update process
    	if (ret != 0)
    	{
    		printk("Failed to request upgrade: %d\n", ret);
    		return;
    	}
    }
    
    static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
    {
    	ARG_UNUSED(dev);
    	switch (evt->type)
    	{
    	case UART_TX_DONE:
    		printk("UART_TX_DONE\n");
    		break;
    
    	case UART_RX_RDY:
    		printk("received %d bytes\n", evt->data.rx.len);
    		printk("offset %d \n", evt->data.rx.offset);
    		length = evt->data.rx.len;
    		// printk("rx_buf = %d %d %d %d %d\n", uart_rx_buf[32330], uart_rx_buf[32331], uart_rx_buf[32332], uart_rx_buf[32333], uart_rx_buf[32334]);
    		flag = 1;
    		//printk("offset %d \n", evt->data.rx.offset);
    		break;
    
    	case UART_RX_DISABLED:
    		break;
    
    	case UART_RX_BUF_REQUEST:
    		printk("REQUEST\n");
    		uart_rx_buf_rsp(uart1, uart_rx_buf, BUF_SIZE);
    		break;
    
    	case UART_RX_BUF_RELEASED:
    		break;
    
    	case UART_TX_ABORTED:
    		printk("UART_TX_ABORTED\n");
    		break;
    
    	default:
    		break;
    	}
    }
    
    void thread2_entry(void *p1, void *p2, void *p3)
    {
    
    	memset(uart_rx_buf, 0, BUF_SIZE);
    	int err = uart_callback_set(uart1, uart_cb, NULL);
    	if (err < 0)
    	{
    		printk("callback configuration failed\n");
    		return;
    	}
    
    	err = uart_rx_enable(uart1, uart_rx_buf, BUF_SIZE, UART_RX_TIMEOUT_MS);
    	if (err < 0)
    	{
    		printk("rxenable configuration failed\n");
    		return;
    	}
    
    	while (1)
    	{
    		k_msleep(3000);
    	}
    }
    
    K_THREAD_DEFINE(thread2, 1024, thread2_entry,
    				NULL, NULL, NULL,
    				K_HIGHEST_APPLICATION_THREAD_PRIO, 0, 0);
    
    
    int main(void)
    {
    	printf("second_version\n");
    
    	int ret;
    	size_t offset = 0;
    	size_t bytes_written;
    
    	if (!gpio_is_ready_dt(&button)) {
    		printk("Error: button device %s is not ready\n",
    		       button.port->name);
    		return 0;
    	}
    
    	ret = gpio_pin_configure_dt(&button, GPIO_INPUT);
    	if (ret != 0) {
    		printk("Error %d: failed to configure %s pin %d\n",
    		       ret, button.port->name, button.pin);
    		return 0;
    	}
    
    	ret = gpio_pin_interrupt_configure_dt(&button,
    					      GPIO_INT_EDGE_TO_ACTIVE);
    	if (ret != 0) {
    		printk("Error %d: failed to configure interrupt on %s pin %d\n",
    			ret, button.port->name, button.pin);
    		return 0;
    	}
    
    	gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
    	gpio_add_callback(button.port, &button_cb_data);
    	printk("Set up button at %s pin %d\n", button.port->name, button.pin);
    
    
    	/*ret = flash_img_init(&flash_ctx);
    	if (ret != 0)
    	{
    		printk("Flash init failed: %d\n", ret);
    		return ret;
    	}*/
    
    	ret = flash_img_init_id(&flash_ctx, SLOT1_PARTITION_ID);
    	if (ret != 0)
    	{
    		printk("Flash init failed: %d\n", ret);
    		return ret;
    	}
    
    	printk("Flash init success\n");
    	while (1)
    	{
    		k_msleep(5);
    		if (flag == 1)
    		{
    			while (offset < length)
    			{
    				size_t write_len = MIN(length - offset, CONFIG_IMG_BLOCK_BUF_SIZE);  //Each time, write in blocks of size blocksize.
    				if (write_len < CONFIG_IMG_BLOCK_BUF_SIZE)
    					break;
    
    				ret = flash_img_buffered_write(&flash_ctx, &uart_rx_buf[offset],
    											   write_len, false);  //During the write process, the data in the last write buffer is less than the block size
    				if (ret != 0)
    				{
    					printk("Flash write failed at offset %zu: %d\n", offset, ret);
    					return ret;
    				}
    
    				offset += write_len;
    			}
    
    			ret = flash_img_buffered_write(&flash_ctx, NULL, 0, true);	//flush The last written buffer
    			/*ret = flash_img_buffered_write(&flash_ctx, &uart_rx_buf[offset],
    										   (length % 512), true);*/  
    			if (ret != 0)
    			{
    				printk("Final flush failed: %d\n", ret);
    				return ret;
    			}
    
    			bytes_written = flash_img_bytes_written(&flash_ctx); //Buffer for the total number of bytes read and written
    			printk("Total bytes written: %zu\n", bytes_written);
    			if (bytes_written % UART_RX_MTU != 0)  //Check if it has been fully written in
    			{
    				ret = boot_request_upgrade(BOOT_UPGRADE_PERMANENT); //If fully written, it will enter the DFU mode and start the update process
    				if (ret != 0)
    				{
    					printk("Failed to request upgrade: %d\n", ret);
    					return ret;
    				}
    				printk("Firmware update completed successfully!\n");
    			}
    			offset = 0;
    			flag = 0;
    		}
    	}
    	return 0;
    }

    Then I built first version (with the printf saying "first_version") and flashed that. Then modified the printf, rebuilt the firmware and generated a hex file of the signed bin file that has the offset for slot 1 like this:

    $ bin2hex.py --offset=0x83000 build/serial_for_mcuboot/zephyr/zephyr.signed.bin build/serial_for_mcuboot/zephyr/zephyr.signed.offset.hex

    Then I programmed that file using nrfjprog, to write it to slot 1:

    nrfjprog --program build/serial_for_mcuboot/zephyr/zephyr.signed.offset.hex --verify

    The I pressed button 1 to call boot_request_upgrade(), and observed in the log that the new image was activated as it should:

    *** Booting MCUboot v2.1.0-dev-12e5ee106034 ***
    *** Using nRF Connect SDK v2.9.1-60d0d6c8d42d ***
    *** Using Zephyr OS v3.7.99-ca954a6216c9 ***
    I: Starting bootloader
    I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Boot source: none
    I: Image index: 0, Swap type: none
    I: Bootloader chainload address offset: 0xc000
    *** Booting nRF Connect SDK v2.9.1-60d0d6c8d42d ***
    *** Using Zephyr OS v3.7.99-ca954a6216c9 ***
    REQUEST
    first_version
    Set up button at gpio@50000000 pin 11
    Flash init success
    Button pressed. Requesting upgrade... (new image must allready be copied into slot 1)
    *** Booting MCUboot v2.1.0-dev-12e5ee106034 ***
    *** Using nRF Connect SDK v2.9.1-60d0d6c8d42d ***
    *** Using Zephyr OS v3.7.99-ca954a6216c9 ***
    I: Starting bootloader
    I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Secondary image: magic=good, swap_type=0x3, copy_done=0x3, image_ok=0x1
    I: Boot source: none
    I: Image index: 0, Swap type: perm
    I: Starting swap using move algorithm.
    I: Bootloader chainload address offset: 0xc000
    *** Booting nRF Connect SDK v2.9.1-60d0d6c8d42d ***
    *** Using Zephyr OS v3.7.99-ca954a6216c9 ***
    REQUEST
    second_version
    Set up button at gpio@50000000 pin 11
    Flash init success

    This tests your whole approach, except the part where you copy the data via UART, so unless you used the wrong image file to test with (?), this is where the problem must be and that should be looked at more closely.

    Br,

    Einar

Reply
  • Hi,

    I have not tested updating via serial as I need exact insructions no how to do that, but fundamentally your approach works. I modified your main.c like this to call "boot_request_upgrade(BOOT_UPGRADE_PERMANENT)" when pressing button 1:

    #include <stdio.h>
    #include <zephyr/drivers/uart.h>
    #include <zephyr/kernel.h>
    #include <zephyr/device.h>
    #include <zephyr/devicetree.h>
    #include <string.h>
    #include <zephyr/dfu/flash_img.h>
    #include <zephyr/dfu/mcuboot.h>
    #include <zephyr/sys/util.h>
    #include <zephyr/storage/flash_map.h>
    #include <zephyr/drivers/gpio.h>
    
    #define SLOT0_PARTITION slot0_partition
    #define SLOT1_PARTITION slot1_partition
    
    #define SLOT0_PARTITION_ID FIXED_PARTITION_ID(SLOT0_PARTITION)
    
    #define SLOT1_PARTITION_ID FIXED_PARTITION_ID(SLOT1_PARTITION)
    
    #define BUF_SIZE 100000
    #define UART_RX_TIMEOUT_MS 20000
    
    #define UART_RX_MTU	34464
    
    const struct device *uart1 = DEVICE_DT_GET(DT_NODELABEL(uart1));
    int global = 65;
    uint8_t uart_tx_buf[128] = {0};
    uint8_t uart_rx_buf[100000] = {0};
    uint8_t uart_rx_buf2[128];
    // uint8_t new_buf[40000] = {0};
    // uint8_t firmware[40000]
    int flag = 0;
    int length = 0;
    #define TARGET_FLASH_AREA_ID 1
    struct flash_img_context flash_ctx;
    
    /*
     * Get button configuration from the devicetree sw0 alias. This is mandatory.
     */
    #define SW0_NODE	DT_ALIAS(sw0)
    #if !DT_NODE_HAS_STATUS_OKAY(SW0_NODE)
    #error "Unsupported board: sw0 devicetree alias is not defined"
    #endif
    static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios,
    							      {0});
    static struct gpio_callback button_cb_data;
    
    
    void button_pressed(const struct device *dev, struct gpio_callback *cb,
    		    uint32_t pins)
    {
    	int ret;
    
    	printk("Button pressed. Requesting upgrade... (new image must allready be copied into slot 1)\n");
    	ret = boot_request_upgrade(BOOT_UPGRADE_PERMANENT); //If fully written, it will enter the DFU mode and start the update process
    	if (ret != 0)
    	{
    		printk("Failed to request upgrade: %d\n", ret);
    		return;
    	}
    }
    
    static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
    {
    	ARG_UNUSED(dev);
    	switch (evt->type)
    	{
    	case UART_TX_DONE:
    		printk("UART_TX_DONE\n");
    		break;
    
    	case UART_RX_RDY:
    		printk("received %d bytes\n", evt->data.rx.len);
    		printk("offset %d \n", evt->data.rx.offset);
    		length = evt->data.rx.len;
    		// printk("rx_buf = %d %d %d %d %d\n", uart_rx_buf[32330], uart_rx_buf[32331], uart_rx_buf[32332], uart_rx_buf[32333], uart_rx_buf[32334]);
    		flag = 1;
    		//printk("offset %d \n", evt->data.rx.offset);
    		break;
    
    	case UART_RX_DISABLED:
    		break;
    
    	case UART_RX_BUF_REQUEST:
    		printk("REQUEST\n");
    		uart_rx_buf_rsp(uart1, uart_rx_buf, BUF_SIZE);
    		break;
    
    	case UART_RX_BUF_RELEASED:
    		break;
    
    	case UART_TX_ABORTED:
    		printk("UART_TX_ABORTED\n");
    		break;
    
    	default:
    		break;
    	}
    }
    
    void thread2_entry(void *p1, void *p2, void *p3)
    {
    
    	memset(uart_rx_buf, 0, BUF_SIZE);
    	int err = uart_callback_set(uart1, uart_cb, NULL);
    	if (err < 0)
    	{
    		printk("callback configuration failed\n");
    		return;
    	}
    
    	err = uart_rx_enable(uart1, uart_rx_buf, BUF_SIZE, UART_RX_TIMEOUT_MS);
    	if (err < 0)
    	{
    		printk("rxenable configuration failed\n");
    		return;
    	}
    
    	while (1)
    	{
    		k_msleep(3000);
    	}
    }
    
    K_THREAD_DEFINE(thread2, 1024, thread2_entry,
    				NULL, NULL, NULL,
    				K_HIGHEST_APPLICATION_THREAD_PRIO, 0, 0);
    
    
    int main(void)
    {
    	printf("second_version\n");
    
    	int ret;
    	size_t offset = 0;
    	size_t bytes_written;
    
    	if (!gpio_is_ready_dt(&button)) {
    		printk("Error: button device %s is not ready\n",
    		       button.port->name);
    		return 0;
    	}
    
    	ret = gpio_pin_configure_dt(&button, GPIO_INPUT);
    	if (ret != 0) {
    		printk("Error %d: failed to configure %s pin %d\n",
    		       ret, button.port->name, button.pin);
    		return 0;
    	}
    
    	ret = gpio_pin_interrupt_configure_dt(&button,
    					      GPIO_INT_EDGE_TO_ACTIVE);
    	if (ret != 0) {
    		printk("Error %d: failed to configure interrupt on %s pin %d\n",
    			ret, button.port->name, button.pin);
    		return 0;
    	}
    
    	gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
    	gpio_add_callback(button.port, &button_cb_data);
    	printk("Set up button at %s pin %d\n", button.port->name, button.pin);
    
    
    	/*ret = flash_img_init(&flash_ctx);
    	if (ret != 0)
    	{
    		printk("Flash init failed: %d\n", ret);
    		return ret;
    	}*/
    
    	ret = flash_img_init_id(&flash_ctx, SLOT1_PARTITION_ID);
    	if (ret != 0)
    	{
    		printk("Flash init failed: %d\n", ret);
    		return ret;
    	}
    
    	printk("Flash init success\n");
    	while (1)
    	{
    		k_msleep(5);
    		if (flag == 1)
    		{
    			while (offset < length)
    			{
    				size_t write_len = MIN(length - offset, CONFIG_IMG_BLOCK_BUF_SIZE);  //Each time, write in blocks of size blocksize.
    				if (write_len < CONFIG_IMG_BLOCK_BUF_SIZE)
    					break;
    
    				ret = flash_img_buffered_write(&flash_ctx, &uart_rx_buf[offset],
    											   write_len, false);  //During the write process, the data in the last write buffer is less than the block size
    				if (ret != 0)
    				{
    					printk("Flash write failed at offset %zu: %d\n", offset, ret);
    					return ret;
    				}
    
    				offset += write_len;
    			}
    
    			ret = flash_img_buffered_write(&flash_ctx, NULL, 0, true);	//flush The last written buffer
    			/*ret = flash_img_buffered_write(&flash_ctx, &uart_rx_buf[offset],
    										   (length % 512), true);*/  
    			if (ret != 0)
    			{
    				printk("Final flush failed: %d\n", ret);
    				return ret;
    			}
    
    			bytes_written = flash_img_bytes_written(&flash_ctx); //Buffer for the total number of bytes read and written
    			printk("Total bytes written: %zu\n", bytes_written);
    			if (bytes_written % UART_RX_MTU != 0)  //Check if it has been fully written in
    			{
    				ret = boot_request_upgrade(BOOT_UPGRADE_PERMANENT); //If fully written, it will enter the DFU mode and start the update process
    				if (ret != 0)
    				{
    					printk("Failed to request upgrade: %d\n", ret);
    					return ret;
    				}
    				printk("Firmware update completed successfully!\n");
    			}
    			offset = 0;
    			flag = 0;
    		}
    	}
    	return 0;
    }

    Then I built first version (with the printf saying "first_version") and flashed that. Then modified the printf, rebuilt the firmware and generated a hex file of the signed bin file that has the offset for slot 1 like this:

    $ bin2hex.py --offset=0x83000 build/serial_for_mcuboot/zephyr/zephyr.signed.bin build/serial_for_mcuboot/zephyr/zephyr.signed.offset.hex

    Then I programmed that file using nrfjprog, to write it to slot 1:

    nrfjprog --program build/serial_for_mcuboot/zephyr/zephyr.signed.offset.hex --verify

    The I pressed button 1 to call boot_request_upgrade(), and observed in the log that the new image was activated as it should:

    *** Booting MCUboot v2.1.0-dev-12e5ee106034 ***
    *** Using nRF Connect SDK v2.9.1-60d0d6c8d42d ***
    *** Using Zephyr OS v3.7.99-ca954a6216c9 ***
    I: Starting bootloader
    I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Boot source: none
    I: Image index: 0, Swap type: none
    I: Bootloader chainload address offset: 0xc000
    *** Booting nRF Connect SDK v2.9.1-60d0d6c8d42d ***
    *** Using Zephyr OS v3.7.99-ca954a6216c9 ***
    REQUEST
    first_version
    Set up button at gpio@50000000 pin 11
    Flash init success
    Button pressed. Requesting upgrade... (new image must allready be copied into slot 1)
    *** Booting MCUboot v2.1.0-dev-12e5ee106034 ***
    *** Using nRF Connect SDK v2.9.1-60d0d6c8d42d ***
    *** Using Zephyr OS v3.7.99-ca954a6216c9 ***
    I: Starting bootloader
    I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Secondary image: magic=good, swap_type=0x3, copy_done=0x3, image_ok=0x1
    I: Boot source: none
    I: Image index: 0, Swap type: perm
    I: Starting swap using move algorithm.
    I: Bootloader chainload address offset: 0xc000
    *** Booting nRF Connect SDK v2.9.1-60d0d6c8d42d ***
    *** Using Zephyr OS v3.7.99-ca954a6216c9 ***
    REQUEST
    second_version
    Set up button at gpio@50000000 pin 11
    Flash init success

    This tests your whole approach, except the part where you copy the data via UART, so unless you used the wrong image file to test with (?), this is where the problem must be and that should be looked at more closely.

    Br,

    Einar

Children
No Data
Related