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.
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ö.
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.
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.
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.