Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.arch.embedded > #27822

Re: Serial EEPROM or Serial Flash?

From pozz <pozzugno@gmail.com>
Newsgroups comp.arch.embedded
Subject Re: Serial EEPROM or Serial Flash?
Date 2018-06-16 08:26 +0200
Organization A noiseless patient Spider
Message-ID <pg2aie$9mm$1@dont-email.me> (permalink)
References (5 earlier) <pg0i0n$nlr$1@dont-email.me> <pg0lfs$es1$1@dont-email.me> <0rSUC.342343$br4.37911@fx34.iad> <pg192b$ifa$1@dont-email.me> <81XUC.342353$br4.314833@fx34.iad>

Show all headers | View raw


Il 16/06/2018 00:25, Richard Damon ha scritto:
 > On 6/15/18 4:54 PM, pozz wrote:
 >> Il 15/06/2018 19:11, Richard Damon ha scritto:
 >>> I typically also do something like this. The data structure is a union
 >>> of the basic data structure with a preamble that includes (in very 
fixed
 >>> locations) a data structure version, checksum/crc, and if a versioning
 >>> store a timestamp/data generation number. A 'Magic Number' isn't often
 >>> needed unless it is a removable media as it will either be or not the
 >>> expected data, nothing else could be there (if the unit might have
 >>> different sorts of programs, then a piece of the data version would 
be a
 >>> program ID.)
 >>>
 >>> Often I will have TWO copies of the data packet.
 >>
 >> TWO copies in EEPROM or in RAM?
 >
 > As I described, normally both.

