netzstaub

beatz & funkz

Sunday, March 20, 2005

Usb Host-Entwicklung

Ich durfte in den letzten Tagen eine USB-Host-Applikation entwickeln. Dazu wurde ein EZ-OTG Kontroller von Cypress eingesetzt. Fürs erste keinen Code, weil der nicht mir gehört.

Der EZ-OTG Kontroller

Der EZ-OTG ist ein kleiner, netter USB-OTG Kontroller. OTG heisst “On-The-Go”, und bezeichnet die Fähigkeit, sowohl USB-Host als auch USB-Device zu sein. Der EZ-OTG kann also im Betrieb seine Funktion wechseln. Der Chip verfügt über 2 sogenannte SIE (Serial Interface Engine), die beide Host oder Device sein können. Nur die erste SIE kann allerdings OTG. Der EZ-OTG ist allerdings nicht nur ein “stumpfer” Kontroller, sondern hat eine eigene 16-Bit CPU, für die man auch Programmcode nachladen kann. Man kann den EZ-OTG also in zwei verschiedenen Modi fahren: in dem einen “Slave”-Modus wird der EZ-OTG praktisch als Kontroller eingesetzt, in dem “Standalone”-Modus ist er CPU und Kontroller zugleich. In beiden Fällen kann man den “BIOS” des EZ-OTG verwenden. Der BIOS besteht aus 8 kB Assembler Code, der sich über Interrupts ansprechen lässt (ganz wie der alte PC-Bios). Er übernimmt schon die meiste Hardware-Funktionalität (z.B. UART Handling), man kann aber jederzeit die Interrupt-Einträge des BIOS überschreibe, um seinen eigenen Code da reinzufrimeln.

In dem Standalone Modus kann der Kontroller Code aus einem EEPROM laden, oder z.B. über USB laden (wie die anderen USB-Device Kontroller von Cypress, dem EZ-FX und EZ-FX2). In dem Slave Modus bietet der Cypress verschiedene Schnittstellen an, über die die eigentliche CPU mit dem LCP Protokoll Kommandos an den Cypress absetzen kann (z.B. BIOS Funktionen aufrufen, oder im RAM rumschreiben). In dem Fall meiner Applikation habe ich den Standalone-Modus verwendet.

Die Entwicklungsumgebung

Das Entwicklungsboard von Cypress zu dem EZ-OTG hat einen EZ-OTG, 4 EEPROMS, eine ganze Reihe an Pins zum Anschliessen von Hardware an den Kontroller, ein paar Taster, ein LED-Display, und 2 SIE-Schnittstellen. An jeder SIE Schnittstelle kann man 2 USB-Devices anschliessen, oder einen USB-Host. Die erste SIE wird standardmässig zum Debuggen verwendet, der BIOS lässt da normalerweise Code laufen, mit dem der GDB dann die CPU steuern kann (so eine Art JTAG für Arme). Die zweite SIE kann man dann frei verwenden.

Software-mässig liefert Cypress eine Cygwin-Umgebung mit Crosscompiler Toolchain für die 16-Bit CPU auf dem EZ-OTG (mal sehen, ob ich irgendwo den Source dazu finde, unter Linux entwickeln wär schick0r). Zum Debuggen kommt ein GDB mit einer anstrengenden Tk-Oberfläche (namens Insight), die über TCP mit einer Zwischensoftware kommuniziert, die dann USB-Kommandos an den Cypress absetzt. Bei dem Entwicklungsboard liegt auch ein Buch bei, das “Developing Multi-Role USB Applications” heisst, von John Hyde, der auch ein Buch über USB-Entwicklung geschrieben hat. Dieses Buch beschreibt, wie man mit dem EZ-Host (der grosse Bruder des EZ-OTGs) und dem EZ-OTG Applikationen baut. Das in einer ziemlich angenehmen Hands-On Art. Ich steh ja normalerweise nicht wirklich auf Bücher, die an eine spezielle Technologie gebunden sind, aber in dem Fall war es recht angenehm. In einem Kapitel stellt er kurz vor, wie man die LEDs blinken lässt (also eher ein Tutorial, wie man überhaupt den GCC und den GDB und so verwendet), wie man ein kleines HID-Device baut, dass die Tastendrücke als Tastatur weiterleitet. Dann kommt ein Kapitel über Host-Entwicklung, in der gerade diese HID-Device jetzt als Host kontrolliert wird. Zu den ganzen Applikationen haben Hyde und seine Kumpanen einen riesigen Framework gebaut, der sage und schreibe 20000 Zeilen Code umfasst. Die Host-Applikation ist dadurch, trotz extensiver Unterstützung durch den BIOS immerhin 16 kB gross (!).

