In einem
früheren Artikel habe ich gesagt, dass es Zeit für uns ist, zu Streaming-Protokollen überzugehen. Aber als ich anfing, eine Geschichte über sie vorzubereiten, wurde mir klar, dass ich selbst in einem sehr wichtigen Thema schwimme. Wie bereits erwähnt, ist meine Beziehung zu Linux ziemlich eigenartig. Im Allgemeinen wurde mir klar, dass ich selbst keine C ++ - Anwendung erstellen kann, die alle Prinzipien der Programmierung für Redd erfüllt. Sie könnten jemanden bitten, dies zu tun, und dann einfach die vorgefertigte Vorlage verwenden, aber die Artikelserie soll jedem beibringen, wie man sich unter Redd von Grund auf neu entwickelt. Deshalb habe ich meinen Chef (einen großartigen Linux-Spezialisten) gefragt und er hat mir erklärt, worauf ich klicken soll. Dann habe ich seine Worte leicht überdacht und jetzt halte ich es für notwendig, alles Wissen schriftlich zu fixieren. Dies wird Leute wie mich vor schmerzhaften Gedanken bewahren: "Also ... was er getan hat, ist verständlich, aber wie kann ich das wiederholen?" Im Allgemeinen kann jeder, der unter Linux arbeitet, die folgenden zwei Abschnitte diagonal ausführen. Es ist unwahrscheinlich, dass Sie dort etwas Neues finden (Sie werden weitere finden). Im Übrigen biete ich eine Auswahl von zwei Entwicklungsmethoden an, die den unter Redd erklärten Arbeitsprinzipien entsprechen: niedrige Arbeitskosten für die Entwicklung und Remote-Debugging.

Alle Artikel des Zyklus:
- Entwicklung der einfachsten „Firmware“ für in Redd installierte FPGAs und Debugging am Beispiel des Speichertests
- Entwicklung der einfachsten „Firmware“ für in Redd installierte FPGAs. Teil 2. Programmcode
- Entwicklung eines eigenen Kerns zur Einbettung in ein auf FPGA basierendes Prozessorsystem
Arbeiten Sie mit Visual Studio Tools
Es stellt sich heraus, dass Sie die Entwicklung für Remote-Linux durchführen können, ohne sie auf Ihrem lokalen Computer zu haben und ohne Software-Tools zu installieren, die nicht von Microsoft stammen. Hier wird gezeigt, wie es in Visual Studio installiert wird (ich habe es in Version 2019 installiert, aber es scheint, dass es in 2015 erschien)
docs.microsoft.com/ru-ru/cpp/linux/download-install-and-setup- the-linux-development-workload? view = vs-2019Und hier ist die
Theorie der Arbeit .
Nun, dort kann man durch die Registerkarten laufen, viel Theorie und alles auf Russisch.
Großartig! Versuchen wir, das erworbene Wissen zu nutzen, um auf den FT2232H-Chip zuzugreifen, über den der Redd-Zentralprozessor mit dem FPGA verbunden ist. Dieser Kanal wird in Zukunft die Grundlage unserer Streaming-Arbeit bilden. Öffnen Sie Visual Studio und wählen Sie "Projekt erstellen". Wählen Sie in den Filtern "Sprache - C ++", "Plattform - Linux", "Projekttyp - Konsole". Ich werde zeigen, wo sich dies bereits für die Art des Projekts befindet. Aus dem, was wir gefiltert haben, wählen wir die „Konsolenanwendung“ aus:

Nennen wir es beispielsweise SimpleConsole. Wir haben einen solchen spartanischen Quellcode erstellt:
#include <cstdio> int main() { printf("hello from SimpleConsole!\n"); return 0; }
Versuchen wir es zu sammeln. Und uns wird eine sehr interessante Frage zum Herstellen einer Verbindung gestellt. Dies ist eine Funktion der Entwicklung in Visual Studio. Die Umgebung enthält keinen Cross-Compiler und keine Bibliotheken. Es wird einfach ein Quellverzeichnis auf dem Remotecomputer erstellt. Anschließend kopiert es für jede Kompilierung die aktualisierten Dateien darauf und beginnt dort mit der Kompilierung. Aus diesem Grund sollte die Verbindung zum Remote-Computer nicht zum Starten hergestellt werden, sondern bereits für die normale Montage des Projekts.
Wir geben die Parameter für den Redd-Benutzer ein, in dessen Auftrag die Arbeiten am Projekt durchgeführt werden.

