Hallo, bin auch gearde mit dem Slave FIFO Interface des FX2 beschäftigt. Leider komme ich momentan nur auf eine Datenrate von 4MB/s. Ich steure es mit einem Zustandsautomaten aus einem FPGA an. FULL flag berücksichtige ich usw. Nun takte ich die FSM einmal mit 12.5 MHz und einmal 25MHz. Beide Male sind die Datenraten gleich. Der Falschenhals liegt also bei Software mit der ich die Daten auslese. Seitens des FX2 verwende ich Bulk-Übertragung, 4x buffered, Auto IN, ext clocked. Ich verwende libusb, synchron. Dort hohle ich in einer Schleife mit usb_bulk_read() Datenblöcke mit je 1024Bytes ab. Im Thread stand, dass man größere Datenblöcke anfordern soll, dann wird die Übertragung schneller. Warum das?
1024Byte pro Transfer ist zu wenig. Da kommst du nur auf so niedrige Raten. Wir erreichen die 40MB/s knapp, wenn wir richtig große Blöcke abholen....128kiByte beispielsweise. Achso, die Rechung: Bei 1024 Byte pro Transfer ist ein Microframe nur mit 1024 Byte gefüllt. Bei USB 2.0 HighSpeed wird alle 125µs ein Microframe generiert. Ist der nur mit 1024 Byte gefüllt, kommst du auf ziemlich genau 8MB/s maximal.
Christian R. schrieb: > 1024Byte pro Transfer ist zu wenig. Da kommst du nur auf so niedrige > > Raten. Wir erreichen die 40MB/s knapp, wenn wir richtig große Blöcke > > abholen....128kiByte beispielsweise. > Aha.. > > > Achso, die Rechung: Bei 1024 Byte pro Transfer ist ein Microframe nur > > mit 1024 Byte gefüllt. Bei USB 2.0 HighSpeed wird alle 125µs ein > > Microframe generiert. Ist der nur mit 1024 Byte gefüllt, kommst du auf > > ziemlich genau 8MB/s maximal. Ok.., und das unter der Vorraussetzung, dass alle 125us usb_bulk_read() ausgeführt wird. Denn der Host ist ja der "master". Wenn die externe Logik in der Lage ist 6656 Bytes alle 125us (pro Microframe) zu liefern, kommt mal also auf eine Datenrate von ca 50MB/s.. Vorrausgesetzt, dass usb_bulk_read() alle 125us aufgerufen werden kann, reicht dann doch also, immer 6656 Bytes mit dieser Funktion anzufordern? Wenn es nun aber nicht nicht möglich ist, alle 125 us die Funktion aufzurufen, muss man größere Blöcke anfordern, sodass mehrere Microframe aufeinander folgend empfangen werden. Also wäre es grundsätzliche ratsam größere Blöcke anzufordern, wie bei euch 128kByte. Dann muss die externe Logik allerdings auch schnell genug nachliefern, sonst gibt es einen timeout. Gibt es da nicht auch eine obere Grenze bei libusb bezüglich der Einlesemenge?
Also die 125µs sind fest. Und darum kümmert sich der Hostcontroller. Das API sollte die Blöcke so groß wie möglich abfragen. Außerdem sind bei HighSpeed die Pakete maximal 512 Byte groß. Pro MicroFrame passen 10 bis 11 512 Byte rein. Man kommt also nur auf etwa 40MB/s. Musst du das TimeOut entsprechend hochsetzen. Wir lesen immer so riesen Brocken. Die Hardware setzt das Packetend an der entsprechenden Stelle, dann kommt der Treiber zurück, auch wenn die Anzahl noch nicht erreicht ist. Und da wir im Voraus exakt wissen, wieviel Daten anliegen, klappt das.
Ok, danke für den Tipp! Sehr gut..Bin jetzt bei meinen erwarteten 15-16Byte/s. Meine FPGA Logik kann theoretisch auch nur 16,66MByte/s Daten produzieren. Soweit so gut. Zum PKTEND: Lasse den FX2 mit AUTOIN=1 laufen. Mit meiner FPGA Logik frage ich das Full Flag ab, sodass wenn das FULL-Flag high ist, keine Daten in das Slave FIFO geschrieben werden. In der Simulation funktioniert der Mechanismus. Ob das FULL Flag aber überhaupt mal high wird, habe ich noch gar nicht geprüft. - Die Daten, die ich empfange sind jedenfalls korrekt, ganz ohne PKTEND. Naja habe ja auch einen kontinuierliche Datenstrom. Der PKTEND Pin ist ja nur für Anwendungen gedacht, wenn keine Daten mehr von der externen Logik mehr generiert werden und der FIFO-Füllstand des Autoin noch nicht erreicht ist.
Naja, wenn der Rechner mal zu tun hat, wirst du schon merken, wie wichtig das Full Flag ist. Das PacketEnd ist schon sehr nützlich, eben weil man dann fast beliebig große Transfers machen kann, die keine ganzzahligen Vielfachen von 512 Byte sind. Und weil man damit einen noch größeren Datenstrom segmentieren kann. Wir nutzen das wie gesagt intensiv.
Hallo Ich habe gerade auch mit dem Chip zu tun. Wie sind eure Erfharungen, in wie weit wirkt sich die MaxPacketSize auf die Transferrate aus? Bei kelienren Paketen wird der prozentuale Anteil des Overheads größer. Kommt sonst noch etwas dazu? Viele Grüße, Tilo
Tilo schrieb: > Wie sind eure Erfharungen, in wie weit wirkt sich die MaxPacketSize auf > > die Transferrate aus? Bei kelienren Paketen wird der prozentuale Anteil > > des Overheads größer. Kommt sonst noch etwas dazu? Naja, es gilt ja die Microframes möglichst voll zu bekommen. Es passen ja zehn bis elf Pakete je 512 Bytes(maximal) in einen Microframe(bei bulk Transfer). Wenn die Pakete nicht voll werden, schafft man eben nicht die volle Bandbreite. Die Anzahl der Pakete ist glaube ich fix. Wie schnell taktet Ihr den FX2? Und taktet ihr ihn extern oder intern?
Genau, je länger die Paketgröße, desto mehr Übertragungsrate. Wir takten mit 40MHz extern, 16 Bit Datenbus.
Guten morgen Leider intern, weil es das Design so vorgibt. Ich bin gerade dabei von Iso auf Bulk umzustellen. Das Problem ist, dass das Datenvolumen nicht fix ist und man den Iso. Transfer auf Worst case auslegen muss. Mit dem CyUSB Treiber scheint dies den PC dann ordentlich zu beschäftigen. Da von libusb die rede ist, verwendet ihr Linux oder Windows?
Also wir nutzen den CyUSB Treiber unter Windows und arbeiten ohne das beknackte API direkt auf den IOCONTROLS. Das API kann parallele asynchrone Transfers nicht korrekt handhaben. Die sind aber nötig, um konstant die volle Datenrate auszuschöpfen. Eine sonderlich hohe Prozessorlast gibts dabei aber nicht (<3% bei 40MB/s auf einen C2D mit 3GHz). Auch da schlagen die möglichst großen Blöcke wieder rein. Je weniger Anfragen gestellt werden müssen, desto weniger Prozessorlast. Wenn man ständig kleine Pakete abholt, steigt die Last rapide an.
Hallo Welche Probleme habt ihr mit der API bei asynchronen Transfers genau? Im Cypress Forum gibts leider kaum etwas :(
Kann ich dir nicht genau sagen. Ich bin der Hardware-Entwicker. Der zuständige SW-Entwickler hat nach 2 Tagen das Handtuch geworfen und den Treiber direkt angesprochen. Das geht super.
Mist, ich bin auch "nur" der Hardwareentwickler. Bei uns die CyAPI eigentlich recht gut. Problematisch war allerdings bisher, dass es gerne zu PacketLoss kommt.
Momentan arbeite ich auch mit den synchronen Interface von libusb. Die Datenrate, die ich zur Zeit habe, reicht mir zunächst. Allerdings möchte ich schon noch das asynchrone Interface als Alternative habe. Ja, ich habe schon einen Versuch gemacht. Leider hat es nicht geklappt. Bis zu dieser ..reap..() Funktion läuft alles super, doch bei dieser Funktion bekomme ich -5 zurück. "Can't find entity" bedeutet das glaube ich. Habe auch schon im Forum nachgefragt, aber da konnte mir auch keiner helfen. Falls du weiter bist, kannst du das hier gerne zum Besten geben:)
PacketLoss haben wir nicht, aber wir haben noch ein kleines Problem bei extreme Datenraten. Wenn wir zusätzlich zum massiven upstream noch einiges an Downstream erzeugen, verhaspelt sich der Chip und/oder der Treiber. Das haben wir noch nicht gänzlich klären können. An der Firmware scheints nicht zu liegen, das tritt erst bei vielen parallelen asynchronen Anfragen an den Treiber auf. Wenn wir mal Zeit haben, stellen wir das mal auf den WinUSB aus dem KMDF um, und schauen, wie das dann aussieht.
Welche Chiprevision verwendet ihr? Ich hab in einem Errate was gelesen, dass Daten zerwürfelt, wenn mehrere OUT-Endpoints verwendet werden. Ihr habt mir mit der CyAPI Angst gemacht. Wir haben nur in eine Richtung etwas größere Datenmengen, glück gehabt. Beim Testen ist mir etwas anderes aufgefallen: An manchen PCs renumeriert sich der FX2 nach upload der Firmware nicht richtig. Dies kann daran erkannt werden, dass in CyConsole zwar das Gerät angezeigt wird, dem Gerät aber alle Endpoints fehlen. Drücke ich in CyConsole auf "Reset" tauchen die EPs auf. Kommt einem von euch das Problem bekannt vor? Was macht ihr in der Firmware zu erst: EPs konfigurieren oder Renumerierung? Hat einer schon mal versucht die EPs anderst zu konfigurieren, muss das Device dann reconnected werden? Viele Grüße, Tilo
Also wir haben nur einen OUT EP und einen IN EP. Die Firmware ist quasi die BulkLoop Beispiel Firmware, halt auf Slave FIFO umgeschaltet. Ich hatte hier auch mal eine ähnliche Firmware gepostet, die auf jeden Fall funktioniert, da sieht man auch die Reihenfolge. Einfach mal suchen. Diese Renum Geschichten haben wir nicht. Wir halten die Firmware komplett im EEPROM und das Laden und enumerieren klappt immer zuverlässig. Mit synchronen Zugriffen funktioniert die CyAPI auch problemlos, nur mehrere parallele asynchrone Anfragen kann die schlecht handhaben. Wahrscheinlich der Treiber an sich auch, das müssen wir wie gesagt, bei viel Zeit mal herausfinden. Prinzipiell ist der WinUSB Treiber bzw. der hier Beitrag "Generischer USB Treiber für Windows mit C++ API" der auch WinUSB nutzt, eine gute Sache.
Hallo Die Beispiele habe ich soweit surch. Prinzipiell halte ich mich auch an die Beispiele. Leider passen die nicht immer. Ich will z.B. folgendes: EP2 soll OUT-EP mit 64Byte Bulk sein EP6 soll: Wenn HS-Mode: IN-EP mit Quad-512Byte Bulk Wenn FS-Mode: IN-EP mit Quad-64Byte Bulk sein Optional ist für Testzwecke nochmal beides als isochron drin. EP6 wird von einem DSP gefüttert. Autocommit soll an sein, so dass der FX2 volle Pakete selbstständig wegschickt. Der DSP schickt immer 64Byte Blöcke. PF soll daher low werden, so bald 64Byte nicht mehr in die Puffer des FX2 passen, damit der DSP weiß, dass er warten muss. Das verrückte ist, an vielen PCs tut alles einwandfrei aber an einzelnen PCs funktioniert das Device reproduzierbar nicht. Ich bin noch nicht dahinter gekommen, warum. Fällt dir eventuell etwas auf? Im ersten Codeteil passe ich die Descriptortable dynamisch an. Diese beginnt bei 0x0500. Danach will ich die EPs für den DSP einstellen. Verwendest du auch Autocommit? Kann es sein, dass ein Paket, das commitet wurde aber noch nicht vom Host abgeholt wurde nicht mehr mit INPKTEND gelöscht werden kann? Vielen Dank, Tilo
Ich hab das Problem gefunden. Ich habe die USB Spec so verstanden, dass im FullSpeed Mode 8,16,32,64 und im HighSpeed Mode dazu zusätzlich 512 Byte Pakete zugelassen sind. Tatsächlich sind es nut 512Byte im HS Mode. Die meisten USB-Hosts machen das mit aber nicht alle.
Wenn ich das PROGLEVEL Flag des FX2 benutze, um zu sagen, dass das FIFO fast voll ist. Muss ich dann auch zwangsweise den PKTEND Pin setzen, damit sich das FIFO wieder leert (Ich arbeite im AUTOIN Modus)? Oder leert es sich automatisch, da ich im AUTOIN Modus bin. Ich mache quad buffering. der letzte Buffer wird dann also nicht ganz voll. Die anderen Buffer werden aufgrund des AUTOIN Modus doch aber geleert, dass sich das FIFO automatisch leert, oder?
Im AUTOIN-Mode werden volle Pakete automatisch commited. Sagen wir, du hast einen Quad buffer. Die ersten drei Buffer sind voll, der 4. zur Hälfte. Wenn der PC nun Daten abholt, werden die drei vollen Puffer abgeholt und freigegeben, der 4. jedoch nicht, da er noch nicht voll ist. Werden nun weiterhin Daten in den FIFO geschoben, wird der angefangene Puffer voll gemacht und dann an den PC geschickt. Mit dem PKTEND kann ein Paket abgeschickt werden, dass noch nicht voll ist. Beispiel 1: Kontinuierlicher Messdatenfluss PKTEND muss nie gezogen werden, da kontinuierlich Daten in den FIFO geschrieben werden und somit die Pakete immer voll werden. Die vollen Pakete werden voll automatisch vom PC abgeholt. Beispiel 2: ACK auf ein Steuerkommando PKTEND muss gezogen werden, da in den meisten Fällen nach dem ACK keine weiteren Daten in den FIFO geschrieben werden. Da das Paket nicht voll ist, würde das Paket ohne PKTEND nie an den PC geschickt. Durch das PKTEND wird alles was im FIFO ist an den PC geschickt. Das Proglevel-Flag hat einen anderen Zweck. Ich verwende einen DSP mit DMA, um die Daten in den FIFO zu kopieren. die DMA kopiert immer 64Byte Blöcke in den FIFO. Mit dem Proglevel Flag kann ich sicherstellen, dass ein Block mit 64Bytes auch in den FIFO passt. Ohne das Flag musste jedes Byte einzeln in den FIFO kopiert werden und dann einzeln das FIFO-Full Flag ausgewertet werden. Das ganze ist ein Performance-Booster. Ich hoffe ich habe alle Klarheiten beseitigt? Viele Grüße,
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.