Forum: Compiler & IDEs crc_ccitt_update


von Stefan (Gast)


Lesenswert?

Hallo,

ich stelle mich schon länger die Frage wie die Ergebnisse der 
crc_ccitt_update Funktion zustande kommen.

Zum Testen nehme ich immer folgendes Datenpaket:
1
  uint8_t data[] = {1, 2, 3, 4, 5, 6, 7, 8};

Lasse ich dieses Paket von der o.g. Funktion berechnen, kommt als 
Ergebniss 0x922b heraus (Startwert 0xFFFF). Lasse ich das gleiche 
Datenpaket von div. Hexeditoren oder CRC Rechnern berechnen, geben diese 
(übereinstimmend) 0x4792 aus. Z.b. hier:

http://www.lammertbies.nl/comm/info/crc-calculation.html?crc=0102030405060708&method=hex

Warum unterscheiden sich die Ergebnisse ?
Desweiteren habe ich irgendwo mal gelesen, dass die CRC 0x0000 ergibt, 
wenn man die CRC eines Blockes hinten mit anhängt. So ergibt das 
Datenpaket
1
  uint8_t data[] = {1, 2, 3, 4, 5, 6, 7, 8, 0x2b, 0x92};
mit der WinAVR Funktion brav 0x0000 aus, was auch bei den anderen 
Rechnern (mit der jeweiligen CRC) funktioniert. Allerdings ist mir 
aufgefallen dass man die CRC bei der WinAVR Funktion LSB anhängen muss 
(0x922b -> 0x2b, 0x92), bei den anderen Rechnern funktioniert das ganze 
nur wenn man die CRC MSB anhängt (0x4792 -> 0x47, 0x92).

Wo liegt also der Unterschied begraben ?

Gruß
Stefan

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Tja, genau die ganze Konfusion um Bit- und Byteorder ist das Problem
der CRC-Routinen: selbst bei gleichem Polynom und gleichem Anfangs-
wert gibt es X verschiedene Varianten.  Tauschst du beispielsweise mal
die Bitorder deines Bitstrings um, d. h. nimmst du
1
  uint8_t data[] = {0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10};
dann erhälst du 0x49e2 als CRC.  Tauschst du dessen Bitorder wieder,
dann ist die CRC 0x4792 -- die von dir erwartete.

Der Algorithmus in _crc_ccitt_update() passt auf die tatsächlichen
CCITT-Übertragungen, ebenfalls auf die IEEE-Übertragungen, wobei
letztere (zumindest ist mir das in IEEE 802.15.4 so übern Weg
gelaufen) als Startwert 0 und nicht 0xffff nehmen.  All diesen
Übertragungen ist gemein, dass Bit 0 des LSB als erstes übertragen
wird (das beginnt bei einer simplen V.24-Übertragung).  Damit wird
bei einer übertragenen 0x01 lediglich das erste übertragenen Bit
gesetzt, alle anderen sind gelöscht.

Da die CRC selbst eine 16-bit-CRC ist, hast du dann auch noch das
Problem der Byteorder.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.