Wenn überhaupt - die Parameter können hier an diesem geheimen Ort geändert werden (versuchen Sie nicht, die Projekteigenschaften zu ändern, da dies zu nichts Gutem führt):


Tatsächlich können Sie einen Haltepunkt in eine einzelne Zeile setzen und überprüfen, ob das Projekt gestartet wurde und funktioniert. Das ist aber trivial. Daher gehen wir zu einer interessanteren Aufgabe über - der Arbeit mit FT2232. Es stellt sich die Frage: Woher bekommen Sie die notwendigen Bibliotheken? Für Linux ist alles im Treiberpaket enthalten. Es gibt den Treiber selbst und Bibliotheken sowie Beispiele für Anwendungen, mit denen Sie arbeiten können, und sogar eine kurze Anleitung. Im Allgemeinen fahren wir in die Suchmaschine:
FTDI D2XX drivers
Er wird zeigen, wo sie heruntergeladen werden können. Richtig, speziell war alles schlecht für mich. Mein Provider blockiert die FTDI-Website (sowie Reprap, 7zip und sogar Osronline) und verweist auf RosKomNadzor. ILV sendet als Antwort auf Aussagen Abmeldungen und sagt, dass wir nichts blockieren, sondern uns selbst um den Anbieter kümmern. Wo nur in diesen Abmeldungen sie mir nicht angeboten haben, mich auch an die Polizei zu wenden. Sie melden sich sehr ab. Versuche, sich über ILV-Untätigkeit zu beschweren, werden an ILV weitergeleitet, wo die nächsten Abmeldungen herkommen. Im Allgemeinen kann sich herausstellen, dass Ihr Provider auch den Zugriff blockiert. Seien Sie nicht beunruhigt, suchen Sie einfach nach anderen Möglichkeiten zum Herunterladen und verbringen Sie Zeit damit. Und dann sind sie überrascht, dass sich die Entwicklung von Raketen um Jahrzehnte verzögert ... Ich habe letzten November mit der Korrespondenz mit ILV begonnen, jetzt ist es Juni, außer bei Abmeldungen - keine Aktion ... Aber ich wurde abgelenkt.
Informationen zur Verwendung der Treiber finden Sie in der Readme-Datei im Paket. Sie finden auch das Dokument
AN_220 FTDI Drivers Installationshandbuch für Linux . Schließlich finden Sie auf YouTube ein Video des
Linux d2xx-Treiberinstallationshandbuchs von FTDI Chips. Ein Link dazu befindet sich auch auf der Treiber-Download-Seite. Im Allgemeinen beschränkte sich FTDI nicht auf Optionen zur Information der Benutzer. Wenn Sie ein fertiges Redd-Paket erhalten haben, sind die Treiber selbst bereits darauf installiert und konfiguriert. Und wir werden uns für Header-Dateien und Beispiele interessieren.
Fügen wir ein Beispiel-Slice
\ release \ examples \ EEPROM \ read ein . Ganz am Anfang der Hauptfunktion, in der das Gerät geöffnet und sein Typ übernommen wird. Dies wird ausreichen, um sicherzustellen, dass alles funktioniert. Ich hasse Etiketten, aber da wir den Code, der 10 Minuten lebt, nur schnell ziehen und ablegen, werde ich das Etikett im ursprünglichen Beispiel ziehen, um Zeit zu sparen. Es stellt sich so heraus:
#include <cstdio> #include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include "ftd2xx.h" int main(int argc, char* argv[]) { printf("hello from ConsoleApplication1!\n"); FT_STATUS ftStatus; FT_HANDLE ftHandle0; int iport; static FT_PROGRAM_DATA Data; static FT_DEVICE ftDevice; DWORD libraryVersion = 0; int retCode = 0; ftStatus = FT_GetLibraryVersion(&libraryVersion); if (ftStatus == FT_OK) { printf("Library version = 0x%x\n", (unsigned int)libraryVersion); } else { printf("Error reading library version.\n"); return 1; } if (argc > 1) { sscanf(argv[1], "%d", &iport); } else { iport = 0; } printf("Opening port %d\n", iport); ftStatus = FT_Open(iport, &ftHandle0); if (ftStatus != FT_OK) { /* This can fail if the ftdi_sio driver is loaded use lsmod to check this and rmmod ftdi_sio to remove also rmmod usbserial */ printf("FT_Open(%d) failed\n", iport); return 1; } printf("FT_Open succeeded. Handle is %p\n", ftHandle0); ftStatus = FT_GetDeviceInfo(ftHandle0, &ftDevice, NULL, NULL, NULL, NULL); if (ftStatus != FT_OK) { printf("FT_GetDeviceType FAILED!\n"); retCode = 1; goto exit; } printf("FT_GetDeviceInfo succeeded. Device is type %d.\n", (int)ftDevice); exit: return 0; }
Ich versuche zu sammeln - ich werde es nicht tun. Nicht genügend Header-Dateien.
1>main.cpp 1>D:\Work\SimpleConsole\SimpleConsole\main.cpp(5,20): error : ftd2xx.h: 1>D:\Work\SimpleConsole\SimpleConsole\main.cpp(5,20): error : #include "ftd2xx.h" 1>D:\Work\SimpleConsole\SimpleConsole\main.cpp(5,20): error : ^ 1>D:\Work\SimpleConsole\SimpleConsole\main.cpp(5,20): error : compilation terminated.
Aber ich setze sie als nächstes! Alles ist einfach. Vor Ort sind sie in der Nähe, aber die Montage erfolgt aus der Ferne. Damit das Studio sie auf einen Remotecomputer übertragen kann, müssen Sie sie dem Projekt hinzufügen. Außerdem füge ich aus der Datei
main.cpp nur
ftd2xx.h hinzu , aber es
zieht immer noch
WinTypes.h während der Übertragung . Sie müssen beide hinzufügen.


