Make NVS saving more resilient
This commit is contained in:
parent
8ac36022e0
commit
ea2049efb2
|
@ -1 +1 @@
|
||||||
457
|
459
|
||||||
|
|
36
src/nvs.c
36
src/nvs.c
|
@ -44,7 +44,7 @@ static uint32_t NVS_CalculateCRC(NVS_Data_t *data)
|
||||||
return CRC->DR;
|
return CRC->DR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NVS_ProgramHalfWord(uint16_t *dest, uint16_t value)
|
static bool NVS_ProgramHalfWord(uint16_t *dest, uint16_t value)
|
||||||
{
|
{
|
||||||
FLASH->CR = FLASH_CR_PG;
|
FLASH->CR = FLASH_CR_PG;
|
||||||
*(uint16_t*)dest = value;
|
*(uint16_t*)dest = value;
|
||||||
|
@ -52,9 +52,11 @@ static void NVS_ProgramHalfWord(uint16_t *dest, uint16_t value)
|
||||||
if(*dest != value)
|
if(*dest != value)
|
||||||
{
|
{
|
||||||
// Write failed
|
// Write failed
|
||||||
__asm__("bkpt");
|
FLASH->CR = 0x00000000;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
FLASH->CR = 0x00000000;
|
FLASH->CR = 0x00000000;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NVS_UnlockFlash(void)
|
static void NVS_UnlockFlash(void)
|
||||||
|
@ -67,7 +69,7 @@ static void NVS_UnlockFlash(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NVS_EraseArea(void)
|
static bool NVS_EraseArea(void)
|
||||||
{
|
{
|
||||||
for(unsigned int i = 0; i < NVS_AREA_SIZE; i += 1024)
|
for(unsigned int i = 0; i < NVS_AREA_SIZE; i += 1024)
|
||||||
{
|
{
|
||||||
|
@ -84,9 +86,11 @@ static void NVS_EraseArea(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Erase failed
|
// Erase failed
|
||||||
__asm__("bkpt");
|
FLASH->CR = 0x00000000;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
FLASH->CR = 0x00000000;
|
FLASH->CR = 0x00000000;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +152,7 @@ bool NVS_Load(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NVS_Save(bool erase_if_needed)
|
bool NVS_Save(bool erase_if_needed)
|
||||||
{
|
{
|
||||||
NVS_UnlockFlash();
|
NVS_UnlockFlash();
|
||||||
|
|
||||||
|
@ -162,9 +166,13 @@ void NVS_Save(bool erase_if_needed)
|
||||||
{
|
{
|
||||||
if(!erase_if_needed)
|
if(!erase_if_needed)
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!NVS_EraseArea())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
NVS_EraseArea();
|
|
||||||
next_block = &NVS_Area[0];
|
next_block = &NVS_Area[0];
|
||||||
current_block = NULL;
|
current_block = NULL;
|
||||||
}
|
}
|
||||||
|
@ -175,14 +183,22 @@ void NVS_Save(bool erase_if_needed)
|
||||||
// The block length is guaranteed to be divisible by 2
|
// The block length is guaranteed to be divisible by 2
|
||||||
for(unsigned int i = 0; i < sizeof(NVS_Block_t) / 2; i++)
|
for(unsigned int i = 0; i < sizeof(NVS_Block_t) / 2; i++)
|
||||||
{
|
{
|
||||||
NVS_ProgramHalfWord((uint16_t*)next_block + i,
|
if(!NVS_ProgramHalfWord((uint16_t*)next_block + i,
|
||||||
*((uint16_t*)&NVS_RAMData + i));
|
*((uint16_t*)&NVS_RAMData + i)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current_block != NULL)
|
if(current_block != NULL)
|
||||||
{
|
{
|
||||||
NVS_ProgramHalfWord((uint16_t*)¤t_block->marker, 0x0000);
|
if(!NVS_ProgramHalfWord((uint16_t*)¤t_block->marker, 0x0000))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NVS_FlashData = next_block;
|
NVS_FlashData = next_block;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,10 @@ extern NVS_Data_t *const NVS_Data;
|
||||||
// defaults were restored instead
|
// defaults were restored instead
|
||||||
bool NVS_Load(void);
|
bool NVS_Load(void);
|
||||||
|
|
||||||
// Stores the current contents of NVS_Data to flash. Pass `false` as a parameter
|
// Stores the current contents of NVS_Data to flash. Pass false as a parameter
|
||||||
// to skip saving unless it can be done without a flash page erase.
|
// to skip saving unless it can be done without a flash page erase. Returns true
|
||||||
void NVS_Save(bool erase_if_needed);
|
// if the operation succeeds and false if there is was an error or erasing was
|
||||||
|
// disallowed but would have been necessary.
|
||||||
|
bool NVS_Save(bool erase_if_needed);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue