Shop OBEX P1 Docs P2 Docs Learn Events
Stupid C programmer Questions - EEPROM variables — Parallax Forums

Stupid C programmer Questions - EEPROM variables

mindrobotsmindrobots Posts: 6,506
edited 2011-12-12 20:05 in Propeller 1
Sorry, I've been getting slammed at work and haven;t had much time to play. I did come up with a couple questions tonight while pondering things. As always, thsi could all just be blamed on my lack of C programming knowledge.

1) How would one go about creating a non-volatile variable in EEPROM that can survive across a reset/power-off. In SPIN, this is relatively easy, grab your EEPROM I2C Object, agree with yourself on a safe place above the 32K line to store your non-volatile data and have at it. So, how can this be done in C and where are the safe places in the EEPROM for non-volatile variables in the various memory models?

2) Is there any indication the program can use to determine if it is being executed for the first time after a load versus a reset? I could see where this could be a useful feature if it didn't exist.

Thanks for being tolerant!

Comments

  • ersmithersmith Posts: 6,099
    edited 2011-12-11 04:08
    mindrobots wrote: »
    1) How would one go about creating a non-volatile variable in EEPROM that can survive across a reset/power-off. In SPIN, this is relatively easy, grab your EEPROM I2C Object, agree with yourself on a safe place above the 32K line to store your non-volatile data and have at it. So, how can this be done in C and where are the safe places in the EEPROM for non-volatile variables in the various memory models?
    I guess you could use the same method, as long as you weren't using the EEPROM form of XMM or XMMC. Others are a bit more familiar with the XMM and XMMC drivers so I'll defer to them :-) but AFAIK it should work.
    2) Is there any indication the program can use to determine if it is being executed for the first time after a load versus a reset? I could see where this could be a useful feature if it didn't exist.
    Hmmm, good question. I can't think of any method off-hand, but perhaps the loader leaves some traces of itself behind. Perhaps David Betz (the author of the loader) will chime in here... he might have an idea.

    Eric
  • ReinhardReinhard Posts: 489
    edited 2011-12-11 04:40
    mindrobots wrote: »
    2) Is there any indication the program can use to determine if it is being executed for the first time after a load versus a reset? I could see where this could be a useful feature if it didn't exist.

    Thanks for being tolerant!

    Hi mindrobots,
    the first idea I have is to reserve 2 variables in non volatile memory

    for example the vars have the value 0xAA and the complement 0x55

    if program starts this 2 vars are read, and if the value and the complement do not match
    the probability to run first time is high and the program write it.

    else ( the vars match ) you have an indicator for the program, it is not first runtime.

    Reinhard

    Edit: As I do a closer look at your first question, I guess you have this solution in mind .
  • mindrobotsmindrobots Posts: 6,506
    edited 2011-12-11 07:05
    To my first point, I was thinking there would be something like an _EEPROM or _PERSISTENT attribute type that would let the compiler set the space in a safe, non-volatile space. Using the EEPROM library is fine if we have addresses for safe space in each memory model. Otherwise, we could poke the persistent value back into the binary image in the EEPROM but that seems like too much to know about the structure of the final binary image for a mere programmer to know.

    For #2, I need to do more testing but last night it seemed uninitialized variables were set to 0 for me after each reset. I wasn't expecting persistence but thought the 0 was a nice touch.

    These seem to be a couple often done embedded controller features that should be easy to do for a programmer.
  • ersmithersmith Posts: 6,099
    edited 2011-12-11 07:51
    mindrobots wrote: »
    For #2, I need to do more testing but last night it seemed uninitialized variables were set to 0 for me after each reset. I wasn't expecting persistence but thought the 0 was a nice touch.
    Uninitialized variables in RAM are set to 0 before execution. That actually is pretty common in the C world (I can't recall if it's required by the standard, but it's so widely implemented that it may as well be).

    Persistent variables in EEPROM are a bit beyond the scope of the compiler, though. I think a library is the right way to do this, since different boards will have different layouts of non-volatile memory.

    Eric
  • TorTor Posts: 2,010
    edited 2011-12-11 13:24
    ersmith wrote: »
    Uninitialized variables in RAM are set to 0 before execution. That actually is pretty common in the C world (I can't recall if it's required by the standard, but it's so widely implemented that it may as well be).
    They're only set to 0 if declared 'static' (at compile time). But non-static variables are not supposed to be set at all. So, in C, static variables: Always initialised to 0, local, non-static variables: Never initialised.
    (Global, non-static variables are also initialised to 0, but global variables are Bad.)

    -Tor
  • jazzedjazzed Posts: 11,803
    edited 2011-12-11 14:21
    mindrobots wrote: »
    To my first point, I was thinking there would be something like an _EEPROM or _PERSISTENT attribute type that would let the compiler set the space in a safe, non-volatile space. Using the EEPROM library is fine if we have addresses for safe space in each memory model. Otherwise, we could poke the persistent value back into the binary image in the EEPROM but that seems like too much to know about the structure of the final binary image for a mere programmer to know.

    Initialized global variable data will be saved to EEPROM when you program with propeller-load -e. Of course, that's write once and read many (read on each boot-up). An I2C driver will be necessary to modify EEPROM. It is not clear whether we can rely on the address of a global variable for modifying EEPROM variables, but it should work for LMM programs.
  • David BetzDavid Betz Posts: 14,516
    edited 2011-12-12 11:32
    mindrobots wrote: »
    Sorry, I've been getting slammed at work and haven;t had much time to play. I did come up with a couple questions tonight while pondering things. As always, thsi could all just be blamed on my lack of C programming knowledge.

    1) How would one go about creating a non-volatile variable in EEPROM that can survive across a reset/power-off. In SPIN, this is relatively easy, grab your EEPROM I2C Object, agree with yourself on a safe place above the 32K line to store your non-volatile data and have at it. So, how can this be done in C and where are the safe places in the EEPROM for non-volatile variables in the various memory models?

    2) Is there any indication the program can use to determine if it is being executed for the first time after a load versus a reset? I could see where this could be a useful feature if it didn't exist.

    Thanks for being tolerant!
    We haven't setup a way to determine whether a program was started through a serial download vs. being loaded from EEPROM. Is there a reason you might want to know that?
  • mindrobotsmindrobots Posts: 6,506
    edited 2011-12-12 18:49
    David,

    I hadn't a specific application in mind. I thought the application code may need/want different initialization routines depending if it was an initial start up or a start up after a reset. If variables can be updated in EEPROM, then a zero value for a reset counter could be used as a flag for initial serial load and a non-zero value wold indicate an EEPROM reload. Success with solving #1 through EEPROM R/W libraries and being able to find variables in EEPROM from a running would solve the load source indicator of #2 for the most part.

    As soon as I get some free time, I'll start working on the EEPROM libraries. (and by way of that, an i2C library, too!)

    Thanks, everyone for all the info and guidance.
  • David BetzDavid Betz Posts: 14,516
    edited 2011-12-12 19:20
    mindrobots wrote: »
    David,

    I hadn't a specific application in mind. I thought the application code may need/want different initialization routines depending if it was an initial start up or a start up after a reset. If variables can be updated in EEPROM, then a zero value for a reset counter could be used as a flag for initial serial load and a non-zero value wold indicate an EEPROM reload. Success with solving #1 through EEPROM R/W libraries and being able to find variables in EEPROM from a running would solve the load source indicator of #2 for the most part.

    As soon as I get some free time, I'll start working on the EEPROM libraries. (and by way of that, an i2C library, too!)

    Thanks, everyone for all the info and guidance.
    We currently only support code in EEPROM not data. It would be relatively easy to change that to support data in EEPROM but I would be worried about both performance and also wear on the EEPROM. It would certainly be possible to have most data be placed in hub memory but a few state variables placed in EEPROM with an appropriate cache driver. I'll look into how difficult it would be to provide that sort of support.
  • mindrobotsmindrobots Posts: 6,506
    edited 2011-12-12 20:00
    David,

    I haven't had a need for EEPROM variables in any applications but it does seem to be a forum question that comes up every month or so. Probably something to take to the PropGCC committee to discuss the need and priority. There are more important things to work on but this is something we've been telling folks how to do in SPIN (and is doable in other languages also) and can be done by other processors.

    I wouldn't think you'd want the runtime variable copies in EEPROM for the reasons you've mentioned but a way to set aside a reserved area for non-volatile user space if needed. The program could just update this space as the dynamic variables changed or a save event occurred. Maybe something in propeller-load.cfg where a space could be set aside if needed in a special definition block? The programmer could set up their own definition block as needed. I don't know, I'm just winging it now.
  • David BetzDavid Betz Posts: 14,516
    edited 2011-12-12 20:05
    If you're writing a program that is intended to run from hub memory it would be easy to use one of the existing EEPROM drivers with a C interface to write data to the high end of a >32k eeprom. It becomes a little more complex if you want to use our eeprom cache driver to run code from eeprom and also want to store persistent data above the code. This will require coordination with the eeprom cache code.
Sign In or Register to comment.