Développement de programmes pour le processeur central Redd utilisant l'accès au FPGA

Dans un article précédent, j'ai dit qu'il était temps pour nous de passer aux protocoles de streaming. Mais après avoir commencé à préparer une histoire à leur sujet, j'ai réalisé que je nage moi-même dans un sujet très important. Comme déjà noté, ma relation avec Linux est assez particulière. En général, je me suis rendu compte que je ne pouvais pas moi-même créer à partir de zéro une application C ++ qui satisferait tous les principes de programmation pour Redd. Vous pouvez demander à quelqu'un de le faire, puis utiliser simplement le modèle prêt à l'emploi, mais la série d'articles est conçue pour enseigner à tout le monde comment développer sous Redd à partir de zéro. Par conséquent, j'ai demandé à mon patron (un grand spécialiste de Linux), et il m'a expliqué sur quoi cliquer. Puis j'ai légèrement repensé ses paroles et maintenant je considère qu'il est nécessaire de fixer toutes les connaissances par écrit. Cela sauvera des gens comme moi de pensées douloureuses: "Alors ... Ce qu'il a fait est compréhensible, mais comment puis-je répéter cela?" En général, toute personne travaillant sous Linux peut exécuter les deux sections suivantes en diagonale. Il est peu probable que vous y trouviez quelque chose de nouveau (vous trouverez plus loin). Et pour le reste, je propose un choix de deux méthodes de développement qui correspondent aux principes déclarés de travailler sous Redd: des coûts de main d'œuvre bas pour le développement et le débogage à distance.



Tous les articles du cycle:

  1. Développement du «firmware» le plus simple pour les FPGA installés dans Redd, et débogage en utilisant le test de mémoire comme exemple
  2. Développement du «firmware» le plus simple pour les FPGA installés dans Redd. Partie 2. Code de programme
  3. Développement de son propre noyau pour l'intégration dans un système de processeur basé sur FPGA

Travailler avec Visual Studio Tools


Il s'avère que vous pouvez effectuer le développement pour Linux distant, sans l'avoir du tout sur votre machine locale et sans installer d'outils logiciels non Microsoft. Ici, il est montré comment il est mis sur Visual Studio (je l'ai installé dans la version 2019, mais il semble qu'il soit apparu en 2015) docs.microsoft.com/ru-ru/cpp/linux/download-install-and-setup- the-linux-development-workload? view = vs-2019

Et voici la théorie du travail .

Eh bien, là, vous pouvez vous promener dans les onglets, beaucoup de théorie et tout en russe.

Super! Essayons d'utiliser les connaissances acquises pour accéder à la puce FT2232H, à travers laquelle le processeur central Redd est connecté au FPGA. C'est cette chaîne à l'avenir qui constituera la base de notre travail de streaming. Ouvrez Visual Studio, sélectionnez «Créer un projet». Dans les filtres, sélectionnez "Langage - C ++", "Plateforme - Linux", "Type de projet - Console". Je montrerai où cela se trouve déjà pour le type de projet. A partir de ce que nous avons filtré, nous sélectionnons «Application console»:



Appelons-le, disons, SimpleConsole. Nous avons créé un tel code source Spartan:

#include <cstdio> int main() { printf("hello from SimpleConsole!\n"); return 0; } 

Essayons de le collecter. Et on nous pose une question très intéressante sur l'établissement d'une connexion. Il s'agit d'une fonctionnalité de développement dans Visual Studio. L'environnement ne contient pas de compilateur croisé et aucune bibliothèque. Il crée simplement un répertoire source sur la machine distante, après quoi, pour chaque compilation, il y copie les fichiers mis à jour et y démarre la compilation. C'est pourquoi la connexion avec la machine distante ne doit pas être établie pour démarrer, mais déjà pour l'assemblage normal du projet.

Nous remplissons les paramètres pour l'utilisateur Redd, pour le compte duquel les travaux seront effectués sur le projet.



