Ich wollte die Redundanz im Eeprom überprüfen und die Daten auf aufgetretene oder nicht aufgetretene Fehler überprüfen, und am Ende las ich den CRC-Code. Ich fand es nützlich, habe aber einige Zweifel, die geklärt werden müssen.
Mein Ziel ist es, die Speicheradressen 0-15k des EEPROM zu überprüfen und die Prüfsumme im Speicher zu speichern und dasselbe für die nächsten 15k-30k Adresspositionen zu tun. Die beiden Adressorte speichern die gleichen Daten und es wird so gemacht, dass der EEPROM-Speicher verwendet wird.
Nun, als ich anfing, die Dokumente zu lesen. Am Ende habe ich einen nützlichen Code:
unsigned int crc32(unsigned char *message) {
int i, j;
unsigned int byte, crc;
i = 0;
crc = 0xFFFFFFFF;
while (message[i] != 0) {
byte = message[i]; // Get next byte.
byte = reverse(byte); // 32-bit reversal.
for (j = 0; j <= 7; j++) { // Do eight times.
if ((int)(crc ^ byte) < 0)
crc = (crc << 1) ^ 0x04C11DB7;
else crc = crc << 1;
byte = byte << 1; // Ready next msg bit.
}
i = i + 1;
}
return reverse(~crc);
}
Hier wartet die ' Nachricht ' nach meinem Verständnis auf Bytes und setzt die CRC-Berechnung fort, bis das Zeichen nicht empfangen wird. Wenn ich die beiden Blöcke des EEPROM-Speichers wie gesagt überprüfen wollte. Wie kann ich den Eeprom-Speicher an die Nachrichtenvariable anhängen?
Nun, mein weiterer * Zweifel ist, ob Eeprom-Lesen eine Grenze beim Lesen von Leseadressen von 0-15k am Stück hat, eher wie Eeprom-Schreiben * Ich brauche Ihre Eingaben, um diesen Versuch nützlich und lohnend zu machen. Grüße
Während der von PeterJ vorgeschlagene Ansatz in Ordnung ist, ist es sauberer, die "Datenschicht" -Logik (EEPROM-Zugriff) von der CRC-Routine zu entkoppeln.
Dieser CRC-32 ist universell einsetzbar, er ist nicht an programmspezifisches Verhalten gebunden:
// CCITT CRC-32 (Autodin II) polynomial
uint32_t CalcCRC32(uint32_t crc, uint8_t *buffer, uint16_t length) {
while(length--) {
crc = crc ^ *buffer++;
for (uint8_t j=0; j < 8; j++) {
if (crc & 1)
crc = (crc >> 1) ^ 0xEDB88320;
else
crc = crc >> 1;
}
}
return crc;
}
Dann füttern Sie einfach Datenblöcke in die CRC-Funktion, wie Sie es für richtig halten und wie es Ihre Anwendung erfordert.
Dieses Anwendungsbeispiel ist nur niedergeschrieben. Es verwendet die fiktive Funktion eeprom_read(), die einen Datenblock aus dem EEPROM liest. Wir beginnen bei der EEPROM-Adresse 0.
const uint8_t BLOCKLENGTH = 128;
uint32_t crc32;
uint8_t buffer[BLOCKLENGTH]; // temporary data buffer
crc32 = 0xFFFFFFFF; // initial CRC value
for (uint16_t i=0; i < NUMBEROFBLOCKS; i++) {
eeprom_read(BLOCKLENGTH * i, buffer, BLOCKLENGTH); // read block number i from EEPROM into buffer
crc32 = CalcCRC32(crc32, buffer, BLOCKLENGTH); // update CRC
}
// crc32 is your final CRC here
Beachten Sie, dass NUMBEROFBLOCKS nur ein Platzhalter ist. Ich hoffe, du verstehst die Idee.
i
, warum nicht einfach while(length--)
anstelle der ersten for-Schleife?Wenn Sie einen Mikrocontroller mit begrenztem RAM verwenden, möchten Sie wahrscheinlich nicht versuchen, einen 16k-Datenblock in den Speicher zu laden. Wenn Sie den obigen Code neu anordnen, können Sie die folgende (ungetestete) Funktion ausprobieren, die das EEPROM Byte für Byte innerhalb der Schleife liest. Die Funktion read_eeprom
habe ich mir ausgedacht, also müssen Sie die passende Funktion für Ihren Compiler finden.
#include <stdint.h>
uint32_t crc32(uint16_t start_address, uint16_t number_of_bytes) {
uint8_t j;
uint32_t crc, byte;
crc = 0xFFFFFFFF;
while (number_of_bytes--) {
byte = read_eeprom(start_address++);
byte = reverse(byte); // 32-bit reversal.
for (j = 0; j <= 7; j++) { // Do eight times.
if ((int32_t)(crc ^ byte) < 0)
crc = (crc << 1) ^ 0x04C11DB7;
else
crc = crc << 1;
byte = byte << 1; // Ready next msg bit.
}
}
return reverse(~crc);
}
Ich habe auch Ihre Variablendeklarationen ersetzt, um stdint.h zu verwenden - es ist wahrscheinlich gut, darüber zu lesen und es zu verwenden. Bei einigen eingebetteten Compilern ist ein unsigned int
beispielsweise nicht 32 Bit, sodass der Code dadurch portabler wird.
Benutzer30985
message
. Aber Sie möchten den CRC von (fast) Ihrem gesamten EEPROM, also ersetzen Sie einfach diewhile
Klausel durch eine Schleife über (den größten Teil) Ihres EEPROM-Adressraums undmessage[i]
durch ein Lesen des i-ten 32-Bit-Wortes Ihres EEPROM. Im Gegensatz zum Schreiben wird es beim Lesen nicht beeinträchtigt. Denken Sie daran, den Teil des EEPROM auszuschließen, in dem Sie die CRC-Prüfsumme zum Vergleich speichern.