ASSERTION FAIL [err == 0] and Error writing variable 1 (err: -116)

Now I am using the https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/samples/bluetooth/direction_finding_central/README.html and https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/samples/bluetooth/direction_finding_peripheral/README.html for a direction finding project.
I am using the nRF52833DK and an antenna array designed by Nordic. The SDK I used is nRF Connect SDK v2.2.0.

-------------------------------------------------------------------------------------------------------

Let's just talk about the RX(central) device in this case.

I need a sample function for the nRF52833DK. The function should reboot the DK 15 seconds after scanning starts if no connection is established. Before rebooting the DK, I need to update a variable value in NVS.

The code should look like:

#define STORAGE_PARTITION_LABEL storage
#define NVS_ID_COUNT 1
#define NVS_ID_AOA_AOD_SETTING 2
#define NVS_ID_INIT_ALL_SETTINGS 3

static struct nvs_fs fs;

static int my_nvs_init(void)
{
    struct flash_pages_info info;
    int err;

    const struct device *flash_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller));

    if (!device_is_ready(flash_dev)) {
        printk("Flash device %s is not ready!\n", flash_dev->name);
        return -ENODEV;
    }

    err = flash_get_page_info_by_offs(flash_dev, FLASH_AREA_OFFSET(STORAGE_PARTITION_LABEL), &info);
    if (err) {
        printk("Unable to get page info (err: %d)\n", err);
        return err;
    }

    fs.offset = FLASH_AREA_OFFSET(STORAGE_PARTITION_LABEL);
    fs.sector_size = info.size;
    fs.sector_count = 3;

    err = nvs_init(&fs, flash_dev->name);
    if (err) {
        printk("Flash initialization failed\n");
        return err;
    }

    return 0;
}

bool AOA_AOD_SETTING_reinit(void){
	printk("AOA_AOD_SETTING reinit...\n");
	AOA_AOD_SETTING = AOA_AOD_START;
	int err = nvs_write(&fs, NVS_ID_AOA_AOD_SETTING, &AOA_AOD_SETTING, len);
	if (err < 0) {
        printk("Error writing variable (err: %d)\n", err);
        return false;
    }
	else{
		printk("AOA_AOD_SETTING reinit success.\n");
	}
	return true;
}

static void scan_timeout(struct k_timer *dummy)
{
    printk("Scan timeout, no connection established. reinit...\n");
	if(AOA_AOD_SETTING_reinit()){

		sys_reboot(SYS_REBOOT_MODEL);
	}
}

void main(void){
    	err = my_nvs_init();
		if (err) {
			printk("Cannot initialize NVS!\n");
			return err;
		}
}

However, I encountered the following error: Error writing variable 1 (err: -116).

I understand that error -116 indicates a certificate/key issue through this issue. However, I have not configured any certificates or keys. Therefore, I suspect this issue might be related to the scanning process. The scan_timeout callback function is triggered while the central device is still scanning. Interestingly, I can successfully write the variable when the central device is connected.

To address this, I added the following:

bool AOA_AOD_SETTING_reinit(void){
	printk("AOA_AOD_SETTING reinit...\n");
	AOA_AOD_SETTING = AOA_AOD_START;
	int err = nvs_write(&fs, NVS_ID_AOA_AOD_SETTING, &AOA_AOD_SETTING, len);
	if (err < 0) {
        printk("Error writing variable 1 (err: %d)\n", err);
        return false;
    }
	else{
		printk("AOA_AOD_SETTING reinit success.\n");
	}
	return true;
}

static void scan_timeout(struct k_timer *dummy)
{
    printk("Scan timeout, no connection established. reinit...\n");
	int err = bt_le_scan_stop();
	k_sleep(K_MSEC(100));
	if (err) {
		printk("Stop LE scan failed (err %d)\n", err);
	}

	if(AOA_AOD_SETTING_reinit()){
		k_sleep(K_MSEC(100));
		sys_reboot(SYS_REBOOT_MODEL);
	}
}

However, I got:

Scan timeout, no connection established. reinit...
ASSERTION FAIL [err == 0] @ WEST_TOPDIR/zephyr/subsys/bluetooth/host/hci_core.c:329
	k_sem_take failed with err -11
[00:00:15.299,468] <err> os: esf_dump: r0/a1:  0x00000003  r1/a2:  0x00000000  r2/a3:  0x00000001
[00:00:15.299,499] <err> os: esf_dump: r3/a4:  0x00020bf5 r12/ip:  0x00000000 r14/lr:  0x00007593
[00:00:15.299,530] <err> os: esf_dump:  xpsr:  0x41000021
[00:00:15.299,530] <err> os: esf_dump: Faulting instruction address (r15/pc): 0x0000759e
[00:00:15.299,560] <err> os: z_fatal_error: >>> ZEPHYR FATAL ERROR 3: Kernel oops on CPU 0
[00:00:15.299,591] <err> os: z_fatal_error: Fault during interrupt handling

[00:00:15.299,621] <err> os: z_fatal_error: Current thread: 0x200016b0 (unknown)
[00:00:15.601,745] <err> fatal_error: k_sys_fatal_error_handler: Resetting system
*** Booting Zephyr OS build v3.2.99-ncs1 ***

