Inhaltsverzeichnis:

WIDI - Wireless HDMI mit Zybo (Zynq Development Board) - Gunook
WIDI - Wireless HDMI mit Zybo (Zynq Development Board) - Gunook

Video: WIDI - Wireless HDMI mit Zybo (Zynq Development Board) - Gunook

Video: WIDI - Wireless HDMI mit Zybo (Zynq Development Board) - Gunook
Video: Getting Started with Microblaze in VIVADO IPI for Zynq : Zedboard FPGA 2024, Juli
Anonim
WIDI - Kabelloses HDMI mit Zybo (Zynq Development Board)
WIDI - Kabelloses HDMI mit Zybo (Zynq Development Board)
WIDI - Kabelloses HDMI mit Zybo (Zynq Development Board)
WIDI - Kabelloses HDMI mit Zybo (Zynq Development Board)

Haben Sie sich schon immer gewünscht, dass Sie Ihren Fernseher als externen Monitor an einen PC oder Laptop anschließen können, wollten aber nicht all diese lästigen Kabel im Weg haben? Wenn ja, ist dieses Tutorial nur für Sie! Obwohl es einige Produkte gibt, die dieses Ziel erreichen, ist ein DIY-Projekt viel zufriedenstellender und möglicherweise billiger.

Dieses Konzept unterscheidet sich von Produkten wie Chromecast, da es an die Stelle eines HDMI-Kabels treten soll, das an einen Monitor angeschlossen wird, anstatt ein Streaming-Gerät zu sein.

Unser Projekt wurde als Abschlussprojekt für einen Kurs für Echtzeit-Betriebssysteme an der California State Polytechnic University in San Luis Obispo erstellt.

Ziel des Projekts ist es, zwei Digilent Zybo-Boards als drahtlose Kommunikationsschnittstelle zwischen einem HDMI-Sendergerät (PC, Blu-ray usw.) zu einem HDMI-Empfangsgerät (Desktop-Monitor, Projektor, TV usw.) zu verwenden.

Ein Digilent Zybo wird über HDMI mit dem sendenden Gerät verbunden, das andere über HDMI mit dem empfangenden Gerät.

Die drahtlose Kommunikation erfolgt unter Verwendung eines drahtlosen lokalen Netzwerks, das dem Sender und Empfänger gewidmet ist, ohne über einen Heimrouter oder ein ähnliches Gerät geleitet zu werden. Das für dieses Projekt verwendete Funkmodul ist der tplink wr802n Nanorouter, von dem einer als Zugangspunkt zum Aufbau des Netzwerks und der andere als Client für die Verbindung mit dem Netzwerk fungiert. Jeder Nanorouter wird über ein Ethernet-Kabel mit einem der Zybo-Boards verbunden. Wenn sie mit diesen Routern verbunden sind, kommunizieren die Geräte über TCP, als wären sie mit einem einzigen Ethernet-Kabel verbunden (d. h. die einzige Konfiguration, die zum Herstellen einer Verbindung erforderlich ist, ist die IP-Adresse des Clients).

Während das Ziel des Projekts darin bestand, einen Videostream von 1080 x 720 bei 60 Hz zu ermöglichen, war dies aufgrund von Bandbreitenbeschränkungen im drahtlosen Netzwerk und der fehlenden Echtzeit-Videokomprimierung zur Reduzierung der zum Senden erforderlichen Daten nicht erreichbar. Stattdessen dient dieses Projekt als Rahmen für die zukünftige Entwicklung, um dieses Ziel zu erreichen, da die Framerate für das ordnungsgemäße Streamen von HDMI-Daten wie beabsichtigt stark eingeschränkt ist.

Projektanforderungen:

2x Digilent Zybo Development Boards (muss mindestens einen HDMI-Port haben)

2x HDMI-Kabel

2x Micro-USB-Kabel (um Zybo für die Entwicklung mit dem PC zu verbinden)

2x tplink wr802n Nanorouter (inklusive adtl. 2x Micro-USB- und Steckdosen-Netzteile)

2x Ethernet-Kabel

***Hinweis: Dieses Tutorial setzt voraus, dass Sie mit der Vivado Design Suite vertraut sind und Erfahrung mit der Erstellung eines neuen Projekts und Blockdesigns haben.***

Schritt 1: Konfigurieren Sie die programmierbare Zynq-Logik für den Sender

Konfigurieren der programmierbaren Zynq-Logik für den Sender
Konfigurieren der programmierbaren Zynq-Logik für den Sender
Konfigurieren der programmierbaren Zynq-Logik für den Sender
Konfigurieren der programmierbaren Zynq-Logik für den Sender
Konfigurieren der programmierbaren Zynq-Logik für den Sender
Konfigurieren der programmierbaren Zynq-Logik für den Sender

