Forum: Mikrocontroller und Digitale Elektronik CRC-Berechnung für HDLC-Format


von Moe E. (moe_espunkt)


Lesenswert?

Hallo Zusammen,

wie im Betreff schon zu vermuten ist, versuche ich seit einiger Zeit die 
CRC-Berechung für einen Frame (HDLC-Format) zu berechnen.

Über eine Software (bzw. Bus-analyzer) lasse ich mir kleine Frames 
anzeigen. Auf dem Bus werden bspw. die Daten "FA01" versendet und der 
CRC-Wert dafür ist "B69F".

Jetzt habe ich natürlich versucht, den CRC-Wert nachzurechnen:

Generatorpolynom: x^16+x^12+x^5+1 = 1000 1000 0001 0000 1
Daten           : FA01            = 1111 1010 0000 0001


Ich fange an, den Daten 16 Nullen anzufügen:

Daten_mit_nullen = 1111 1010 0000 0001 0000 0000 0000 0000


Nun beginnt die eigentlich Division:

Daten_mit_nullen
---------------- ==> Der Rest dieser Division(XOR) ist der CRC-Wert.
Generatorpolynom

Aber ich komme nicht auf den CRC-Wert "B69F" !!  Auch sämtliche 
Onlinerechner geben mit ständig etwas unterschiedlich aus...

Ich habe relativ oft etwas gelesen von "Initialwert" oder "Abschließende 
XOR-Verknüpfung", aber selbst wenn ich das berücksichtige (sofern ich es 
denn richtig verstanden habe), komme ich nicht auf den genannten 
CRC-Wert.

Kann es sein, dass ich beim HDLC-Format die Daten vorher drehen muss 
(also "01FA")? Kann jemand helfen?

Ich bedanke mich recht herzlich für eure Hilfe

Viele Grüße

: Bearbeitet durch User
von Narf (Gast)


Lesenswert?

Hi,

keine Lösung aber schonmal hier nachgelesen:
http://read.pudn.com/downloads138/sourcecode/others/589576/ISO13239.pdf 
(Ab Seite 13 im Dokumente unter FCS)

Gruß

von Moe E. (moe_espunkt)


Lesenswert?

Hallo Narf,

vielen Dank für deine Antwort.

Hab da mal rein geschaut, aber im Detail wird das leider auch nicht 
erklärt. Da steht eigentlich nur das, was ich schon wusste. Dennoch 
vielen Dank!

von Georg G. (df2au)


Lesenswert?

Bei CRC gibt es n+1 Möglichkeiten. "HDLC" sagt erst einmal nicht viel. 
Es gibt unterschiedliche Anfangswerte und unterschiedliche Polynome. Und 
man kann erst das LSB oder das MSB senden. Genormt ist da nichts. Es 
hilft dir nur probieren (oder den Autor der Software befragen, die das 
sendet).

von Moe E. (moe_espunkt)


Lesenswert?

Hallo Georg,

vielen Dank für deine Antwort.

Georg G. schrieb:
> Es gibt unterschiedliche Anfangswerte und unterschiedliche Polynome. Und
> man kann erst das LSB oder das MSB senden.

- Das Polynom ist ja bekannt.
- In der Spezifikation des Busses steht, dass man zu erst das MSB 
sendet.
- der Anfangwert ist 0xFFFF ( was auch immer der Anfangswert sein soll 
... )

Reicht das aus, um den CRC-Wert zu bestimmen?

_________________________________
Ergänzung:

Georg G. schrieb:
> "HDLC" sagt erst einmal nicht viel

Ist im HDLC-Format nicht festgelegt wie die CRC-Wert/Berechnung aussehen 
soll?

: Bearbeitet durch User
von Kringelgast (Gast)


Lesenswert?

Moe Espunkt schrieb:
> Ist im HDLC-Format nicht festgelegt wie die CRC-Wert/Berechnung aussehen
> soll?

Damals in Bereich der öffentlichen Netzwerke wurde HDLC/X.25 mit CRC 
verwendet, das ist standardisiert durch ITU-T:

https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-X.25-199610-I!!PDF-E&type=items

Kapitel 2.2.7.4.

von Georg G. (df2au)


Lesenswert?

Moe Espunkt schrieb:
> Ist im HDLC-Format nicht festgelegt wie die CRC-Wert/Berechnung aussehen
> soll?

Leider nein, HDLC beschreibt, wie Frames aussehen (Flag, Daten, CRC, 
Flag) und wie zB. Bitstuffing gemacht wird.

Übrigens, Norm... dein Polynom ist eigentlich typisch für HDLC. Bei 
Herrn IBM nahm man aber X16 + X15 + X2 + 1.

Die CRC-Prüfsumme wird üblicherweise mit 0xffff initialisiert.

von Georg (Gast)


Lesenswert?

Georg G. schrieb:
> Übrigens, Norm... dein Polynom ist eigentlich typisch für HDLC.

Nennt sich in meinen Unterlagen CCITT CRC.

Georg G. schrieb:
> Bei
> Herrn IBM nahm man aber X16 + X15 + X2 + 1.

Und das CRC-16.

Da gibts im Netz jede Menge Unterlagen, auch Software.

Georg

von Moe E. (moe_espunkt)


Lesenswert?

Wenn ich das ganz theorethisch betrachte, dann müsste doch die 
CRC-Berechnung folgende sein:

