Hallo,
Wintermonate sind SW-Spielmonate.
Ich will bei meinem Datenprotokoll die bisherige 16bit Checksum durch
CRC16 nach CCITT erstezen. Aber das funzt nicht.
Ich will nicht nerven, habe auch fleißig rumgegoogelt und auch hier im
Forum gesucht, aber ich stehe auf dem Schlauch.
Nehmen wir mal an, die Nachricht besteht nur aus $55, $AA,
dann müßte die CRC laut "Breitbandkatze" sowie laut
http://www.lammertbies.nl/comm/info/crc-calculation.html übereinstimmend
0xF8E5 ergeben.
Aber die Nutzung Funktion des AVR-libc: _crc_ccitt_update (crc16, data)
ergibt 0x57a7.
Parallel habe ich das LIBC-Beispiel auf VB-express implementiert. Die
Funktion:
Private Function crc_ccitt_update(ByVal crc As UInt16, ByVal idata
As Byte) As UInt16
Dim xdata As UInt16
xdata = idata
xdata = xdata Xor (crc And &HFF)
xdata = (xdata Xor (xdata << 4)) And &HFF
crc = (((xdata << 8) Or (crc And &HFF00)) Xor (xdata >> 4) Xor
(xdata << 3))
Return crc
' data ^= lo8 (crc);
' data ^= data << 4;
' return ((((uint16_t)data << 8) | hi8 (crc)) ^
(uint8_t)(data >> 4)
' ^ ((uint16_t)data << 3));
End Function
ergibt den Wert: 0xFDD5 Dieser stimmt weder mit dem ergebnis der
ASM-Implementierung der libc laut crc16.h überein noch mit
Breitbandkatze.
Eine Implementierung aus einer anderen Quelle:
Private Function crc_ccitt_update_5(ByVal crc As UInt16, ByVal idata
As Byte) As UInt16
Dim xdata As UInt16
xdata = idata
' x = ((crc>>8) ^ data) & 0xff;
xdata = ((crc >> 8) Xor xdata) And &HFF
' x ^= x>>4;
xdata = xdata Xor (xdata >> 4)
' crc = (crc << 8) ^ (x << 12) ^ (x <<5) ^ x;
crc = (crc << 8) Xor (xdata << 12) Xor (xdata << 5) Xor xdata
crc = crc And &HFFFF
Return crc
End Function
hingegen ergab den "richtigen" Breitbandkatzewert 0xF8E5
Ist die libc bzw crc16.h falsch? Muß ich ggf. das Makefile anpassen?
Meines ist "Standard" laut AVR Studio? Osder hat einer eine korrekte
schnelle Implementierung in ASM?
Danke für Eure Mühen :-)
Yogy
_crc_xmodem_update mit Startwert 0xffff liefert dir dein gewünschtes
0xF8E5 (und mit Startwert 0 das auch in den Internetrechnern für
crc_xmodem gezeigte 0xE5EA).
Ob jetzt eher die Internet-Rechner oder die avrlibc richtig liegen,
darfst du selber rausfinden. Dem folgenden Kommentar in der avrlib-Doku
nach tippe ich allerdings auf die avrlibc:
1
Note:
2
Although the CCITT polynomial is the same as that used by the Xmodem protocol,
3
they are quite different.
4
The difference is in how the bits are shifted through the alorgithm.
5
Xmodem shifts the MSB of the CRC and the input first,
6
while CCITT shifts the LSB of the CRC and the input first.
Oh, das ging aber fix. Danke. Oliver. Damit funzt es.
Ich vermute nal, die libc ist da fehlerhaft. Denn die ASM-Routinen
entsprechen auch nicht dem genannten C-Beispiel, bzw. in C ist ein ODER
anstelle eines XOR (bei return). Auch scheint mir der ASM Teil ein wenig
verquer.
Aber Hauptsache, es geht jetzt und ich kann das in C oder VB auf dem PC
und mittels crc26.h auf dem AVR in C nutzen. Mal sehen, vlt. setze ich
mich nochmals dran und versuche eine ASM Implementierung (Kenne mich
-noch- nicht mit dem Interface GNU-C und ASM für den AVR aus) der
erwähnten C-Routine "crc_ccitt_update_5" (Bei mir als VB laufend)
Danke nochmals und schönes WE. Ich habe ja was zu tun...
Yogy
Eine eigene Frage?
Dieser Thread ist über 14 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.