Hallo, ich hab ein VHDL Modul, das 16 bit vom FIFO liest und in einem IN cypress EP Buffer schreibt. Der usb contoller ist in slave fifo Mode asynchron getrieben. ich verwende SLWR, FIFOADR(10), PKEND = 1, SLRD = 1 als inputs (alle Flags Low activ)für den cypress SLCS Flag hab ich weggelassen als output bekomme ich FULL Flag Signal Problem: 1-Die daten kommen nicht vollständig zu PC: Ursache: Der Full Flag cypress output(Low activ), der mein VHDL Modul steuert bleibt zu lange auf null -> die Folge: Daten Stau in FPGA FIFO und FPGA Eingangsdaten gehen verloren. Wie kann ich das Problem lösen? Gruß bernadette
Darfst halt nur Daten aus dem FIFO lesen, wenn das Full-Flag nicht low ist. Datenstau ist noch kein Datenverlust. Wenn du streaming machen willst, also vorne schreibt einer Daten ins FIFO und du liest das FIFO per USB aus, kann es natürlich zu Datenverlust kommen, wenn die FIFOs zu klein sind. Das Betriebssystem hat gerne mal was anderes zu tun, als Daten vom USB abzuholen, besonders bei BULK Transfer. Willst du eine garantierte Bandbreite musst du isochronen Transfer machen, oder die FIFO Speicher drastisch erhöhen. Arbeitest du mit doppelt-gepufferten IN_FIFO am Cypress? Wir haben wir 4-fach gepuffert, davor einen riesen FPGA-Internen FIFO und trotzdem bleibts immer mal für 20ms stehen, weil das OS gerade nix abholen mag.
@ christian Vielen Danke für deine Antwort! ja ich arbeite mit double buffering Bulk mode FPGA FIFO 8K groß am Eingang vom usb controller ist die Datenrate 21,2 Mbit/s in meiner PC Anwendung die datenrate ist auch 21,2 Mbit/s. sowie ich das verstanden hab, du meinst dass der usb controller unschuldig ist?
Ja, das ist halt das Problem. Standard-Windows und Standard-Linux sind nicht echtzeitfähig. Deshalb kann das abholen der Daten nicht garantiert werden. Bei BULK sowieso. BULK Transfer wird gemacht, wenn sonst nix anderes auf dem Bus ist. Man erreicht damit zwar durchschnittlich die höchsten Datenraten, aber eben nicht in genauen Abständen. Bei unseren Intel-Bürorechnern hier hab ich Lücken von max. 25ms ausgemessen, in denen keinerlei USB Transfer von/zum FX2 stattfindet. Das solltest du mit einem Osziloskop mal messen. Dementsprechend müssen die FIFO-Puffer dimensioniert sein. Bei dir wären das mindestens 54 kByte FIFO, wenn du 20ms überbrücken willst! In der Praxis aber eher noch mehr. Ich denke, mit 128kByte FIFO wirst du eventuell deine Datenrate kontinuierlich schaffen (also auf der FIFO-Schreib-Seite). Ansonsten schafft der FX2LP durchschnittlich etwa 41 MByte/s im BULK Modus mit Slave FIFO und Quad-Bufferung bei 512 Byte Paketgröße. Vielleicht solltest du über isochronen Transfer nachdenken. Da kann man ziemlich genau 24 MByte/s erreichen. Allerdings wird dann bei Datenverlust nix wiedrholt, lediglich gemeldet, dass ein Fehler aufgetreten ist.
Übrigens....wieso asynchron....das macht man doch nicht, wenn´s keinen zwingenden Grund gibt.
Na ja! asynchron Mode hab ich nicht ausgewählt, und niemand will das ändern. es ist ein standard für andere applictions, die nicht mit meiner aufgabe zu tun haben. mit dem Oszi hab ich 384 ms Lücken, das heisst ich soll ein sehr sehr grossen FIFO verwenden und so viele ressourcen hab ich nicht zu verfügung. hat die synchrone betriebsart einfluß auf die full flag lücken?
Bernadette wrote: > Na ja! > asynchron Mode hab ich nicht ausgewählt, und niemand will das ändern. es > ist ein standard für andere applictions, die nicht mit meiner aufgabe zu > tun haben. Achso. Synchrones Interface macht das FPGA Design aber leichter... > mit dem Oszi hab ich 384 ms Lücken, das heisst ich soll ein sehr sehr > grossen FIFO verwenden und so viele ressourcen hab ich nicht zu > verfügung. Hm....mal schnelleren Rechner und/oder anderen USB Host Controller auswählen? Welche Software holt denn die Daten ab? Sowas wie LabView? Wir holen hier über den Cypress-Treiber asynchron mit C# Programm die Daten. Da haben wir bisher maximal 25ms Lücken gehabt. > hat die synchrone betriebsart einfluß auf die full flag lücken? Nö.
eine C# applikation liest die usb daten, sie hat einen direkten zugriff auf den treiber, und damit verliert sie nicht viel zeit
Hm komisch. Das geht bei uns deutlich schneller. Zumindest auf den aktuellen Rechnern. Sind hier HP-Rechner mit Intel Board und ICH9. Hast du mal versucht, die Kernel-Transfer-Size hochzusetzen? Bei uns läufts am schnellsten mit 128k TransferSize.
ich hab einen fujitsu siemens rechner (intel core 2 vpro), OS windows xp Tranfersize untersuche ich gerade
die anwendung ist so programmiert, dass sie jedes mal nur 512 Byte liest Könnte das die ursache von diesen grossen lücken sein?
Ja, das ist äußerst unklug. Wir haben dann nur etwa 3...5MB/s geschafft. Man muss schon in großen Blöcken lesen und die Transfer Size hochschrauben. Dann wirds besser. Aber die 20ms Lücken sind bei uns trotzdem da.
@ christian Das werde ich in den näschten tagen tun. vielen vielen dank für deine hilfe frohe feiertagen!
Hallo zusammmen, ich habe eine kurze frage. Ich habe mir den Thread hier gerade durchgelesen und verwende auch den FX2. Ich kann im FX2 einen Buffer pro EP nur einen Buffer von X(512,1024) einstellen. Richtig ? In der C# Applikation kann ich angeben wieviele Bytes gelesen werden sollen. Dem Thread hier habe ich entnommen, dass es Sinn macht die zulesenden Bytes größer zu wählen als die in der Firmware eingestellt sind. Beispiel(1. Frage): Firmware EP2 IN 512 bytes Doublebufferd PC liest immer nur Blöcke der größe 512 byte. Dann ist die max. Übertragungsgeschwindigkeit 3-5 Mybte/Sek. RICHTIG? Beispiel(2. Frage): Firmware EP2 IN 512 bytes Doublebufferd PC liest immer nur Blöcke der größe 1024 byte. Dann ist die max. Übertragungsgeschwindigkeit größer als im Beispiel 1 RICHTIG? Gruß Thomas
Hallo Chris! Wie genau liest du die Daten vom FX2? Bei heutigen Quadcore-CPUs à 3GHz kann ich mir die Verzögerung von 25ms nur schwer vorstellen, zumal die eigentliche Arbeit ja der USB Host Controller in Hardware erledigt. Verwendest du mehrere Threads zum Lesen? Grüße
@Thomas Nein, es mach Sinn so viele Bytes zu lesen, wie du vom µC erwartest. Falls deine Firmware Daten zum PC streamt d.h. dauernd mit hohem Datendurchsatz sendet kannst du den Lesepuffer gar nicht groß genug machen. Bedenke, dass du alle ~10us bei HS einen Block liest. Um den Datendurchsatz zu erhöhen, solltest du so selten wie möglich die Read Methode aufrufen. Somit große Puffer anlegen und oder mehrere Threads zum Lesen verwenden. In der FX2 FW kannst du den EP-Puffer nur auf 512(BULK) bzw. 1024(ISO) einstellen, jedoch hindert dich niemand daran weniger Bytes zu senden auch 0 Bytes sind erlaubt. Grüße
Mein Bürorechner hat einen C2D mit 1,833GHz, außerdem jede Menge Software installiert. Das hindert sicher auch den Transfer. Zumal die Pausen ziemlich genau alle 1 Sekunde auftreten, wie ich gestern gemessen habe. Wer weiß, was Windows da spielt.... Aber da wir genug Puffer vorgesehen haben und auch mehrere Datensätze zusammenfassen können, wird das sicher nicht mehr auftreten, sobald die PC-Software diese Pufferung kann. Ist alles noch in Arbeit...
Hallo nochmal @ Mars wie soll ich folgende Aussagen verstehen : Ja, das ist äußerst unklug. Wir haben dann nur etwa 3...5MB/s geschafft. Man muss schon in großen Blöcken lesen und die Transfer Size hochschrauben. Dann wirds besser. Aber die 20ms Lücken sind bei uns trotzdem da. Wenn ich die Firmware auf Bulktransfer einstelle (512 Byte, double bufferd) und aus einem EP jeweils 512 Byte blöcke lese komme ich auf ca. 3 Mbyte / sek. Welches ist die richtige schraube an der gedrecht werden soll damit ich auf 20 Mbyte komme? Oder komme ich nur auf solche datensätze wenn ich aus mehreren EP lese? Gruß Thomas
Nein, auf der PC Seite solltest du nicht nur 1KB lesen, sondern 1MB oder mehr. Und auf der µC Seite musst du natürlich den GPIF oder Slave FIFO Modus verwenden. Der 8051 alleine schafft nie 480MBit. Grüße
Wenn du für jedes 512 Byte Stückchen einen neuen Transfer startest, gehts nicht schneller, weil ja immerfort ein neues Paket angerfordert werden muss. Wenn die Daten auf der Hardware-Seite verfügbar sind, dann kannst du gleich viel mehr anfordern, der USB Host-Controller bzw. USB Stack kümmert sich dann selbständig um die Paketbildung und sammelt die Pakte ein, bis alles da ist oder Timeout kommt. Der Hintergrund ist der: Wenn du für jedes 512 Byte Paket eine extra Anfrage stellst, kann nur dieses eine Paket in einem Microframe transportiert werden. Ein Microframe ist 125µs lang. Jetzt bekommst du alle 125µs 512 Byte, was etwa 4MB/s sind. Stellst du jetzt eine Anfrage über sagen wir mal 12 Pakete a 512 Byte, dann kann der USB Controller den Microframe voll packen, da gehen maximal 11 Pakete zu je 512 Byte rein. Und schwupps, ist man bei über 40 MB/s. Das paraktische Maximum ist 42MB/s, weil die Auslastung mal 10 und mal 11 Pakete ist. Warum, weiß ich aber auch nicht. Kann man schön mit einem schnellen Oszilloskop direkt an D+ oder D- beobachten.
Hi! Mars wrote: Nein, auf der PC Seite solltest du nicht nur 1KB lesen, sondern 1MB oder mehr. Und auf der µC Seite musst du natürlich den GPIF oder Slave FIFO Modus verwenden. Der 8051 alleine schafft nie 480MBit. Speicher im Kernel ist begrenzt. Gibt es keine andere alternative?
Speicher begrenzt? Die Kernel Transfer Size kann man bis auf 3MB hochsetzen, erst dann gehts nicht mehr. Außerdem kannst du beim Lesen viel mehr als 1k anfordern, und das bekommst du auch, wenn die Daten schnell genug von der Hardware angeliefert werden und das Timeout nicht abläuft.
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.