Hello everyone, i need some help and suggestions in understanding what is exactly happening. I have read a lot about bugs and workarounds in pstorage and now i actually don't know what to try, so i need some ideas :) Im using S110 v.8.0, SDK v9 and no, i am not using device manager. Im still debugging the code so you might see some strange flag names and etc. (sorry for kinda bad code formatting)
-
Before starting to see a code, i will try to explain my problem. I have registered two different pieces of flash with pstorage module. One is holding sensor configuration data, and the other should hold sensor measurements. While i am writing sensor data for the first time in flash, there are no problems. But when i try to update these sectors, the callback function is never called. The strange thing is for me that i am ussing the same callback for another block of flash which holds sensor configuration data and the handler is called for that and update operation happens successfully.So the question is, why i am able to update one segment of the flash and app_data_flash_manager_cb_handler() calback is called, but this callback is not called when i am updating another part of the flash.
-
I have created two modules to hold parameters in flash. One is to hold sensor configurations and the other one two hold sensor data (right now i made a small simulator to put "sensor" data in that place. Code for this:
static void flash_area_for_pstorage_init(void) { /* Initialize pstorage module */ pstorage_retval = pstorage_init(); if(pstorage_retval == NRF_SUCCESS) { // Module initialization successful. pstorage_dead = 0; } else { // Initialization failed, take corrective action. pstorage_dead = 1; } param1.block_size = 32; // Block size is 32bytes param1.block_count = 1; // Get 1 block for data. param1.cb = app_data_flash_manager_cb_handler; pstorage_retval = pstorage_register(¶m1, &handle1); if (pstorage_retval == NRF_SUCCESS) { // Registration successful. pstorage_dead = 0; } else { // Failed to register, take corrective action. pstorage_dead = 1; } param.block_size = 128; param.block_count = 3; param.cb = app_data_flash_manager_cb_handler; pstorage_retval = pstorage_register(¶m, &handle); if (pstorage_retval == NRF_SUCCESS) { // Registration successful. pstorage_dead = 0; } else { // Failed to register, take corrective action. pstorage_dead = 1; } }
-
As you can see from the code above, i registered the same callback handler for both modules of pstorage. The code for handler is just to change flag value:
static void app_data_flash_manager_cb_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_STORE_OP_CODE: if (result == NRF_SUCCESS) { flash_manager_status_flag = 1; // Store operation successful. } else { flash_manager_status_flag = 2; } case PSTORAGE_LOAD_OP_CODE: if (result == NRF_SUCCESS) { flash_manager_status_flag = 3; } else { flash_manager_status_flag = 4; } // Source memory can now be reused or freed. break; case PSTORAGE_UPDATE_OP_CODE: if (result == NRF_SUCCESS) { flash_manager_status_flag = 5; } else { flash_manager_status_flag = 6; } break; case PSTORAGE_CLEAR_OP_CODE: if (result == NRF_SUCCESS) { flash_manager_status_flag = 7; } else { flash_manager_status_flag = 8; } break; default: flash_manager_status_flag = 0xAA; break; } }
-
Thats pretty much it, now i am modifying the flash space which should hold the values for sensor configuration. I am doing this when i connect to the device and write to the characteristic (this is my own made custom service, code for this)
static void gld_write_handler(ble_gld_t * p_gld, uint8_t *characteristic_data, uint8_t length) { for(myvar1 = 0; myvar1 < length; myvar1++) { write_data[myvar1] = characteristic_data[myvar1]; } characteristic_write_flag = 1; /* Write parameters to the flash */ err_code = pstorage_block_identifier_get(&handle1, 0, &p_block_id1); // Get 1 block APP_ERROR_CHECK(err_code); // Update data hold in this flash area where params are err_code = pstorage_update(&p_block_id1, write_data, param1.block_size, 0); APP_ERROR_CHECK(err_code); }
-
The above piece of code is working without problems. I can modify this flash space as i want. The problem shows up when i am trying to work with another flash space. The problem is that while it using pstorage_store() to just store the data to flash everything works fine, but when all three blocks of data are full, i am starting to use pstorage_update(), but that does not even call my callback handler. Here is exactly how i am doing this(this handler is called every 500ms by a timer,
RAM_BLOCK_SIZE = 128
static void fill_data_simulator_handler(void * p_context)
{
UNUSED_PARAMETER(p_context);
sensor_data[ram_index] = cnt_nu;
ram_index++;
if(ram_index == (RAM_BLOCK_SIZE-1))
{
store_data_flag = 1;
if(flash_overwrite_flag==1)
{
app_timer_stop(m_simulator_timer_id);
APP_ERROR_CHECK(err_code);
}
}
}
- The main function code,
RAM_BLOCK_COUNT=3
int main(void)
{
// Initialize.
timers_init();
ble_stack_init();
gap_params_init();
services_init();
advertising_init();
conn_params_init();
flash_area_for_pstorage_init();
/* Store sensor configuration in flash */
err_code = pstorage_block_identifier_get(&handle1, 0, &p_block_id1); // Get 1 block
APP_ERROR_CHECK(err_code);
err_code = pstorage_store(&p_block_id1, write_data, param1.block_size, 0);
APP_ERROR_CHECK(err_code);
nrf_dongle_led_init(); // Led pins init.
application_timers_start();
advertising_start();
// Enter main loop.
for (;;)
{
power_manage();
if(store_data_flag == 1)
{
store_data_flag = 0;
ram_index = 0;
err_code = pstorage_block_identifier_get(&handle, block_id, &p_block_id); // Get 1 block
APP_ERROR_CHECK(err_code);
if(flash_overwrite_flag == 1)
{
err_code = pstorage_update(&p_block_id, sensor_data, param.block_size, 0);
APP_ERROR_CHECK(err_code);
err_code = app_timer_start(m_simulator_timer_id, SIMULATOR_INTERVAL, NULL);
APP_ERROR_CHECK(err_code);
}
else
{
err_code = pstorage_store(&p_block_id, sensor_data, param.block_size, 0);
APP_ERROR_CHECK(err_code);
}
block_id++;
counter++;
cnt_nu++;
if(block_id == RAM_BLOCK_COUNT)
{
flash_overwrite_flag = 1;
block_id = 0;
}
}
}
}
-
And yes, i have registered for the system events:
static void sys_evt_dispatch(uint32_t sys_evt) { if ((sys_evt == NRF_EVT_FLASH_OPERATION_SUCCESS) || (sys_evt == NRF_EVT_FLASH_OPERATION_ERROR)) { pstorage_sys_event_handler(sys_evt); } ble_advertising_on_sys_evt(sys_evt); }