Crc16 on power failure

Discussion in 'C Programming' started by maxthebaz@libero.it, Jan 18, 2007.

  1. Guest

    Our machines have this requirement: if power failure occurs, many
    important variables are to be resumed from where they were interrupted
    after the machine is restarted (power on in this case). In other words,
    the basic idea is to keep a snapshot of the state machine before it is
    interrupted.
    The board is provided with:
    - a 32-bit H8S/2633 Hitachi microprocessor;
    - a battery-backed memory (BBM), where these variables are stored; BBM
    area involved is about 16 Kbytes (the whole BBM has a 128KB capability)
    - 2 big capacitors; if a blackout occurs, they guarantee a 400 msec
    (Tsave) extra power supply time.
    When power supply is going to fall down, a function is invoked by power
    failure NMI. This function, within Tsave time, has to perform the
    following main operations:
    - it calculates CRC16 checksum for the BBM variable area (for our 16KB,
    this requires a long time: 90 msec!).
    - it saves the CRC16 checksum in BBM (of course, in a different BBM
    address from the previous variable area).
    Then, when machine is re-started, a new checksum of the interested BBM
    area is performed: the result is compared with the previous stored one.
    If they differ, a BBM corruption is assumed (error detection).

    Now I am seeking a better solution: the target is to reduce the 2 big
    capacitors, i.e. to reduce Tsave time. The reason is to save space (and
    money) by reducing them. I'm looking for a way to anticipate CRC16
    calculation in a safe and fast way, before power failure.
    One solution could be a CRC16 computation invoked at every time a BBM
    variable is changed, but this operation needs 90 msec (as I wrote
    before), while main loop now is about 10 msec. That's why this solution
    is not applicable at all.

    Note: because of our application, I can't consider solutions like
    saving every second, i.e. loosing "only" last second changes.

    Thank you very much.
     
    , Jan 18, 2007
    #1
    1. Advertising

  2. Ben Pfaff Guest

    "" <> writes:

    > Our machines have this requirement: if power failure occurs, many
    > important variables are to be resumed from where they were interrupted
    > after the machine is restarted (power on in this case). In other words,
    > the basic idea is to keep a snapshot of the state machine before it is
    > interrupted.


    You didn't state a question about the C programming language
    anywhere, so I'm going to suggest that further followups should
    go only to comp.arch.embedded.
    --
    Here's a tip: null pointers don't have to be *dull* pointers!
     
    Ben Pfaff, Jan 18, 2007
    #2
    1. Advertising

  3. Didi Guest

    > - it calculates CRC16 checksum for the BBM variable area (for our 16KB,
    > this requires a long time: 90 msec!).


    I don't know the CPU you are using, but apr. 10 uS per 16 bits sounds
    like
    there may be room for improvement just of the code (using that now
    widely
    popular algorithm which includes table lookup etc., you can find it in
    the one of the PPP related RFC-s, I _think_ it was described in
    sufficient detail either in rfc1661 or in rfc1662. (OK, just checked,
    it
    really is inside RFC1662, not bad for over 2 years not having to deal
    with it :).
    How fast is the CPU you are using (I mean clock frequency)?

    Another possibility might be to split the 16K in several pieces and
    calculate the CRC only for the piece which has been modified, if the
    nature of the data and the application would allow that.

    Dimiter

    ------------------------------------------------------
    Dimiter Popoff Transgalactic Instruments

    http://www.tgi-sci.com
    ------------------------------------------------------

    wrote:
    > Our machines have this requirement: if power failure occurs, many
    > important variables are to be resumed from where they were interrupted
    > after the machine is restarted (power on in this case). In other words,
    > the basic idea is to keep a snapshot of the state machine before it is
    > interrupted.
    > The board is provided with:
    > - a 32-bit H8S/2633 Hitachi microprocessor;
    > - a battery-backed memory (BBM), where these variables are stored; BBM
    > area involved is about 16 Kbytes (the whole BBM has a 128KB capability)
    > - 2 big capacitors; if a blackout occurs, they guarantee a 400 msec
    > (Tsave) extra power supply time.
    > When power supply is going to fall down, a function is invoked by power
    > failure NMI. This function, within Tsave time, has to perform the
    > following main operations:
    > - it calculates CRC16 checksum for the BBM variable area (for our 16KB,
    > this requires a long time: 90 msec!).
    > - it saves the CRC16 checksum in BBM (of course, in a different BBM
    > address from the previous variable area).
    > Then, when machine is re-started, a new checksum of the interested BBM
    > area is performed: the result is compared with the previous stored one.
    > If they differ, a BBM corruption is assumed (error detection).
    >
    > Now I am seeking a better solution: the target is to reduce the 2 big
    > capacitors, i.e. to reduce Tsave time. The reason is to save space (and
    > money) by reducing them. I'm looking for a way to anticipate CRC16
    > calculation in a safe and fast way, before power failure.
    > One solution could be a CRC16 computation invoked at every time a BBM
    > variable is changed, but this operation needs 90 msec (as I wrote
    > before), while main loop now is about 10 msec. That's why this solution
    > is not applicable at all.
    >
    > Note: because of our application, I can't consider solutions like
    > saving every second, i.e. loosing "only" last second changes.
    >
    > Thank you very much.
     
    Didi, Jan 18, 2007
    #3
  4. You need to use a better implementation of the CRC16. Even performing the
    calculation one bit at a time you could probably do better than 90ms.

    <> wrote in message
    news:...
    > Our machines have this requirement: if power failure occurs, many
    > important variables are to be resumed from where they were interrupted
    > after the machine is restarted (power on in this case). In other words,
    > the basic idea is to keep a snapshot of the state machine before it is
    > interrupted.
    > The board is provided with:
    > - a 32-bit H8S/2633 Hitachi microprocessor;
    > - a battery-backed memory (BBM), where these variables are stored; BBM
    > area involved is about 16 Kbytes (the whole BBM has a 128KB capability)
    > - 2 big capacitors; if a blackout occurs, they guarantee a 400 msec
    > (Tsave) extra power supply time.
    > When power supply is going to fall down, a function is invoked by power
    > failure NMI. This function, within Tsave time, has to perform the
    > following main operations:
    > - it calculates CRC16 checksum for the BBM variable area (for our 16KB,
    > this requires a long time: 90 msec!).
    > - it saves the CRC16 checksum in BBM (of course, in a different BBM
    > address from the previous variable area).
    > Then, when machine is re-started, a new checksum of the interested BBM
    > area is performed: the result is compared with the previous stored one.
    > If they differ, a BBM corruption is assumed (error detection).
    >
    > Now I am seeking a better solution: the target is to reduce the 2 big
    > capacitors, i.e. to reduce Tsave time. The reason is to save space (and
    > money) by reducing them. I'm looking for a way to anticipate CRC16
    > calculation in a safe and fast way, before power failure.
    > One solution could be a CRC16 computation invoked at every time a BBM
    > variable is changed, but this operation needs 90 msec (as I wrote
    > before), while main loop now is about 10 msec. That's why this solution
    > is not applicable at all.
    >
    > Note: because of our application, I can't consider solutions like
    > saving every second, i.e. loosing "only" last second changes.
    >
    > Thank you very much.
    >
     
    Colin Hankins, Jan 18, 2007
    #4
  5. <> wrote in message
    news:...
    > Our machines have this requirement: if power failure occurs, many
    > important variables are to be resumed from where they were interrupted
    > after the machine is restarted (power on in this case). In other words,
    > the basic idea is to keep a snapshot of the state machine before it is
    > interrupted.
    > The board is provided with:


    Snip.

    Please redirect this question to:

    comp.arch.embedded

    --
    David T. Ashley ()
    http://www.e3ft.com (Consulting Home Page)
    http://www.dtashley.com (Personal Home Page)
    http://gpl.e3ft.com (GPL Publications and Projects)
     
    David T. Ashley, Jan 18, 2007
    #5
  6. hagman Guest

    schrieb:

    > Our machines have this requirement: if power failure occurs, many
    > important variables are to be resumed from where they were interrupted
    > after the machine is restarted (power on in this case). In other words,
    > the basic idea is to keep a snapshot of the state machine before it is
    > interrupted.
    > The board is provided with:
    > - a 32-bit H8S/2633 Hitachi microprocessor;
    > - a battery-backed memory (BBM), where these variables are stored; BBM
    > area involved is about 16 Kbytes (the whole BBM has a 128KB capability)
    > - 2 big capacitors; if a blackout occurs, they guarantee a 400 msec
    > (Tsave) extra power supply time.


    I assume that some higher-level transaction/rollback system is
    implemented as well
    in your data structure?

    > When power supply is going to fall down, a function is invoked by power
    > failure NMI. This function, within Tsave time, has to perform the
    > following main operations:
    > - it calculates CRC16 checksum for the BBM variable area (for our 16KB,
    > this requires a long time: 90 msec!).


    There are specialized CRC chips. Might this help?
    I assume that BBM is somewhat slow in access.
    How much of the 90ms is pure reading time?

    > - it saves the CRC16 checksum in BBM (of course, in a different BBM
    > address from the previous variable area).
    > Then, when machine is re-started, a new checksum of the interested BBM
    > area is performed: the result is compared with the previous stored one.
    > If they differ, a BBM corruption is assumed (error detection).
    >
    > Now I am seeking a better solution: the target is to reduce the 2 big
    > capacitors, i.e. to reduce Tsave time. The reason is to save space (and
    > money) by reducing them. I'm looking for a way to anticipate CRC16
    > calculation in a safe and fast way, before power failure.
    > One solution could be a CRC16 computation invoked at every time a BBM
    > variable is changed, but this operation needs 90 msec (as I wrote
    > before), while main loop now is about 10 msec. That's why this solution
    > is not applicable at all.


    CRC should be possible incremental.
    If you change Byte[k] from OLD to NEW, the CRC should change by
    TABLE8[k,OLD] ^ TABLE8[k,NEW]
    This requires 256*n words of precalculated tables for n bytes of
    memory,
    so here it's 8MB, which might be too much.

    Here's a slower but less memory demanding idea of mine (n words, i.e.
    32KB):

    // the battery-backed-memory.
    // 1) byte array for the main variables
    byte BBMbyte[BBM_ByteCount];
    // 2) the saved checksum
    uint16 BBM_CRC;

    // precalculated table of influence of lowest bit at index
    const uint16 TABLE1[BBM_ByteCount] = { .... };

    // for protection against NMI during SetBBMByte
    int global_index;
    uint16 global_CRC;
    byte global_NEW;
    bool global_dirty;

    void SetBBMByte(int index, byte NEW)
    {
    byte OLD = BBMbyte[index];
    if (OLD==NEW) return;

    unsigned int crc = global_CRC;

    int pat = TABLE1[index];
    int changes = NEW ^ OLD;
    for (int i=0; i<8; ++i)
    if (changes & (1<<i))
    crc ^= pat<<i;

    for (int i=7; i>=0; --i)
    if (crc & (1<<(16+i)))
    crc ^= CRC16POLY << (i+1);

    // poor man's critical section, prevent optimizer from changing
    anything here
    global_index = index;
    global_NEW = NEW;
    global_dirty = true;
    global_CRC = crc;
    BBMbyte[index] = NEW;
    BBM_CRC = crc;
    global_dirty = false;
    }

    void NMIfunc()
    {
    if (global_dirty) {
    // NMI during critical section of SetBBMByte
    if (global_CRC != BBM_CRC) {
    // NMI after "global_CRC = crc", before "BBM_CRC = crc"
    BBMbyte[global_index] = global_NEW;
    BBM_CRC = global_crc;
    global_dirty = false;
    } //else SetBBMbyte was totally ignored or completed
    }

    // additional transaction protection code might be put here

    halt_cpu(); // must not return to running process!!
    }



    You can adapt this to handle words instead of bytes.
    However, with the variable names as above, you must have
    sizeof(crc) >= sizeof(NEW) +16/sizeof(char)
    where the 16 is the 16 from CRC16.

    SetBBMByte is much slower than a simple memory access,
    but you may halt the cpu almost immediately upon NMI.

    >
    > Note: because of our application, I can't consider solutions like
    > saving every second, i.e. loosing "only" last second changes.


    A) What is the cost of loosing last second changes?
    B) What is the cost of the capacitors?
    It sounds like A is much bigger than B, hence keep the capacitors. ;)


    > Thank you very much.
     
    hagman, Jan 18, 2007
    #6
  7. Arlet Guest

    wrote:

    > Our machines have this requirement: if power failure occurs, many
    > important variables are to be resumed from where they were interrupted
    > after the machine is restarted (power on in this case). In other words,
    > the basic idea is to keep a snapshot of the state machine before it is
    > interrupted.
    > The board is provided with:
    > - a 32-bit H8S/2633 Hitachi microprocessor;
    > - a battery-backed memory (BBM), where these variables are stored; BBM
    > area involved is about 16 Kbytes (the whole BBM has a 128KB capability)
    > - 2 big capacitors; if a blackout occurs, they guarantee a 400 msec
    > (Tsave) extra power supply time.
    > When power supply is going to fall down, a function is invoked by power
    > failure NMI. This function, within Tsave time, has to perform the
    > following main operations:
    > - it calculates CRC16 checksum for the BBM variable area (for our 16KB,
    > this requires a long time: 90 msec!).
    > - it saves the CRC16 checksum in BBM (of course, in a different BBM
    > address from the previous variable area).
    > Then, when machine is re-started, a new checksum of the interested BBM
    > area is performed: the result is compared with the previous stored one.
    > If they differ, a BBM corruption is assumed (error detection).
    >
    > Now I am seeking a better solution: the target is to reduce the 2 big
    > capacitors, i.e. to reduce Tsave time. The reason is to save space (and
    > money) by reducing them. I'm looking for a way to anticipate CRC16
    > calculation in a safe and fast way, before power failure.
    > One solution could be a CRC16 computation invoked at every time a BBM
    > variable is changed, but this operation needs 90 msec (as I wrote
    > before), while main loop now is about 10 msec. That's why this solution
    > is not applicable at all.


    You could divide your total variable area in a number of shorter
    blocks, say 512 bytes, or 1KB each, and perform a CRC16 only on the
    block where a variable has been updated. Of course, this won't work if
    you frequently change many variables throughout the entire memory.

    It does have an added advantage of better protection against errors,
    and in the case a CRC error is detected in a block you may still be
    able to use the other blocks.
     
    Arlet, Jan 19, 2007
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ALuPin

    USB CRC5 / CRC16

    ALuPin, Jan 8, 2004, in forum: VHDL
    Replies:
    7
    Views:
    15,003
    OutputLogic
    May 22, 2009
  2. CRC16 CCITT

    , Feb 26, 2004, in forum: Java
    Replies:
    2
    Views:
    9,762
    Marco Schmidt
    Feb 26, 2004
  3. Tumzadoc

    CRC16 not the same

    Tumzadoc, Jan 21, 2005, in forum: C++
    Replies:
    5
    Views:
    681
    Tumzadoc
    Jan 25, 2005
  4. Tuvas

    CRC16

    Tuvas, Sep 23, 2005, in forum: Python
    Replies:
    4
    Views:
    10,267
    Tuvas
    Sep 26, 2005
  5. Replies:
    8
    Views:
    380
    Mark Dickinson
    Apr 17, 2008
Loading...

Share This Page