Unser Ansatz zur Entwicklung der programmierbaren Logik des Senders bestand darin, einen HDMI-zu-HDMI-Pass-Through vom PC zum Monitor mit zwei Video Direct Memory Access (VDMA)-Blöcken durchzuführen, einen zum Schreiben und einen zum Lesen.

Beide sind für den freilaufenden 3-Frame-Puffer-Modus (0-1-2) ausgewählt. Da der Videokern auf 60 Bilder pro Sekunde optimiert ist, bedeutet dies, dass der VDMA alle 16,67 ms in dieser Reihenfolge ein neues Bild schreibt oder liest: 0, 1, 2, 0, 1, 2, 0, 1, 2. Die DDR-Speicherplätze für jeden Frame sind für die beiden VDMAs unterschiedlich, da sie nicht mehr miteinander synchronisiert sind. Stattdessen wird ein für 60 Hz konfigurierter Hardware-Timer (TTC1) verwendet, um die Bewegung der Daten zwischen den beiden Speicherplätzen zu synchronisieren.

Das obige Bild zeigt 3 Frames, ihre Abmessungen und den jeweils benötigten Speicherplatz (rechts neben dem Frame). Wenn wir diesen Speicherplätzen den Schreib-VDMA zuweisen, dann können wir die Lese-VDMA-Speicherplätze jenseits dieses Satzes zuweisen, beispielsweise beginnend mit 0x0B000000. Jeder Frame besteht aus 1280*720 Pixeln und jedes Pixel besteht aus 8 Bit Rot, Grün und Blau, also insgesamt 24 Bit. Dies bedeutet, dass ein Frame aus 1280*720*3 Bytes (2,76 MB) besteht.

Innerhalb des Timers IRQ, der im VDMA-Treiber-Setup beschrieben ist, übernimmt das Kopieren von Daten zwischen den beiden VMDA-Speicherplätzen. Der VDMA stellt einen Zeiger auf den aktuellen Rahmen bereit, in den geschrieben oder aus dem gelesen wird. Der Rahmen wird durch einen bestimmten Gray-Code dargestellt, der in Software umgewandelt wird. Die Gray-Code-Definitionen für eine 3-Frame-Buffer-Konfiguration finden Sie im AXI VDMA-Produkthandbuch im Anhang C.

Dies ermöglicht es uns, den Inhalt, der in den Speicher geschrieben wird, zu kopieren, ohne aus einem Rahmen zu lesen, in den gerade geschrieben wird.

***Beachten Sie, dass der gelesene VDMA nicht verwendet wird, wenn Daten über das drahtlose Netzwerk gesendet werden. Sein einziger Zweck besteht darin, den ordnungsgemäßen Betrieb des Kopierens von Speicher von der Schreib-VMDA zu überprüfen. Die Lese-VMDA sollte deaktiviert sein.***

