Datenprüfung

20/03/2010 - 08:34 von Karsten Sosna | Report spam
Hallo NG,
vielleicht bin ich einfach zu vorsichtig. Ich muss vorerst 2 Byte über die
serielle Schnittstelle übertragen. Ist nicht ganz richtig, ist eigentlich
USB. Nutzen tue dazu die Serialport-Klasse, der Comport ist ein virtueller
Port. Genauer hàngt an einem USB-Anschluß ein FT232R USB UART IC. Dieses IC
wandelt den USB-Datenstrom wieder in ein RS232 Signal um. Dieses wiederum
geht auf einen ATMEGA32(8-Bit AVR-Microcontroller).
Jetzt ist es so, dass ich mir keine Fehler bei der Übertragung der 2 Bytes
leisten kann, also dachte ich an eine CRC-Prüfung mit einem Generatorpolynom
7. Ordnung. Damit wàre mein Datenstrom nur 3 Bytes lang(2 Byte Nutzdaten und
1 Byte CRC-Prüfsumme). Ok, also schnell die Routine erstellt, die die
Checksumme berechnet.
\\\
Private Function GetCRC(ByVal HighByte As Byte, ByVal LowByte As Byte,
ByVal CRC As Byte) As Byte

Dim Poly As Byte = 149 'Eine Primzahl mit maximale Pegelwechsel
Dim ShftCnt As Byte = 0

'Grundsàtzlich erst mal teilen und einmal nach links schieben um
einen Startwert zu erhalten
'Console.WriteLine("{0}{1}{2}", Convert.ToString(HighByte,
2).PadLeft(8, "0"c), Convert.ToString(HighByte, 2).PadLeft(8, "0"c),
Convert.ToString(CRC, 2).PadLeft(7, "0"c))
HighByte = HighByte Xor Poly
HighByte = HighByte << 1
CRC = CRC << 1
If (LowByte And 128) = 128 Then
HighByte = HighByte Or CByte(1)
End If
LowByte = LowByte << 1
ShftCnt += CByte(1)
'Console.WriteLine("{0}", Convert.ToString(Poly, 2).PadLeft(8,
"0"c))
'Console.WriteLine("{0}", "==")
'Console.WriteLine("{0}{1}", New String(" "c, ShftCnt),
Convert.ToString(HighByte, 2).PadLeft(8, "0"c))

Do
If (HighByte And 128) = 128 Then
'Console.WriteLine("{0}{1}", New String(" "c, ShftCnt),
Convert.ToString(Poly, 2).PadLeft(8, "0"c))
'Console.WriteLine("{0}{1}", New String(" "c, ShftCnt),
"==")
HighByte = HighByte Xor Poly
If ShftCnt >= 15 Then
Exit Do
End If
Else
If ShftCnt >= 15 Then
Exit Do
ElseIf ShftCnt > 7 Then
ShftCnt += CByte(1)
HighByte = HighByte << 1
If (CRC And 128) = 128 Then
HighByte = HighByte Or CByte(1)
End If
CRC = CRC << 1
Else
ShftCnt += CByte(1)
HighByte = HighByte << 1
If (LowByte And 128) = 128 Then
HighByte = HighByte Or CByte(1)
End If
LowByte = LowByte << 1
End If
End If
'Console.WriteLine("{0}{1}", New String(" "c, ShftCnt),
Convert.ToString(HighByte, 2).PadLeft(8, "0"c))
Loop

'Console.WriteLine()
'Console.WriteLine("{0}{1}", New String(" "c, ShftCnt),
Convert.ToString(HighByte, 2).PadLeft(8, "0"c))

Return HighByte

End Function
///
Die Routine ist so geschrieben, da ich sie auch schnell in Assembler
schreiben kann, den Microcontroller muss ja prüfen.

Nun ist es aber so, dass ich die Routine mal so getestet habe, das ich nur 2
Nullbytes übertragen will, die Prüfsumme dafür ist dann b00110010. Ich habe
also mal alle möglichen Bytekombination mit dieser Prüfsumme checken lassen,
das Ergebnis hat mich schon etwas verblüfft. 511 Fehler wurden nicht
erkannt!
Ich weiß jetzt nicht, ob ich die Routine auch richtig implementiert habe,
möchte nun aber nicht, dass sich jemand die Arbeit macht das obige "Ding" zu
analysieren und zu testen. Meine Frage geht eher in 2 Richtungen:
1.) Ist es richtig, das es keine 100% CRC-Prüfung gibt?
2.) Kann ich mir das eigentlich nicht sparen? Eigentlich müsste doch die
USB-Übertragung schon Fehler erkennen. Über die Verbindung vom UART zum
Microcontroller mache ich mir keine Gedanken( a) sind beide auf einer
Platine platziert und dort vielleicht mit einem Abstand von maximal 2cm und
b) ist die Elektronik in einem abgeschirmten Gehàuse untergebracht. Dort
gibt es auch keine weiteren Einflüsse die stören könnten.)

Wenn 2.) nicht zutrifft, wie schaffe ich es 1.) auf jeden Fall auf 100%
zubekommen? Hierzu 2 Dinge: Der Datenstrom darf nicht zu lang werden und die
Prüfung muss in Assembler nachprogrammiert werden können, ergo keine
hochkomplexen Klassen.

Danke für jede Hilfe.
Gruß Scotty
 

Lesen sie die antworten

#1 Thomas Scheidegger
20/03/2010 - 08:54 | Warnen spam
Hallo Karsten

1.) keine 100% CRC-Prüfung gibt?



richtig, die meisten CRCs erkennen Fehler
nur akzeptabel zuverlàssig,
wenn in den Daten (bis bestimmter Lànge) 'einige wenige Bits kippen'.
Grundlagen und Alternativen etwa:
http://de.wikipedia.org/wiki/Zyklis...%C3%BCfung

2.) Eigentlich müsste doch die USB-Übertragung schon Fehler erkennen



ja, Prinzip etwa:
http://www.usb.org/developers/white...crcdes.pdf

P.S.
Oft werden 'bessere' CRCs nicht zu Laufzeit berechnet,
sondern via Tabellen 'beschleunigt'.
Vorausgesetzt man kann dafür 'einige hundert' Bytes
(zB 256 bei CRC8, 512 bei CRC-16)
Speicher (zB auch ROM) fix belegen.



Thomas Scheidegger - 'NETMaster'
http://dnetmaster.net/

Ähnliche fragen