Some stm8 have eeprom (also called data memory in the manual).
We could introduce the keyword __eprom, and such variables would be allocated in the eeprom.
Since the eeprom is in the normal address space, and can be written with the same instructions as RAM (however see write protection below) normal pointers could be used (or, if we have pointers to __eprom, casting them to normal ones would not require a warning).
Open issues:
- What about initialization? I suggest to initialize them in place in the image, so they are initialized when the program is first written onto the microcontroller
- AFAIR, free tools such as stm8flash do not yet support writing to the eeprom or not as well as writing to the flash
- eeprom meory has write protection that can be enabled and disabled by writing certain I/O ports. Upon reset it is enabled, and the eeprom cannot be written. Should there be compiler support for enabling and disabling the write protection?
Philipp
My suggestion,
eeprom can be global, static global, and local, all of them are placed in the eeprom, and there difference are their scopes.
the initialization of eeprom vars is like the global vars', explicitly in the image, not like the static global and local ones via assembly code.
cast between eeprom and normal pointers is forbidden.
offer functions, eeprom_enable() eeprom_disable(), let the user to have full control. But warnings can be delivered if some illegal opreations were detected, for example, writing an eeprom var immediately after calling eeprom_disable().
1,2,4 seem fine to me (initialization directly, not through the copy function we currently use for globals though).
I disagree with 3. Allowing pointers to eeprom to be cast to normal pointers makes eprom much more usable.
Philipp
Yep, forget 3. And I would also drop 4 part two: no warnings. This is the user's responsibility.
About 1: I'd say global, static global and static local, not auto local.
Now what about variables that should not be initialized at download time? Use the __at() method?
Sorry, I have confused with AVR's EEPROM, which is a seperated space than SRAM. Since eeprom and sram are access with the same mothod in stm8, their pointers' cast is reasonable.
Keep in mind that EEPROM start is not the same for every STM8 mcu. Give us a means to let linker know where EEPROM area starts (and how long it is). I'd prefer a #pragma, so EEPROM parameters can be derived from mcu type #define.
Don't confuse global, static, and volatile. "Global" always implies "static", as globally accessible variables must not change nor share place. EEPROM Variables must be treated as volatile, i.e., no auto initialization, every write must be executed, even if never read.
I'm afraid it's you who confuses global and static. Static has two meanings and it differs according to context. A global static is a variable defined outside any function and is visible only within its own source file; it has no external linkage. A local static otoh is visible only within its own function. Both have a fixed location.
You already can give every segment in the linker its own start address. The same would go for a new EEPROM segment. But none of these can be set with a pragma and thus I would not start to do so now. For comparison, you can't set RAM length or start with a pragma either and I'm sure it's different for many STM8.
Should have said "static storage duration". Still, "volatile" is what you need for variables to be initialized explicitely only.
Linker options, ok. There's ways to get a #define into linker option.
I have a different opinion about eeprom variables' initialization.
They should not be initialized, and kept unknown random values at startup.
For example, a program accepted a RSA private key via UART and stored it into EEPROM. Then the program used it for encription and should not changed it each time reset. Unless a different private key is specified.
If eeprom variables were initlialized each time reset, there could be no difference comparing to RAM variables.
Ben
I don't think anyone suggested to initialize eeprom variables at reset. It was suggested to initialize them at download. And if you don't want them initialized at all, I'd say don't provide an initializer. This means that uninitialized globals in eeprom are not automatically zeroed as the standard requires of normal globals, but only allocated.
Diff:
I would suggest eeprom variables are entirely uninitialized, only allocated in a eeprom section in the image.
Global variables are zeroed, this rule should apply to normal vars each time reset, but obviously need not for eeprom vars.
So eeprom variables are not allowed to have an initializer then, right? Or will they be rewritten at every reset when they do have an initializer?
i suggest no initialization at all.
With no initialization at all, how can my application decide after reset, whether EEPROM keeps valid data or just data garbage?
I suggest it is up to the user to decide data consistency. For example, a RSA private key should has a particular format.
Implementing this might not be as easy as it seemed at first. It will definitely need a lot of testing on various hardware. A simple google search will find many cases of people having troubles using the eeprom. There is a nasty erratum that can result in system lockup when doing DMA during an eeprom write in some stm8 microcontrollers.
Valentin's stm8flash currently only supports writing the eeprom using stlinkv2, not the stlink.
Philipp