Hier sind die Schritte zum Erstellen des Sender-Design-Blocks:

  1. Beim Anlegen eines neuen Projekts empfiehlt es sich, dem Projekt einen Chip oder eine Platine zuzuweisen. Dieser Link beschreibt, wie Sie dem Vivado-Verzeichnis neue Board-Dateien hinzufügen und das richtige Board mit Ihrem Projekt verknüpfen. Dies ist praktisch, wenn Sie den Verarbeitungssystemblock hinzufügen und von Hardware zu Software (SDK-Seite) wechseln.
  2. Fügen Sie die folgenden Blöcke hinzu:

    • dvi2rgb
    • Video in Axi4-Stream
    • Zeitsteuerung
    • axi4-stream zum vid-out
    • rgb2dvi
    • AXI VDMA x2
    • AXI-GPIO x2
    • Uhr-Assistent
    • Konstante
    • Zynq-Verarbeitungssystem
  3. Klicken Sie beim Hinzufügen des Verarbeitungssystems in der oberen grünen Leiste auf "Blockautomatisierung ausführen" und stellen Sie sicher, dass die Option "Board-Voreinstellung anwenden" ausgewählt ist. Lassen Sie alles andere standardmäßig.
  4. Bilder der einzelnen Blockkonfigurationsfenster finden Sie in den obigen Bildern. Wenn Sie für ein bestimmtes Fenster kein Bild sehen, belassen Sie es einfach als Standard.
  5. Beginnen Sie mit der Konfiguration des Zynq-Verarbeitungssystems:

    • Aktivieren Sie in PS-PL Configuration AXI Non Secure GP Master AXI aktivieren, M AXI GP0 Interface
    • Aktivieren Sie in der PS-PL-Konfiguration HP Slave AXI Interface sowohl HP0 als auch HP1
    • Stellen Sie in der MIO-Konfiguration sicher, dass ENET0 unter I/O Peripherals aktiviert ist, dann Application Processor Unit, aktivieren Sie Timer0
    • Aktivieren Sie in Clock Configuration PL Fabric Clocks FCLK_CLK0 und stellen Sie es auf 100 MHz ein.
    • OK klicken
  6. Bevor Sie auf "Verbindungsautomatisierung ausführen" klicken, stellen Sie sicher, dass die Videoblöcke wie im TX-Block-Design oben abgebildet verbunden sind. Sie möchten die Konstante in VDD umbenennen und den Wert auf 1 setzen. Verbinden Sie die Videoblöcke entsprechend.
  7. Machen Sie die HDMI TMDS-Takt- und Datenpins an den rgb2dvi- und dvi2rgb-Blöcken extern
  8. Erstellen Sie einen Eingangs- und Ausgangsport für das Hot-Plug-Erkennungssignal (HPD) und verbinden Sie diese miteinander, diese sind in der Einschränkungsdatei definiert
  9. Der Pixeltakt wird aus TMDS_Clk_p wiederhergestellt, das in der Constraint-Datei erstellt wird. Das sind 74,25 MHz bei 720p-Auflösung. Es ist wichtig, den Pixeltakt (aus dem dvi2rgb-Block) an die folgenden Pins anzuschließen:

    • vid_io_in_clk (vid in axi stream block)
    • vid_io_out_clk (Axi-Stream zum Vid-Out-Block)
    • clk (Zeitsteuerung)
    • PixelClk (rgb2dvi)
  10. ***Hinweis: Derzeit müssen die HDMI-rx- und tx-Anschlüsse an eine aktive Quelle/Senke angeschlossen werden, um die Pixeltaktwiederherstellung zu aktivieren. Eine Möglichkeit, dies zu umgehen, besteht darin, die Video-RX- und TX-Blöcke in verschiedene Taktdomänen aufzuteilen (mit anderen Worten, einen neuen 74,25-MHz-Takt zu erzeugen, der in den TX-Block eingespeist wird).***
  11. Als nächstes richten Sie den Taktassistenten so ein, dass Sie einen 100-MHz-Eingang (globale Pufferquelle) und 3 Ausgangstakte @ 50 MHz (AXI-Lite-Takt), 150 MHz (AXI4-Stream-Takt), 200 MHz (dvi2rgb RefClk-Pin) haben.
  12. Verbinden Sie den Verarbeitungssystem-Pin FCLK_CLK0 mit dem Eingang des Taktassistenten
  13. Klicken Sie an dieser Stelle in der grünen Leiste oben im Designfenster auf "Verbindungsautomatisierung ausführen". Es ist eine gute Idee, dies für einen Block nach dem anderen zu tun und dem obigen TX-Block-Design-Bild zu folgen.
  14. Das Tool versucht, die AXI-Verbindung hinzuzufügen, die als Master/Slave-Verbindung für die Blöcke fungiert, die den AXI-Lite-Bus verwenden (VDMAs und GPIOs).
  15. Außerdem wird AXI SmartConnect hinzugefügt, das als Master/Slave-Verbindung für die vom VDMA verwendeten AXI4-Stream- und High-Performance-Prozessorschnittstellen (Stream to Memory Map und umgekehrt) fungiert.
  16. Das Tool fügt auch einen Prozessorsystem-Reset hinzu. Stellen Sie sicher, dass dieser nur mit den VDMAs, GPIOs und prozessorbezogenen Blöcken verbunden ist. Verbinden Sie es nicht mit Videoblöcken (z. B. dvi2rgb, Timing-Controller, Video zum Streamen usw.)
  17. Überprüfen Sie nach Abschluss der Verbindungsautomatisierung, ob die Verbindungen mit denen des TX-Blockdesign-Images übereinstimmen. Sie werden einen zusätzlichen System-ILA-Block bemerken, der nicht erwähnt wurde. Dies dient nur zum Debuggen und wird vorerst nicht benötigt. Es verwendet den 150M Prozessor-Reset, so dass dies auch nicht erforderlich ist. Überall sieht man kleine grüne "Bugs" an Bussen, das liegt an der ILA und kann ignoriert werden.
  18. Der letzte Schritt besteht darin, mit der rechten Maustaste auf das Blockdesign im Projektquellenbaum zu klicken und "HDL-Wrapper erstellen" auszuwählen. Wenn Sie dem Wrapper Logik hinzufügen möchten, wird diese bei jeder Auswahl überschrieben.
  19. Einzelheiten zur SDK-Seite finden Sie im Abschnitt VDMA-Treibereinrichtung.

Uhren und Resets

Ich habe festgestellt, dass der wichtigste Aspekt jedes programmierbaren Logikprojekts die sorgfältige Berücksichtigung von Taktdomänen und Rücksetzsignalen ist. Wenn diese richtig konfiguriert sind, haben Sie gute Chancen, Ihr Design zum Laufen zu bringen.

