2021-12-18 07:58 PM
I have the following trouble:
I am using a radio which needs a address and channel parameters, this is given in production phase. So I am planning to flash every board with this parameters modified each time before the board is flashed.
This parameters are loaded to the radio only the first time. Which means, after a reset the parameters should not be loaded.
So my idea is create 3 constant in code:
const uint8_t first_time = 0xff;
const uint8_t address = 0;
const uint8_t channel = 0;
My code at the beginning will ask for first time in order to recognize the 0xff value.
If(first_time == 0xff)
Then read parameters address and channel and load to radio.
Modify using half flash program the const first_time with 0 value, so the next time this process wont be execute.
The parameters address and channel will be changed by modifying the binary.
Is this viable?
2021-12-18 11:46 PM
This isnt good idea, but doable.
Compiler use your constants directly in code and when is used on more as one place then modifying binary will not work.
More better is use EEPROM emulation in free page on flash. Read appnote
And how you plan read parameters address and channel and load ...???
2021-12-19 07:22 AM
Not really viable.
The Flash sectors are typically large and need erasing to rewrite content. Typically one would journal things across the larger page, and find the most recent entry.
For configuration, perhaps a larger structure, where defaults are configured on first usage. Or pushed in via final production test, etc.
Partition the Flash memory to free up the smaller sectors for this type of usage. Establish a location for the configuration structure.
2021-12-19 07:23 AM
On most families this is viable. On some families flash can only be written once, even if it's 0xFFs.
2021-12-19 11:50 PM
> This parameters are loaded to the radio only the first time. Which means, after a reset the parameters should not be loaded.
You could find one bit in the option bytes and (ab)use that as an indicator for the first boot and reprogram it afterwards.
hth
KnarfB
2021-12-20 01:51 AM
As TDK wrote, "On some families flash can only be written once, even if it's 0xFFs"
I confirmed this on STM32H743. Defined a big enough array in flash data initialized with FFs, indeed rewriting it does not work.
No error is returned, the data just is not written.
So, your "patch" should be placed outside of the flash image.
For example, you can define in the linker script a NOLOAD section at very end of the flash data. Then add the following to your code:
__attribute__((section("flash_patch"), align(32)))
struct {
char init_done;
.............
.........
} config;
bool write_patch_once()
{
if (config.init_done == 0xFF) {
// program your data into the config struct
}
}
2021-12-20 03:10 AM
> On some families flash can only be written once, even if it's 0xFFs.
ECC? But then just leave the given area erased and unprogrammed (this boils down to ability to control content of .hex and any utility used for programming). And it also implies a write granularity. IMO it's documented in RM for every family where relevant. My copy of RM0433 says, for example,
This mechanism uses 10 ECC bits per 256-bit Flash word
so you'd need to set aside well-aligned 32 bytes for every one-time-programmable item (I assume here both address and channel could be written at once, so that's only one such area).
In other words, it does not mean it's not viable, just potentially cumbersome.
Btw. 'F0 and 'F3 have two halfwords available for the user in Option bytes (confusingly NOT the field called USER, but Data0 and Data1).
JW
2021-12-20 08:09 AM
I am using stm32f411. There is one opt byte with name not used. I am not sure if I can use it for my purpose.
2021-12-20 08:10 AM
This is a good idea. Probably i will try this.
2021-12-20 08:10 AM
Stm32f411 in option bytes for user just have a bit which is called not used. I am not sure if I can use it for my purpose.