Daten+16 Nullen dran       FA010000 (hex)
--------------------   =   -----------------
Generatorpolynom           10001000000100001 (binär)

Der Rest dieser Division müsste ja der CRC-Wert sein. Das ganze hab ich 
mal in Wolfram Alpha eingegeben und es kommt nicht der gewünschte wert 
von "B69F" raus!! Dabei habe ich mich ganz genau an die Literatur 
gehalten !!

Wolfram Alpha liefert nämlich "BEF1":
http://www.wolframalpha.com/input/?i=%28FA010000+base+16%29+mod+%2810001000000100001+base+2%29

Aber wo ist bloß mein Denkfehler? Was mache ich Falsch? Das kann doch 
unmöglich so schwer sein?

_______________________________
Ergänzung:

Verwende ich den folgenden Online CRC-Rechner, kommt das richtige raus 
unter folgender Eingabe:

http://www.zorc.breitbandkatze.de/crc.html

CRC-Order: 16
CRC-Polynom: 1021
Inital Value : FFFF
Final XOR value: FFFF
reverse data bytes :ON
reverse CRC result before Final XOR: ON

Eingabe : %FA%01

: Bearbeitet durch User
von Georg G. (df2au)


Lesenswert?

Moe Espunkt schrieb:
> Der Rest dieser Division müsste ja der CRC-Wert sein. Das ganze hab ich
> mal in Wolfram Alpha eingegeben und es kommt nicht der gewünschte wert
> von "B69F" raus!! Dabei habe ich mich ganz genau an die Literatur
> gehalten !!

Naja, fast... Du hast den Startwert 0xffff ignoriert (der bei HDLC 
üblich ist).

von Moe E. (moe_espunkt)


Lesenswert?

Georg G. schrieb:
> Naja, fast... Du hast den Startwert 0xffff ignoriert (der bei HDLC
> üblich ist).

Wie lasse ich denn den Startwert 0xFFFF in die Rechnung mit einfließen? 
Weiß ehrlich gesag nicht, was ich mit diesem Startwert anfangen soll ...

von Georg G. (df2au)


Lesenswert?

Aus Wikipedia:


Schieberegister := Startwert
solange Bits im Datenstrom verbleiben:
  falls  das am weitesten links stehende Bit vom Schieberegister
        ungleich dem nächsten Bit aus dem Datenstrom ist:
    Schieberegister := (Schieberegister linksschieben um 1, rechtes Bit 
0)
                       xor CRC-Polynom
  andernfalls:
    Schieberegister := Schieberegister linksschieben um 1, rechtes Bit 0
  nächstes Bit im Datenstrom
Schieberegister enthält das Ergebnis.

Oft findet man andere Startwerte, etwa 1111…. Dies entspricht einer 
Polynomdivision, wenn die ersten n Bits des Datenstroms invertiert 
werden.

Ende Wikipedia

Sieh dir mal die CRC-Lib aus dem Atmel Studio an.
Wenn CRC Erzeugung oder Check schnell gehen muss, macht man das mit 
Tabellen.

Beispiel (mit falscher und deshalb gekürzter Tabelle). crc wird vor dem 
ersten Aufruf mit dem Startwert initialisiert. Funktion wird für jedes 
Byte des Datenstromes aufgerufen. crc enthält den zu übertragenden 
CRC-Wert.

static void calc_crc(WORD *crc, BYTE c)
{
  static const WORD Crc_table[] = {
    0x0f87, 0x1e0e, 0x2c95, 0x3d1c, 0x49a3, 0x582a, 0x6ab1, 0x7b38,
...
    0xf808, 0xe981, 0xdb1a, 0xca93, 0xbe2c, 0xafa5, 0x9d3e, 0x8cb7,
    0x7440, 0x65c9, 0x5752, 0x46db, 0x3264, 0x23ed, 0x1176, 0x00ff
  };

  *crc = (*crc << 8) ^ Crc_table[(*crc >> 8) ^ c];
}

: Bearbeitet durch User
von Tiramisu (Gast)


Lesenswert?

$ ./pycrc.py  --model x-25 --check-hexstring="FA01"
0x9fb6

bzw. b69f mit einem Byteswapper.... mit pycrc < 3 Minuten gebraucht ;-)

von Moe E. (moe_espunkt)


Lesenswert?

Hallo Tiramisu,

vielen Dank für deine sehr hilfreiche Antwort.

Ich habe das jetzt ebenfalls mit Python (Pycrc) gemacht. Als Ergebnis 
erhalte ich jedoch folgendes:

C:\Python27>python pycrc.py --model x-25 --check-string="FA01"
0x6bf1

Irgendwie schon kurios oder? Eine Vermutung voran es liegen könnte?
Ich überlege langsam einfach die CRC-Berechnung selber zu programmieren 
in dem ich einfach ein Schieberegister mit XOR-Verknüpfungen realisiere.
Kann ja "eigentlich" nicht so schwer sein den CRC-Code zu implementieren 
...
Geht wahrscheinlich schneller als, wenn ich mich jetzt in andere Codes 
einarbeite.

: Bearbeitet durch User
von Moe E. (moe_espunkt)


Lesenswert?

Wer lesen kann ist klar im Vorteil :

es heißt "HEXSTRING"  und nicht "STRING" !

also : C:\Python27>python pycrc.py --model x-25 --check-hexstring="FA01"
0x9fb6

: Bearbeitet durch User
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.