Pixeluhr und Timing gesperrt

Um zu überprüfen, ob bestimmte Signale aktiv sind, empfiehlt es sich, diese Signale mit LEDs (Uhren, Resets, Sperren usw.) zu verknüpfen. Zwei Signale, die ich auf der Senderplatine als hilfreich empfunden habe, waren der Pixeltakt und das "gesperrte" Signal auf dem AXI4-Stream zum Videoausgangsblock, der Ihnen sagt, dass das Videotiming mit dem Timing-Controller und der Videoquelle synchronisiert wurde Daten. Ich habe dem Designblock-Wrapper eine Logik hinzugefügt, die den Pixeltakt verfolgt, indem das PixelClkLocked-Signal auf dem dvi2rgb-Block als Reset verwendet wird. Ich habe die Datei als hdmi_wrapper.v hier angehängt. Die Constraint-Datei ist auch hier angehängt.

Schritt 2: Konfigurieren der programmierbaren Zynq-Logik für den Empfänger

Konfigurieren der programmierbaren Zynq-Logik für den Empfänger
Konfigurieren der programmierbaren Zynq-Logik für den Empfänger
Konfigurieren der programmierbaren Zynq-Logik für den Empfänger
Konfigurieren der programmierbaren Zynq-Logik für den Empfänger
Konfigurieren der programmierbaren Zynq-Logik für den Empfänger
Konfigurieren der programmierbaren Zynq-Logik für den Empfänger

Der programmierbare Logikblock für den Empfänger ist einfacher. Der Hauptunterschied, abgesehen von den fehlenden HDMI-Eingangsblöcken, ist das Fehlen eines wiederhergestellten Pixeltakts. Aus diesem Grund müssen wir unsere eigene aus dem Uhrenassistenten generieren. Dieses Design sollte in einem separaten Projekt vom Sender durchgeführt werden. Für unsere Zwecke folgte das Empfängerprojekt der Zybo 7Z-20-Platine, während der Sender der Z7-10-Platine folgte. Die FPGAs auf den Boards sind unterschiedlich, also… seien Sie vorsichtig.

Hier sind die Schritte zum Erstellen des Empfänger-Design-Blocks:

  1. Fügen Sie Ihrem Design die folgenden IP-Blöcke hinzu:

    • Zeitsteuerung
    • AXI4-Stream zum Videoausgang
    • RGB zu DVI
    • AXI VDMA
    • AXI-GPIO
    • Verarbeitungssystem
    • Uhr-Assistent
    • Konstante (VDD auf 1 gesetzt)
  2. Folgen Sie dem gleichen Muster für die Konfiguration dieser Blöcke wie der Sender. Bilder für die bemerkenswerten Unterschiede in der Konfiguration wurden hier eingefügt. Die anderen bleiben gleich dem Sender.
  3. Konfigurieren Sie den VDMA für dieses Design nur als Lesekanal. Deaktivieren Sie den Schreibkanal.
  4. Der Uhrenassistent sollte für folgende Ausgänge konfiguriert werden:

    • clk_out1: 75 MHz (Pixeltakt)
    • clk_out2: 150 MHz (Stream-Takt)
    • clk_out3: 50 MHz (Axi-Lite-Takt)
  5. Verbinden Sie die Videoblöcke wie im RX-Block-Designbild gezeigt.
  6. Führen Sie dann die Verbindungsautomatisierung aus, die die Blöcke AXI Interconnect, AXI SmartConnect und System Reset hinzufügt und versucht, die entsprechenden Verbindungen herzustellen. Gehen Sie hier langsam vor, um sicherzustellen, dass keine unerwünschten Verbindungen hergestellt werden.
  7. Stellen Sie die HDMI TMDS-Takt- und Daten-Pins extern auf den rgb2dvi-Block
  8. Bei diesem Design ist kein Hot-Plug-Signal erforderlich.

Schritt 3: VDMA-Treiber einrichten

VDMA-Treiber einrichten
VDMA-Treiber einrichten

Die Einrichtung der verschiedenen Blöcke, die über die AXI-Lite-Schnittstelle konfiguriert werden, erfolgt am besten mithilfe von Demoprojekten, die im BSP als Referenz enthalten sind. Nachdem Sie die Designhardware exportiert und das SDK von Vivado gestartet haben, möchten Sie ein neues Board-Support-Paket hinzufügen und die lwip202-Bibliothek in das BSP-Einstellungsfenster einbinden. Öffnen Sie die Datei system.mss vom BSP und Sie sehen die Peripherietreiber Ihres Blockdesigns. Mit der Option "Beispiele importieren" können Sie Demoprojekte importieren, die diese Peripheriegeräte verwenden, und Ihnen so zeigen, wie Sie sie in Software mit den verfügbaren Xilinx-Treibern konfigurieren (siehe angehängtes Bild).

