Hallo Leute! Ich habe hier einen Atmel SAM4 Mirocontroller, den ich per USB an einen PC angeschlossen habe. Dabei wird die USB Communication Device Class (CDC) verwendet, um einen virtuellen COM Port benutzen zu können. Da ich nicht in die Untiefen von USB eindringen will, habe ich dazu einfach das Atmel Software Framework verwendet, d.h. ich könnte bspw. ganz einfach per printf() Daten an ein Terminalprogramm senden. Das funktioniert auch alles soweit. Jetzt möchte ich aber bestimmte Daten (byteweise) sicher übertragen. Jetzt stellt sich allerdings die Frage, welchen USB Transfer Modus das Atmel Software Framework für CDC benutzt. Laut diesem PDF http://www.atmel.com/Images/doc6269.pdf wird entweder ein Isochroner oder ein Bulk Transfer verwendet. Wie kann ich jetzt herausfinden, was genau verwendet wird? Der ASF Source Code ist leider sehr umfangreich und für mich als USB-Neuling nur schwer zu durchblicken. Allerdings hängt von der Übertragungsart ab, ob ich noch eine CRC an die Daten anhängen sollte oder nicht. Kommt ein Bulk Transfer zum Einsatz, wird automatisch eine CRC16 Prüfsumme berechnet und mitgeschickt. Da wäre es natürlich überflüssig nochmal eine CRC Summe zu berechnen, zumal Bulk Transfers eine Übertragung ohne Fehler sicherstellen (d.h. erneutes Senden der Daten bei Fehlern). Hat sich schon mal jemand mit dem Thema beschäftigt und kann mir weiterhelfen oder ein paar nützliche Hinweise geben, wie ich das herausfinden kann? Besten Dank im Voraus! Edit: Bevor es einer sagt: Ich weiß, dass der Begriff "Prüfsumme" bei CRC nicht ganz korrekt ist ;-)
:
Bearbeitet durch User
Unter Linux kann man sich z.B. mit Wireshark auch das USB-Protokoll mit anzeigen lassen. Beim der Arduino Kommunikation wird dort Bulk-Transfer verwendet. Zum Sam kann ich nichts sagen.
PittyJ schrieb: > Unter Linux kann man sich z.B. mit Wireshark auch das USB-Protokoll mit > anzeigen lassen. > Beim der Arduino Kommunikation wird dort Bulk-Transfer verwendet. > > Zum Sam kann ich nichts sagen. Danke für den Tipp, das werd ich mir mal genauer ansehen
Andi K. schrieb: > Jetzt stellt sich allerdings die Frage, welchen USB Transfer Modus das > Atmel Software Framework für CDC benutzt. Bei CDC Serial Port wird praktisch immer USB Bulk Mode für die Daten benutzt. Isochrone Transfers sind nur bei USB Audio üblich. > Wie kann ich jetzt herausfinden, was genau verwendet wird? An einer Linux Kiste (Live CD oder virtuell) anstecken und
1 | # lsusb -v | less |
ausführen. Das zeigt Dir u.a. die Endpoint Deskriptoren und auch deren Typ an. Ein CDC Serial Port hat 2 Interfaces, eins mit 1x Interrupt Endpoint für Steuerzwecke und eins mit 2x Bulk (In+Out) für die eigentlichen Daten. Einfacher ist es natürlich, wenn man den USB Configuration Descriptor im Source Code findet, da steht das ja auch drin. Andi K. schrieb: > Kommt ein Bulk Transfer zum Einsatz, > wird automatisch eine CRC16 Prüfsumme berechnet und mitgeschickt. Da > wäre es natürlich überflüssig nochmal eine CRC Summe zu berechnen Hätte ich auch gedacht - bis eine einfache XOR 8 Bit Prüfsumme einen subtilen Fehler in einem CDC Code Beispiel für NXPs LPC1768 aufdeckte. Auch eigene Fehler sind mit Checksumme oft leichter zu finden.
Jim Meba schrieb: > Einfacher ist es natürlich, wenn man den USB Configuration Descriptor im > Source Code findet, da steht das ja auch drin. Müsste ich da nicht eher nach dem Endpoint Descriptor suchen? Im Configuration Desciptor steht doch eher drin, ob das Gerät Bus oder Self powered ist etc. Der eigentliche Transfermodus dürfte im Endpoint Descriptor stehen, oder täusche ich mich da? Edit: Okay mit Wireshark in Verbindung mit USBPcap habe ich mir das ganze mal angesehen. Im Inteface Desciptor "class CDC data" gibt es zwei Endpoint Descriptors für die Datenübertragung und beide sind wie erwartet im Bulk-Modus ;)
:
Bearbeitet durch User
Hallo Andi, der Transfertyp steht, bei Offset 3, als "bmAttributes" im Endpunkt-Descriptor. Mögliche Werte: 00=Control, 01=isochron, 10=Bulk und 11=interrupt. Bei USB2.0 werden auch die Bits 2...5 benutzt, näheres findest du in der Spezifikation dazu. Gruß. Tom
Um das Ganze nochmal zu vervollständigen für alle Interessierten: In der Datei udi_cdc.h des Atmel Software Frameworks steht die Festlegung der Transfermodi der beiden Data Endpoints:
1 | #define UDI_CDC_DATA_DESC_COMMON \
|
2 | .iface.bLength = sizeof(usb_iface_desc_t),\
|
3 | .iface.bDescriptorType = USB_DT_INTERFACE,\
|
4 | .iface.bAlternateSetting = 0,\
|
5 | .iface.bNumEndpoints = 2,\
|
6 | .iface.bInterfaceClass = CDC_CLASS_DATA,\
|
7 | .iface.bInterfaceSubClass = 0,\
|
8 | .iface.bInterfaceProtocol = 0,\
|
9 | .ep_in.bLength = sizeof(usb_ep_desc_t),\
|
10 | .ep_in.bDescriptorType = USB_DT_ENDPOINT,\
|
11 | .ep_in.bmAttributes = USB_EP_TYPE_BULK,\
|
12 | .ep_in.bInterval = 0,\
|
13 | .ep_out.bLength = sizeof(usb_ep_desc_t),\
|
14 | .ep_out.bDescriptorType = USB_DT_ENDPOINT,\
|
15 | .ep_out.bmAttributes = USB_EP_TYPE_BULK,\
|
16 | .ep_out.bInterval = 0,
|
Das Ganze ist sehr verschachtelt und unübersichtlich, aber irgendwann kommt man doch zu der eigentlichen Definition ;) Jim Meba schrieb: > Hätte ich auch gedacht - bis eine einfache XOR 8 Bit Prüfsumme einen > subtilen Fehler in einem CDC Code Beispiel für NXPs LPC1768 aufdeckte. > Auch eigene Fehler sind mit Checksumme oft leichter zu finden. Okay, das ist interessant. D.h. du würdest sicherheitshalber trotzdem eine CRC Checksumme vorschlagen?
Zu Daten senden brauchst du aber trotzdem ein Protokoll, sonst weiß du ja nicht wann ein Datenpaket anfäng und Aufhört.
uwe schrieb: > Zu Daten senden brauchst du aber trotzdem ein Protokoll, sonst weiß du > ja nicht wann ein Datenpaket anfäng und Aufhört. Das ist schon klar, ein Protokoll ist auch vorhanden. Mir geht es jetzt nur um die Frage, ob eine CRC benötigt wird oder ob die "interne" CRC16, die bei Bulk-Transfers genutzt wird, ausreichend ist.
Hat keiner Erfahrung mit USB Bulk Transfers bezüglich sicherer Datenübertragung und ob eine zusätztliche CRC/Prüfsumme o.Ä. verwendet werden sollte?
Andi K. schrieb: > Hat keiner Erfahrung mit USB Bulk Transfers Anstatt dich auf umfängliche und leider oftmals nicht wirklich passende Libs von anderen zu verlassen ohne diese zu verstehen, solltest du besser die geräteseitige Funktionalität von sowas wie virtuellen COM Ports usw. verstehen lernen. Ja, ich weiß, die Doku ist auf den ersten Blick schwer verdaulich, aber wenn man erst mal das Prinzip verstanden hat, dann kommt man eigentlich mit allen USB-Devicecores klar. Der Knackpunkt liegt m.E. immer wieder auf der Stoßstelle zwischen interruptgesteuertem blockweisen Abholen von Daten (dev --> host) und dem asynchronen byteweisen Eingeben von zu sendenden Daten von der Anwendung in den Treiber. Was da schiefgeht, darf man der eigentlichen USB-Funktionalität nicht anlasten, die funktioniert in sich - jedenfalls bei Bulk-Transfers - schon sicher. Wenn du aber ganz besonders sicher gehen willst, dann bleibt dir nix anderes übrig, als auf die gesamte Datenübertragung noch ein blockweises prüfsummengesichertes Protokoll oben drauf zu setzen. W.S.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.