Si quelque chose - les paramètres peuvent être modifiés ici dans cet endroit secret (n'essayez pas de changer les propriétés du projet, cela ne mènera à rien de bon):





En fait, vous pouvez mettre un point d'arrêt sur une seule ligne et vérifier que le projet démarre et fonctionne. Mais c'est trivial. Par conséquent, nous passons à une tâche plus intéressante - travailler avec FT2232. La question se pose: où trouver les bibliothèques nécessaires? Pour Linux, tout est inclus dans le package de pilotes. Il y a le pilote lui-même, et les bibliothèques, et des exemples d'applications pour travailler avec eux, et même une brève instruction. En général, nous entrons dans le moteur de recherche:

 FTDI D2XX drivers 

Il montrera où ils peuvent être téléchargés. Certes, tout était mauvais pour moi. Mon fournisseur bloque le site Web FTDI (ainsi que reprap, 7zip et même osronline), se référant à RosKomNadzor. ILV, en réponse aux déclarations, envoie des désabonnements, disant que nous ne bloquons rien, mais traitons avec le fournisseur vous-même. Où seulement dans ces désabonnements ne m'ont-ils pas proposé de me tourner, même à la police. Ils sont très désabonnés. Les tentatives de se plaindre de l'inaction d'ILV finissent par être transmises à ILV, d'où proviennent les prochains désabonnements. En général, il se peut que votre fournisseur bloque également l'accès. Ne vous inquiétez pas, recherchez simplement d'autres moyens de télécharger, en y consacrant du temps. Et puis ils sont surpris que les dates de développement des missiles soient retardées de plusieurs dizaines d'années ... J'ai commencé la correspondance avec ILV en novembre dernier, maintenant c'est en juin, sauf pour les désabonnements - aucune action ... Mais j'ai été distrait.

Comment utiliser les pilotes peut être trouvé dans le fichier readme, dans le package lui-même. Vous pouvez également trouver le document Guide d'installation des pilotes FTDI AN_220 pour Linux . Enfin, vous pouvez trouver sur YouTube une vidéo du Guide d'installation du pilote Linux d2xx par FTDI Chips. Un lien vers celui-ci se trouve également sur la page de téléchargement du pilote. En général, FTDI n'a pas hésité sur les options d'information des utilisateurs. En fait, si vous avez reçu un package Redd prêt à l'emploi, les pilotes eux-mêmes sont déjà installés et configurés dessus. Et nous serons intéressés par des fichiers d'en-tête et des exemples.

Insérons un exemple de tranche \ release \ examples \ EEPROM \ read . Le tout début de la fonction principale , où l'appareil s'ouvre et son type est pris. Ce sera suffisant pour vous assurer que tout fonctionne. Je déteste les étiquettes, mais comme nous glissons et déposons rapidement le code qui dure 10 minutes, je vais faire glisser l'étiquette qui était dans l'exemple d'origine pour gagner du temps. Il se présente comme ceci:

 #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; } 

Essayer de collecter - ne va pas. Pas assez de fichiers d'en-tête.

 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. 

Mais je les mets ensuite! Tout est simple. Localement, ils sont à proximité, mais le montage se fait à distance. Pour que le Studio les transfère sur une machine distante, vous devez les ajouter au projet. De plus, à partir du fichier main.cpp , j'ajoute uniquement ftd2xx.h , mais il tire toujours WinTypes.h en transit . Vous devez ajouter les deux.





Maintenant, l'éditeur de liens jure.

 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 

Il est clair qu'il n'y a pas assez de bibliothèque. En inspectant les makefiles de l' exemple, j'ai réalisé que je devais ajouter quelques paramètres aux paramètres de l'éditeur de liens:





Maintenant, le projet se déroule avec succès. Nous avons mis un point d'arrêt sur la dernière ligne, essayons de courir. Nous voyons le texte suivant:

 hello from ConsoleApplication1! Library version = 0x10408 Opening port 0 FT_Open succeeded. Handle is 0x555555768540 FT_GetDeviceInfo succeeded. Device is type 10. 

Dans l'ensemble - pas mal. Quelque chose s'est ouvert, même un appareil a été trouvé. Qu'est-ce que le type 10? Dans le fichier d'en-tête de FTDI, nous trouvons:

 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, }; 

Nous comptons le doigt de haut en bas - devant nous est le FT4222H. Oui, Redd a beaucoup d'appareils FTDI. Maintenant, je vais simplement dire brièvement que nous devons trier le numéro du périphérique passé à la fonction FT_Open () , ce nombre est passé à la fonction main () comme argument. Il peut être défini dans les propriétés de débogage du projet.

