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

Calling pstorage_store without pstorage_clear

Hi, I have a problem with pstorage_store() function. The function pstorage_store() doesn't seem to write the correct data when called multiple times without calling the pstorage_clear() before.

In other words, if I call the pstorage_store() multiple times without calling the pstorage_clear() before, the data stored in flash aren't correct. But, if I call the pstorage_clear() every time before the pstorage_store() the data written in flash are always correct.

These are the function used to store/load/clear data (in the complete firmware the scheduler is used):

typedef struct __attribute__ ((aligned (4))) {
uint8_t     data[64];
uint16_t    crc;
} application_settings_t;

static application_settings_t  m_settings = { 0 };

static void ps_handler(pstorage_handle_t * handle, uint8_t op_code, uint32_t result, uint8_t * p_data, uint32_t data_len)
{
#if ( ENABLE_DEBUG_LOG_SUPPORT )
	printf("op = %d, res = %d, len = %d\r\n", (unsigned int)op_code, (unsigned int)result, (unsigned int)data_len);
#endif
switch(op_code) {
	case PSTORAGE_ERROR_OP_CODE:
	break;
	case PSTORAGE_STORE_OP_CODE:
	break;
	case PSTORAGE_CLEAR_OP_CODE:
	break;
	case PSTORAGE_UPDATE_OP_CODE:
	break;
	case PSTORAGE_LOAD_OP_CODE:			
	break;
}
}


void ps_config_erase(void)
{
uint32_t err_code;
uint32_t count;

// Clear
err_code = pstorage_clear(&m_ps_block_handle, PS_BLOCK_SIZE);
APP_ERROR_CHECK(err_code);

// Wait for clear
do { pstorage_access_status_get(&count); app_sched_execute(); } while (count > 0);
}


void ps_config_store(uint8_t * p_data, uint8_t p_len)
{
uint32_t err_code;
uint32_t count;

if (p_len > 64)
	return;

// Memclr 
memset(&m_settings, 0, sizeof(application_settings_t));
// Memcpy
memcpy(m_settings.data, p_data, p_len);
m_settings.crc = crc16_compute(m_settings.data, sizeof(m_settings.data), NULL);

#if ( ENABLE_DEBUG_LOG_SUPPORT )
uint8_t i;
for (i=0; i < p_len; i++)
	printf("%.2x ", data[i]);
printf("\r\n");
#endif

// Erase (NEED TO BE CALLED ALWAYS?)
// ps_config_erase();

// Store
err_code = pstorage_store(&m_ps_block_handle, (uint8_t *)&m_settings, sizeof(application_settings_t), 0);
APP_ERROR_CHECK(err_code);

// Wait for store
do { pstorage_access_status_get(&count); app_sched_execute(); } while (count > 0);
}

void ps_config_load(uint8_t * p_data)
{
uint32_t err_code;
uint16_t crc;	

// Clear structs
memset(&m_settings, 0, sizeof(application_settings_t));

// Try loading configuration from flash
err_code = pstorage_load((uint8_t *)&m_settings, &m_ps_block_handle, sizeof(application_settings_t), 0);
APP_ERROR_CHECK(err_code);

// Check CRC
crc = crc16_compute(m_settings.data, sizeof(m_settings.data), NULL);

#if ( ENABLE_DEBUG_LOG_SUPPORT )
uint8_t i;
for (i=0; i < sizeof(m_settings.data); i++)
	printf("%.2x ", m_settings.data[i]);
printf("\r\n");
if (crc == m_settings.crc) {
	printf("crc OK\r\n");		
}
#endif	
}
Parents
  • Hi Samuele,

    This is how flash memory work unfortunately. When it is cleared, it is set with all bits either high or low. Doing a write operation will flip some of the bits in order to make up the data you want to store. It is not possible to flip them back to the initial state without erasing.

    In this chapter there is an important note stating:

    Flash memory is unreliable when writing to a block already containing data. A clear operation is needed because the SDK implementation does not clear the blocks before writing to them. The application, not the storage module, must perform a clear operation before new data is written to the block.

    The reason for this is that erase operations take quite a long time, and it might be hard to fit it in between ongoing radio operation. It is still possible to store more data in the same block, but at another offset, without erasing though. So to write more data, you can just write at a different offset. To update or overwrite data, you must do an erase first.

Reply
  • Hi Samuele,

    This is how flash memory work unfortunately. When it is cleared, it is set with all bits either high or low. Doing a write operation will flip some of the bits in order to make up the data you want to store. It is not possible to flip them back to the initial state without erasing.

    In this chapter there is an important note stating:

    Flash memory is unreliable when writing to a block already containing data. A clear operation is needed because the SDK implementation does not clear the blocks before writing to them. The application, not the storage module, must perform a clear operation before new data is written to the block.

    The reason for this is that erase operations take quite a long time, and it might be hard to fit it in between ongoing radio operation. It is still possible to store more data in the same block, but at another offset, without erasing though. So to write more data, you can just write at a different offset. To update or overwrite data, you must do an erase first.

Children
No Data
Related