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

Write Application Data to Flash with pstorage

Hi,

i am having trouble to understand and use flash to store data. First of all as far as i understand ble_flash is obsolete and replaced by the pstorage module, correct?

What i want to achieve is, i want to save user settings to flash to be able to set my system to the same state after it has been e.g. reset. Therefore i need to write, erase, read and update existing settings to/in flash.

I read the following documentation part and used it as base of my own code: devzone.nordicsemi.com/.../a00018.html

Do i need to change any addresses in pstorage_platform to match it to my application? I was not sure whether i need to change code in pstorage_platform or not so i didn't changed anything.

The coded i copied from the documentation and the code i added is shown in the file attached.

The pstorage_init is called in my init_app_data_flash_manager function and after the ble_stack_init. Futhermore pstorage_init is called only once.

    // Initialize in main
leds_init();
timers_init();
gpiote_init();
buttons_init();
ble_stack_init();
init_app_data_flash_manager();
scheduler_init();    
gap_params_init();
services_init();
advertising_init();
conn_params_init();
sec_params_init();

My code does the following like descibed in the documentation. I register one block with specific size (in bytes) after pstorage_init. The handle generated while registering is saved and later used to read/write to get a block_handle using pstorage_block_identifier_get. Afterwards this block handle is used to read/write using pstorage_load and pstorage_store.

To test all this I write and read to flash after my device is disconnected (see BLE_GAP_EVT_DISCONNECTED). I also stop adversting to read and write to flash so radio should be inactiv.

            case BLE_GAP_EVT_DISCONNECTED:
        m_conn_handle = BLE_CONN_HANDLE_INVALID;
        
            //advertising_start();
			//test_app_system_settings is empty, test data is generated in save_settings_to_flash

					save_settings_to_flash(&test_app_system_settings);
					read_settings_from_flash(&test_app_system_settings);
        break;

When i debug it the array i read in read_settings_from_flash is empty (just zero).

Can anyone tell me what i am doing wrong and/or help me get it working?

Regards

code.c

Edit: I almost forgot the maybe most importat thing: How do I manage to read and write to the same address every time cause the address i wrote to in the first place is gone after a reset and saving it to flash is not possible cuase this would require a address i dont know after reset as well?

Parents
  • For all, who still travel in dark - see answer Nordic employee Stefan Birnir Sverrisson

    It also include example (wow! at the end!!! incredible)!

    devzone.nordicsemi.com/.../

    For clearification:

      0) Using documentation only you can erase->save and after that wait (in my case i comment save section, uncomment read section and upload new firmware after a minute) you can (proove it possible) read data.
      1) All operations takes time and going not in main thread - you need special loop for it
      2) Handler for indicating only. Stop trying implement your routine on it.
    handler(pstorage_handle_t  * handle,
                                uint8_t              op_code,
                                uint32_t             result,
                                uint8_t            * p_data,
                                uint32_t             data_len)
    
    switch(op_code)
    	    {
    		    case PSTORAGE_***_OP_CODE:
    
      3) Short version.
    pstorage_handle_t       handle;
    pstorage_handle_t	      block_0_handle;
    pstorage_handle_t	      block_1_handle;
    pstorage_module_param_t param;
    uint32_t                retval;
    uint8_t                 source_data[16] = {0x31, 0x32, 0x33, 0x34, ...};
    uint8_t                 dest_data[16];
    
    //@me init it
    retval = pstorage_init();
    	if(retval != NRF_SUCCESS)
    	{
    			nrf_gpio_pin_set(PSTORAGE_ERROR_LED_PIN_NO);
    	}
    
    //@me meter of taste - in theory
    param.block_size  = 16;                   //Select block size of 16 bytes
    param.block_count = 10;                   //Select 10 blocks, total of 160 bytes
    param.cb          = example_cb_handler;   //Set the pstorage callback handler
    
    //@me register it
    retval = pstorage_register(&param, &handle);
    	if (retval != NRF_SUCCESS)
    	{
    			nrf_gpio_pin_set(PSTORAGE_ERROR_LED_PIN_NO);
    	}
    
    //@me WHAT? couple of handles???
    //Get block identifiers
    pstorage_block_identifier_get(&handle, 0, &block_0_handle);
    
    pstorage_clear(&block_0_handle, 48);                       //Clear 48 bytes
    
    //Store data to blocks. Wait for the last store operation to finish before reading out the data.
    //Write to flash, only one block is allowed for each pstorage_store command
    pstorage_store(&block_0_handle, source_data, 16, 0);
    
    pstorage_wait_handle = block_1_handle.block_id;            //Specify which pstorage handle to wait for
    pstorage_wait_flag = 1;                                    //Set the wait flag. Cleared in the example_cb_handler
    pstorage_store(&block_1_handle, source_data, 16, 0);    
    
    //@me need to wait last task in queue
    while(pstorage_wait_flag) { power_manage(); }              //Sleep until store operation is finished.
    	
    //@me now we can check data from our couple of blocks
    pstorage_load(dest_data, &block_0_handle, 16, 0);				 //Read from flash, only one block is allowed for each pstorage_load command
    pstorage_load(dest_data, &block_1_handle, 16, 0);				 //Read from flash
    

    and do NOT FORGET

    static void example_cb_handler(pstorage_handle_t  * handle,	 
    uint8_t              op_code,
                               uint32_t             result,
                               uint8_t            * p_data,
                               uint32_t             data_len)
    {
    	**if(handle->block_id == pstorage_wait_handle) { pstorage_wait_flag = 0; }**
        ...
    } 
    

    ALSO NOT FORGET

    // Register with the SoftDevice handler module for System events.
    err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
    APP_ERROR_CHECK(err_code);
    
    <and>
    
       static void sys_evt_dispatch(uint32_t sys_evt)
       {
            pstorage_sys_event_handler(sys_evt);
        }
    
  • @karem I'm using 7.1.0 and everything works in non-advertisment mode (before ob after). Check if you are try to swich on adv. mode and save to flash at the same time. It shoud work in theory but in practice it didn't.

Reply Children
No Data
Related