cancel
Showing results for 
Search instead for 
Did you mean: 

writing constants to flash

dmakhrov9
Associate II
Posted on February 22, 2013 at 11:48

Hi everybody, hi clive1!

in an older PIC design, I use to store calibration data in flash. Then, an update can be done with values received via serial. With PIC, the pages to work with are smaller. With STM32F4xx (as far as I understand), the entire sector of 16 kB must be erased first.

Anyway, how can I make sure that my data in flash occupies this sector only starting at the beginning of the sector, no program code is there, so I can erase it and rewrite with fresh values?

Actually, the same old question about mapping data to predefined addresses in flash.

Thanks

Dima
3 REPLIES 3
trevor23
Associate III
Posted on February 22, 2013 at 18:04

Hi Dima, what tool chain are you using?

I tend to put the config pages at the end of flash memory and then just reduce the flash size for program memory (e.g. for Rowley this is a flash memory map XML file). I then just use the flash read and write functions from the ST library to read and write config.

There are other ways that would allow you to read the constants directly with variable names but this is tool chain dependant.
Posted on February 22, 2013 at 18:40

Trevor, the problem with the F4 is the end pages are very big, and very slow (1-4 second !!)

Generally with the F4 I'd recommend a boot loader in the first 16K, calibration data in the second, and the APP starting at 0x08008000, or 0x08010000

// Suggest you park all your data in a simple structure, a final test app
// can fill out, or you can detect blank and fill with defaults.
typedef struct _EEPROM_CALIBRATION_DATA {
DWORD Signature; // Signature Word, non 0xFFFFFFFF
DWORD Version; // Handle version changes from the outset
// Content
BYTE MACAddr[6];
BYTE Serial[16];
DWORD Crc32; // CRC Checksum - Should be on a 4-byte boundary
} EEPROM_CALIBRATION_DATA;
EEPROM_CALIBRATION_DATA *CalData = (EEPROM_CALIBRATION_DATA *)0x08004000; // Say Second 16KB
#define CALSIG 0xDEADBEEF
void ReadCalibration(void)
{
if (CalData->Signature == 0xFFFFFFFF)
{
// Fill with default or prompt for data and rewrite
}
if ((CalData->Signature == CALSIG) && (CalData->Version == 1))
{
// Check integrity of Ver 1 structure
// Copy fields to internal parameters as required
}
}

You can also carve out spaces using scatter-files or linker scripts. Use #pragma or attributes to force section/segment usage, or absolute addresses.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dmakhrov9
Associate II
Posted on February 25, 2013 at 14:00

thanks you both for interest and help!

Keil seems to accept __attribute__((at(ADDR))) in the declaration.