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.