Forum: PC-Programmierung CRC auf einem Raspberry Pi in C


von asd (Gast)


Lesenswert?

Hallo,

mit dem avr-gcc habe ich immer
#include <util/crc16.h>
benutzt wenn ich eine CRC Checksumme gebraucht habe. Jetzt stelle ich 
fest dass das auf dem Raspberry Pi mit gcc nicht funktioniert. Etwas 
googlen hat mich in der Frage auch nicht weiter bebracht: Gibt es diese 
lib nicht für den Pi? Was benutzt man wenn man eine CRC berechnen will, 
mit dem gcc auf dem Raspberry Pi?

Viele Grüße,

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

asd schrieb:
> Jetzt stelle ich fest dass das auf dem Raspberry Pi mit gcc nicht
> funktioniert.

Die Fehlermeldung lautete "es funktioniert nicht"? Was ist das für ein 
merkwürdiger Compiler?

> Gibt es diese lib nicht für den Pi?

Welche "lib"? crc16.h ist eine Headerdatei, keine Library.

von Dennis S. (eltio)


Lesenswert?

Einfach selber schreiben. Oder wenn du das nicht hinbekommst eine 
fertige Lösung googlen. CRC ist ein offenes Verfahren keine proprietäre 
Geheimniskrämerei.

Gruß
Dennis

von asd (Gast)


Lesenswert?

Du hast recht, ich hätte gleich etwas genauer Fragen könne.
Mit dem avr-gcc (bzw. WinAVR) binde ich diese Header-Datei ein und nutze 
dann die CRC16-Funktionen:

#include <util/crc16.h>

...

crcsum=0xffff;  // startwert
data=0x00;
crcsum=_crc16_update (crcsum,data);

...

Als ich das gerade auf den Raspberry Pi gemacht habe fand der gcc die 
Header-Datei nicht. ("no such file or directory")
Und ich fand mit google das Problem nicht. Bzw. ich hab nicht raus 
gefunden ob die <util/crc16.h> was spezifisches des avr-gcc ist oder ob 
das Problem wo anders liegt. Bzw. hab ich dann kein Beispiel gefunden 
wie man in C auf dem Raspberry eine crc berechnet. Gibts dieses Paket 
(Header-Datei? Library?) auch für den gcc auf dem Raspberry Pi? Muss man 
da was extra installieren? Oder liegt das Problem an einem ganz anderem 
Eck?

von Dennis S. (eltio)


Lesenswert?

Der Raspberry ist auch kein AVR sonder ein ARM. Deswegen ist es erstmal 
nicht sinnvoll den "falschen" Compiler mit Libraries zu installieren. 
Auf dem Raspberry hast du dementsprechend standardmäßig nur den normalen 
C-Compiler. Also google einfach nach einer fertigen CRC-Implementierung 
in C die du dann in dein Programm einbindest. Es steht dir aber 
natürlich auch frei die avr-gcc-Sachen zu installieren oder 
runterzuladen.

: Bearbeitet durch User
von asd (Gast)


Lesenswert?

Ich hab doch nicht den avr-gcc auf dem Raspberry installiert...
Sondern ich war gewohnt dass beim avr-gcc für die AVR-Megas auf einfache 
weise CRC-Funktionen zur Verfügung stehen. Jetzt war meine Frage ob das 
beim gcc (der, der per default installiert ist) auf dem Raspberry Pi 
auch so sein sollte und ich mich nur zu dumm anstelle, oder ob bei gcc 
für x86 oder ARM die <util/crc16.h> gar nicht dabei ist und ich mir die 
CRC Funktionen auf andere Art und Weise besorgen muss (und wenn ja, wäre 
mir ein Tipp, wo und wie genau auch sehr lieb).

von Dennis S. (eltio)


Lesenswert?

asd schrieb:
> Jetzt war meine Frage ob das
> beim gcc (der, der per default installiert ist) auf dem Raspberry Pi
> auch so sein sollte
Nein, das ist in der "normalen" C-Library nicht dabei.

asd schrieb:
> ich mir die
> CRC Funktionen auf andere Art und Weise besorgen muss (und wenn ja, wäre
> mir ein Tipp, wo und wie genau auch sehr lieb).
Ja... wurde ja schon gesagt! Einfach googlen nach: crc source. Ich denke 
selbst Wikipedia hat eine Implementierung. Auch hier im Forum finden 
sich unzählige Implementierungen die du nutzen kannst.
Zum "wie": In der Regel gibt es eine Header-Datei und eine C-Datei die 
du runterladen kannst.

P.S.: Es lohnt sich ein Blick in die Doku zum Beispiel unter
https://de.wikipedia.org/wiki/C-Standard-Bibliothek
oder
http://en.cppreference.com/w/
um den Funktionsumfang kennenzulernen.

: Bearbeitet durch User
von Kaj (Gast)


Lesenswert?


von Vancouver (Gast)


Lesenswert?

Du könntest mal in das AVR-Headerfile hineinschauen. Würde mich nicht 
wundern, wenn Du dort die  Implementierung der crc-Updatefunktion 
findest.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