Dies war die Methode, die zum Konfigurieren von VDMA, Timer & Interrupt und GPIO verwendet wurde. Der Quellcode für Senden und Empfangen wurde hier eingefügt. Die Unterschiede liegen fast ausschließlich in main.c.

***HINWEIS: Da das System zum Zeitpunkt der Erstellung dieses Tutorials noch nicht voll funktionsfähig ist, enthält der Quellcode in diesem Abschnitt nicht den Code des drahtlosen Netzwerks. Als Ergebnis der Kombination der Videokern-Sende-/Empfangsprojekte mit den Netzwerk-Sende-/Empfangsprojekten müssen mehrere Fehler behoben werden. Daher werden sie in diesem Tutorial vorerst separat behandelt.***

TX-Interrupt-Handler-Funktion (IRQHandler)

Diese Funktion liest die Gray-Codes, die sowohl von den lesenden als auch von den schreibenden VDMAs über die GPIO-Blöcke bereitgestellt werden. Die Gray-Codes werden in Dezimalzahlen umgewandelt und zum Auswählen des Rahmenbasisspeicherplatzes des aktuellen Rahmens verwendet. Der kopierte Frame ist der vorherige Frame gegenüber dem Frame, in den der VDMA schreibt (z. B. wenn der VDMA in Frame 2 schreibt, kopieren wir Frame 1; wenn wir nach Frame 0 schreiben, umbrechen und lesen wir aus Frame 2).

Die Funktion erfasst nur jeden 6. Frame, um die Framerate auf 10 Hz statt auf 60 Hz zu reduzieren. Die Obergrenze des Netzwerks beträgt 300 Mbit/s. Bei 10 Bildern pro Sekunde wird eine Bandbreite von 221,2 Mbit/s benötigt.

Das Kommentieren/Entkommentieren von zwei Zeilen in dieser Funktion ermöglicht es dem Benutzer, zu Debug-/Testzwecken in den HDMI-Passthru-Modus zu wechseln (der Code wird kommentiert, um die entsprechenden Zeilen anzuzeigen). Es kopiert derzeit den Frame an einen Speicherort, der vom Ethernet-Code verwendet wird.

RX-Interrupt-Handler-Funktion (IRQHandler)

Diese Funktion ist der TX-Funktion sehr ähnlich, kopiert jedoch von einem 2-Puffer-FIFO, das vom Ethernet verwendet wird, um eingehende Daten zu schreiben. Der Ethernet-Code zeigt an, in welchen Frame des FIFO geschrieben wird, Daten werden aus dem gegenüberliegenden Frame kopiert. Die Daten werden in den Frame direkt hinter dem vom VDMA gelesenen Frame kopiert, um ein Tearing zu vermeiden.

Schritt 4: Nanorouter-Netzwerk einrichten

Nanorouter-Netzwerk einrichten
Nanorouter-Netzwerk einrichten

Um ein Netzwerk mit den TPlink-Nanoroutern zu erstellen, schalten Sie sie einzeln ein und verbinden Sie sich mit der Standard-WLAN-SSID für die Geräte. Weitere Informationen zu den Konfigurationseinstellungen für dieses spezielle Gerät finden Sie im Benutzerhandbuch des Geräts.

Richten Sie eines der Geräte als Zugangspunkt ein, dies dient als primäre Verbindung für das Netzwerk. Stellen Sie sicher, dass Sie das Netzwerk benennen und den Namen notieren und DHCP deaktivieren (wir möchten nicht, dass der Router die IP-Adressen dynamisch konfiguriert, wir möchten, dass die Sender- und Empfänger-Zybo-Boards ihre IP-Adressen selbst festlegen, damit sie konsistent sind). Stellen Sie nach der Konfiguration sicher, dass das Gerät neu startet und dieses Netzwerk aufbaut.

Richten Sie das andere Gerät als Client ein und stellen Sie sicher, dass es sich mit der Netzwerk-SSID verbindet, die Sie mit dem ersten Nanorouter eingerichtet haben. Stellen Sie erneut sicher, dass DHCP für den Client deaktiviert ist.

Sobald der Client fertig ist und neu gestartet wurde, sollte er sich mit dem Zugangspunkt-Nanorouter verbinden (wenn dies nicht der Fall ist, liegt wahrscheinlich ein Problem in Ihrer Konfiguration eines der Geräte vor). Sie werden feststellen, dass die LED-Leuchte am Client dauerhaft leuchtet, sobald er mit dem Access Point verbunden ist.

