Assertion fail on first dfu_target_offset_get() call after FW update

Hello,

We are using DFU target library with MCUboot (Connect SDK v2.9.0):

uint32_t offset = 0;
dfu_target_mcuboot_set_buf(mcuboot_buf, sizeof(mcuboot_buf));
dfu_target_init(DFU_TARGET_IMAGE_TYPE_MCUBOOT, 0, 0, dfu_target_callback_handler);
dfu_target_offset_get(&offset);

And we are getting assertion fail on first dfu_target_offset_get() call after FW update:

ASSERTION FAIL [handler != ((void *)0)] @ WEST_TOPDIR/zephyr/kernel/work.c:687

On second attempt, after watchdog reboots MCU, everything works fine.

What could cause this issue?

Parents
  • Hi, 

    Are you using a custom board or nRF54L15DK?

    Is it possible to reproduce with nRF54L15DK? If so, could you provide a simple project for us to investigate the issue?

    Regards,
    Amanda H.

  • Hello,

    we were able to reproduce same issue on DK. Simple project is attached. If flash is erased with "nrfutil device erase" before flashing, on first startup we are getting the same assert fail:

    ASSERTION FAIL [handler != ((void *)0)] @ WEST_TOPDIR/zephyr/kernel/work.c:687
    [00:00:00.752,454] <err> os: r0/a1:  0x00000004  r1/a2:  0x000002af  r2/a3:  0x00000003
    [00:00:00.752,462] <err> os: r3/a4:  0x00000004 r12/ip:  0x00000000 r14/lr:  0x00037fbf
    [00:00:00.752,469] <err> os:  xpsr:  0x01000000
    [00:00:00.752,475] <err> os: Faulting instruction address (r15/pc): 0x0003cd00
    [00:00:00.752,496] <err> os: >>> ZEPHYR FATAL ERROR 4: Kernel panic on CPU 0
    [00:00:00.752,512] <err> os: Current thread: 0x20004008 (unknown)
    [00:00:00.812,376] <err> os: Halting system

    We use sysbuild, -Os optimization and our devicetree overlay:

    &cpuapp_rram {
    	reg = <0x0 DT_SIZE_K(1524)>;
    };
    
    &cpuapp_sram {
    	reg = <0x20000000 DT_SIZE_K(256)>;
    	ranges = <0x0 0x20000000 0x40000>;
    };
    

    The issue can only be replicated if BT settings are enabled in prj.conf.

    Could you inform us how to resolve this problem?


    assert_fail.7z

  • Hi, 

    What is your nRF54L15DK version on the white sticker?

    Do you want to update image with DFU via Bluetooth? If so, Check FOTA updates on nRF54L Series devices.

    dairup said:
    The issue can only be replicated if BT settings are enabled in prj.conf.

    I would suggest you use a BT sample as the basement to develop your application such as zephyr\samples\bluetooth\peripheral to enable BT without issue. Then, move to mcuboot part. I can use this test project peripheral_339380.7z base on the peripheral sample to test your code without issue. 

    -Amanda H.

  • Hello,

    Thank you for your response.

    We do not want to update FW via Bluetooth. We are updating FW via serial interface using our own protocol. The problem we are facing is assert fail on the first FW boot after update. Our example project demonstrates that assert fail occurs even without FW update procedure. All we have to do is erase entire memory, write fresh image to the memory and upon the first boot assert failure occurs. However this can be reproduced only if BT settings are enabled for reasons unknown to us. Despite the fact our example code does not use any BT functionality. Assert failure upon the first boot is the problem we are trying to resolve.

    Please note in order to successfully build our example project our devicetree overlay file must be included and "use sysbuild" must be set. Please see build configuration picture attached.

  • Hi,

    dairup said:
    The problem we are facing is assert fail on the first FW boot after update.

    Do you get any issues while running the new image without issue before updating?

    Is it possible to provide a simple project as your real case to reproduce the issue?

    dairup said:
    However this can be reproduced only if BT settings are enabled for reasons unknown to us. Despite the fact our example code does not use any BT functionality. Assert failure upon the first boot is the problem we are trying to resolve.

    I am not sure if they are the same issue causing the assert or not. There are two Devzone cases (this and this) with the "[handler != ((void *)0)]" assert, but they are caused by different issues. For your upload project, it can be fixed by adding the following code:

    	int err;
    	err = bt_enable(NULL);
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    		return 0;
    	}
     

    Here is the test project : assert_fail_updated.7z

    I would suggest you refer to Debugging with addr2line to figure out which file name and line number are associated with the address.

    Could you use the addr2line application to provide the file name and line number of r14/lr and r15/pc?

    -Amanda H.

  • Hello,

    Thank you for your response.

    Do you get any issues while running the new image without issue before updating?

    Your suggestion helps to eliminate "assert fail" problem in both cases, our example project as well our main project. Thank you.

    Could you use the addr2line application to provide the file name and line number of r14/lr and r15/pc?

    In both cases PC points to "ncs/v2.9.0/zephyr/lib/os/assert.c:44" and LR points to "ncs/v2.9.0/zephyr/include/zephyr/spinlock.h:147".

    Is it possible to provide a simple project as your real case to reproduce the issue?

    Yes, it is possible, however it would take considerable amount of time to prepare. As far as we understand, our initial simple example is sufficient for "assert fail" reproduction. As well, it is evident now the problem is about to be resolved. Is there something else on your mind you would like to confirm with additional project example we are not aware of?

    Calling of bt_enable() at the beginning of main() solves assert fail on the first boot. Could you please clarify if calling bt_enable() would not increase power consumption in case we are not using BT functionality?

    In order to be sure of minimum power consumption we call bt_disable() immediately after bt_enable():

    However we found a comment in bluetooth.h file, which states that bt_disable() can only be called after bt_enable has completed:

    Does it mean we should wait for a callback to confirm bt_enable has completed before we call bt_disable() or is it not necessary?

    Besides, is there a clear explanation why bt_enable() solves the "assert fail" upon initial boot problem? 

  • In your uploaded project, the assert is caused by CONFIG_BT_SETTINGS=y, and bt_enable() will call bt_settings_init. That fixes the assertion. See this similar post

Reply Children
Related