Hallo,
Ich habe versucht, Datenübertragungen von 1024 Bytes mittels VUSB
zwischen einem Ubuntu-PC und einem ATMEGA328p zu realisieren. Nur aus
irgendeinem mir nicht ersichtlichen Grund funktioniert dieses einfache
Bsp nicht.
Könnte mir jemand sagen wo mein Fehler liegt?
Danke im Voraus
Folgender Code(µC):
Die Größe von Endpoint 0 ist limitiert auf 64 Bytes.
D.h. 1024 bytes werden in 16 "short-packets" übertragen.
Gut möglich, dass deine Funktionen hardwareseitig oder host-seitig die
short packets nicht automatisch handeln, und du dich selbst drum kümmern
musst.
Da 1024/64 genau 16 sind, muss als 17. packet ein packet mit 0 byte
größe übertragen werden.
Hast du einen USB Analyzer mit dem du dir angucken kannst, was auf dem
Bus tatsächlich übertragen wird?
Wenn du größere Datenmengen schnell übertragen willst, benötigst du für
jede Richtung einen extra Endpoint (bulk oder isochronous). Die können
mehr als 64 bytes in einem Paket.
Roman B. schrieb:> Nein ich habe leider keinen solchen Analyzer. Wie definiere ich einen> extra Endpoint?
Dazu muss der Devicedescriptor des Gerätes entsprechend erweitert
werden.
> Und welche Art wäre besser?
Isochronous nimmt man z.B. für Streaming (z.B. Audio), für das auf dem
Bus eine feste Bandbreite reserviert wird. Es gibt aber kein
Error-Handling. Kaputte Pakete werden verworfen.
Bulk für alles andere (Mass Storage etc.).
Ist das mit VUSB überhaupt
> möglich?
Weiss ich nicht.
Mal anders herum gefragt:
Welche Datenmenge willst du denn pro Sekunde übertragen.
Evtl. reicht Endpoint 0 mit short packets ja auch aus.
Roman B. schrieb:> Ich will nur 1024 Bytes hin und wieder zurück schicken.
das geht, eben in 64 byte happen. und davon gehen max. 1000 stueck pro
sek.
wenn das reicht, machs ueber ep0.
du musst rausfinden, ob deine funktionen ein grosses paket automatisch
zerlegen/zusammensetzen. ansonsten musst du das von hand prigrammieren.
VUSB ist ja grundsätzlich Low Speed. Und für Low Speed Devices gilt,
dass Datenpakete maximal 8 Bytes groß sein dürfen. Bei Full Speed sind
64 Byte Pakete erlaubt. Siehe USB 2.0 Standard, Kapitel 8, Abschnitt
8.4.4 "Data Packets".
Außerdem kannst Du nur Control und Interrupt Transfers zu einem Low
Speed Device durchführen, Bulk Transfers erlaubt der USB 2.0 Standard
nicht. Siehe USB 2.0 Standard, Kapitel 5, Abschnitt 5.8.3 "Bulk Transfer
Packet Size Constraints": "A low-speed device must not have bulk
endpoints."
Also bleibe bei Control Transfers, spalte Dein Kilobyte in 8-Byte
Päckchen und verschicke die.
Wenn Du mit dieser Lösung unzufrieden bist, dann musst Du halt einen
richtigen USB-Controller verwenden, der Full-Speed USB in Hardware
macht. Das ist dann auch wirklich USB 2.0 Standard-konform.
fchk
Nein, hab leider keinen Hardware-USB-Controller:( Macht aber nix - hab
zwei Funktionen geschrieben die den Datentransfer in 128 Byte Blöcken
übernehmen! Das klappt einwandfrei:) Nur mehr als 254 Byte kann ich
nicht auf einmal transferieren (auch mit USB_CFG_LONG_TRANSFERS=1
nicht)- daher die 128 Byte Blöcke.
Ich persönlich finde VUSB echt gut weil man mithilfe von 5
"Standard-Bauteilen" (3 Widerstände, 2 Zener-Dioden) einen AVR über USB
kommunizieren lassen kann. Man muss sich halt manchmal softwaretechnisch
etwas behelfen aber sonst klappt´s (bei mir zumindest) einwandfrei
(obwohl ich mich mit USB nicht besonders gut auskenne - mehr als
control-transfers bring ich nicht zustande).
Danke für die Hilfe - Problem gelöst
P.S.: Danke für den Tipp mit Wireshark als USB Analyzer