Hallo ich versuche gerade in meine Anwendung ein CRC Check einzusetzen
und bin dabei über diess Seite gestoßen:
http://www.easics.com/webtools/crctool
Bei diesem Tool wird ein Package erzeugt das ich in meiner Anwendung
benutzen kann.Der Funktionsaufruf benötigt zum einem die Daten (logisch)
und einen CRC Wert(versteh ich nicht)
Sollte es nicht eigentlich so sein das er mir aus meinen Daten ein CRC
erzeugt?
Würde mich freuen wenn mir jemand weiterhelfen könnte
Gruß Denis
Nein, das Prüfpolynom steckt bereits in den erzeugten Zuweisungen samt
xor drinne.
Mit dem crc wert ist lediglich die Initialisierung gemeint bzw der alte
Wert aus dem der Neue erzeugt wird.
Mein Tipp : benutz ruhig die Xor-Gleichungen, aber bastel den Rest vom
Aufbau um.
Das ganze macht mMn als Funktionsaufruf wenig Sinn.
Besser ist es ein Modul daraus zu basteln:
- das den aktuellen crc sowohl liefert als auch intern puffert
- einen reseteingang hat(um wieder den puffer auf initial zu setzen)
- einen Eingang hat um die neuen Daten mit dem alten crc zu akkumulieren
(sinnvollerweise + enable)
- das ganze getaktet vornimmt
So hab ichs zumindest gemacht(auch mit dem Generator) und es
funktioniert tadellos bei minimalem Ressourcenverbrauch.
Man muss einmal den Datenwert initialisieren, i.d.R. mit Null. Dann
zyklisch in den Code (als Funktion) reingehen und den aktuellen CRC aus
dem alten + dem neuen Datum ehrhalten.
Man muss nur aufpassen, welches bei deren Zählweise Bit1 und Bit n ist.
Bei mir ist das immer irgendwie verdreht.
@ Iulius
Ok das mit der Umarbeitung habe ich auch schon gemacht, habe das ganze
nur als Vorlage benutzt.
Aber wenn ich immer wieder den voherigen Wert nehme um daraus den neuen
zu generieren verstehe ich nicht wie der Check funktionieren soll.
Ich habe gestern mal versucht die Pakete auszuwerten aber das
funktioniert nicht.
Meines Wissens nach muss ich doch "data <= data_in and crc_in" und "c <=
crc_in" übergeben werden damit beim newcrc null rauskommt,oder nicht?
mit crc übergibst du wie schon gesagt einen startwert (meist != 0x00,
ich seh relativ oft 0xAA) für dein berechnungspolynom bzw. wenn du mehr
daten hast, als in den datenvektor reinpassen, dann musst du deine daten
natürlich splitten. mit crc übergibst du dann den crc-wert des
vorhergehenden teils.
für jeden datenblock (der einen eigenen crc bekommen soll) fängst du
natürlich wieder mit dem startwert an.
woher weißt du eg dass dein crc mit polinomial-verfahren berechnet wird,
wenn da das tabellenverfahren genutzt wird, ist das berechnen schon
recht schwierig ohne den ursprungs-quellcode zu kennen.
@Erik
Ah danke diese Info hat mir gefehlt.Mein Aufbau sieht nämlich gerade so
aus das ich 20Pakete a 32Bit schicken möchte Plus ein Header mit CRC für
diese 20 Pakete.
Ok wenn ich danach wieder den Startwert nehme macht es natürlich Sinn
aber das ging bisher aus dem was ich gelesen habe nicht hervor.
Aber wie genau muss ich jetzt den Checker aufbauen?
War mein oberer Ansatz dann richtig, bis auf das ich für c den Startwert
einsetze.
Und zu deiner Frage der Aufbau des XOR entspricht doch genau der
Polynomendivision oder nicht?
Denis schrieb:
> Aber wie genau muss ich jetzt den Checker aufbauen?>> War mein oberer Ansatz dann richtig, bis auf das ich für c den Startwert> einsetze.
also dein 32 bit packet splittest du also in 4 teile à 8 bit
erster funktionsaufruf:
Data <- ersten 8 Bit Daten
crc <- Startwert
liefert crc1
zweiter funktionsaufruf
Data <- zweiten 8 Bit Daten
crc <- crc1
liefert crc2
usw. nach dem vierten funktionsaufruf hast du dann den crc für dein
komplettes packet
> Und zu deiner Frage der Aufbau des XOR entspricht doch genau der> Polynomendivision oder nicht?
meine frage hat sich erledigt...hat sich so angehört, als wolltest du
einen übergebenen crc prüfen, aber wenn du den erstellen willst um ihn
in den header zu schreiben ist das schon okay.
@Erik :
also den Code den ich angehangen habe dient nur als Grundlage für dieses
Gesrpäch. Ich verwende natürlich einen 32 Bit breiten Bus damit die
Durchlaufzeit verkürzt wird.
Aber wie ich den Checker mache weiß ich trotzdem noch nicht meiner
spuckt mir falsche Werte aus.Der Generator ist jetzt klar.
d <= data_in and crc_in
c <= crc_startwert
dabei sollte dann doch null rauskommen oder?
so sollte es gehen
d <= data_in & crc_in
c <= crc_startwert
du musst crc_in an data_in anhängen, bei dir war das ne logische
und-verknüpfung (brauchste natürlich auch nen größeren bus)
Also der Checker gibt immer noch falsche Werte aus.
Ich habe mal die relevanten Teile mit angehangen.
Ich sende ein Paket mit der Info X"11111111" der CRC Generator erzeugt
ein CRC von X"B313" wenn ich das versuche auszuwerten kommt raus X"7F15"
Wie kann das sein?
Das ist viel zu aufwendig, vor allem : warum speicherst du Tonnen an
Informationen ?
Das einzige was du speichern musst ist der alte CRC Wert, der ggf auf
einen Init Wert resettet wird.
Diese alte Wert wird dann mit dem Eingang verknüpft. Mal ein Auszug wie
das aussehen kann :
dataIn : IN unsigned (7 downto 0);
data_wrEn : IN std_logic;
...
signal crc_buffer : unsigned(15 downto 0) := (others => '0');
...
if data_wrEn='1' then ...
crc_buffer(6) <= dataIn(0) xor crc_buffer(14) xor crc_buffer(0);
Keine Ahnung was z.b.
"d<= DATA_IN & X"B313";"
bei dir bewirken soll...das Polynom steckt komplett in dem xor-Wust !
@Iulius :
wieso speichere ich Tonnen von Daten? Also ich glaub du verstehst mich
gerade nicht.Das was ich dort mache war nur ein Test um zu überprüfen ob
der CRC Check funktioniert
Mein Generator bekommt ein Datenpaket d <= X"11111111" und den Startwert
für CRC X"FFFF" daraus erzeugt er mir den neuen CRC Wert der X"B313"
Im Checker sollte dann durch Verknüpfen der empfangen Datenpakete die
derzeit dauerhaft X"11111111" sind beim durchlaufen des Generators einen
CRC von null ergeben.
So sieht doch der normale CRC Check aus,oder nicht?
ah ich seh grad, dass du ja nen anderes polynom nimmst...wär nich
schlecht, wenn du das mal angibst
dann gleich noch ne frage, wo wird deinem Checker eigentlich der zu
überprüfende crc-wert übergeben?
@Erik
ja das Polynom ist ja eher unwichtig nur es muss bei Sender und
Empfänger gleich sein.
Ich benutze diese Konfiguration:
-- polynomial: (0 2 15 16)
-- data width: 32
-- convention: the first serial bit is D[31]
Das was du vorschlägst ist auch die Weise die ich bevorzugen
würden.Diese habe ich auch schon programmiert und getestet und sie
funktioniert. Nur mein Chef wollte es nach dem Standart machen und da
ist es doch eigentlich so, dass der Check den CRC Wert des Senders mit
in die Generierung des neuen CRC Werts einbezieht. Der neue CRC Wert
muss bei korrekter Übertragung dann null ergeben.
Also Frage, ist das was du vorschlägst und ich auch schon umgesetzt habe
ein echter CRC Check?Sprich auf Sende und Empfangseite die Daten durch
den gleichen Generator laufen lassen und die beiden CRC's vergleichen.
Wenn diese identisch sind war die Übertragung ok.
ja wenn du den crc-wert einfach hinten anhängst müsste bei der
berechnung 0 herauskommen.
aber ich seh grad, dass du für die vollständige berechnung noch elemente
nicht mit einbeziehst.
dein DATA_IN sind 32 bit dein CRC 16bit
wenn du nun mit d<= DATA_IN & X"B313"
beide aneinander hängst hat d folglich eine länge von 48 bit
deine CRC berechnung geht aber nur bis d(31).
wenn du den generator von oben benutzen willst mach einfach nen haken
bei 32 und einen bei 16 und schon hast du nen 48 bit datenbus.
dann sollte bei der berechnung 0 rauskommen.
Ich versteh immer noch nicht was ihr mit dieser Zeile macht :
>> wenn du nun mit d<= DATA_IN & X"B313"
Warum zum Kuckuck hängt ihr einen Fixen Wert an das Data_in dran ?
so mache ichs :
- reset kommt rein -> crc_buffer wird resettet
- data_in kommt rein
- data_in wird mit crc_buffer xor verknüft nach Polynom und in
crc_buffer gespeichert
- crc_buffer enthält zu jedem zeitpunkt den aktuell berechneten crc Wert
aus allen gelieferten Datenworten.
Damit kann man problemlos einen Datenstream aus z.b. bytes in den
crc-check reinschleusen und wenn der Stream zuende ist und am streamende
auch der crc vom Empfänger enthalten war liegt am Ausgang des crc-check
moduls 00...00 an auf das man prüfen kann.
>> wieso speichere ich Tonnen von Daten?
wozu speicherst du data_in in d ?
Das kannst du direkt in den gleichungen verwendenund musst es nicht
einen takt puffern
wozu einen i_crc und ein newcrc ?
der newCRC ergibt sich direkt aus der Xor-Verknüpfung des alten CRC mit
dem data_in
Am besten ich mach nachher mal schnell für nen 8er crc ein modul +
testbench um zu zeigen was ich meine.
Das hier sieht einfach kompliziert hoch 10 aus obwohl es doch eigentlich
soooo einfach ist.
einfach wär es geblieben hätt er die funktion die der generator erzeugt
benutzt. versteh sowieso nich, warum man für ne lineare crc-berechnung
glei nen eigenes modul machen muss
Hmm, vielleicht weil man dann einfach die Daten durchschleusen kann und
nicht den ganzen Krempel außerhalb speichern muss ?
Hier mal schnell zusammengeschustert, aber funktioniert wunderbar :
crc-8 (8+2+1+0) auf 8 bit datenstream, erzeugt mit easics, umgeschrieben
zum modul, verifiziert mit diesem calculator :
http://smbus.org/faq/crc8Applet.htm
code + testbench + waveform im anhang
@Iulius
Das X"B313 war nur der CRC Wert den Generator ausgibt wenn ich das
Datenwort X"11111111" eingebe.
Aber ich weiß jetzt worauf du hinaus willst.
@Erik
Ich habe es als Prozess eingebunden und geclockt damit ich synchron
bleibe mein Compiler bringt sonst Fehler und sagt ich erzeuge ein Latch.
Habe es jetzt hinbekommen danke für eure Hilfe!
Mein Fehler war das ich das letzte Datenwort meiner Payload mit dem CRC
verbunden habe anstatt den CRC am Schluss in den Generator einzugeben.
Entweder habe ich das bei Wikipedia falsch verstanden oder es ist ein
Fehler drin denn dort wird das Paket mit dem CRC verbunden und gecheckt.
Ich benutze jetzt den CRC32 Ethernet für einen 32 Bit breiten Datenbus
und überprüfe 20 Pakete und speise den erzeugten CRC Wert wieder mit
ein. Am Schluss wird der CRC Wert als Datenwort in den Checker geladen
und wenn das Senden der Daten erfolgreich war kommt als neuer CRC Wert
null raus.
Denis schrieb:
> Entweder habe ich das bei Wikipedia falsch verstanden oder es ist ein> Fehler drin denn dort wird das Paket mit dem CRC verbunden und gecheckt.
ne das is schon richtig, was im wiki steht...dein check ging aber nur
bis zum 32ten bit...wenn du crc und daten aneinander hängen musst hast
du aber 48 bit. damit war deine überprüfung unvollständig.