Forum: FPGA, VHDL & Co. FX2 auf PC-Seite


von Pit (Gast)


Lesenswert?

Hallo,

ich habe hier nach einiger Zeit eine FX2-Schaltung im Slave-Mode am 
Laufen. Der Daten-Transfer funktioniert unter C# auch zum Teil.
Das Problem ist, das die Daten gestreamt werden müssen und ich eine Rate 
von ca. 2 MBytes/s im Moment habe. Das ist natürlich zu wenig (so 15 - 
25 MB/s brauch ich schon).
Gestreamt heißt in diesem Fall, daß ich die Daten ohne Unterbrechung an 
den PC senden muß.

Meine Frage: Wie mach ich das am Besten? Mit C# oder vlt. doch besser 
mit C++. Das ist ja 'von Natur aus' schneller.

Wer hat Tipps für mich (möglichst detailiert)?

Danke im Vorraus. Gruß Pit

von Pit (Gast)


Lesenswert?

Sry, falsches Forum - bitte verschieben.

von Christian R. (supachris)


Lesenswert?

Wir arbeiten auch mit C# und dem FX2, nehmen den WinUSB Treiber und 
erreichen damit ca. 40MB/s. 2MB/s klingt, als würdest du nur ganz kleine 
Pakete übertragen? Wenn du hohe Datenraten brauchst, musst du auf der 
FPGA Seite viel puffern und auf der PC Seite per BULK rieige Blöcke 
anfordern. Und keinesfalls nur 512 Byte nur pro Transfer. Auch mit dem 
Packet End sparsam umgehen, denn dann ist ein ganzes MicroFrame 
abgeschlossen.

von Pit (Gast)


Lesenswert?

Naja, ich puffer momentan garnicht. Ich jage alles raus wie es kommt. 
Ich kann mir nicht vorstellen, dass puffern etwas bringt. Bei 20MBytes/s 
brauch ich ja 6 MBytes an Puffer, wenn sich Windows mal 300ms 
anderweitig beschäftigt.

Auf der Empfangsseite lese ich mit 64kByte-Paketen aus. Allerdings immer 
nur ein Lese-Aufruf. Irgendwo habe ich gelesen, dass mehrere parallele 
Aufrufe der Renner sind. Allerdings weiß ich nicht wie ich das am Besten 
anstelle.

von Christian R. (supachris)


Lesenswert?

Naja, wenn du konstante Datenraten brauchst, aber auch Datensicherheit 
kannst du nur über BULK gehen und viel puffern. 6MB ist schon heftig, 
wir nutzen momenten 64k x 16 Bit in unserer Applikation. Mehrere 
Leseanfragen geht über Asynchronne Transfers, aber das bringts nicht so 
wirklich. Für 20MB/s wirst du ohne Puffer nicht auskommen, es sei denn, 
du nutzt isochrones Streaming, da hast du 24MB/s, aber keine 
Datensicherheit. Wenn Daten weg sind, sind die weg, wiederholt wird 
nichts.

von delta (Gast)


Lesenswert?

Pit schrieb:
> Ich kann mir nicht vorstellen, dass puffern etwas bringt. Bei 20MBytes/s
> brauch ich ja 6 MBytes an Puffer, wenn sich Windows mal 300ms
> anderweitig beschäftigt.

Und das soll der Grund sein das puffern nichts bringt???
Wenn du ein Stream hast, denn du ohne Verlust/Fehler an den PC schicken 
willst, dann musst du umbedingt auf Device Seite puffern.

von Pit (Gast)


Lesenswert?

>6MB ist schon heftig, wir nutzen momenten 64k x 16 Bit in unserer Applikation.
Das ist reine Theorie: 300ms * 20MBytes/s = 6 MBytes.

>Und das soll der Grund sein das puffern nichts bringt???
>Wenn du ein Stream hast, denn du ohne Verlust/Fehler an den PC schicken
>willst, dann musst du umbedingt auf Device Seite puffern.
Der Grund steht oben schon. Bei einer Datenrate von 20MB/s fallen 
soviele Bytes an, daß ich mangels RAM sowieso einen Datenverlust habe. 
Wozu also puffern?

Ich glaube auch nicht, daß der USB das Problem ist. Wenn man keine 
Unmengen an USB-Geräten am Bus hat, dann sollte das mit Bulk-Transfers 
gehen. Der FT2232H schaft ja auch ca. 10MBytes/s asynchron.
Ich glaube die Wahrheit liegt in der Software auf PC Seite und hatte 
gehofft, jemand hat da schon rumgetüftelt.