Il est utile de placer une plaque présentant des problèmes typiques. Généralement, il est indiqué «configurer Redd» partout sans détails. Le fait est que les complexes seront distribués sur mesure, donc tous les lecteurs n'ont pas besoin de règles de configuration. En cas de problème, les administrateurs s'occupent généralement de la configuration. Il s'avère donc que vous pouvez, bien sûr, décrire les règles de configuration, mais cela prendra beaucoup de place. Il est logique de consacrer de l'énergie à cela uniquement si quelqu'un en a vraiment besoin. Alors ici, je me limiterai à indiquer les problèmes et comment les résoudre, je décrirai s'il y a des applications dans les commentaires.

SymptômeRaison
Pas un seul appareil ne s'ouvre.Par défaut, Linux nécessite des droits d'administrateur pour ouvrir des périphériques USB, mais l'utilisateur qui se connecte pour le débogage ne les possède pas. Vous devez configurer les ports afin qu'ils puissent être utilisés par un utilisateur normal.
Seuls quelques appareils s'ouvrent, les deux FT4222H.Par défaut, un pilote de port COM virtuel standard est installé sur le contrôleur FT2232H. Vous devez dire au système d'exploitation de ne pas le faire.
Aucune bibliothèque trouvée.Les pilotes D2XX ne sont pas installés sur le système d'exploitation du périphérique Redd.

Super. Nous sommes prêts pour des réalisations utilisant exclusivement des outils Microsoft. En général, cela peut être suffisant, mais juste au cas où, je vais vous parler d'une alternative que mon patron m'a apprise.

Travailler avec Linux exécuté sur une machine virtuelle


Le principal inconvénient de la méthode précédente est l'assemblage à distance. Vous pouvez penser à mille et une raisons pour lesquelles l'assemblage doit être fait localement, et seul le fichier binaire terminé sera transféré vers la machine distante. Ce sont toutes sortes de restrictions paranoïaques (bien que les fichiers soient transférés à l'aide d'un protocole sécurisé, et vous pouvez séparer leur stockage des autres utilisateurs avec des politiques de sécurité), c'est juste le soin que le lecteur Redd ne déborde pas de toutes sortes de bibliothèques, c'est aussi la réticence à enregistrer chaque fichier d'en-tête, s'il y en a des milliers ... Eh bien, et bien plus encore. En général, la technique d'assemblage local peut être utile, alors pensez-y.

Tout d'abord, nous avons placé le programme VirtualBox d'Oracle sur la machine locale. S'il y a des problèmes de licence (je l'utilise gratuitement, en tant qu'individu, mais je ne sais pas exactement ce qui se passe avec les entités juridiques), sélectionnez une machine physique distincte et mettez Linux à cet endroit. Lequel? C’est plus facile pour moi, je les comprends tous de la même façon. Je veux dire, je ne comprends presque pas un. Par conséquent, le patron m'a dit que vous devez utiliser Debian, j'ai installé Debian. Vous pouvez suivre le même chemin (utilisez le principe «Pourquoi pas?»). Au moins à l'avenir, je compterai sur ma collaboration avec lui.

Lorsque vous travaillez avec Linux, vous devez respecter deux règles qui facilitent grandement la vie:

  1. Si, en réponse à une commande, ils nous disent qu'il n'y a pas assez de droits, cela vaut la peine de le répéter, en ajoutant au début le sort magique sudo .
  2. Si en réponse à une commande, on nous dit qu'il n'en existe pas, cela vaut la peine d'essayer de l'installer en lançant le sort magique apt-get install <chose manquante> .

Alors. Nous venons d'installer le système d'exploitation. Ajoutez immédiatement la prise en charge C ++ en installant le compilateur g ++, ainsi que le débogueur gdb. Comment? Donc, en utilisant la règle 2:

apt-get install g ++
apt-get install gdb

Ne donnez pas? Super! Répétez en utilisant la règle 1:

sudo apt-get install g ++
sudo apt-get install gdb

Maintenant on va sur Internet, dans le moteur de recherche on tape:

IDE Eclipse

Nous trouvons un lien vers eclipse.org, où les premières options sont pour Java, nous trouvons et téléchargeons une option pour C / C ++:



Téléchargez et déballez, disons, à la maison.