Ich muss jetzt wirklich ein bisschen rumlästern. Den dieses Framework wär ja vielleicht noch ganz nett, wenn es a) gut dokumentiert wäre, und b), noch viel wichtiger, keine groben Bugs beinhalten würde. Scheinbar haben Cypress und Hyde den Code aber nie “wirklich” verwendet, denn es ist z.B. unmöglich, in der Form ein dual-Host Device zu schreiben, oder BULK-Transfers sauber zu machen. In dem ersten Fall hat ein scheinbar dummer Fehler beim Copy/Paste Code die Auswirkung, dass ein zweites Gerät nicht erkannt wird, und dafür den Zustand des ersten kaputt-schreibt. Bei BULK-Transfers resettet ein Lesen immer das Data-Toggle-bit vom Schreiben, so dass die DATA0 und DATA1-Pakete Abwechslung, die bei USB notwendig ist, nicht mehr passiert. Ich finde das wirklich sehr peinlich, und es gingen ein paar Stunden aufgeregtes Debuggen drauf, diese Fehler zu finden. Der GDB, der für jeden Singlestep 5 Sekunden braucht, ist da auch keine wirklich Hilfe. Ich musste ziemlich schnell auf das alt-bewährte Mittel des printf-Debuggings zurückgreifen.

Ich frage mich also, wieso Cypress mit dem EZ-OTG und EZ-Host dieses Framework vertreibt (man kann natürlich ohne programmieren, dafür gibt es aber keine Application Notes). Viel schöner wäre es doch gewesen, kleine Standalone-Applikationen zu bauen, die zwar dann komplizierter zu verstehen sind, weil sie das ganze Host-Handling selber machen. Dafür aber kein 16 kB-grosses Code-Monstrum mit sich schleppen (mit, achtung, dynamischer Speicheralloziierung, verketteten Listen in jede Richtung, einer Treiber-Infrastruktur, und was weiss ich noch alles geile). Nun gut, vielleicht werde ich da noch was schönes schreiben, wenn ich an die passende Hardware komme. In dem Umfeld wäre es auch denke ich ganz schick, Protothreads zu verwenden, anstatt riesige Callback-basierte State-Machines zu verwenden, wie es im Moment der Fall ist.

posted by manuel at 3:44 pm  

2 Comments »

  1. Hi manuel,

    vielleicht kannst du mir helfen?

    Ich habe seit einigen Tagen das Devboard des EZ-OTG auf dem Tisch un versuche hier eine auf den ersten Blick einfache Sache wie Tastatur erkennen, Eingaben Puffern und auf Anforderung weitergeben zu basteln. SIE1 Host, SIE2 Debug, RS232 Ausgabe der Tastatur.

    Hierzu wollte ich als Test mal die ansich logischen Beispiele DE3 und SE6 modifizieren.

    Naja nun ist schon die fünfte Nacht rum und so richtig tut sich nichts.

    DE3 lässt sich zwar ins E²Prom laden und ausühren, aber mit den Debugger nicht über RS232 debuggen. Habe dann versucht den SIE2 als ebugport zu nutzen(Devicefunktion raus Debug rein), hat leider auch nicht funktioniert.
    -> Ich kann die Applikation zwar ruterladen, aber nicht debuggen. Hast du hier eine Idee wie ich hier ordentlich debugen könnte?

    SE6 Hier habe ich einiges an Zeit verschwendet, um das Programm in den EZ-OTG zu senden und anzustarten, beim Debuggen ist das Teil bei der Allocierung immer im Nirvana verschwunden. Naja wer lesen kann ist klar im Vorteil, das Programm ist für den EZ-HOST und ich habe nur das EZ-OTG Board. Vielleicht eine Dumme Frage, aber wie bekomme ich es hin, daß die EZ-HOST SW im EZ-OTG läuft.

    Gruß und Dank

    Philip

    Comment by Philip — January 5, 2006 @ 11:06 am

  2. Enlightening article, thanks a lot. Unfortunately, my German isn’t that good so I’m just commenting in English for fear of embarassment.

    Comment by Gucci Handbags — June 4, 2008 @ 9:45 am

RSS feed for comments on this post.

Leave a comment

Powered by WordPress