Jetzt schwört der Linker.
1> 1>D:\Work\SimpleConsole\SimpleConsole\obj\x64\Debug\main.o : error : In function `main': 1>D:\Work\SimpleConsole\SimpleConsole\main.cpp(18): error : undefined reference to `FT_GetLibraryVersion' 1>D:\Work\SimpleConsole\SimpleConsole\main.cpp(37): error : undefined reference to `FT_Open' 1>D:\Work\SimpleConsole\SimpleConsole\main.cpp(55): error : undefined reference to `FT_GetDeviceInfo' 1>collect2 : error : ld returned 1 exit status
Es ist klar, dass es nicht genug Bibliothek gibt. Als ich die
Makefiles des Beispiels untersuchte, stellte ich fest, dass ich den Linker-Einstellungen einige Parameter hinzufügen musste:


Jetzt läuft das Projekt erfolgreich. Wir setzen einen Haltepunkt in die letzte Zeile und versuchen zu rennen. Wir sehen den folgenden Text:
hello from ConsoleApplication1! Library version = 0x10408 Opening port 0 FT_Open succeeded. Handle is 0x555555768540 FT_GetDeviceInfo succeeded. Device is type 10.
Insgesamt nicht schlecht. Etwas öffnete sich, sogar ein Gerät wurde gefunden. Was ist Typ 10? In der Header-Datei von FTDI finden wir:
enum { FT_DEVICE_BM, FT_DEVICE_AM, FT_DEVICE_100AX, FT_DEVICE_UNKNOWN, FT_DEVICE_2232C, FT_DEVICE_232R, FT_DEVICE_2232H, FT_DEVICE_4232H, FT_DEVICE_232H, FT_DEVICE_X_SERIES, FT_DEVICE_4222H_0, FT_DEVICE_4222H_1_2, FT_DEVICE_4222H_3, FT_DEVICE_4222_PROG, };
Wir zählen den Finger von oben nach unten - vor uns steht der FT4222H. Ja, Redd hat viele FTDI-Geräte. Jetzt
möchte ich nur kurz sagen, dass wir die Nummer des Geräts sortieren müssen, das an die Funktion
FT_Open () übergeben wurde. Diese Nummer wird als Argument an die Funktion
main () übergeben . Sie kann in den Debugging-Eigenschaften des Projekts festgelegt werden.
Es ist nützlich, eine Platte mit typischen Problemen zu platzieren. Im Allgemeinen heißt es "Redd konfigurieren" überall ohne Details. Tatsache ist, dass die Komplexe individuell verteilt werden, sodass nicht alle Leser Konfigurationsregeln benötigen. Bei Problemen kümmern sich Administratoren normalerweise um die Konfiguration. Es stellt sich also heraus, dass Sie natürlich die Konfigurationsregeln beschreiben können, aber es wird viel Platz beanspruchen. Es ist nur dann sinnvoll, Energie dafür aufzuwenden, wenn jemand sie wirklich braucht. Daher beschränke ich mich hier nur darauf, Probleme anzuzeigen und zu beheben. Ich werde beschreiben, ob Anwendungen im Feedback enthalten sind.
Großartig. Wir sind bereit für Erfolge, bei denen ausschließlich Microsoft-Tools verwendet werden. Im Allgemeinen mag dies ausreichen, aber für alle Fälle erzähle ich Ihnen von einer Alternative, die mir mein Chef beigebracht hat.
Arbeiten mit Linux in einer virtuellen Maschine
Der Hauptnachteil des vorherigen Verfahrens ist die Fernmontage. Sie können sich tausend und einen Grund vorstellen, warum die Montage lokal durchgeführt werden sollte und nur die fertige Binärdatei auf den Remotecomputer übertragen wird. Dies sind alle Arten von paranoiden Einschränkungen (obwohl die Dateien mithilfe eines sicheren Protokolls übertragen werden und Sie ihren Speicher mit Sicherheitsrichtlinien von anderen Benutzern trennen können). Dies ist nur ein Problem, dass das Redd-Laufwerk nicht aus allen Arten von Bibliotheken überläuft. Dies ist auch die Zurückhaltung, jede Header-Datei zu registrieren. wenn es Tausende von ihnen gibt ... Nun, und vieles mehr. Im Allgemeinen kann die lokale Montagetechnik nützlich sein.
Zunächst stellen wir das VirtualBox-Programm von Oracle auf den lokalen Computer. Wenn es Lizenzprobleme gibt (ich benutze es kostenlos als Einzelperson, weiß aber nicht genau, was mit juristischen Personen los ist), wählen Sie eine separate physische Maschine aus und platzieren Sie Linux dort. Welches? Es ist einfacher für mich, ich verstehe sie alle ungefähr gleich. Ich meine, ich verstehe fast keinen. Daher sagte mir der Chef, dass Sie Debian verwenden müssen, ich habe Debian installiert. Sie können den gleichen Weg gehen (verwenden Sie das Prinzip „Warum nicht?“). Zumindest in Zukunft werde ich mich darauf verlassen, mit ihm zusammenzuarbeiten.
Wenn Sie mit Linux arbeiten, müssen Sie zwei Regeln einhalten, die das Leben erheblich erleichtern:
- Wenn sie uns als Antwort auf einen Befehl mitteilen, dass nicht genügend Rechte vorhanden sind, lohnt es sich, ihn zu wiederholen und den sudo- Zauber am Anfang hinzuzufügen.
- Wenn uns als Antwort auf einen Befehl mitgeteilt wird, dass es keinen solchen gibt, lohnt es sich, ihn zu installieren, indem Sie den Zauber ' apt-get install <fehlendes Ding> wirken .
Also. Wir haben gerade das Betriebssystem installiert. Fügen Sie dort sofort C ++ - Unterstützung hinzu, indem Sie den g ++ - Compiler sowie den gdb-Debugger installieren. Wie? Verwenden Sie also Regel 2:
apt-get install g ++
apt-get install gdbNicht gegeben? Großartig! Wiederholen Sie mit Regel 1:
sudo apt-get installiere g ++
sudo apt-get install gdbJetzt gehen wir ins Internet und geben in der Suchmaschine Folgendes ein:
Eclipse IDEWir finden einen Link zu eclipse.org, wo die ersten Optionen für Java sind. Wir finden und laden eine Option für C / C ++ herunter:

Laden Sie es beispielsweise zu Hause herunter und entpacken Sie es.
Eigentlich ist keine Installation erforderlich. Gehen Sie einfach in das Verzeichnis, in das gerade alles entpackt wurde, und führen Sie die Eclipse-Datei aus:

Wir befinden uns in einer Entwicklungsumgebung. Wenn Sie bereits mit Mikrocontrollern und sogar Prozessorkernen für FPGAs gearbeitet haben, wissen Sie wahrscheinlich bereits, was Eclipse ist. So sind ungewohnte Dinge fast vollständig. Wir beginnen uns in mehr oder weniger vertrauten Dingen umzusehen. Wir erstellen das C ++ - Projekt. Ich muss sofort sagen, dass es zwei Möglichkeiten gibt. Einer wird zum Erfolg führen, der zweite zu einer Sackgasse. Folgen Sie daher sorgfältig dem Weg, den ich gehe:



Wir haben ein Projekt erstellt, das gut läuft. Wechseln Sie zum Konfigurieren des Debuggens zu den GDB-Eigenschaften:

Erstellen Sie eine Konfiguration vom Typ C / C ++ Remote Application. Klicken Sie in der Gruppe Verbindung auf Neu:

Wählen Sie eine Verbindung wie SSH:

Wir füllen die Verbindungseigenschaften aus, indem wir das Optionsfeld des Berechtigungstyps auf Kennwortberechtigung umschalten:

Tatsächlich ist das System zum Debuggen bereit. Nachdem wir sichergestellt haben, dass der Begrüßungstext tatsächlich angezeigt wird, versuchen wir, den Code aus dem vorherigen Beispiel (das sich in Visual Studio befand) hier zu übertragen. Um zusätzliche Bibliotheken zu registrieren, wählen Sie die Projekteigenschaften aus:

Da die Assembly lokal ausgeführt wird, müssen sich die Bibliotheken außerdem im lokalen Verzeichnis usr / local / lib befinden. Ich erinnere Sie daran, dass die Bibliotheken mit dem Treiber heruntergeladen werden und die Installation in der Readme-Datei sowie in AN220- und YouTube-Videos erfolgt. Weitere Informationen finden Sie im Abschnitt zu Visual Studio.
Nach all diesen Vorbereitungen erhalten wir die bekannten Zeilen. Das heißt, der Code, der vollständig mit dem im vorherigen Abschnitt betrachteten identisch ist, wird nicht weniger identisch ausgeführt.
Das ist alles. Abhängig von der Situation können wir den Code jetzt sowohl über Visual Studio als auch über eine virtuelle Maschine ausführen. Wie Sie sehen können, ist Visual Studio rein in Bezug auf die Einstellungen einfacher, daher werde ich es ceteris paribus wählen. Es ist jedoch besser, beide Technologien zu besitzen, da das Durcharbeiten des Studios seine Nachteile darin besteht, dass nicht nur das Debuggen, sondern auch die Montage dort entfernt erfolgt.
FPGA-Schreibgeschwindigkeitsmessung über FT2232H
Und was. Lassen Sie uns die erworbenen Fähigkeiten auf ein mehr oder weniger reales Projekt übertragen. Natürlich ist es nicht mehr möglich, etwas sehr Ernstes zu beginnen, alle sind bereits müde. Aber wir bekommen ein mehr oder weniger praktisches Ergebnis. Zum Beispiel messen wir, mit welcher maximalen Geschwindigkeit wir Daten über den FT2232H-Chip zum FPGA übertragen können. Das Protokoll dort ist nicht das einfachste, daher übertragen wir es nicht auf beiden Seiten, sondern beschränken uns darauf, von uns auf den Kanal zu übertragen, auf dessen anderem Ende das FPGA installiert ist. Das Dokument
AN_130 FT2232H, das in einem synchronen FIFO-Modus im FT245-Stil verwendet wird, hilft uns dabei, da in dem Komplex die Steuerung in diesem Modus eingeschaltet ist (synchrones FIFO). Dieses Dokument enthält auch eine Beschreibung der Schlussfolgerungen in der Form, in der sie in diesem Modus verwendet werden, sowie Zeitdiagramme und sogar Codebeispiele, von denen wir uns inspirieren lassen werden.
Also. Wir wollen mit dem Controller im FIFO aufnehmen. Was wird aus uns werden? Ich habe es versucht, ich weiß. Es wird 1 Kilobyte Daten benötigt, wonach der Controller hängen bleibt. Er wird sich weigern, zusätzliche Daten zu akzeptieren. Die Sache ist, dass ein Kilobyte die Größe seines internen Puffers hat. Während es möglich ist, werden Daten von USB genommen und in diesem Raum gespeichert. Damit sie jedoch zum Synchronkanal gehen können, muss er über die Bereitschaft informieren, sie zu empfangen. Wir schauen uns den entsprechenden Behelf an.

Also. Wenn der Controller Daten im FIFO hat, lässt er das RXF-Signal fallen. Als Reaktion darauf müssen wir zuerst das OE-Signal fallen lassen und es für mindestens einen Taktzyklus auf Null halten (dies folgt mehr aus der Beschreibung des Diagramms als aus dem Diagramm selbst). Wir erhalten Daten auf dem Bus, wir müssen ihren Empfang mit einem niedrigen RD-Signalpegel bestätigen. Und so - für den ganzen Rahmen. Wenn der Controller die RXF-Leitung anhebt, müssen wir die OE und RD entfernen. Wir werden die Daten heute nicht verwenden. Um die Geschwindigkeit zu messen, simulieren Sie einfach den Empfang von Daten auf dem FPGA von FT2232H. Na dann. Für eine so einfache Operation wird kein Prozessorsystem benötigt. Es reicht aus, einen entarteten Automaten herzustellen, dessen Entwicklung viel weniger Zeit in Anspruch nimmt als nur die Vorbereitung des Prozessors und des Programms dafür. Daher erstellen wir ein Projekt, das nur eine SystemVerilog-Datei mit den folgenden Inhalten enthält:
module JustRead( input logic clk, input logic rxf_n, output logic oe_n, output logic rd_n ); enum {IDLE,TRANSFER} state = IDLE; always @ (posedge clk) begin oe_n <= 1; rd_n <= 1; case (state) IDLE: begin if (rxf_n == 0) begin oe_n <= 0; state <= TRANSFER; end end TRANSFER: begin if (rxf_n == 0) begin oe_n <= 0; rd_n <= 0; end else begin state <= IDLE; end end endcase end endmodule
Die Maschine hat zwei Zustände. In diesem Fall wird die Dauer des OE-Signals dadurch bestimmt, dass es unmittelbar nach dem Takt gespannt und bis zum nächsten gehalten wird. Dies kann mit dem folgenden Modell überprüft werden:
module JustReadTB( output logic clk, output logic rxf_n, input logic oe_n, input logic rd_n ); JustRead dut ( .clk, .rxf_n, .oe_n, .rd_n ); always begin clk = 1; #16; clk = 0; #16; end initial begin rxf_n = 1; #120; rxf_n = 0; #120; rxf_n = 1; end endmodule
Die Zeit, die ich gebraucht habe, ist die erste verfügbare. Es ist die Reihenfolge der Umschaltung, die mit dem Taktsignal verbunden ist, die wichtig ist. Wir erhalten das folgende Zeitdiagramm:

In erster Näherung entspricht dies den Anforderungen des Dokuments. Die eigentlichen Daten werden wir aber trotzdem nicht verarbeiten.
Die Zuweisung von FPGA-Beinen in diesem Projekt verursacht auch beim Bearbeiten der Tabelle keine Schwierigkeiten (das Übertragen von Zuweisungen aus der * .QSF-Datei dauert länger, und ich betone ständig, dass bei der Entwicklung von Eintagesystemen für Redd Zeitersparnis eine Priorität ist).

Wir sammeln, füllen es, bevor Sie die Stromversorgung des Komplexes ausschalten. Sie können mit dem Programm arbeiten. Es hängt nicht mehr nach einem Pufferüberlauf.
Im Programm habe ich zwei Funktionen gemacht. Der erste sucht und öffnet das Gerät. Ich habe etwas vom letzten Test genommen und etwas von
AN130 ausgeliehen :
FT_HANDLE OpenFT2232H() { FT_HANDLE ftHandle0; static FT_DEVICE ftDevice; // int nDevice = 0; while (true) { // if (FT_Open(nDevice, &ftHandle0) != FT_OK) { // , return 0; } // ? if (FT_GetDeviceInfo(ftHandle0, &ftDevice, NULL, NULL, NULL, NULL) == FT_OK) { // , if (ftDevice == FT_DEVICE_2232H) { // , AN130 FT_SetBitMode(ftHandle0, 0xff, 0x00); usleep(1000000); //Sync FIFO mode FT_SetBitMode(ftHandle0, 0xff, 0x40); FT_SetLatencyTimer(ftHandle0, 2); FT_SetUSBParameters(ftHandle0, maxBlockSize, maxBlockSize); return ftHandle0; } } // FT_Close(ftHandle0); // nDevice += 1; } }
Als Windows-Fan musste ich die Geschwindigkeitsmessfunktion schreiben und ständig das Internet überprüfen, da ich normalerweise die klassischen hochauflösenden Timer der WIN32-API verwende. Vielleicht können Sie effizienter schreiben, aber dies ist ein eintägiges Programm.
const int maxBlockSize = 0x100000; uint8_t buf[maxBlockSize]; … // BlockSize , 1 double TestSpeed(FT_HANDLE ftHandle0,int totalSize, int blockSize) { if (blockSize > maxBlockSize) { return -1; } DWORD dwWrittenTotal = 0; timespec before; clock_gettime(CLOCK_REALTIME, &before); for (int i = 0; i < totalSize; i += blockSize) { DWORD dwWritten; FT_Write(ftHandle0, buf, blockSize, &dwWritten); // dwWrittenTotal += dwWritten; } timespec after; clock_gettime(CLOCK_REALTIME, &after); if (dwWrittenTotal < (DWORD)totalSize) { return -2; } // uint64_t nsBefore = before.tv_nsec; uint64_t nsAfter = after.tv_nsec; // nsAfter += (after.tv_sec - before.tv_sec) * 1000000000; // nsAfter -= nsBefore; // double res = ((double)nsAfter)/((double)1000000000); // - return ((double)dwWrittenTotal) / res; }
Nun, der Code, der die Grundfunktionalität ausführt, stellte sich wie folgt heraus:
int main(int argc, char* argv[]) { FT_HANDLE ftHandle0 = OpenFT2232H(); if (ftHandle0 == 0) { printf("Cannot open device\n"); return -1; } const int totalSize = 0x100000; static const int blockSizes[] = { 0x10,0x20,0x40,0x80,0x100,0x200,0x400,0x800,0x1000,0x2000, 0x4000,0x8000,0x10000,0x20000,0x40000,0x80000,0 }; for (int i = 0; blockSizes[i] != 0; i++) { double speed = TestSpeed(ftHandle0, totalSize, blockSizes[i]); printf("%d,%d\n", blockSizes[i], (int)(speed/1000.)); int stop = 0; } // , FT_Close(ftHandle0); return 0; }
Ich weiß, dass die Geschwindigkeit bei USB stark von der Größe des gesendeten Blocks abhängt. Daher überprüfe ich die Geschwindigkeit auf verschiedene Optionen. Eine lineare Aufzählung wird kaum benötigt. Ich habe gerade eine Liste typischer Größen erstellt. Ich gebe die Daten in Kilobyte pro Sekunde aus. Bytes sind für die Augen unangenehm, Megabyte haben eine niedrige Auflösung mit einer kleinen Blockgröße. Kilobyte pro Sekunde ist ein vernünftiger Kompromiss. Wir erhalten folgende Ergebnisse:
16,59 32,110 64,237 128,490 256,932 512,1974 1024,3760 2048,5594 4096,10729 8192,16109 16384,20170 32768,24248 65536,26664 131072,28583 262144,29370 524288,29832
Wir speichern sie in einer * .csv-Datei, laden sie in Excel und erstellen ein Diagramm der Geschwindigkeit gegenüber der Blockgröße.

Die Grenze liegt bei 30 Megabyte pro Sekunde. Bis zu einem theoretischen Maximum von 52 MB / s weit. Vielleicht können Sie irgendwie beschleunigen, aber es den Lesern in Form von praktischer Arbeit überlassen. Die Hauptsache ist, dass wir alle Schritte der Arbeit mit dem Kanal gemeistert haben und bereit sind, das FPGA mit dem Zentralprozessor in einem einzigen System zu verbinden.
Während der
Kompilierung des Artikels wurde das Dokument
AN_165 gefunden, das besagt, dass die maximale Geschwindigkeit im synchronen FIFO-Modus 35 MB / s betrug. Das heißt, Raum für Wachstum - bis zu einer bestimmten Größe. Aber es ist immer noch da.
Fazit
Wir haben zwei Strategien zum Entwickeln und Debuggen von Programmcode kennengelernt, der auf dem Zentralprozessor des Redd-Komplexes ausgeführt wird (mithilfe von Microsoft Visual Studio-Tools und auf einer virtuellen Maschine mit Linux-Betriebssystem). Wir haben auch praktische Kenntnisse in der Arbeit mit dem Kanal erworben, über den der Zentralprozessor des Komplexes mit dem FPGA kommuniziert.
Anscheinend hindert uns jetzt nichts mehr daran, aussagekräftige Daten von der CPU zum FPGA und umgekehrt zu übertragen (obwohl ich im letzten Artikel diese Worte geschrieben habe).
Ein Beispiel mit der einfachsten „Firmware“ für FPGAs und einem Programm, das die Schreibgeschwindigkeit auf USB misst, kann hier heruntergeladen werden .