En fait, aucune installation n'est requise. Accédez simplement au répertoire où tout vient d'être décompressé et exécutez le fichier eclipse:



Nous sommes dans un environnement de développement. Eh bien, si vous avez déjà travaillé avec des microcontrôleurs et même des cœurs de processeur pour FPGA, vous savez probablement déjà ce qu'est Eclipse. Les choses inconnues sont donc presque terminées. Nous commençons à regarder autour de choses plus ou moins familières. Nous créons le projet C ++. Je dois dire tout de suite qu'il y a deux façons. L'un mènera au succès, le second à une impasse. Par conséquent, suivez attentivement le chemin que je parcours:







Nous avons créé un projet qui va bien. Pour configurer son débogage, accédez aux propriétés GDB:



Créez une configuration de type Application distante C / C ++, dans le groupe Connexion, cliquez sur Nouveau:



Choisissez une connexion comme SSH:



Nous remplissons les propriétés de connexion en basculant le bouton radio du type d'autorisation sur l'autorisation de mot de passe:



En fait, le système est prêt pour le débogage. Après avoir vérifié que le texte de bienvenue est réellement affiché, nous essayons de transférer le code de l'exemple précédent (qui était dans Visual Studio) ici. Pour enregistrer des bibliothèques supplémentaires, sélectionnez les propriétés du projet:



De plus, comme l'assembly se déroule localement, les bibliothèques doivent également se trouver dans le répertoire local usr / local / lib. Je vous rappelle que les bibliothèques sont téléchargées avec le pilote, et comment les installer est lisez-moi, ainsi que les vidéos AN220 et YouTube, pour plus de détails, voir la section sur Visual Studio.

Après toute cette préparation, nous obtenons les lignes familières. C'est-à-dire que le code complètement identique à celui considéré dans la section précédente est exécuté de la même manière.

C’est tout. Maintenant, selon la situation, nous pouvons exécuter le code à la fois via Visual Studio et via une machine virtuelle. Comme vous pouvez le voir, purement en termes de paramètres, Visual Studio est plus simple, donc, ceteris paribus, je vais le choisir. Mais il vaut mieux posséder les deux technologies, car travailler à travers le Studio a ses inconvénients liés au fait que non seulement le débogage, mais aussi l'assemblage y sont distants.

Mesure de vitesse d'écriture FPGA via FT2232H


Eh bien quoi. Fixons les compétences acquises sur un projet plus ou moins réel. Bien sûr, commencer quelque chose de très sérieux n'est plus possible, tout le monde est déjà fatigué. Mais nous obtenons un résultat plus ou moins pratique. Par exemple, nous mesurons à quelle vitesse maximale nous pouvons transférer des données vers le FPGA via la puce FT2232H. Le protocole n’est pas le plus simple, donc nous ne le transmettrons pas des deux côtés, mais nous nous limiterons à transmettre de nous au canal, à l’autre extrémité où le FPGA est installé. Le document AN_130 FT2232H utilisé dans un mode FIFO synchrone de style FT245 nous y aidera, car dans le complexe le contrôleur est activé précisément dans ce mode (FIFO synchrone). Ce document contient également une description des conclusions, sous la forme dans laquelle elles sont utilisées dans ce mode, et des chronogrammes, et même des exemples de code, dont nous nous inspirerons.

Alors. Nous voulons enregistrer en FIFO en utilisant le contrôleur. Qu'adviendra-t-il de nous? J'ai essayé, je sais. Cela prendra 1 kilo-octet de données, après quoi le contrôleur se bloquera. Il refusera d'accepter des données supplémentaires. Le fait est qu'un kilo-octet est la taille de son tampon interne. Bien que cela soit possible, les données seront prises à partir de l'USB et stockées dans cet espace. Mais pour qu'ils se rendent sur le canal synchrone, il doit informer de leur disponibilité à les recevoir. Nous regardons le fortune de fortune correspondant.