asd schrieb:
> Was benutzt man wenn man eine CRC berechnen will,
> mit dem gcc auf dem Raspberry Pi?

Kommt auf die Programmiersprache an. Bei C++ würde ich einfach boost 
verwenden.

mfg Torsten

von Hmm... (Gast)


Lesenswert?

Als Schnellschuss:

apt-get install libcrcutil-dev libcrcutil-doc libcrcutil

Damit hast du eine fertige Linux-Library installiert, die du benutzen 
kannst. Wie gut die Doku ist, weiß ich nicht, es sollte aber notfalls 
aus den installierten Headerfiles erkennbar sein wie man das benutzt. 
Vorteil wäre ein ferig getestetes Package was auch schon gut optimiert 
ist. Besser bekommt man das aus der Kalten keinesfalls hin ;)

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


Lesenswert?

Vancouver schrieb:
> Würde mich nicht wundern, wenn Du dort die  Implementierung der
> crc-Updatefunktion findest.

So isses, jeweils im Kommentar der (als inline asm implementierten)
Funktionen steht C-Code.  In einigen (wenigen) Fällen muss man noch
die Pseudo-Funktionen lo8() und hi8() passend ersetzen, aber das
sollte ja nun nicht gerade Raketenwissenschaft sein.

von Hmm... (Gast)


Lesenswert?

Was spricht den dagegen auf einem Linux Rechner eine Standard Linux 
Bibliothek zu benutzen? So ziemlich alle Debian Pakete sind doch für ARM 
Linux / Raspbian portiert und per apt-get verfügbar. Oder hab ich 
irgendwo was von Baremetal überlesen?

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


Lesenswert?

Hmm... schrieb:
> Was spricht den dagegen auf einem Linux Rechner eine Standard Linux
> Bibliothek zu benutzen?

Dass die 5 Zeilen CRC so einfach sind, dass es sich fast nicht lohnt,
daraus eine Bibliothek zu machen? ;-)

Es ist einfach am TE, das für sich zu entscheiden.

von Hmm... (Gast)


Lesenswert?

@Jörg: kommt drauf an was man braucht, für kleine Controller habe ich 
auch schon ein paar Mal CRCs selbst geschrieben, teilweise auch mit 
eigenen Polynomen. Aber eine optimierte Fertige Fassung die sogar HW 
Beschleunigung drin hat schreibt man nicht mal eben nebenbei.

Auch 5 Zeilen Code können Fehler enthalten ;-)

von Peter II (Gast)


Lesenswert?

Jörg W. schrieb:
> Dass die 5 Zeilen CRC so einfach sind, dass es sich fast nicht lohnt,
> daraus eine Bibliothek zu machen? ;-)

openssl
boost
libbotan
libcrcutil
LibreSSL


Das Problem ist viel mehr sich zu entscheiden, welche davon "Standard" 
ist.

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


Lesenswert?

Hmm... schrieb:
> Aber eine optimierte Fertige Fassung die sogar HW Beschleunigung drin
> hat schreibt man nicht mal eben nebenbei.

Hardwarebeschleunigung für ein bisschen CRC?  Was außer dem (bei ARM
sowieso vorhandenen) Barrelshifter stellst du dir noch vor?

> Auch 5 Zeilen Code können Fehler enthalten ;-)

Können, müssen aber nicht.  Known to work (bspw. gemäß IEEE 802.15.4):
1
uint16_t crc_ccitt_update(uint16_t crc, uint8_t data)
2
{
3
    data ^= crc & 0xFF;
4
    data ^= data << 4;
5
6
    return ((((uint16_t)data << 8) | ((crc & 0xFF00) >> 8)) ^
7
            (uint8_t)(data >> 4) ^
8
            ((uint16_t)data << 3));
9
}

Peter II schrieb:
> Das Problem ist viel mehr sich zu entscheiden, welche davon "Standard"
> ist.

Vermutlich funktionieren sie einfach nur alle. :-)

: Bearbeitet durch Moderator
von Hmm... (Gast)


Lesenswert?

Vermutlich hat der TE in der Zwischenzeit seine eigene crc 
geschriebenund mit drei ausgewählten fertigen Implementierungen 
verglichen ;-)

von asd (Gast)


Lesenswert?

> Vermutlich hat der TE in der Zwischenzeit seine eigene crc
> geschriebenund mit drei ausgewählten fertigen Implementierungen
> verglichen ;-)

Heute Abend werde ich mich damit wieder beschäftigen, bin in der 
Zwischenzeit ein wenig auf Arbeit ;-)


Jörg Wunsch schrieb:
> Können, müssen aber nicht.  Known to work (bspw. gemäß IEEE 802.15.4):
>
> uint16_t crc_ccitt_update(uint16_t crc, uint8_t data)
> ...

Ich vermute das Polynom steckt implizit in der Return-Anweisung?
Dann wäre das genau ein Codeschnippsel nach dem ich gesucht habe.
Vielen Dank.

Bei den Codebeispielen in Wikipedia werden die Bits einzeln 
durchgeschoben, das schien mir dann ggü. einer optimierten Routine in 
einer lib dann doch zu ineffizient.


