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

Bootloader project, sd_mbr_command gets Hard Fault at address 0x2000FF74

Using nRF52832, SDK16, SD132.

I have a (background)bootloader which is derived from dfu "secure_bootloader" example.

When there is nothing to flash bootloader successfully calls the app and everything works.

But, when bootloader has some bootloading to do and I use sd_mbr_command with command SD_MBR_COMMAND_COMPARE I get a hard fault with address 0x2000FF74.

nRF52832 map does not show anything above 0x20000000 or I'm looking at the wrong or incomplete address map.

It would be good to mention that when I try to use sd_mbr_command  with SD_MBR_COMMAND_COPY_BL I get error 9 (NRF_ERROR_INVALID_LENGTH) which is weird, the size I'm giving it is 15904 (in bytes).

This are the only 2 mbr calls I use (except "nrf_dfu_mbr_irq_forward_address_set" function which has SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET) and they both don't work.

Any ideas what to check?

Thanks!

  • Update:

    Checked MBR_BOOTLOADER_ADDR and MBR_UICR_BOOTLOADER_ADDR they are both 0x78000. Checked MBR_PARAM_PAGE_ADDR and MBR_UICR_PARAM_PAGE_ADDR and they are both 0x7E000. So they are valid and SD_MBR_COMMAND_COPY_BL should work since size I give it is 15904 bytes and in words  15904/4 = 3976. Bootloader goes from 0x78000 to 0x7E000 which is 0x6000 => 24576 bytes.

    I don't use SoftDevice in Bootloader so SD is not initialized. Checked the existance of MBR, it's on flash as is SD and everything else. Verification was done with nRF Connect's programmer app.

    EDIT: Address or "src" which is given to COPY_BL is application start address = 0x26000 (MBR size + SD size).

  • which is weird, the size I'm giving it is 15904 (in bytes).

    SD_MBR_COMMAND_COPY_BL calculates words for the bl_len field - and 4x 15904  won't fit into the available flash space.

  • 15904 is in bytes, that is 3976 words.

    Function call:

    uint32_t addr = APPLICATION_REGION_START;
    err_code = BOOTLOADER_CopyBootloader(&addr, header->bootloaderSize);

    header->bootloaderSize -> 15904 (bytes)

    APPLICATION_REGION_START -> 0x26000

    The calling function:

    uint32_t BOOTLOADER_CopyBootloader(uint32_t* src, uint32_t len)
    {
        sd_mbr_command_t sd_mbr_cmd;
        sd_mbr_cmd.command = SD_MBR_COMMAND_COPY_BL;
        sd_mbr_cmd.params.copy_bl.bl_src = src;
        sd_mbr_cmd.params.copy_bl.bl_len = (len / sizeof(uint32_t));
        return sd_mbr_command(&sd_mbr_cmd);
    }

    I don't see an error here...

    It also fails if len is 100...

  • uint32_t addr = APPLICATION_REGION_START;
    err_code = BOOTLOADER_CopyBootloader(&addr, header->bootloaderSize);

    That will put an address on the STACK (&addr) into the src parameter.

    Correct code should look like this:

    uint32_t addr = APPLICATION_REGION_START;
    err_code = BOOTLOADER_CopyBootloader((uint32_t*)addr, header->bootloaderSize);

  • You are correct, I've copied one of my testing attempts. Unfortunately it does not matter since I use BOOTLOADER_CopyBootloader((uint32_t*)APPLICATION_REGION_START, header->bootloaderSize) from the start and it doesn't work. Whatever I use -> Error 9.

    Thanks for noticing and replaying!

Related