Error using dfu_target_init() api of dfu_target library

I want to use dfu_target lib to implement dfu. 

I refer to fota_download.c and test\subsys\dfu. But when I use dfu_target_init() I get an error return value. 

I did it based on the hello_world demo. The development board used is nrf9160_nrf52840.  My ncs version is 1.8.0.

My prj.conf file: 

CONFIG_BOOTLOADER_MCUBOOT=y
CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="D:\\Code\\ncs\\bootloader\\mcuboot\\enc-rsa2048-priv.pem"
CONFIG_MCUBOOT_ENCRYPTION_KEY_FILE="D:\\Code\\ncs\\bootloader\\mcuboot\\enc-rsa2048-pub.pem"

CONFIG_DFU_TARGET=y
CONFIG_DFU_TARGET_MCUBOOT=y
CONFIG_FLASH=y
CONFIG_IMG_ERASE_PROGRESSIVELY=y
CONFIG_IMG_MANAGER=y
CONFIG_MCUBOOT_IMG_MANAGER=y

My code: 

void dfu_target_test()
{
char bin_header[512] = {0x3D, 0xB8, 0xF3, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00,
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

    int ret = 0;
    int img_type = dfu_target_img_type(bin_header, sizeof(bin_header));
    printk("image type: 0x%x\n", img_type);

    ret = dfu_target_init(img_type, 0x1000, NULL);
    if (ret) {
        printk("error: 0x%x\n", ret);
    }

    size_t offset = 0;
    ret = dfu_target_offset_get(&offset);
    if (ret != 0) {
        printk("error: target offset isn't zero\n");
    }

    ret = dfu_target_write(bin_header, sizeof(bin_header));
    if (ret) {
        printk("write flash error: 0x%x\n", ret);
    }
}

The bin_header comes from app_update.bin header.

output:

I: vcom0_pins_routing is ENABLED
I: vcom2_pins_routing is ENABLED
I: led1_pin_routing is ENABLED
I: led2_pin_routing is ENABLED
I: led3_pin_routing is ENABLED
I: led4_pin_routing is ENABLED
I: switch1_pin_routing is ENABLED
I: switch2_pin_routing is ENABLED
I: button1_pin_routing is ENABLED

I: button2_pin_routing is ENABLED

I: nrf_interface_pins_0_2_routing is disabled
I: nrf_interface_pins_3_5_routing is disabled
I: nrf_interface_pins_6_8_routing is disabled
I: Board configured.
*** Booting Zephyr OS build v2.7.0-ncs1  ***
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: Swap type: none

I: Bootloader chainload address offset: 0xc000
I: Jumping to the first image slot
*** Booting Zephyr OS build v2.7.0-ncs1  ***
Hello World! nrf9160dk_nrf52840
app version: 2.0
image type: 0x1
error: 0xffffffed
write flash error: 0xfffffff4

I need to write the firmware myself to complete the upgrade project. The code here just does a test to write the firmware, but it fails on initialization. And looking at address 0x83000 through J-Flash, nothing is written. I think maybe my configuration is incorrect.

Please help me to see if my prj.conf is configured correctly. Or is this due to other issues?

Thanks.

Parents
  • Hi Rive, 
    If you print the error as int, you can find that 0xffffffed is -19 meaning 

    #define ENODEV 19 /**< No such device */

    And it's caused by there was no buffer defined for mcuboot. Please have a look at dfu_target_mcuboot_init() function in dfu_target_mcuboot.c 

    The following code worked for me : 

    #include <dfu/dfu_target.h>
    #include <dfu/dfu_target_mcuboot.h>
    uint8_t mcubuf[1000] ;
    
    
    void dfu_target_test()
    {
    char bin_header[512] = {0x3D, 0xB8, 0xF3, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    
        int ret = 0;
        int img_type = dfu_target_img_type(bin_header, sizeof(bin_header));
        printk("image type: 0x%x\n", img_type);
    	dfu_target_mcuboot_set_buf(mcubuf,sizeof(mcubuf));
        ret = dfu_target_init(img_type, 0x1000, NULL);
        if (ret) {
            printk("error: 0x%d\n", ret);
        }
    
        size_t offset = 0;
        ret = dfu_target_offset_get(&offset);
        if (ret != 0) {
            printk("error: target offset isn't zero\n");
        }
     	ret = dfu_target_write(bin_header, sizeof(bin_header));
        if (ret) {
            printk("write flash error: 0x%x\n", ret);
        }
    	dfu_target_done(true);
    
    }

Reply
  • Hi Rive, 
    If you print the error as int, you can find that 0xffffffed is -19 meaning 

    #define ENODEV 19 /**< No such device */

    And it's caused by there was no buffer defined for mcuboot. Please have a look at dfu_target_mcuboot_init() function in dfu_target_mcuboot.c 

    The following code worked for me : 

    #include <dfu/dfu_target.h>
    #include <dfu/dfu_target_mcuboot.h>
    uint8_t mcubuf[1000] ;
    
    
    void dfu_target_test()
    {
    char bin_header[512] = {0x3D, 0xB8, 0xF3, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    
        int ret = 0;
        int img_type = dfu_target_img_type(bin_header, sizeof(bin_header));
        printk("image type: 0x%x\n", img_type);
    	dfu_target_mcuboot_set_buf(mcubuf,sizeof(mcubuf));
        ret = dfu_target_init(img_type, 0x1000, NULL);
        if (ret) {
            printk("error: 0x%d\n", ret);
        }
    
        size_t offset = 0;
        ret = dfu_target_offset_get(&offset);
        if (ret != 0) {
            printk("error: target offset isn't zero\n");
        }
     	ret = dfu_target_write(bin_header, sizeof(bin_header));
        if (ret) {
            printk("write flash error: 0x%x\n", ret);
        }
    	dfu_target_done(true);
    
    }

Children
  • Is dfu_target_mcuboot.h the implementation of dfu_target in MCUBoot way? Also, the code you provided above will no longer throw an error, however, it doesn't work. After calling dfu_target_write(), nothing is written to the flash. I'm guessing the write address should be 0x86000 above 52840 for hello_world since app_moved_test_update.hex starts at 0x86000.


    I switched to img_util and both writes and updates work fine. My routine using dfu_target still doesn't seem right. Should I use the API in dfu_target_mcuboot.h instead of dfu_target.h?

  • Hi River, 
    When you use dfu_target_write() with MCUBoot it will write to the secondary slot address. 
    To find the secondary slot address you need to look into the partitions.yml in build folder. 
    In your case it should be 0x84000. I tested and I can see the bin_header [] at address 0x84000. 

    Note that if dfu_target_done() is used it will boot the new firmware on next boot. 

Related