2022-05-01 08:34 AM
Hello everyone!
I'm writing a STM32F446RE-based flight computer for a rocket. I want to use internal flash memory to keep some key data like base pressure or flight time. So if a power failure happens, the system can keep the base data.
These are the two main functions that I use:
void writeInternalFlash()
{
uint32_t Flash_Address = 0x08060000;
HAL_FLASH_Unlock();
FLASH_Erase_Sector(FLASH_SECTOR_7,VOLTAGE_RANGE_3);
HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE,Flash_Address,systemStartCount); // These values are uint8_t
HAL_Delay(1);
HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE,(Flash_Address+4),systemState);
HAL_Delay(1);
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,(Flash_Address+8),(uint32_t)previousFlightTime); // These values are float
HAL_Delay(1);
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,(Flash_Address+12),(uint32_t)basePressure);
HAL_Delay(1);
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,(Flash_Address+16),(uint32_t)offsetax);
HAL_Delay(1);
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,(Flash_Address+20),(uint32_t)offsetay);
HAL_Delay(1);
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,(Flash_Address+24),(uint32_t)offsetaz);
HAL_FLASH_Lock();
}
void readInternalFlash()
{
uint32_t Flash_Address = 0x08060000;
systemStartCount = *(uint8_t*) (Flash_Address);
if (systemStartCount >= 1) {
systemState = *(uint8_t*) (Flash_Address+4);
previousFlightTime = *(uint32_t*) (Flash_Address+8);
basePressure = *(uint32_t*) (Flash_Address+12);
offsetax = *(uint32_t*) (Flash_Address+16);
offsetay = *(uint32_t*) (Flash_Address+20);
offsetaz = *(uint32_t*) (Flash_Address+24);
}
}
These are the steps that I follow, basically:
1-) I check the *systemStartCount* when the system is started. Doing this with the flash read function.
2-) If the system is never started before; I measure the base pressure, accelerometer offsets, etc. And systemStartCount++;
3-) But if the *systemStartCount* is greater than one, I take the data from flash.
4-) When it comes to the while loop, I measure the sensor data, check some algorithm things, and write the data to SD and internal flash.
The errors that I come across:
* It really doesn't work quite well, like sometimes it keeps the data and sometimes not.
* I encountered a lot of debugging failures on CubeIDE. Target not found, flash error, etc.
* It's slowing the while loop. Loop have about 100ms interval but when I add the read flash thing it becomes about 1 second.
And also I have a timer interrupt to get flightTime data. This one can affect the flash?
What can be the wrong thing that I do?
Thanks!
2022-05-01 09:22 AM
FLASH_Erase_Sector isn't meant to be called directly. Use HAL_FLASHEx_Erase.
Check return values from all HAL routines to ensure they are HAL_OK. If not, enter some error handler so you can identify and fix the issue.
> I encountered a lot of debugging failures on CubeIDE. Target not found, flash error, etc.
Probably because you are messing with FLASH, which can make the debugger unresponsive.
> It's slowing the while loop. Loop have about 100ms interval but when I add the read flash thing it becomes about 1 second.
Flash reads shouldn't slow down your program. Erases will. Show your code. 100ms interval seems slow in itself.
FLASH reads (including code execution) will block while an erase is ongoing.
> if (systemStartCount >= 1) {
If flash is erased (0xff), this check will succeed and you will read bogus values.
2022-05-01 09:36 AM
The erase will be rather slow the sector is very large.
Consider perhaps erasing it once, and then writing your records incrementally across the memory space, retreiving the last one as being valid. You could walk the array of structures looking for the 0xFF erased pattern.
You shouldn't need to HAL_Delay() on the writes to flash.
Erase and Write operations will stall the MCU