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

pstorage / maximum storage allowed & memory address

hi guys,

So i made a board with an nrf51822 chip (256kb ) and some sensors + RTC(realtime clock). The RTC will generate an interruption every 1 minutes. During the interruption the nrf will read data from the sensors + date & time from the RTC then save them into the nrf51822 flash memory.

So I'm planings to reserve flash memory for 4 days of data with a block size of 16 bits. Every block should contain the data that I read from sensors + time&date every minutes. These datas can be contained in 12bits but the block size should be dividable by 1024 (page size) so this is why I choose 16bits as block size.

So the necessary flash memory that I need is equal to = block_size * 60 secondes * 24 hours * 4 days = 16 * 60 * 24 * 4 = 92160 bits = 90 KB or pages. So we get 5760 blocks of 16bits each.

So inside the pstorage_platform.h I put #define PSTORAGE_NUM_OF_PAGES 90 and inside the main I put these value to p_example_param.block_size = 16; // p_example_param.block_count = 5760;

The first block I would reserved it to contain the number of samples done. Meaning I have to increment this variable every time I make samples and store it into the flash. For example if this variable is equal to 30 meaning I have in memory 30 samples stored from block 1 to 30 (30 minutes of sampling). once I read the samples via my phone app I reset the variable to zero.

image description

And here's my problems/concerns :

1- how can I determine the maximum memory size that I can reserve without overtaking the other memory area reserved for the application / softdevice..

for now i'm not using the bootloader. But i'm planning later to use it.

For example with the actual configuration (block_size = 16 & block_count = 5760 ) the program work correctly, I can write and read for example the first block0 and last block 5759 without any problem. But when I try to raise the memory size by raising the block count and taking into account the value of PSTORAGE_NUM_OF_PAGES the nrf stuck and won't work. I think because the app data storage overflow its limit and enter into the area reserved for the application code.

It's too random and I can't figure out how can I know the size limit that I can reserve it for my data storage.

2- I want to know for example if my nrf works correctly and storing data each minutes to the flash memory then I decide to restart the nrf. Normally after the restart the program will initializes again a new pstorage with the same parameter as before the restart, meaning the same block size and block count.

did the new reserved memory area will be at the same addresse as it was before the restart ? For example if after the restart I read the block0 will I found the value of the variable that contain the number of sample ?

3- I was trying to test the storage by writing some random values to different blocks and then trying to reading them in order to be sure that everything work correctly. Here's the code

    uint32_t err_code;         

uint16_t dummy_block = 0;
// Must be static as the pstorage module processes the queue asynchronously
static uint8_t dummy_data[16] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF };
	static uint8_t dummy_data1[16] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
	static uint8_t dummy_data2[16] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F };
	static uint8_t dummy_data3[16] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F };
uint16_t dummy_size = 16;
uint16_t dummy_offset = 0;
pstorage_handle_t p_block_id;


	
err_code = pstorage_block_identifier_get(&m_p_example_id, 0, &p_block_id);
APP_ERROR_CHECK(err_code);
	
	err_code = pstorage_clear(&p_block_id, 16);

err_code = pstorage_store(&p_block_id, dummy_data, dummy_size, dummy_offset);
APP_ERROR_CHECK(err_code);	
	
		
	

    err_code = pstorage_block_identifier_get(&m_p_example_id, 1, &p_block_id);
APP_ERROR_CHECK(err_code);
	
	err_code = pstorage_clear(&p_block_id, 16);

err_code = pstorage_store(&p_block_id, dummy_data1, dummy_size, dummy_offset);
APP_ERROR_CHECK(err_code);
	
		

I notice that the value when reading them aren't correct. So I tried to add some a delay of 30ms between each writing operation and the problem was resolved and the values were properly saved.

err_code = pstorage_block_identifier_get(&m_p_example_id, 0, &p_block_id);
APP_ERROR_CHECK(err_code);
	
	err_code = pstorage_clear(&p_block_id, 16);

