Hallo liebes Forum,
ich habe eine Frage an Leute die schon einmal einen USB Host Controller
mit dazu gehörigen Treiber integriert haben.
Ich bin gerade dabei einen Host Controller vom System Bus (AHB) zu
trennen und auf einen zweiten Bus(AHB) zu hängen. Ich entwickele einen
Bridge (Network on Chip) der es dem Processor ermöglicht weiterhin auf
der Host Controller zu zugreifen. Leider wird der Round Trip Time für
den Prozessor zu lange sein um einen direkten Zugriff zu zulassen
(Performance). Stattdessen will ich am System Bus vom Prozessor ein
lokales Register (die alle 1000 clock cycle upgedatet wird) einrichten
und dem Prozessor einen HC vorspielen.
Es klingt ein bisschen gefährlich in meinen Ohren in Bezug auf Hardware
und Treiber Interaktion und ungewünschte/unbemerkte Zuständen, aber ich
sehe sonst keinen anderen Weg ohne einen neuen HC Treiber zu schreiben.
Momentan hoffe ich dass der USB zugriffen einfach nur ewig lange dauern
wird.
Kennt sich jemand mit USB 2.0 auf Hardware-Ebene aus?
Lg
Elvin S. schrieb:> Ich bin gerade dabei einen Host Controller
EHCI?
> Leider wird der Round Trip Time für> den Prozessor zu lange sein um einen direkten Zugriff zu zulassen> (Performance). Stattdessen will ich am System Bus vom Prozessor ein> lokales Register (die alle 1000 clock cycle upgedatet wird) einrichten> und dem Prozessor einen HC vorspielen.>> Es klingt ein bisschen gefährlich in meinen Ohren in Bezug auf Hardware> und Treiber Interaktion und ungewünschte/unbemerkte Zuständen,
Ein bisschen? Wie soll denn die Synchronisation mit den ganzen
Datenstrukturen im RAM funktionieren?
Wenn das ein normaler Hostcontroller (U/O/EHCI) ist, dann läuft der doch
ohnehin eigenständig aus den RAM-Datenstrukturen und produziert nur ab
und zu einen Interrupt, wenn ein Transfer "durch" ist. Der *HCI-Treiber
schaut dann in den RAM-Strukturen nach, was sich geändert hat. Das
sollte im ms-Raster passieren können, die Zugriffe auf die HW-Register
sind relativ überschaubar.
Ich sehe nicht, dass da 1000 Taktzyklen irgendwas stören könnten.
Allerdings gibt es halt auch wegen dem Root-Hub schon eine ganze Menge
R/W-Register, die man da umsetzen muss, das ist nicht nur eines...
Wenn das ein anderer Spar-Controller ist, wirds interessant ;)
Ja ich implementiere UHCI und EHCI für Low-speed, Full-speed und
High-speed.
Für den Host Controller wird eine Chip IP benutzt weil das ganze ein
ASIC werden soll. Momentan arbeite ich an einem FPGA ohne USB-PHY. Finde
aber kein einziges Board wo ein echter USB drauf ist.
Momentan bin ich eh nicht so weit dass was zum Testen hätte. Ich lese
mich gerade in USB UHCI und EHCI Manuals von Intel ein. Ist aber sehr
trocken und unverständlich wie die einzelnen Register voneinander
abhängen. Root-Hub Register gibt es eh nicht soviele bei UHCI (6 +
1/Port) und EHCI(14 + 1/Port), wenn man PCI Register deaktiviert, da es
bei mir an einem AHB Bus hängt.
Das Updaten der Register sollte dann übersichtlich sein. Ich werde als
Fallback die Möglichkeit einbauen nur direkt auf die Register zu
schreiben ohne lokale Kopie (echter Bridge), ist sicherer und macht das
Teil nur extremst langsam aber dafür funktionierts.
Trotzdem muss ich versuchen mit lokaler Kopie zu arbeiten wegen der
Performance. Deshalb sammele ich aus allen Quellen soviel Informationen
über USB damit ich weiß worauf ich achten muss.
----------
Vielleich sollte ich noch erwähnen warum ich mir das antue.
Das ist meine Diplomarbeit. Die am Institut wollen eine MPSoC
produzieren lassen, wo auf jedem Prozessor ein Betriebssystem läuft. Ein
Prozessor kann sich dann über Network on Chip mit dem USB verbinden und
ihn verwalten. Soll aber nicht immer der selbe sein, damit man später
bisschen experementieren kann.
Elvin S. schrieb:> Trotzdem muss ich versuchen mit lokaler Kopie zu arbeiten wegen der> Performance.
OHCI/EHCI wurden für PCI entworfen, und da kann ein Register-Zugriff
durchaus mal eine Mikrosekunde dauern. (Deswegen liegen die Deskriptoren
auch im RAM, so dass normalerweise keine Register benötigt werden.)
Mit diesen lokalen Kopien riskierst du nur Datenfehler. Was ist, wenn
ein Interrupt ankommt, aber das Bit im USBSTS- oder PORTSC-Register noch
nicht gesetzt ist? Du musst die Software ändern, so dass sie nach 1000
Taktzyklen noch einmal nachschaut, und dann kannst du es gleich sein
lassen.
> Mit diesen lokalen Kopien riskierst du nur Datenfehler. Was ist, wenn> ein Interrupt ankommt, aber das Bit im USBSTS- oder PORTSC-Register noch> nicht gesetzt ist? Du musst die Software ändern, so dass sie nach 1000> Taktzyklen noch einmal nachschaut, und dann kannst du es gleich sein> lassen.
Mit der lokalen Kopie habe ich es mir so vorgestellt: der USB Interrupt
wird vom meinem Bridge verwaltet. Die Bridge initiert von der USB-Seite
eine Update der Kopie und anschließend wird der Interrupt zum
Interrupt-Controller vom Prozessor weitergeleitet. Kann man das so
machen? Würde da wo anderes ein Problem auftauchen?
Größere Sorge momentan ist ob es Register gibt die wenn geschrieben
werden ein anderes Register umsetzt welche ich dann sofort updaten muss?
Elvin S. schrieb:> Würde da wo anderes ein Problem auftauchen?
Das kann ich nicht ausschließen.
> Größere Sorge momentan ist ob es Register gibt die wenn geschrieben> werden ein anderes Register umsetzt welche ich dann sofort updaten muss?
Du kannst dich nicht darauf verlassen, dass bei allen interessanten
Ereignissen auch ein Interrupt kommt.
Wie langsam wäre den ein Registerzugriff über den anderen Bus?
Also der direkte Zugriff würde beim Tunneln von AHB (parallel) über
Network on Chip (NoC) (seriell) 4x32bits brauchen (=128 zyklen seriell).
Nach meinem Protokoll, 32bits für Verwaltung, 32bits für AHB
Kontrollsignal, 32bits für Adresse, 32bits für Daten.
Diese brauchen zusätzlich einem NoC Header und einen CRC (+ 2x32bits=64
Zyklen seriell) läuft minimum über 2 Router, Maximum 5 die
wahrscheinlich jeder intern nochmal paar taktzyklen verbraucht. Also
schon einige Taktzyklen deshalb wird der NoC Takt einiges höher sein als
der vom Systembus. Wir sind noch dabei die Timing Anforderungen
durchzugehen. Aber ja 1000 NoC Zyklen können da schon anfallen für ein
einzelnes Register. (Wenn wir den sagen NoC_clk=4*AHB_clk speed)
entspricht das schon 250 Zyklen deshalb 500zyklen round trip time.
Wenn man aber mehrer hintereinander ohne ACKs überträgt kommen sie im
Abstand von (192/4=)50 (NoC_clk=4*AHB_clk) Systembuszyklen an.
> Und in welchem Teil des Treibers würde das ein Problem werden?
Keine Ahnung. Kenne mich da zu wenig aus, aber für meinen Betreuer wäre
das zu lange um drauf zu warten, Performance und Zeugs oder es ist
einfach viel zu uncool solange drauf zu warten, frag mich nicht.
Ich suche nur nach Wegen wie man das mit der lokalen Kopie der Register
machen könnte bzw. Gründe warum man das nicht machen sollte damit ich es
argumentieren kann.
Ich werde sowieso die Option des direkten Zugriffs einbauen ohne Kopie
der Register auch wenn es langsamer ist. Falls alles schief gehen
sollte, kann man dann mit dem Teil mehr machen als im Winter zu heizen
;)
Elvin S. schrieb:> Ich suche nur nach Wegen wie man das mit der lokalen Kopie der Register> machen könnte bzw. Gründe warum man das nicht machen sollte damit ich es> argumentieren kann.
Wenn du einen Cache baust, ist es deine Aufgabe, zu beweisen, dass er
sich immer noch an die *HCI-Spezifikationen hält.
Es wäre einfacher, wenn du einen Cache nur für die Register hast, bei
denen es wirklich notwendig ist. (Und meiner Meinung nacht gilt das für
keines der Register.)
> für meinen Betreuer wäre das zu lange um drauf zu warten, Performance> und Zeugs oder es ist einfach viel zu uncool solange drauf zu warten,> frag mich nicht.
Doch, ich frage dich. :-)
Und in deiner Diplomarbeit musst du begründen, warum du einen Cache
eingebaust hast.
> Doch, ich frage dich. :-)>> Und in deiner Diplomarbeit musst du begründen, warum du einen Cache> eingebaust hast.
Touché.
Ja du hast mich auf einen interessanten Gedankengang geführt den ich bis
jetzt komischer noch nicht verfolgt habe und die Aussagen meiner
Betreuer als bare Münze genommen habe.
Warum wären diese 500Zyklen zu langsam? Oder ab welcher Latenz wäre ein
direkter Zugriff das System ausbremsen? Wie sieht es bei der Latenz von
PCI-Systemen aus? Hmmmmm. Danke.
Von Zeit in ns reden wir eigentlich? Wen sich das im einstelligen
us-Bereich abspielt, ist das für die sonstige Interrupt-Latenz zwar eher
unschön, die USB-Funktion bzw. Treiberinteraktion wird davon sicher
nicht gestört. Schau doch mal in den EHCI-Treiber von Linux, der greift
ausser im Setup und dem Hub-Handling nur wenig auf die
Controller-Register zu.
Gibs da einen Link wo der Treiber erklärt wird oder hast du gemeint ich
soll den Quellcode durchstöbern.
Die Info das der USB hauptsächlich mit RAM-Datenstrukturen arbeitet und
der Rest sehr selten benutzt wird war schon sehr hilfreich. Es
verbessert das Verständnis beim Lesen vom EHCI Manual enorm. Danke
> Gibs da einen Link wo der Treiber erklärt wird oder hast du gemeint ich> soll den Quellcode durchstöbern.
Bei Linux wird nichts erklärt, also letzteres ;) Register-Zugriffe beim
Linux-EHCI-Treiber werden über ehci_readl bzw. ehci_writel gekapselt.
Davon gibts gar nicht soviele, am meisten noch in ehci-hub.c, das
Hubport-Handling läuft halt über viele Status-Register.
Du kannst auch UHCI nehmen, der ist vom Prinzip her sehr ähnlich, aber
deutlich einfacher, da ist es dann uhci_readw/writew.