Alors. Lorsque le contrôleur a des données en FIFO, il supprime le signal RXF. En réponse à cela, nous devons d'abord supprimer le signal OE et le maintenir à zéro pendant au moins un cycle d'horloge (cela découle plus de la description du diagramme que du diagramme lui-même). Nous recevrons des données sur le bus, nous devons confirmer leur réception avec un faible niveau de signal RD. Et donc - pour l'ensemble du cadre. Lorsque le contrôleur soulève la ligne RXF, nous devons supprimer l'OE et le RD. Nous n'utiliserons pas les données aujourd'hui. Pour mesurer la vitesse, simulez simplement la réception de données sur le FPGA du FT2232H. Eh bien. Pour une opération aussi simple, aucun système de processeur n'est nécessaire. Il suffit de faire un automate dégénéré, dont le développement prendra beaucoup moins de temps que de s'occuper de la préparation du processeur et du programme. Par conséquent, nous créons un projet contenant un seul fichier SystemVerilog avec le contenu suivant:

 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 

La machine a deux états. Dans ce cas, la durée du signal OE est déterminée par le fait qu'il est armé immédiatement après l'impulsion d'horloge et est maintenu jusqu'à la suivante. Cela peut être vérifié en utilisant le modèle suivant:

 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 

Le temps que j'ai pris est le premier disponible, c'est la séquence de commutation qui est attachée au signal d'horloge qui est importante. Nous obtenons le chronogramme suivant:



En première approximation, cela correspond à ce que requiert le document. Mais nous ne traiterons pas les données réelles de toute façon.

L'affectation des jambes FPGA dans ce projet ne pose pas non plus de difficultés, même pour l'édition via une table (il faudra plus de temps pour transférer les affectations à partir du fichier * .QSF, et je souligne constamment que lors du développement de systèmes d'un jour sous Redd, gagner du temps est une priorité).



Nous collectons, remplissons, avant de couper l'alimentation du complexe, vous pouvez travailler avec le programme, il ne se bloquera plus après un débordement de tampon.

Dans le programme, j'ai fait deux fonctions. Le premier recherche et ouvre l'appareil. J'ai pris quelque chose du dernier test, j'ai emprunté quelque chose à AN130 :

 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; } } 

En tant que fan de Windows, j'ai dû écrire la fonction de mesure de vitesse, en vérifiant constamment Internet, car j'utilise généralement les minuteries haute résolution classiques de l'API WIN32. Vous pouvez peut-être écrire plus efficacement, mais il s'agit d'un programme d'une journée.

 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; } 

Eh bien, le code qui exécute la fonctionnalité de base s'est avéré comme ceci:

 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; } 

Je sais qu'en USB, la vitesse dépend fortement de la taille du bloc envoyé, donc je vérifie la vitesse pour différentes options. L'énumération linéaire n'est guère nécessaire. Je viens de vous présenter une liste de tailles typiques. Je produis les données en kilo-octets par seconde. Les octets sont inconfortables pour les yeux, les mégaoctets ont une faible résolution avec une petite taille de bloc. Les kilo-octets par seconde sont un compromis raisonnable. Nous obtenons les résultats suivants:
 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 

Nous les enregistrons dans un fichier * .csv, les chargeons dans Excel, construisons un graphique de la vitesse en fonction de la taille du bloc.



La limite est de 30 mégaoctets par seconde. Jusqu'à un maximum théorique de 52 Mo / s. Peut-être pouvez-vous accélérer d'une manière ou d'une autre, mais laissez-le aux lecteurs sous forme de travaux pratiques. L'essentiel est que nous maîtrisions toutes les étapes de l'utilisation du canal et sommes prêts à connecter le FPGA au processeur central en un seul système.

Pendant la compilation de l'article, le document AN_165 a été trouvé, indiquant que la vitesse maximale en mode FIFO synchrone était de 35 Mo / s. Autrement dit, l'espace pour la croissance - jusqu'à une taille donnée. Mais il est toujours là.

Conclusion


Nous nous sommes familiarisés avec deux stratégies de développement et de débogage de code programme exécutées sur le processeur central du complexe Redd (à l'aide des outils Microsoft Visual Studio et sur une machine virtuelle avec Linux OS). Nous avons également acquis des compétences pratiques en travaillant avec le canal par lequel le processeur central du complexe communique avec le FPGA.

Apparemment, maintenant rien ne nous empêche de transmettre des données significatives du CPU au FPGA et vice versa (bien que dans le dernier article j'ai écrit ces mots).

Un exemple contenant le «firmware» le plus simple pour les FPGA et un programme qui mesure la vitesse d'écriture sur USB peut être téléchargé ici .

Source: https://habr.com/ru/post/fr456008/


All Articles