err_code = pstorage_store(&p_block_id, dummy_data, dummy_size, dummy_offset);
APP_ERROR_CHECK(err_code);	
	
		nrf_delay_ms(30);
	

    err_code = pstorage_block_identifier_get(&m_p_example_id, 1, &p_block_id);
APP_ERROR_CHECK(err_code);
	
	err_code = pstorage_clear(&p_block_id, 16);

err_code = pstorage_store(&p_block_id, dummy_data1, dummy_size, dummy_offset);
APP_ERROR_CHECK(err_code);
	
		nrf_delay_ms(30);

but the thing of the delay is too random and I want to replace it with something strong, below what I 've done. is that correct enough ??

I add a new varaible called 'pstorage_finish_writing'

static volatile bool pstorage_finish_writing = false;

and test its value after each write operation:

			pstorage_finish_writing = false;
    err_code = pstorage_block_identifier_get(&m_p_example_id, 1, &p_block_id);
APP_ERROR_CHECK(err_code);
	
	err_code = pstorage_clear(&p_block_id, 16);

err_code = pstorage_store(&p_block_id, dummy_data1, dummy_size, dummy_offset);
APP_ERROR_CHECK(err_code);
	
	 while(pstorage_finish_writing == false);

and add this code inside the pstorage handler

 case PSTORAGE_LOAD_OP_CODE:
       if (result == NRF_SUCCESS)
       {
           // Store operation successful.
					  pstorage_finish_writing = true;
       }
       else
       {
           // Store operation failed.
       }
       // Source memory can now be reused or freed.
       break;

is that correct and enough ?

Thx ,

  • Hi Tizana

    1. Perhaps the answer on this thread will help you realize how the different things are constructed in the memory map. To realize the size of your application, look at this thread.

    2. For the pstorage module, the block allocation in flash should always be the same after restart, as soon as you alsways start the same application. For the new flash modules, this might be different.

    3. To realize why this delay is needed between writing flash and reading, look at the answer on this thread. There is also an answer here that contains pstorage example code. That code is doing similar things as you are attempting now with setting a flag when receiving the callback in order to know how long you should wait. Additionally, what is done in the pstorage example is:

    • go to sleep while waiting, instead of busy waiting
    • specify what pstorage operation to wait for. Since pstorage implements queuing mechanisms for flash operation commands, I suspect you might false trigger your flag if you don't specify what flash operation to wait for
  • thx for the answers stefan.

    i have another issue while writing or updating into the flash memory.

    	uint32_t err_code;
    	uint8_t	data_toStore_mem[16]= { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
    	uint8_t           dest_data[4];
    	pstorage_handle_t p_block_id;
    	
    	err_code = pstorage_block_identifier_get(&m_p_example_id,50, &p_block_id);
    APP_ERROR_CHECK(err_code);
    
    	pstorage_wait_handle = p_block_id.block_id;
    	pstorage_wait_flag = 1;	
    	err_code = pstorage_store(&p_block_id, data_toStore_mem, 16, 0);
    APP_ERROR_CHECK(err_code);	
    	while(pstorage_wait_flag);
    

    the code above work perfectly. but when i try to change the Size of data and put for example 2 the write operation won't work

    	uint32_t err_code;
    	uint8_t	data_toStore_mem[16]= { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
    	uint8_t           dest_data[4];
    	pstorage_handle_t p_block_id;
    	err_code = pstorage_block_identifier_get(&m_p_example_id,50, &p_block_id);
    APP_ERROR_CHECK(err_code);
    	pstorage_wait_handle = p_block_id.block_id;
    	pstorage_wait_flag = 1;	
    	err_code = pstorage_store(&p_block_id, data_toStore_mem, 2, 0);
    APP_ERROR_CHECK(err_code);	
    	while(pstorage_wait_flag);
    

    i tried different size of data and i notice when i put a size data from 4 to 16 the store operation work perfectly but when i put a size equal to 1 or 2 or 3 i got an error during writing.

    i don't know where the problem come from.

  • Hi Tizana

    I suspect it is because flash writes need to be word aligned, i.e. you must write 4,8,12,16,20,... bytes at once.

Related