So you are so lucky that you have abundant RAM.


 >>> Often organized something like this:
 >>>
 >>> struct SystemParameters {
 >>>       // List of data parameters that need to be saved
 >>> } parms;
 >>>
 >>> union {
 >>>      uint8_t    raw_data[DATA_SIZE];
 >>>      struct {
 >>>          struct StandardHeader header;
 >>>          struct SystemParameters parms;
 >>>
 >>> } flash_parms;
 >>>
 >>> /* Check that sizeof(flash_parms) == DATA_SIZE, and that DATA_SIZE is
 >>> a multiple of the flash sector size */
 >>
 >> Do you need raw_data[] array only to set a well-known size to 
flash_parms?
 >> Do you alloc an entire (or a multiple of) flash sector in RAM?  Even if
 >> your params in flash take only 1/5 or 1/2 or 1/10 of a sector?
 >>
 >
 > One purpose of the raw_data array is to fix the size of the flash data.

Sincerely I can't understand why you need a fixed data size in RAM.
Suppose release 1.0 needs 2kB, but I'm so smart to provide a double 
space for new params in future releases. So I decide to use 4kB blocks 
*on the serial memory*.  Maybe this big space will never be used in all 
the future releases.

Why the hell I should load all 4kB datablock in RAM at startup?  IMHO it 
is sufficient to load only 2kB.

The only reason I see is to simplify the checksum calculation.
CRC must be calculated over the entire fixed-size 4kB block, otherwise 
how to know the datablock size if it could change from one release to 
the other?
However you can calc the checksum of 4kB block by reading small blocks 
multiple times (for example, 16 sections of 256 bytes).
After CRC validation passed, you can read in RAM *only* 2kB of data that 
the application 1.0 needs.

I know, maybe this process is slower, but it happens only at startup.
During writing of 4kB datablock, the checksum can be calculated on-the-fly.


 > Another purpose is to provide an easy way to access to pre-'zero' the 
data
 > Another purpose is to provide an easy way to compute the CRC/Checksum.
 >
 > Yes, the last two could be done via type casting via void* parameters.

Yes, indeed.


 >>> And a request to save the data will fill flash_parms with a 'NULL'
 >>> fill (0 or all ones, or whatever I want unused flash locations to be),
 >>
 >> Is it really necessary?  What happens if you don't care about unused
 >> bytes in flash_parms?  I think... nothing.
 >>
 >>
 >
 > Setting them to what an erased byte is can sometimes save you power and
 > time for programming. Having them be a know value can also make it
 > easier to read the contents, and
 >
 >>> then
 >>> copy the parms into flash_parms.parms, then fill in the header, and 
then
 >>> program the flash. Only the part that copys parms to flash_parms.parms
 >>> needs to be protected from other operation in the system updating the
 >>> main parms structure.
 >>>
 >>> The flash_parms structure can be further modified to be a union of the
 >>> current data structure of the SystemParameters structure and any
 >>> previous 'incompatible' version of it. (A version from just prior to
 >>> adding elements at the end doesn't need to be listed). This way at
 >>> startup I can read the values into that same structure, and if it was
 >>> old, parse to old version in flash_parms to get the new version in
 >>> parms, defaulting new parameters as needed.
 >>
 >> It seems difficult, if the changes from one version to the other are
 >> "important".
 >>
 >> struct {
 >>    uint16_t foo;
 >>    uint16_t bar;
 >>    uint16_t dummy;
 >> } SystemParameters;
 >>
 > should be struct SystemParameters { or typedef struct { you are defining
 > a type here, not a varaiable.

Yes, you're right.


 >> struct {
 >>    uint8_t foo;
 >>    uint8_t bar;
 >>    uint8_t dummy;
 >> } SystemParametersOld;
 >
 > ditto.

Of course.


 >> union {
 >>     uint8_t    raw_data[DATA_SIZE];
 >>     struct {
 >>         struct StandardHeader header;
 >>         struct SystemParameters parms;
 >>         struct SystemParametersOld parms_old;
 >> } flash_parms;
 >>
 > should be:
 >
 > union {
 >     uint8_t raw_data[DATA_SIZE];
 >     struct {
 >        struct StandardHeader header;
 >        union {
 >           struct SystemParameters parms_new;
 >           struct SystemParametersOld parms_old;
 >        } parms;
 >     } data;
 > } flash_parms;

Again you're right.


 > I actually don't use labels like Old but like Rev1, Rev2 etc.

Yes, it was only for the example here.


 > For some compilers you can use an 'anonymous union' an omit the parms
 > name here and in the code.
 >>
 >> for (uint8_t sector = 0; sector < SECTORS_NUM; sector++) {
 >>    uint16_t memory_address = OFFSET + sector * SECTOR_SIZE;
 >>    sermem_read(&flash_params, memory_address, sizeof(flash_params));
 >>    uint16_t chk_read = flash_parms.header.crc;
 >>    flash_parms.header.crc = 0xFFFF;
 >>    if (checksum_calc(&flash_parms, sizeof(flash_parms)) == chk_read) {
 >>      /* Datablock is valid */
 >>      if (flash_parms.header.counter > prev_counter) {
 >>        /* Datablock is newer */
 >>        prev_counter = flash_parms.header.counter;
 >>        if (flash_parms.header.version == FLASH_PARMS_OLD) {
 >>          /* How to convert old version in new version in place? */
 >>          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 >>        } else {
 >>          /* Ok, new version. No convertion is needed. */
 >>        }
 >>      }
 >>    }
 >> }
 >>
 >> As I wrote in the comment, how to convert old version to new version,
 >> using the same union in RAM?  Do I need another union?
 >
 > You do NOT convert 'in place', but in transfering from the flash_parms
 > block to the main usage block. Only the flash parm save/load routine has
 > access to flash_parms, and they are used just for save and load. If you
 > are tight on memory, it could be allocated on the heap only for load
 > and/or save and freed after, but you then you do need to be sure the
 > memory IS available when you need it. maybe something else turns off for
 > a bit when you need to do it.
 >
 > sample code:
 >
 > parms.foo = flash_parms.data.parms.parms_old.foo;
 > parms.bar = flash_parms.data.parms.parms_old.bar;
 > parms.dummy = flash_parms.data.parms.parms_old.dummy;
 >
 > and for the new code, you do
 >
 > parms = flash_parms.data.parms.parms_new;
 >
 > you can do a single line and let the compiler move it all.

Now I understand your process.  You have an image in RAM of datablock 
saved in serial memory *and* you have another "operative" datablock in 
RAM (maybe identical, maybe differently organized) that is actually used 
by the code.

I don't like to waste so much space in valuable RAM memory, maybe 
because I started with very limited 8-bit MCUs where the RAM was very small.

One good compromise could be to change datablock layout with great care, 
only:
* adding variables at the end
* nullifying no-more used parameters by simply changing their name with 
"_deprecated" (or "_old") suffix (in order to be sure the code will 
never use them again).
Immediately after an upgrade, the "_old" params will be converted in new 
params, if needed (for example if they change from uint8_t in uint16_t).

Back to comp.arch.embedded | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Serial EEPROM or Serial Flash? pozz <pozzugno@gmail.com> - 2018-06-14 12:20 +0200
  Re: Serial EEPROM or Serial Flash? David Brown <david.brown@hesbynett.no> - 2018-06-14 12:49 +0200
    Re: Serial EEPROM or Serial Flash? pozz <pozzugno@gmail.com> - 2018-06-15 09:38 +0200
      Re: Serial EEPROM or Serial Flash? Jack <jack4747@gmail.com> - 2018-06-15 00:54 -0700
        Re: Serial EEPROM or Serial Flash? Reinhardt Behm <rbehm@hushmail.com> - 2018-06-15 16:26 +0800
          Re: Serial EEPROM or Serial Flash? Jack <jack4747@gmail.com> - 2018-06-15 01:31 -0700
          Re: Serial EEPROM or Serial Flash? pozz <pozzugno@gmail.com> - 2018-06-15 10:50 +0200
            Re: Serial EEPROM or Serial Flash? Reinhardt Behm <rbehm@hushmail.com> - 2018-06-15 17:03 +0800
              Re: Serial EEPROM or Serial Flash? pozz <pozzugno@gmail.com> - 2018-06-15 14:59 +0200
                Re: Serial EEPROM or Serial Flash? David Brown <david.brown@hesbynett.no> - 2018-06-15 15:51 +0200
        Re: Serial EEPROM or Serial Flash? pozz <pozzugno@gmail.com> - 2018-06-15 10:47 +0200
          Re: Serial EEPROM or Serial Flash? Jack <jack4747@gmail.com> - 2018-06-15 02:20 -0700
            Re: Serial EEPROM or Serial Flash? Stef <stef33d@yahooI-N-V-A-L-I-D.com.invalid> - 2018-06-15 13:41 +0200
            Re: Serial EEPROM or Serial Flash? pozz <pozzugno@gmail.com> - 2018-06-15 15:01 +0200
      Re: Serial EEPROM or Serial Flash? David Brown <david.brown@hesbynett.no> - 2018-06-15 11:25 +0200
        Re: Serial EEPROM or Serial Flash? pozz <pozzugno@gmail.com> - 2018-06-15 15:10 +0200
          Re: Serial EEPROM or Serial Flash? Jack <jack4747@gmail.com> - 2018-06-15 06:51 -0700
          Re: Serial EEPROM or Serial Flash? David Brown <david.brown@hesbynett.no> - 2018-06-15 16:21 +0200
            Re: Serial EEPROM or Serial Flash? pozz <pozzugno@gmail.com> - 2018-06-15 17:20 +0200
              Re: Serial EEPROM or Serial Flash? Richard Damon <Richard@Damon-Family.org> - 2018-06-15 13:11 -0400
                Re: Serial EEPROM or Serial Flash? pozz <pozzugno@gmail.com> - 2018-06-15 22:54 +0200
                Re: Serial EEPROM or Serial Flash? Richard Damon <Richard@Damon-Family.org> - 2018-06-15 18:25 -0400
                Re: Serial EEPROM or Serial Flash? pozz <pozzugno@gmail.com> - 2018-06-16 08:26 +0200
                Re: Serial EEPROM or Serial Flash? Richard Damon <Richard@Damon-Family.org> - 2018-06-16 09:20 -0400
                Re: Serial EEPROM or Serial Flash? pozz <pozzugno@gmail.com> - 2018-06-16 19:38 +0200
                Re: Serial EEPROM or Serial Flash? Richard Damon <Richard@Damon-Family.org> - 2018-06-16 16:41 -0400
                Re: Serial EEPROM or Serial Flash? pozz <pozzugno@gmail.com> - 2018-06-16 23:05 +0200
              Re: Serial EEPROM or Serial Flash? David Brown <david.brown@hesbynett.no> - 2018-06-17 18:41 +0200
            Re: Serial EEPROM or Serial Flash? pozz <pozzugno@gmail.com> - 2018-06-16 20:12 +0200
              Re: Serial EEPROM or Serial Flash? David Brown <david.brown@hesbynett.no> - 2018-06-17 19:27 +0200
                Re: Serial EEPROM or Serial Flash? pozz <pozzugno@gmail.com> - 2018-06-19 17:40 +0200
              Re: Serial EEPROM or Serial Flash? Richard Damon <Richard@Damon-Family.org> - 2018-06-17 17:05 -0400
                Re: Serial EEPROM or Serial Flash? pozz <pozzugno@gmail.com> - 2018-06-19 17:44 +0200
                Re: Serial EEPROM or Serial Flash? Richard Damon <Richard@Damon-Family.org> - 2018-06-19 23:14 -0400
                Re: Serial EEPROM or Serial Flash? pozz <pozzugno@gmail.com> - 2018-06-20 11:03 +0200
                Re: Serial EEPROM or Serial Flash? Richard Damon <Richard@Damon-Family.org> - 2018-06-20 08:03 -0400
  Re: Serial EEPROM or Serial Flash? Michael Karas <mkaras@carousel-design.com> - 2018-06-23 09:43 -0700

csiph-web