von Strubi (Gast)


Lesenswert?

Moin,

mit Bulk und libusb sollten ansich bis zu 27 MB/s (gemessen) drinliegen, 
wenn man schick grosse Blöcke anfragt. Das Problem ist aber der 
blockierende Aufruf von usb_bulk_read(), man kriegt die Performance nur 
hin, wenn man eben auch fix, grosse Blöcke von der HW bekommt, also 
tendentiell was wie einen Paket-Transfer implementiert. In der 
Abfrage-Mainloop darf sonst auch nicht viel laufen.
Bei Streaming mit irregulären Blöcken geht die Performance runter, da 
muss man es per asynchrone API 'non-blocking' machen. Mit isochron 
kriegt man ansich die 48 MB/s mit einer dauernd gefüllten "buffer queue" 
hin, wenn man drei Pakete in den Microframe packt, aber wenn man die 
nicht vollhalten kann, motzt der Protokoll-Layer. Und am Anfang verliert 
man sowieso immer mal Pakete, bis der Acquisitionsprozess sich 
warmgelaufen hat (unter nicht realtime-Linux zumindest). Es hängt also 
sehr vom eigentlichen logischen (selbst implementierten) Protokoll ab, 
wie man am effizientesten Daten einzieht.
Wenn möglich, würde ich in deinem Fall versuchen, es als erstes im 
Bulk-Mode und cleverer Paketisierung zu machen.

Viel Erfolg,

- Strubi

P.S. Hilft übrigens sehr, mit einem Oszi/LA die RX full/TX empty flags 
zu monitoren

von Christian R. (supachris)


Lesenswert?

48MB/s? Naja, das wohl eher nicht. Iso macht 24MB/s bei 3 x 1024 Byte 
pro Paket, jedenfalls steht das im FX2 Manual.
40MB/s sind durchaus auch synchron möglich, aber nur mit großen Paketen 
und Buffern. Das Problem ist, dass die Buffer in einem Rutsch geleert 
werden, da passen, wenn im Buffer auf Device Seite verfügbar, 10 bis 11 
512 Byte Pakete in einen Microframe, was dann die reichlich 40MB/s 
ergibt. Aber die müssen auch verfügbar sein. Wenn die nicht im Puffer 
liegen, dann sinkt die Datenrate rapide. 300ms wäre schon worst case, 
wir hatten hier max. 50ms Pause im Normalbetrieb gemessen. Wenn keine 
Daten verloren gehen sollen, dann musst du entsprechend puffern, da 
beißt die Maus keinen Faden ab. Unser System funktioniert aber so, dass 
die Messdaten sowieso angefordert werden, Daten dürfen keine verloren 
gehen, also sinkt dann die Trigger-Rate...

Probier mal den WinUSB Treiber, kann ich echt nur empfehlen.

von Strubi (Gast)


Lesenswert?

Sorry, ja, sind nur 24 pro Endpoint.
Die volle Bandbreite zu kriegen ist recht wüst und klappte auch nicht 
mit allen Host-Chipsets gut.

von Pit (Gast)


Lesenswert?

Hallo,

eine kurze Rückmeldung:
Ich habe das jetzt mit den Funktionen BeginDataXfer, WaitForXfer und 
FinishDataXfer gelöst.

Man muß etwas rumprobieren, um die passende Anzahl an parallelen 
Aufrufen und die Puffergröße richtig einzustellen. Dann klappt es aber 
ganz gut. Bisher habe ich die Datenpakete noch nicht ausgewertet, aber 
die FULL-Flag-LED blitzt jedenfalls nicht mehr auf (bei 15MBytes/s).

Danke für die Hilfen, Gruß Pit

von obelix (Gast)


Lesenswert?

Pit schrieb:
> Bisher habe ich die Datenpakete noch nicht ausgewertet, aber
> die FULL-Flag-LED blitzt jedenfalls nicht mehr auf (bei 15MBytes/s).
lol...
Werte besser mal deine Datenpakete aus. Wenn du kein blitzen der LED 
siehst, heisst das noch lange nicht dass da kein Blitzen ist. Es könnte 
so kurz sein, dass du es nicht realisierst. Am Besten du schliesst mal 
das Oszi an den FULL Flag Pin.

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
Noch kein Account? Hier anmelden.