Die Nanorouter-LED des Access Points wird wahrscheinlich an dieser Stelle weiter blinken, das ist in Ordnung! Das blinkende Licht bedeutet, dass es über seinen Ethernet-Port nicht mit einem anderen Gerät verbunden ist, und sobald es mit einem konfigurierten Zybo verbunden ist, leuchtet die LED konstant und zeigt eine erfolgreiche Netzwerkverbindung an.

Nachdem wir unsere Nanorouter eingerichtet haben, verfügen wir über ein drahtloses Netzwerk, über das wir kommunizieren können. Ein wichtiger Hinweis ist, dass unsere Konfigurationsmethode für die Nanorouter (als Access Point und Client) es uns ermöglicht, vom sendenden Zybo-Board zum empfangenden Zybo-Board zu kommunizieren, als ob die beiden mit einem einzigen Ethernet-Kabel verbunden wären. Dies macht unser Netzwerk-Setup weniger schwierig, da die Alternative wahrscheinlich die Konfiguration der Zybo-Boards beinhalten würde, um eine explizite Verbindung mit dem Server zusammen mit der beabsichtigten Verbindung herzustellen.

Sobald beide Geräte eingerichtet sind, sind die Nanorouter konfiguriert und können in Ihr WIDI-Netzwerk integriert werden. Es gibt keine spezielle Paarung zwischen den Nanoroutern und den Zybo-Boards, da entweder der Access Point oder der Client entweder für das Sende- oder Empfangsgerät funktioniert.

Schritt 5: Zynq-Verarbeitungssystem für die Datenübertragung über Ethernet einrichten

Einrichten des Zynq-Verarbeitungssystems für die Datenübertragung über Ethernet
Einrichten des Zynq-Verarbeitungssystems für die Datenübertragung über Ethernet
Einrichten des Zynq-Verarbeitungssystems für die Datenübertragung über Ethernet
Einrichten des Zynq-Verarbeitungssystems für die Datenübertragung über Ethernet

Um die HDMI-Daten von einem Zybo-Board zum anderen zu übertragen, müssen wir in unseren VDMA-Treiber ein Ethernet-Protokoll einbinden. Unser Ziel hier ist es, einzelne Videoframes über das Ethernet-Peripheriegerät im Verarbeitungssystem mit einer festgelegten Rate zu streamen, die unserer Netzwerkbandbreite entspricht. Für unser Projekt haben wir TCP verwendet, das von der Bare-Metal-LwIP-API bereitgestellt wird. Da beide Projektmitglieder relativ unerfahren mit Netzwerkdienstprogrammen sind, wurde diese Wahl getroffen, ohne die Auswirkungen und Einschränkungen, die mit TCP verbunden sind, vollständig zu erkennen. Das Hauptproblem bei dieser Implementierung war die begrenzte Bandbreite und die Tatsache, dass sie wirklich nicht dafür ausgelegt ist, große Datenmengen zu streamen. Alternative Lösungen zum Ersetzen von TCP und zur Verbesserung von tbe in diesem Projekt werden später diskutiert.

Eine kurze Beschreibung von TCP mit LwIP: Daten werden über das Netzwerk in Paketen der Größe tcp_mss (TCP maximale Segmentgröße) gesendet, die in der Regel 1460 Byte beträgt. Der Aufruf von tcp_write benötigt einige Daten, auf die ein Zeiger verweist, und konfiguriert pbufs (Paketpuffer), um die Daten zu speichern und eine Struktur für die TCP-Operationen bereitzustellen. Die maximale Datenmenge, die gleichzeitig in die Warteschlange gestellt werden kann, wird als tcp_snd_buf (TCP-Senderpufferspeicherplatz) festgelegt. Da es sich bei diesem Parameter um eine 16-Bit-Zahl handelt, sind wir auf eine Sendepuffergröße von 59695 Bytes beschränkt (im Sendepuffer sind einige Auffüllungen erforderlich). Sobald die Daten in die Warteschlange gestellt wurden, wird tcp_output aufgerufen, um mit der Übertragung der Daten zu beginnen. Vor dem Senden des nächsten Datensegments ist es zwingend erforderlich, dass alle vorherigen Pakete erfolgreich übertragen wurden. Dieser Vorgang wird mit der Funktion recv_callback durchgeführt, da dies die Funktion ist, die aufgerufen wird, wenn die Bestätigung vom Empfänger gesehen wird.

Die Verwendung der Beispielprojekte im Vivado SDK ist sehr hilfreich, um die Funktionsweise von LwIP TCP zu erlernen, und ist ein guter Ausgangspunkt für den Beginn eines neuen Projekts.

