Forum: Mikrocontroller und Digitale Elektronik Problem mit CRC16 Berechnung (Hin/Rückrechnung)


von Oz z. (ozzy)


Lesenswert?

Hi,

ich möchte meine zu sendenden Daten über eine CRC16 absichern. Die 
crc16.h bietet mir für meinen Atmega ja schon mal einen guten 
Anhaltspunkt:
1
uint16_t U16crc;
2
3
void crc_fInit( void )
4
{
5
  U16crc = 0xffff;
6
}
7
8
void crc_fUpdate(uint8_t value)
9
{
10
  uint8_t i;
11
12
  U16crc ^= value;
13
  for (i = 0; i < 8; ++i)
14
  {
15
    if (U16crc & 1)
16
    {
17
      U16crc = (U16crc >> 1) ^ 0xA001;
18
    }
19
    else
20
    {
21
      U16crc = (U16crc >> 1);
22
    }
23
  }
24
}
Allerdings will das ganze bei mir nicht klappen.
Also, angenommen ich habe diese Nachricht:
1
unsigned char message[9] = {'M','e','s','s','a','g','e',0,0};
Dann lasse ich die CRC16 mit den Polynom 0xA001 rüberlaufen:
1
    crc_fInit();
2
    for (i=0; i<9; i++)
3
    {
4
      crc_fUpdate(message[i]);
5
    }
Als Ergebnis erhalte ich hier "54110".
Nun kopiere ich dieses Ergebnis in die letzten beiden "Zeichen"
1
    message[7] = (U16crc>>8);
2
    message[8] = (U16crc & 0xFF);
und lasse den Algorithmus erneut über die Nachricht laufen (was ja nun 
die Empfängerseite wäre):
1
    crc_fInit();
2
    for (i=0; i<9; i++)
3
    {
4
      crc_fUpdate(message[i]);
5
    }
Allerdings bekomme ich hier nicht die erwartete "0", sondern eine "7042" 
als Ausgabe.

Sehr Ihr vielleicht, wo hier der Fehler stecken könnte?

Vielen Dank im Voraus für Eure Hilfe!!!

von Georg G. (df2au)


Lesenswert?

Oz zy schrieb:
> Nun kopiere ich dieses Ergebnis in die letzten beiden "Zeichen"

Das ist nicht ganz richtig. Berechne CRC über die Nutzdaten (7 Zeichen 
in deinem Fall) und hänge dann die CRC dran. Achte auf die richtige 
Reihenfolge.

Es gibt n+1 erprobte und fehlerfreie Implementationen im Netz. Bei 
GCC-AVR ist auch eine Lib dabei. Warum das Rad neu erfinden?

von Oz z. (ozzy)


Lesenswert?

Hi,

erst einmal danke für Deine Antwort! Ich hatte es immer so verstanden, 
dass für die CRC zuerst so viele Nullen (in Bits) an die Nachricht, wie 
das Polynom groß ist. Über diese neu entstandene Nachricht wird dann die 
CRC-Summe gebildet. Anschließend wird an den Rahmen (dann allerdings 
ohne die Nullen) die Summe angehängt.

Ich erfinde ja auch das Rad nicht neu. Der Code, den ich oben 
geschrieben habe ist der aus der avr-lib. Ich habe nur die crc global 
gemacht, so dass sie nicht mitübergeben werden muss...

Viele Grüße
Ozzy

von Purzel H. (hacky)


Lesenswert?

Man muss eh die implementation des CRC haben, dh den sourcecode. dann 
macht man den eben auf beiden Seiten gleich und gut ist.

von Stefan E. (sternst)


Lesenswert?

Oz zy schrieb:
> Ich hatte es immer so verstanden,
> dass für die CRC zuerst so viele Nullen (in Bits) an die Nachricht, wie
> das Polynom groß ist.

Eine CRC wird über einen Bitstrom gebildet. Die Länge dieses Bitstroms 
und die Größe des CRC sind komplett unabhängig voneinander. Du könntest 
auch eine 64-Bit-CRC über 5 Bits erstellen (ohne irgendetwas auffüllen 
zu müssen). Dass die CRC-Funktionen die Bits in "Paketen" (8, 16, 32, 
... Bits) entgegennehmen, dient nur der Bequemlichkeit.

von Oz z. (ozzy)


Lesenswert?

Hm,

ich kenne es eben auch aus Büchern so, wie es bei Wikipedia beschrieben 
ist (ich weiß, das ist nicht die Quelle aller Quellen). Und da wird eben 
doch etwas angehängt...

von Stefan E. (sternst)


Lesenswert?

Oz zy schrieb:
> ich kenne es eben auch aus Büchern so, wie es bei Wikipedia beschrieben
> ist (ich weiß, das ist nicht die Quelle aller Quellen). Und da wird eben
> doch etwas angehängt.

Wo (Link)?

von Oz z. (ozzy)


Lesenswert?


von Stefan E. (sternst)


Lesenswert?

Da wird doch nur für die theoretische Betrachtung (bzw. das
händische Dividieren) was angehängt. Bei einer realen 
CRC-Implementierung ist dieses "Anhängsel" der CRC-Startwert, und nichts 
was du deinen Nutzdaten hinzufügen müsstest.

von Oz z. (ozzy)


Lesenswert?

Ok, danke, dann bin ich damit schon mal schlauer. Stimmt es aber 
trotzdem, dass, wenn ich die CRC an die Nachricht anhänge und den 
Algorithmus erneut durchlaufen lasse, eine "0" rauskommen sollte?

von Stefan E. (sternst)


Lesenswert?

Oz zy schrieb:
> Stimmt es aber
> trotzdem, dass, wenn ich die CRC an die Nachricht anhänge und den
> Algorithmus erneut durchlaufen lasse, eine "0" rauskommen sollte?

Ja.

von Peter II (Gast)


Lesenswert?

Oz zy schrieb:
> Ok, danke, dann bin ich damit schon mal schlauer. Stimmt es aber
> trotzdem, dass, wenn ich die CRC an die Nachricht anhänge und den
> Algorithmus erneut durchlaufen lasse, eine "0" rauskommen sollte?

ja, so mache ich es auch. Aber wenn ich mich recht daran erinnere denn 
errechne ich die CRC ohne die beiden 0 bytes. Könnte ich heute abend mal 
nachschauen.

von Oz z. (ozzy)


Lesenswert?

Ok, also selbst wenn ich so mache funktioniert es nicht...
Also bei der ersten CRC-Berechnung:
1
    crc_fInit();
2
    for (i=0; i<7; i++)
3
    {
4
      crc_fUpdate(message[i]);
5
    }
Als Ergebnis kommt da "15420" raus. Also weit weg von einer 0...

von Stefan E. (sternst)


Lesenswert?

Oz zy schrieb:
> Also bei der ersten CRC-Berechnung:
> ...
> Als Ergebnis kommt da "15420" raus. Also weit weg von einer 0...

Wieso sollte da denn jetzt auch 0 raus kommen?

von Peter II (Gast)


Lesenswert?

Oz zy schrieb:
> Als Ergebnis kommt da "15420" raus. Also weit weg von einer 0...

ist ja wohl klar, wenn du jetzt aber die  "15420" in der richtige 
Reihenfolge anghägst und dann über die 9 zeihcen die CRC brechnest dann 
sollte eine 0 rauskommen.

von Stefan E. (sternst)


Lesenswert?

Peter II schrieb:
> Aber wenn ich mich recht daran erinnere denn
> errechne ich die CRC ohne die beiden 0 bytes.

Diese "beiden 0 bytes" sind in Wirklichkeit der Startwert.

von Oz z. (ozzy)


Lesenswert?

Sorry, da habe ich mich unglücklich ausgedrückt. Ich berechne die CRC 
über die Nachricht (ohne Anhang). Ergebnis: "31531". Diese 2 Byte hänge 
ich an die Nachricht dran, und lasse die CRC-Berechnung nun über die 
Nachricht + CRC laufen. Ergebnis: "15420" != "0"...

von Peter II (Gast)


Lesenswert?

Oz zy schrieb:
> Ergebnis: "31531". Diese 2 Byte hänge
> ich an die Nachricht dran,

dann tausche mal die reihenfolge der bytes.

von Oz z. (ozzy)


Lesenswert?

Shit, shit, shit, genau das war es!!!!!! Ich dachte, ich hätte das schon 
ausprobiert...

Vielen, vielen Dank auf jeden Fall für Hilfe!!!

MfG, Ozzy

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.