The cases about error -11 found in Devzone do not address my issue.. For example.

error -11 (EAGAIN) means "No more contexts." So, why can't I stop the scanning? I have added some k_sleep calls, but they didn't help.

Here are the steps I have tried. The main issue remains: why can't I update a variable in NVS?

Thank you! Any information would be appreciated.

Parents
  • More precise. my issue is why can't I update a variable in NVS when the k_timer is triggered?

    I know it's not recommended to call a Read/Write function in a k_timer event call back function. So I defined a variable TIMEOUT_FLAG = false.

    When the k_timer event occur, the TIMEOUT_FLAG well be set to true.

    And in my main function:

    while(1){

        if(TIMEOUT_FLAG){

            Write_to_NVS();

            k_sleep(K_MSEC(500));

            sys_reboot(0);

         }

        k_sleep(K_MSEC(500));

    }

    But the Errors still exist. 

    Scan timeout, no connection established. TIMEOUT...
    ASSERTION FAIL [0] @ WEST_TOPDIR/zephyr/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c:476
    	lll_preempt_calc: Actual EVENT_OVERHEAD_START_US = 2990
    [00:00:15.302,795] <err> os: esf_dump: r0/a1:  0x00000003  r1/a2:  0x00000000  r2/a3:  0x00000001
    [00:00:15.302,825] <err> os: esf_dump: r3/a4:  0x00020c29 r12/ip:  0x00000000 r14/lr:  0x00001f7b
    [00:00:15.302,825] <err> os: esf_dump:  xpsr:  0x41000028
    [00:00:15.302,856] <err> os: esf_dump: Faulting instruction address (r15/pc): 0x00001f86
    [00:00:15.302,886] <err> os: z_fatal_error: >>> ZEPHYR FATAL ERROR 3: Kernel oops on CPU 0
    [00:00:15.302,886] <err> os: z_fatal_error: Fault during interrupt handling
    
    [00:00:15.302,947] <err> os: z_fatal_error: Current thread: 0x200016b0 (unknown)
    [00:00:15.603,393] <err> fatal_error: k_sys_fatal_error_handler: Resetting system
    *** Booting Zephyr OS build v3.2.99-ncs1 *** 

Reply
  • More precise. my issue is why can't I update a variable in NVS when the k_timer is triggered?

    I know it's not recommended to call a Read/Write function in a k_timer event call back function. So I defined a variable TIMEOUT_FLAG = false.

    When the k_timer event occur, the TIMEOUT_FLAG well be set to true.

    And in my main function:

    while(1){

        if(TIMEOUT_FLAG){

            Write_to_NVS();

            k_sleep(K_MSEC(500));

            sys_reboot(0);

         }

        k_sleep(K_MSEC(500));

    }

    But the Errors still exist. 

    Scan timeout, no connection established. TIMEOUT...
    ASSERTION FAIL [0] @ WEST_TOPDIR/zephyr/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c:476
    	lll_preempt_calc: Actual EVENT_OVERHEAD_START_US = 2990
    [00:00:15.302,795] <err> os: esf_dump: r0/a1:  0x00000003  r1/a2:  0x00000000  r2/a3:  0x00000001
    [00:00:15.302,825] <err> os: esf_dump: r3/a4:  0x00020c29 r12/ip:  0x00000000 r14/lr:  0x00001f7b
    [00:00:15.302,825] <err> os: esf_dump:  xpsr:  0x41000028
    [00:00:15.302,856] <err> os: esf_dump: Faulting instruction address (r15/pc): 0x00001f86
    [00:00:15.302,886] <err> os: z_fatal_error: >>> ZEPHYR FATAL ERROR 3: Kernel oops on CPU 0
    [00:00:15.302,886] <err> os: z_fatal_error: Fault during interrupt handling
    
    [00:00:15.302,947] <err> os: z_fatal_error: Current thread: 0x200016b0 (unknown)
    [00:00:15.603,393] <err> fatal_error: k_sys_fatal_error_handler: Resetting system
    *** Booting Zephyr OS build v3.2.99-ncs1 *** 

Children
  • OK, I tried to delete the ASSERTION in WEST_TOPDIR/zephyr/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c:476. After that, my project worked fine.

    The ASSERTION is:

    	if (diff > HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US)) {
    		/* TODO: for Low Latency Feature with Advanced XTAL feature.
    		 * 1. Release retained HF clock.
    		 * 2. Advance the radio event to accommodate normal prepare
    		 *    duration.
    		 * 3. Increase the preempt to start ticks for future events.
    		 */
    		
    		/*
    		LL_ASSERT_MSG(false, "%s: Actual EVENT_OVERHEAD_START_US = %u",
    			      __func__, HAL_TICKER_TICKS_TO_US(diff));
    		*/
    		
    		return 1U;
    	}
    

    However, I'm not sure if this operation has any additional drawbacks. In my development experience, assertions are sometimes left in release versions, and if such assertions are not satisfied, the consequences can be fatal.

Related