Die Vorgehensweise für das WiDi-Sendegerät ist wie folgt:

  1. Initialisieren Sie das TCP-Netzwerk mithilfe der Bare-Metal-LWIP-Treiberfunktionsaufrufe.
  2. Geben Sie alle Rückruffunktionen an, die für den Netzwerkbetrieb erforderlich sind.
  3. Verbinden Sie sich mit dem WiDi-Empfänger, indem Sie sich mit seiner IP-Adresse und seinem Port verbinden (unsere Konfiguration: Empfänger-IP ist 192.168.0.9, verbinden Sie sich mit Port 7).
  4. Wenn der VDMA-Treibertimer abläuft, geben Sie den TX ISR ein.
  5. Bestimmen Sie den aktuellen Framebuffer, auf den Sie zugreifen möchten, basierend auf dem VDMA-Gray-Code
  6. Stellen Sie das erste Datensegment im TCP-Sendepuffer in die Warteschlange
  7. Geben Sie die Daten aus und aktualisieren Sie lokale Variablen, um zu verfolgen, wie viele Daten vom aktuellen Frame gesendet wurden.
  8. Beim Erreichen des empfangenen Rückrufs (Funktionsaufruf, der erfolgt, nachdem der Sender eine Bestätigung des Datenabrufs erhalten hat), wird das nächste Datensegment in die Warteschlange gestellt.
  9. Wiederholen Sie die Schritte 7 & 8, bis der gesamte Frame gesendet wurde.
  10. Kehren Sie in einen Ruhezustand zurück, um auf die nächste Zeitgeberunterbrechung zu warten, um anzuzeigen, dass ein neuer Rahmen bereit ist (zurück zu Schritt 4).

Stellen Sie sicher, dass die LwIP-Einstellungen des Board Support Package wie in der Abbildung oben gezeigt eingerichtet sind. Alle Werte sind Standardwerte außer tcp_snd_buf, tcp_pueue_ooseq, mem_size, memp_n_tcp_seg. Beachten Sie auch, dass ein detailliertes Debugging erreicht werden kann, indem die BSP-Parameter für die Gruppe debug_options geändert werden.

Schritt 6: Zynq-Verarbeitungssystem für den Datenempfang über Ethernet einrichten

Das Zybo-Entwicklungsboard, das als drahtloser Empfänger fungiert, funktioniert ähnlich wie das Sendegerät. Die Einstellungen des Board-Support-Pakets für LwIP sind mit denen im vorherigen Schritt identisch.

Das Gerät nimmt Pakete mit den Videoframesegmenten vom Nanorouter auf und kopiert die Videoframedaten in den Dreifach-Frame-Pufferraum für den empfangenden VDMA. Um das Überschreiben von Daten zu vermeiden, wird beim Sammeln von Daten vom Nanorouter ein doppelter Datenpuffer (wir werden als Netzwerkpuffer bezeichnet) verwendet, damit der Netzwerkverkehr weiterhin einströmen kann, während der vorherige vollständige Videoframe in den VDMA-Puffer.

Das Verfahren für das WiDi-Empfangsgerät erfordert zwei Aufgaben, eine davon ist der Empfang von Ethernet-Daten und die andere das Kopieren von Videoframes aus dem Netzwerkpuffer in den Triple Frame Buffer des VDMA.

Ethernet-Empfangsaufgabe:

  1. Initialisieren Sie das TCP-Netzwerk mit den Bare-Metal-LWIP-Treiberfunktionsaufrufen (Setup mit IP-Adresse, mit der sich der Sender verbinden wird, 192.168.0.9 in unserer)
  2. Geben Sie alle Rückruffunktionen an, die für den Netzwerkbetrieb erforderlich sind.
  3. Kopieren Sie bei empfangenem Ethernet-Paket Paketdaten in den aktuellen Netzwerkpuffer, erhöhen Sie die aktuellen akkumulierten Daten.
  4. Wenn das Paket den Netzwerk-Frame-Puffer füllt, fahren Sie mit den Schritten 5 und 6 fort. Andernfalls kehren Sie für diese Aufgabe zu Schritt 3 zurück.
  5. signalisieren, dass die VDMA-Triple-Frame-Puffer-Aufgabe aus dem neu fertiggestellten Netzwerkpuffer kopieren soll.
  6. Wechseln Sie zum anderen Netzwerkpuffer und fahren Sie mit dem Sammeln von Daten über Ethernet fort.
  7. Im Leerlauf, bis ein neues Ethernet-Paket empfangen wird (Schritt 3).

Netzwerkpuffer in VDMA Triple Frame Buffer kopieren:

  1. Wenn der VDMA-Treibertimer abläuft, geben Sie den RX ISR ein.
  2. Bestimmen Sie den aktuellen Frame-Puffer, auf den basierend auf dem VDMA-Gray-Code zugegriffen werden soll.
  3. Bestimmen Sie, welcher Netzwerkpuffer in den VDMA-Puffer kopiert wird, und kopieren Sie diese Daten

Schritt 7: Verbinden Sie Ihre Zybo-Boards mit der HDMI-Quelle und der HDMI-Senke

Verbinden Sie Ihre Zybo-Boards mit der HDMI-Quelle und der HDMI-Senke
Verbinden Sie Ihre Zybo-Boards mit der HDMI-Quelle und der HDMI-Senke

Schließen Sie nun die HDMI-Kabel für Empfänger und Sender an, programmieren Sie die FPGAs und starten Sie das Verarbeitungssystem. Die Bildrate wird aufgrund des immensen Overheads im LwIP-Betrieb und der begrenzten Bandbreite wahrscheinlich sehr langsam sein. Wenn Probleme auftreten, stellen Sie eine Verbindung über UART her und versuchen Sie, Warnungen oder Fehler zu identifizieren.

Schritt 8: Alternative Ideen zur Verbesserung

Alternative Verbesserungsideen
Alternative Verbesserungsideen

Ein großes Problem bei diesem Projekt war die Datenmenge, die zum Senden über WLAN benötigt wird. Dies war zu erwarten, aber wir haben die Auswirkungen unterschätzt und führten eher zu einer Bildserie auf einem Bildschirm als zu einem Video-Feed. Es gibt mehrere Möglichkeiten, dieses Projekt zu verbessern:

  • Videokomprimierung in Echtzeit. Das Komprimieren des eingehenden Video-Feeds Frame für Frame würde die Datenmenge, die über das Netzwerk gesendet werden muss, stark reduzieren. Idealerweise würde dies in Hardware erfolgen (was keine leichte Aufgabe ist), oder es könnte in Software erfolgen, indem der andere ARM-Kern verwendet wird, um einen Komprimierungsalgorithmus auszuführen (dies würde eine weitere Analyse erfordern, um sicherzustellen, dass das Timing funktioniert). Es gibt einige Open-Source-Komponenten zur Echtzeit-Videokomprimierung, die wir im Internet gefunden haben, aber die meisten sind IP.
  • Implementieren des Ethernet-Streams in Hardware statt in Software. Es gab eine Menge Overhead aufgrund des Mangels an verfügbarem Platz, um ausgehende Daten in den Sender einzureihen, aufgrund der Beschränkung der Segmentgröße. Ein viel effizienterer Prozess ist die Verwendung von AXI Ethernet IP mit einem FIFO-Puffer oder DMA, um Daten einzuspeisen. Dies würde das zusätzliche Gepäck von LwIP TCP reduzieren und mehr Datenfluss ermöglichen.

Schritt 9: Zugänglichkeit

Das Ergebnis dieses WiDi-Projekts sollte ein vollständig integriertes, kompaktes Gerätepaar sein, das ein Benutzer an eine beliebige HDMI-Quelle anschließen und dann den Video-Feed drahtlos an ein Display mit HDMI-Fähigkeit senden kann. Die Geräte würden den Zynq-7000-SoC auf dem Zybo-Referenzboard enthalten und die Netzwerkhardware der TP-Link-Nanorouter integrieren. Idealerweise wäre der Benutzer in der Lage, das Sendemodul von einem diskreten Ort innerhalb des Zielbetriebssystems aus zu steuern, ohne dass erhebliche technische Fähigkeiten erforderlich wären.

Sicherheit und Konnektivität

Die Geräte sollten auch Transport Layer Security (TLS) enthalten und über eine begrenzte Fähigkeit zur automatischen Verbindung verfügen, beides aus Datenschutzgründen. Es ist die Absicht der Designer, die Verbindung mit einem Display über eine drahtlose Schnittstelle zu einer bewussten Aktion des Benutzers zu machen, um eine versehentliche Übertragung von sensiblem Material zu vermeiden.

Aktueller Status

Bis zu diesem Zeitpunkt ist der Stand des Projekts noch in Arbeit. Damit der aktuelle Endpunktbenutzer von diesem Tutorial profitieren kann, muss er oder sie über ein solides technisches Verständnis des Designs von eingebetteten Systemen verfügen und mit der Zusammenarbeit von programmierbarer Hardware und eingebetteter Software vertraut sein.

Die über das Netzwerk gesendeten Daten werden zu diesem Zeitpunkt nicht verschlüsselt und es wird angenommen, dass es sich um eine rohe Übertragung von TCP/IP-Paketen handelt.

Das Video-Core-Projekt wurde sowohl beim Senden als auch beim Empfangen erfolgreich getestet. Andererseits wurde die drahtlose Verbindung zwischen zwei Zybo-Boards hergestellt und die Testrahmendaten wurden erfolgreich gesendet. Es ist jedoch weiterhin erforderlich, den Netzwerkcode zu jedem Video-Core-Projekt zu kombinieren und die Übertragung von tatsächlichen Videoframes zu testen.

Empfohlen: