This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem with pstorage

Good morning, I´m trying the example of this post (ble_app_template_with_pstorage_operations_nRF51DK.zip). I have SDK 8.1.0, softdevice 110 and nrf51-dk.

The source works, but i need to modify, following the example, pstorage functions. I have added uart to show messages and data, I have modified only "pstorage_test_store_and_update" and "example_cb_handler" (adding printf) functions.

The example uses three blocks but as I only want to do a bit test, I only use one block. Save, clear, load works without error but when load the data and show it, is corrupt. I have seen posts about pstorage but i don´t find why when i load, the data is corrupt.

uart_event_handle function:

void uart_event_handle(app_uart_evt_t * p_event){
    uint8_t cr;
    static uint8_t index = 0;
    uint32_t       err_code;
    switch (p_event->evt_type){
    case APP_UART_DATA_READY:
					UNUSED_VARIABLE(app_uart_get(&cr));
					UNUSED_VARIABLE(app_uart_put(cr));
				
					if(cr == 's'){
						pstorage_test_store_and_update(0);
					}					
					if(cr == 'l'){
						pstorage_test_store_and_update(1);
					}
					if(cr == 'c'){
						pstorage_test_store_and_update(2);
					}
					if(cr == 'u'){
						pstorage_test_store_and_update(3);
					}
        break;

    case APP_UART_COMMUNICATION_ERROR:
        APP_ERROR_HANDLER(p_event->data.error_communication);
        break;

    case APP_UART_FIFO_ERROR:
        APP_ERROR_HANDLER(p_event->data.error_code);
        break;

    default:
        break;
    }
}

pstorage_test_store_and_update function:

static void pstorage_test_store_and_update(int funcion){
	pstorage_handle_t       handle;
	pstorage_handle_t				block_0_handle;
	pstorage_module_param_t param;
	uint8_t                 source_data_0[10] = {(uint8_t)0, (uint8_t)1, (uint8_t)2, (uint8_t)3, (uint8_t)4, (uint8_t)5, (uint8_t)6, (uint8_t)7, (uint8_t)8, (uint8_t)9};
	uint8_t                 dest_data_0[10];
	uint32_t                error_code;
	
	error_code = pstorage_init();
	if(error_code != NRF_SUCCESS){
			bsp_indication_set(BSP_INDICATE_FATAL_ERROR);
				printf("error: %zu ", error_code);
	}
     
	param.block_size  = 16;                   //Select block size of 16 bytes
	param.block_count = 1;                   //Select 1 block, total of 16 bytes
	param.cb          = example_cb_handler;   //Set the pstorage callback handler
		
	error_code = pstorage_register(&param, &handle);
	if (error_code != NRF_SUCCESS){
			bsp_indication_set(BSP_INDICATE_FATAL_ERROR);
				printf("error: %zu ", error_code);
	}
	
	//Get block identifiers
	pstorage_block_identifier_get(&handle, 0, &block_0_handle);
		
	if(funcion == 0){
	//Store data 
		pstorage_store(&block_0_handle, source_data_0, 16, 0);     //Write to flash, only one block is allowed for each pstorage_store command
		if(error_code != NRF_SUCCESS){
				bsp_indication_set(BSP_INDICATE_RCV_ERROR);
		} 
  }
	if(funcion == 1){
		error_code = pstorage_load(dest_data_0, &block_0_handle, 16, 0);				 //Read from flash, only one block is allowed for each pstorage_load command
		printf("error_code: %zu\n", error_code);
		printf("datos: %d / %d / %d ", (int)dest_data_0[0], (int)dest_data_0[1], (int)dest_data_0[2]);
	}
	if(funcion == 2){
		//Clear 16 bytes, i.e. one block
		error_code = pstorage_clear(&block_0_handle, 16);                       
		if(error_code != NRF_SUCCESS){
				bsp_indication_set(BSP_INDICATE_RCV_ERROR);
		}
	}
	if(funcion == 3){
		pstorage_update(&block_0_handle, source_data_0, 16, 0);
	}
}

Hyperterminal with messages from uart. image description

Thank you.

  • Hi javier

    Two pointers:

    1. You register pstorage every time you call pstorage_test_store_and_update function. Every time pstorage_register is called you register a new flash memory space, so you are probably not reading the same flash memory as you write to.

    2. I see no pstorage callback function in your code. You should verify that the pstorage write/erase/update operation is complete before loading data from the same flash memory space. Otherwise you are risking that read operation is performed before the write/erase/update operation.

    I have uploaded a new example on the thread that you linked to, that prints pstorage operation results out on UART. The example includes printout that verifies flash data integrity.

  • Thank for your answer.

    Point 1:

    You are right, I have implemented another function where I init and register pstorage which it is in main before loop, and when uart detects ('l', 's', 'u', 'c') calls pstorage_test_store_and_update function, with this, save, clean and load work perfect.

    I have added a new array "source_data_1" to update with diferents data. Update, returns me that was success but when i load, the data are corrupts.

    And i don´t know why but happen to me a thing very rare. If i change where update function lf data to save "pstorage_update(&block_0_handle, source_data_1, 16, 0);" to "pstorage_update(&block_0_handle, source_data_0, 16, 0);", when i load after to save (without call in any moment update function), data are corrupts.

    Original:

    image description

    Modified:

    image description

    Point 2:

    It was my fault, when i said "example_cb_handler (adding printf)", i meant that i modify "example_cb_handler" to prints if save, load, update , clean was successful or what err_code happened. i didn´t put code because i thought it was a lot of code between "uart_event_handle", "pstorage_test_store_and_update" and screen. I only had if save for example was succesfull, print "save" else "error-> :", but i have changed my printf by yours to see it better.


    My static void pstorage_test_store_and_update at this moment:

    static void pstorage_test_store_and_update(int funcion){
      pstorage_handle_t       block_0_handle;
      uint8_t                 source_data_0[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
      uint8_t                 source_data_1[16] = { 3, 2, 1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
      uint8_t                 dest_data_0[16];
      uint32_t                error_code;
    
      //Get block identifiers
      pstorage_block_identifier_get(&handle, 0, &block_0_handle);
    
      switch(funcion){
    		case 0: //Store data 
    				pstorage_store(&block_0_handle, source_data_0, 16, 0);     //Write to flash, only one block is allowed for each pstorage_store command
    				if(error_code != NRF_SUCCESS){
    				    bsp_indication_set(BSP_INDICATE_RCV_ERROR);
    				 }
    			    break;
    		case 1: //load
    			 	error_code = pstorage_load(dest_data_0, &block_0_handle, 16, 0);                 //Read from flash, only one block is allowed for each pstorage_load command
    				printf("error_code: %zu \t", error_code);
    				printf("datos: %d / %d / %d \r\n", dest_data_0[0], dest_data_0[1], dest_data_0[2]);
    				break;
    		case 2:	//Clear 16 bytes, i.e. one block
    				error_code = pstorage_clear(&block_0_handle, 16);                   
    				if(error_code != NRF_SUCCESS){
    					bsp_indication_set(BSP_INDICATE_RCV_ERROR);
    				}
    				break;
    		case 3: //update
    				pstorage_update(&block_0_handle, source_data_1, 16, 0);
    				break;
            default:
    				break;
    	}
    }
    

    And this this is the screen that shows corrupts data:

    image description

    The last thing, you wrote in your thread, "Update 22.1.2015" instead of "Update 22.1.2016" xD

  • Hi Javier

    I suspect why the pstorage update function results in corrupt data. You need to define source_data_1 as global array. Right now it is local which means that the application is allowed to overwrite the memory contents of source_data_1 when the pstorage_test_store_and_update finishes execution. This is also stated here in the "Update Data" section.

    Let me know if defining source_data_1 as global makes a difference or not.

    Thanks for pointing out the incorrect year. Time flies ;)

  • Hi Stefan.

    I have tried to define source_data_1 as global array and Update works but this way, Save doesn´t work, so, I defined source_data_0 as global array to, and all works correctly.

    Thanks for all.

    If you want, i can send you proyect, maybe it can help another people with similar problems.

Related