Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Crc16 on power failure

Reply
Thread Tools

Crc16 on power failure

 
 
maxthebaz@libero.it
Guest
Posts: n/a
 
      01-18-2007
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.

 
Reply With Quote
 
 
 
 
Ben Pfaff
Guest
Posts: n/a
 
      01-18-2007
"" <> 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!
 
Reply With Quote
 
 
 
 
Didi
Guest
Posts: n/a
 
      01-18-2007
> - 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.


 
Reply With Quote
 
Colin Hankins
Guest
Posts: n/a
 
      01-18-2007
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: ups.com...
> 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.
>



 
Reply With Quote
 
David T. Ashley
Guest
Posts: n/a
 
      01-18-2007
<> wrote in message
news: ups.com...
> 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)


 
Reply With Quote
 
hagman
Guest
Posts: n/a
 
      01-18-2007
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.


 
Reply With Quote
 
Arlet
Guest
Posts: n/a
 
      01-19-2007

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.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
USB CRC5 / CRC16 ALuPin VHDL 7 05-22-2009 12:06 AM
CRC16 eeh C Programming 2 01-12-2006 07:05 AM
CRC16 Tuvas Python 4 09-26-2005 05:36 PM
CRC16 not the same Tumzadoc C++ 5 01-25-2005 08:22 AM
CRC16 CCITT nospam@nospam.com Java 2 02-26-2004 07:12 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57