using persistent data storage, NRF Connect.

I am trying to save some data in flash.

it works, but it corrupts the Bluetooth thread .

If  I call my_settings_init(), then bt_enable(NULL) never returns.

in prj.conf I added:

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

# config using settings store and load:
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_NVS=y
CONFIG_SETTINGS=y
# in file my.overlay the storage allocated is 8 pages = 32K (8 x 0x1000)
CONFIG_SETTINGS_NVS_SECTOR_COUNT=8

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

the my.overlay is as so:

&flash0 {
   partitions {
       compatible = "fixed-partitions";
       #address-cells = <1>;
       #size-cells = <1>;

       storage_partition: partition@78000 {
           label = "storage";
           reg = <0x00078000 0x00008000>;  // Allocate 32K for settings storage
       };
   };
};

added in Cmakelist.txt:

set(DTC_OVERLAY_FILE "my.overlay")

 BT working is no setting system is used, setting working but currups BT.

What is wrong?

Thanks

void read_settings(void)
{
	settings_load();
}

int my_settings_init(void)
{
	int err = settings_subsys_init();
	if (err) {
		LOG_INF("Can't init settings subsys (%d)\n", err);
		return err;
	}
	
	err = settings_register(&my_conf);
	if (err) {
		LOG_INF("Can't register my settings handler (%d)\n", err);
		return err;
		
	}
	/* Load settings from persistent storage */
	read_settings();
	return 0;
}

Parents
  • Hi,

     

    If a single-image build is being performed, zephyr's DT defined partition layout is used.

    If a multi-image (for instance with MCUBoot) is performed, then the Partition Manager is used for defining the partition layout.

     

    The latter uses a yml-based layout (check if build-folder/partitions.yml is present), and requires a different syntax.

    One can create a my_application/pm_static.yml file containing:

    storage:
        address: 0x78000
        size: 0x8000
        region: flash_primary

     

    For the same functionality as you have set in the overlay.

     

    If you're not using partition manager, can you please share the build-folder/zephyr/zephyr.dts file?

     

    Kind regards,

    Håkon

  • Hi Håkon,

    Obviously, my knowledge map of Zephyr and NRF Connect has many white spots. Current project will need a bootloader for firmware update via mobile DFU. So should I develop the project for multi image from start, or should I develop as singly image, and later do the partition for application and bootloader?

    If the correct approach is to go for multi-image at the development stage, how do I test the application without a debugger connected ?(I do it every step I take, removing the debugger and restarting, in order to check that power consumption has not jumped due to some added new code)

    I tried to set that pm_static.yml, but then setting_init() failed and the bl_enable() also never returned.. I need to get better understanding of the whole  system configurations.

    Thanks for your help.

    Johanan

  • Well, that was rather silly of me :-), I should know HEX numbers already.

    Now it builds OK, I will test the setting save/load later today.

    Thanks very much.

    Johanan

  • The following creates a hard error:

    static ssize_t write_char_fun(struct bt_conn *conn,
    	const struct bt_gatt_attr *attr,
    	const void *buf,
    	uint16_t len,
    	uint16_t offset,
    	uint8_t flags)
    {
    	LOG_INF("Attribute write, handle: %u, conn: %p",
    		attr->handle,
    		(void *)conn);
    	
    	// store in eeprom: 
    	if (len == 1)
    	{
    		house_id = ((int8_t *)buf)[0];  
    		save_settings(); // ,<<<--- This creates MPU FAULT, Data Access violation
    		LOG_INF("Write House: %d ",house_id);
    		return len;
    	}
    	LOG_INF("Write House fail len=: %d ", len);
    	return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
    }

    However, if I call save_settings()  just at main() , before anything else, like bt_enable() , it works OK, and writes the setting in memory.

    What can be the reason?

    Thanks.

    Johanan

  • I resolved the save_settings issue by taking it to the main loop from the write cb function, using a queue.

    So now it works, but I would like to know why it does not work from inside the char write cb function.

    BR

    Johanan

    //------  in the char write cb: 
    	
    	// store in eeprom: 
    	if (len == 1)
    	{
    		
    		house_id = ((int8_t *)buf)[0]; 
    		
    		// save_settings();// ,<<<--- This creates MPU FAULT, Data Access violation
    		k_msgq_put(&setting_q, NULL, K_FOREVER); // just signal to save settings in main
    		LOG_INF("Write House: %d ",house_id);
    		return len;
    	}
    	
    	// --- and in the main loop:
    	 	
    		k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
    		
    		if (k_msgq_get(&setting_q, NULL, K_NO_WAIT)== 0)
    		{
    			save_settings(); 
    			LOG_INF("Settings successfully saved");
    		}

  • Hi,

     

    BT callbacks are running in interrupt context, and you should not call such functions directly from interrupts.

     

    Kind regards,

    Håkon

  • Aha, that explains it.

    Thanks very much for your support.

Reply Children
No Data
Related