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,
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.
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
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?
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.
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).
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.
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
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 ;)
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.
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?
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.
@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 ;-)
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.
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_tcrc_ccitt_update(uint16_tcrc,uint8_tdata)
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. :-)
> 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...
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.
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.
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.