Hmm... schrieb:
> apt-get install libcrcutil-dev libcrcutil-doc libcrcutil
>
> Damit hast du eine fertige Linux-Library installiert, die du benutzen
> kannst. Wie gut die Doku ist, weiß ich nicht, es sollte aber notfalls
> aus den installierten Headerfiles erkennbar sein wie man das benutzt.

Auf das Risiko hin dass ich damit die gleiche Reaktion verursache wie am 
Anfang, aber mir geht es jetzt nicht nur um CRC, sondern darum wie man 
libs allgemein benutzt: Wenn ich das installiert habe, wo finde ich die 
Header Files und die ggf. vorhandene Doku?
Bisher habe ich nur die AVR-Megas in C programmiert, so dass ich beim 
Raspberry Pi (und Linux-PC allgemein) gerade einen etwas holprigen 
Einstieg hin lege...

Hmm... schrieb:
> Was spricht den dagegen auf einem Linux Rechner eine Standard Linux
> Bibliothek zu benutzen? So ziemlich alle Debian Pakete sind doch für
> ARM
> Linux / Raspbian portiert und per apt-get verfügbar. Oder hab ich
> irgendwo was von Baremetal überlesen?

Nur die Tatsache dass ich noch den Einstieg in die LINUX-Programmierung 
suche. Kennst du ein Tutorial o.ä. das die Schritte erklärt die man 
braucht um eine der vielen existierenden libs einzubinden?

Vielen Dank an alle für die Tipps...

von Hmm... (Gast)


Lesenswert?

Naja, das schwierige ist meistens herauszufinden, WELCHE der 100 
möglichen Bibliotheken geeignet ist (Jörg hatte ja schon angedeutet das 
es neben der von mir erwähnten Lib noch ein Dutzend weitere gibt die 
eine CRC implementieren).

Unter Debian/Ubuntu & Co kann man sich die Quellen per Paketmanager mit 
herunterladen, meistens ist das die Endung *-dev (also für libcrcutil 
wäre dass dann libcrcutil-dev). Am besten dann noch die Doku dazu 
(libcrcutil-doc) mit installieren. Dann hat man die Bibliotheken (.so) 
schonmal auf dem System, ebenso die Header. Aus diesen kann man sich 
dann als Einstiegspunkt einige Funktionsaufrufe heraussuchen. Die 
ManPage dazu liefert dann eine Beschreibung und Verweise auf andere 
Funktionen.

Ebenso hilfreich ist es oft, wenn man sich mal die Quellen besorgt:

apt-get install bzr
bzr branch lp:ubuntu/wily/libcrcutil

Da finden sich dann häufig auch Test- und Beispielprogramme um mit der 
Lib warm zu werden.

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


Lesenswert?

asd schrieb:
> Ich vermute das Polynom steckt implizit in der Return-Anweisung?

Ja.  Ich hatte sogar mal verstanden, wie das zustande kommt. :)

Auf jeden Fall funktioniert die Routine erfolgreich auch gegen
entsprechende Hardwareimplementierungen.  Dieses Polynom (x^16 +
x^12 + x^5 + x^0) ist in der Kommunikationswelt recht häufig
anzutreffen.

Wichtig bei CRCs ist es noch zu wissen, dass es eine gewisse
Konfusion in der Anordnung der Bits im Byte gibt, sodass das gleiche
Polynom auf zwei Weisen implementiert werden kann.  Wenn du in den
schon genannten Header <util/crc16.h> der avr-libc siehst, wirst
du dasselbe Polynom in umgekehrter Bitreihenfolge nochmal als X-Modem
wiederfinden.

von Toni Tester (Gast)


Lesenswert?

Um die Beantwortung der Eingangsfrage des TO noch ein wenig 
detaillierter auszuführen:

WinAVR beinhaltet die AVR-libc. Die dort vorhandenen 
CRC-Implementierungen sind demzufolge kein C-Standard, sondern 
Erweiterungen dieser AVR-libc, deren Implementierungen speziell auf die 
AVR-Architektur optimiert sind.

Siehe: http://www.nongnu.org/avr-libc/user-manual/group__util__crc.html

Dort sind auch die funktionsäquivalenten C-Codes der Implementierungen 
enthalten.

von ♪Geist (Gast)


Lesenswert?

Wäre vielleicht das hier für dich hilfreich:

1
#include <stdio.h>
2
#include <string.h>
3
4
static uint16_t const  
5
CRC16Table [256] = {
6
  0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
7
  0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
8
  0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
9
  0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
10
  0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
11
  0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
12
  0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
13
  0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
14
  0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
15
  0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
16
  0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
17
  0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
18
  0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
19
  0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
20
  0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
21
  0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
22
  0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
23
  0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
24
  0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
25
  0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
26
  0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
27
  0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
28
  0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
29
  0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
30
  0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
31
  0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
32
  0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
33
  0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
34
  0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
35
  0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
36
  0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
37
  0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 
38
};
39
40
uint16_t 
41
CRC16Check (uint8_t* pByteData, int Length) {
42
  uint16_t Crc16Value;
43
  while(Length--) Crc16Value = CRC16Table[Crc16Value ^ *pByteData++];
44
  return Crc16Value;
45
}

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.