AVR CRC-16 CCITT mit HxD berechnen?

Moderator Persönliche Seite #7110712
Lesenswert?

Der Code sagt, dass das Polynom 0x8048 ist. Letztlich das gleiche wie 
die 0x1021 von Xmodem bit-swapped.

Aber: das Bit-Swapping bei CCITT ist nicht nur beim Polynom, sondern 
generell. (Hängt damit zusammen, dass Kommunikationsprotokolle immer Bit 
0 zuerst senden.) Musst du mal gucken, ob eine der "Reflektion"-Optionen 
(oder beide?) dann genau das bewirken.

Schieb doch einfach mal einen Testvektor da durch. Aus 802.15.4 kenne 
ich den hier:
1
0x02 0x00 0x6A 0xE4 0x79

Im Original liest der sich:
1
   0100 0000 0000 0000 0101 0110
2
b0 ............................b23
3
FCS:
4
   0010 0111 1001 1110
5
r0 ..................r15
Gast #7111370
Lesenswert?

Danke Jörg,

bin weitergekommen. Ich habe mal Deinen Testvektor genommen:
1
#include <iostream>
2

3
using namespace std;
4

5
void updateCCITTCrc(uint16_t &crc, const void* buf, size_t len) {
6
  uint8_t b;
7
  uint8_t *ptr = (uint8_t*) buf;
8

9
  while (len--) {
10
    b = *ptr++ ^ (crc & 0xFF);
11
    b ^= b << 4;
12
    crc = ((((uint16_t)b << 8) | (crc >> 8)) ^ (uint8_t)(b >> 4) ^ ((uint16_t)b << 3));
13
  }
14
}
15

16
int main() {
17
    uint8_t testvect[] = {0x02, 0x00, 0x6A, 0xE4, 0x79};
18
    uint16_t crc = 0xFFFF;
19
    
20
    updateCCITTCrc(crc, testvect, sizeof(testvect));
21
    
22
    cout << hex << crc << endl; //-> 0x3088
23

24
    return 0;
25
}

Da kommt 0x3088 als Ergebnis raus. Dann mal diesen Testvektor z. B. hier 
einhacken:

http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

Einstellungen:
CRC 16, Polynom 0x1021, Init Value 0xFFFF, Input- & Resultreflect 
aktiviert, dann kommt man auf das selbe Ergebnis.

Im HxD gilt das gleiche:
CRC 16,
Polynom 0x1021,
Startwert 0xFFFF,
Ein-/Ausgang reflektieren

Vielen Dank!
Moderator Persönliche Seite #7111515
Lesenswert?

Werner schrieb:
> Da kommt 0x3088 als Ergebnis raus

Seltsam. Es sollte 0 rauskommen.

Ich hatte das vor Jahrzehnten mal geschrieben (als ich bei Atmel mit 
IEEE-802.15.4-Transceivern gearbeitet habe), leider finde ich den 
Sourcecode gerade nicht mehr, aber das Binary funktioniert noch:
1
% ./bin/gencrc 0x02 0x00 0x6A 0xE4 0x79
2
CRC = 0x0000
3
% ./bin/gencrc 0x02 0x00 0x6A 
4
CRC = 0x79e4

Ich glaube, der Unterschied ist, dass der Startvektor nicht 0xFFFF 
sondern 0x0000 ist.
Moderator Persönliche Seite #7111541
Lesenswert?

Jörg W. schrieb:
> leider finde ich den Sourcecode gerade nicht mehr

Ah, doch noch gefunden.
1
#include <stdint.h>
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include <unistd.h>
5

6
uint16_t crc_ccitt_update (uint16_t crc, uint8_t data)
7
{
8
    data ^= crc & 0xff;
9
    data ^= data << 4;
10

11
    return ((((uint16_t)data << 8) | ((crc & 0xff00) >> 8))
12
            ^ (uint8_t)(data >> 4)
13
            ^ ((uint16_t)data << 3));
14
}
15

16
static void
17
usage(void)
18
{
19
    fprintf(stderr, "usage: gencrc [-b base] number...\n");
20
    exit(64);
21
}
22

23
int
24
main(int argc, char **argv)
25
{
26
    long i;
27
    int c, base;
28
    uint16_t crc = 0;
29
    uint8_t byte;
30

31
    base = 0;
32
    while ((c = getopt(argc, argv, "b:")) != -1)
33
        switch (c)
34
        {
35
        case 'b':
36
            base = strtol(optarg, 0, 0);
37
            break;
38

39
        default:
40
            usage();
41
        }
42
    argc -= optind;
43
    argv += optind;
44

45
    while (argc-- > 0) {
46
        i = strtol(argv[0], 0, base);
47
        byte = (uint8_t)i;
48
        crc = crc_ccitt_update(crc, byte);
49
        argv++;
50
    }
51
    printf("CRC = 0x%04x\n", crc);
52
    return 0;
53
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren