Überblick
Das häufigste Einsatzszenario von Xillybus ist die Datenerfassung (data acquisition). Diese Seite zeigt, wie Sie damit beginnen, Daten vom FPGA an den Host zu übertragen.
Eine detailliertere Betrachtung der Interaktion mit Xillybus im FPGA finden Sie im Handbuch für den FPGA-Entwurf mit Xillybus.
Wenn die Anwendung eine hohe Datenrate aufweist, empfiehlt es sich außerdem, die Richtlinien dazu in Kapitel 5 des Leitfadens für den Einstieg unter Linux bzw. für Microsoft Windows zu lesen.
Die Seite des Hosts
Um zu verstehen, wie Xillybus funktioniert, ist es am einfachsten, auf der Seite des Rechners zu beginnen: Mit dem folgenden Befehl können Sie Daten in eine Datei auf der Festplatte erfassen:
$ cat /dev/xillybus_read_32 > capture-file.dat
„cat“ ist ein Standard-Linux-Befehl, der alle Daten aus einer Datei liest und auf die Standardausgabe schreibt. In diesem Beispiel ist die Eingabe keine reguläre Datei, sondern eine Gerätedatei (device file). Diese Eingabe besteht aus einem Datenstrom, der vom FPGA kommt. Die Standardausgabe wird umgeleitet, sodass diese Daten in eine Datei auf der Festplatte geschrieben werden.
Das ist kein konstruiertes Beispiel: In manchen Einsatzszenarien ist das tatsächlich die richtige Art, Xillybus praktisch zur Datenerfassung zu nutzen. Unter Umständen ist „dd“ besser geeignet, um eine bestimmte Datenmenge zu erhalten. Häufiger wird jedoch ein eigenes Computerprogramm verwendet, das die Daten aus der Gerätedatei liest. Jede Anwendung hat ihre eigene bevorzugte Art, die Daten zu konsumieren.
Es spielt also keine Rolle, welche Programmiersprache Sie bevorzugen oder ob Sie Linux oder Windows verwenden. Die Computersoftware, die die Daten vom FPGA empfängt, braucht nur dasselbe zu tun wie „cat“: eine Datei öffnen und daraus lesen. Auf einer separaten Seite werden die üblichen Programmiertechniken für die Datei-E/A (file I/O) vorgestellt. Noch ausführlichere Informationen zur Programmierung mit Xillybus finden Sie in den Programmierhandbüchern für Linux und Windows.
Die Logik für die Datenerfassung
Nun schauen wir uns an, was im FPGA passiert. Der Xillybus-IP-Core und die Anwendungslogik kommunizieren über ein FIFO: Die Anwendungslogik schreibt Daten in das FIFO, und Xillybus sorgt dafür, dass diese Daten den Host erreichen. Falls Sie mit diesem Konzept nicht vertraut sind, gibt es eine separate Seite, die erklärt, wie FIFOs funktionieren.
Das Demopaket von Xillybus enthält eine Datei namens xillydemo.v. Das ist der Verilog-Code, der die Verbindung zum IP-Core herstellt. Im Demopaket gibt es auch eine VHDL-Datei: xillydemo.vhd. Das folgende Beispiel ist jedoch in Verilog.
Die Instanziierung (instantiation) des Xillybus-IP-Cores erfolgt in xillydemo.v (bzw. xillydemo.vhd). Im Folgenden sind die Teile gezeigt, die für das Beispiel der Datenerfassung mit dem obigen „cat“-Befehl relevant sind (die übrigen Teile sind weggelassen).
// Wires related to /dev/xillybus_read_32
wire user_r_read_32_rden;
wire user_r_read_32_empty;
wire [31:0] user_r_read_32_data;
wire user_r_read_32_eof;
wire user_r_read_32_open;
[ ... ]
xillybus xillybus_ins (
[ ... ]
// Ports related to /dev/xillybus_read_32
// FPGA to CPU signals:
.user_r_read_32_rden(user_r_read_32_rden),
.user_r_read_32_empty(user_r_read_32_empty),
.user_r_read_32_data(user_r_read_32_data),
.user_r_read_32_eof(user_r_read_32_eof),
.user_r_read_32_open(user_r_read_32_open),
[ ... ]
.bus_clk(bus_clk),
[ ... ]
);
Die Bedeutung der Ports des IP-Cores ist ausführlich im Leitfaden von Xillybus zur Logik-API beschrieben.
In xillydemo.v gibt es eine Instanziierung eines FIFO. Dieses FIFO ist ein FIFO mit nur einem Takt (single-clock FIFO) und eignet sich für den Loopback, der im ursprünglichen Verilog-Code demonstriert wird. Für eine Datenerfassungsanwendung ist ein FIFO mit zwei Takten (dual-clock FIFO) besser geeignet, weil die Datenerfassungslogik üblicherweise mit einem eigenen Takt arbeitet.
Sie können xillydemo.v also wie folgt in ein Modul umändern, das Datenerfassung durchführt: Entfernen Sie die Instanziierung des Single-Clock-FIFO (es heißt fifo_32x512). Fügen Sie stattdessen Folgendes ein:
assign user_r_read_32_eof = 0;
dualclock_fifo_32 fifo_32
(
.rd_clk(bus_clk),
.rst(!user_r_read_32_open),
.rd_en(user_r_read_32_rden),
.dout(user_r_read_32_data),
.empty(user_r_read_32_empty),
.wr_clk(capture_clk),
.wr_en(capture_en),
.din(capture_data),
.full(capture_full)
);
Das Dual-Clock-FIFO
dualclock_fifo_32 ist ein Standard-Dual-Clock-FIFO. Sie müssen es als IP mit der FPGA-Entwicklungssoftware erzeugen. Die Tiefe dieses FIFO sollte 512 Elemente oder mehr betragen. Aufgrund von Unterschieden zwischen den FPGA-Programmen können die Namen der Ports anders lauten als oben gezeigt. Es sollte dennoch einfach sein, die Verbindungen der FIFO-Ports abzuleiten.
Wie gesagt gibt es eine Seite, die FIFOs vorstellt, falls Sie mit ihnen noch nicht vertraut sind.
Mehrere Ports des FIFO sind direkt mit dem IP-Core von Xillybus verbunden: @rd_clk, @rd_en, @dout und @empty (leer). Beachten Sie, dass diese Verbindungen genauso hergestellt werden wie im Demopaket. Der IP-Core verwendet diese vier Signale, um Daten aus dem FIFO herauszuholen. Das ist immer der richtige Weg, diese Ports mit dem IP-Core zu verbinden.
Beachten Sie, dass @rd_clk mit @bus_clk verbunden ist. Dieses Signal stammt vom IP-Core von Xillybus. Mit anderen Worten: Der IP-Core gibt den Takt vor, der auf einer Seite des FIFO verwendet wird.
Was @rst betrifft, so ist @rst mit !user_r_read_32_open verbunden. @user_r_read_32_open ist nur dann high, wenn die zugehörige Gerätedatei auf dem Host geöffnet ist. Dadurch wird das FIFO zurückgesetzt, wenn die Datei nicht geöffnet ist. Folglich ist das FIFO leer (empty), wenn der Host die Gerätedatei öffnet: Falls sich im Speicher des FIFO noch Reste aus einer früheren Sitzung befanden, wurden sie beim Schließen der Gerätedatei gelöscht.
Dieses Verhalten erwarten wir normalerweise von einer Datenquelle. Wenn das FIFO seine Daten beim Schließen der Gerätedatei jedoch behalten soll, verbinden Sie etwas anderes mit @rst. Oder halten Sie @rst dauerhaft auf low.
Beachten Sie, dass @user_r_read_32_eof in diesem Beispiel ebenso wie im Demopaket null ist. Mit diesem Signal kann ein End-of-File an den Host gesendet werden. Mehr dazu finden Sie im Leitfaden zur API.
Schnittstelle zur Anwendungslogik
Bei einer Datenerfassungsanwendung gibt es immer eine Anwendungslogik, die Daten zur Übertragung an den Host erzeugt. Dieser Teil ist von Anwendung zu Anwendung verschieden und daher für diese Betrachtung nicht von Belang. Wir konzentrieren uns darauf, diese Daten an den Host zu senden.
Dieser Teil ist erstaunlich einfach: Die Anwendungslogik schreibt die Daten in das FIFO. Die Daten, die in das FIFO geschrieben werden, kommen auf dem Host als zusammenhängender Datenstrom im Computerprogramm an.
Entsprechend verwendet die Anwendungslogik die übliche Konvention zum Schreiben in ein FIFO. Im obigen Beispiel wird das mit @capture_clk, @capture_en, @capture_data und @capture_full gezeigt. Diese Logik muss lediglich die Daten auf @capture_data legen und @capture_en steuern, um korrekt in das FIFO zu schreiben. Beachten Sie, dass die Anwendungslogik zum Schreiben in das FIFO ihren eigenen Takt verwendet.
Der Datenfluss
Dies ist ein vereinfachtes Blockdiagramm, das den Datenfluss von der Anwendungslogik zum Anwendungsprogramm auf dem Host veranschaulicht.
Beachten Sie, dass in diesem Blockdiagramm zwei technische Details weggelassen wurden: Der PCIe-Block und der Kerneltreiber sind nicht dargestellt, weil sie für die Wahrnehmung des Datenflusses durch den Anwender nicht von Bedeutung sind. Der richtige Umgang mit Xillybus besteht darin, diese Details zu vergessen und sich auf die Anwendungslogik und die Anwendungssoftware zu konzentrieren.
Es ist nicht nötig, die Daten in Pakete zu organisieren: Der Kommunikationskanal zwischen der Anwendungslogik und dem Rechner ist ein kontinuierlicher Datenstrom. Der IP-Core und der Treiber sorgen dafür, dass sich der Datenfluss wie andere Streaming-Protokolle verhält, beispielsweise wie Pipes zwischen Programmen unter Linux. Ein weiteres Protokoll mit ähnlichem Verhalten ist TCP/IP. Mit anderen Worten: Es spielt keine Rolle, wie viele Daten Sie in das FIFO schreiben. Diese Daten erreichen bald das Anwendungsprogramm auf dem Host.
Ein häufiger Fehler besteht darin, die Daten in Pakete zu organisieren und die DMA-Puffer des IP-Cores an die Größe dieser Pakete anzupassen. Das bringt keinen Vorteil. Selbst wenn die Daten in Paketen konstanter Größe gesendet werden, muss der IP-Core nicht an diese Größe angepasst werden.
Was aber, wenn das FIFO voll wird?
Eine der Grundregeln für ein FIFO lautet: Wenn der Port @full (voll) high ist, muss @wr_en low sein. Einfach gesagt: Schreiben Sie nicht in ein volles FIFO. Was aber, wenn das doch passiert? Mit dieser Situation umzugehen würde die Anwendungslogik erheblich verkomplizieren.
Die kurze Antwort lautet, dass das FIFO niemals voll (full) werden sollte: Unter normalen Betriebsbedingungen wird das aktiv verhindert: Der IP-Core liest Daten aus dem FIFO und kopiert sie in den RAM des Hosts. Das geschieht schnell genug, um ein Füllen des FIFO zu verhindern. Normalerweise braucht das FIFO nicht tiefer als 512 Datenelemente zu sein.
Das FIFO kann jedoch voll werden, wenn die Anwendungslogik zu schnell in das FIFO schreibt. Wenn also die mittlere Datenrate der Anwendungslogik das Limit des IP-Cores überschreitet (wie es für jeden IP-Core-Typ angegeben ist), kann der IP-Core die Daten nicht schnell genug aus dem FIFO lesen.
Eine weitere Möglichkeit besteht darin, dass die Anwendungssoftware (z. B. „cat“ im obigen Beispiel) die Daten nicht schnell genug aus der Gerätedatei liest. Dadurch wird der Puffer im RAM des Hosts voll, was wiederum verhindert, dass der IP-Core aus dem FIFO liest (weil der IP-Core die Daten nirgendwo hinschreiben kann). Infolgedessen kommt es zu einem Überlauf (overflow). Das kann passieren, weil die Anwendungssoftware schlecht programmiert ist. Ein anderer möglicher Grund hängt mit dem Betriebssystem zusammen, worauf weiter unten näher eingegangen wird.
Die Größe des RAM-Puffers auf dem Host hängt vom Xillybus-IP-Core ab. Beispielsweise beträgt diese Größe 4 MB für xillybus_read_32 und xillybus_write_32 (bei dem IP-Core, der Teil des Demopakets ist). Mit der IP Core Factory lassen sich eigene IP-Cores erzeugen, die deutlich größere Puffer anfordern.
Zusammenfassend lässt sich sagen: Einen Überlauf zu verhindern, ist eine Frage der richtigen Wahl der Parameter für den IP-Core: Allen voran muss dieser IP-Core in der Lage sein, die Datenrate zu bewältigen. Zusätzlich sollte der RAM-Puffer des Hosts groß genug sein. Dadurch kann der Datenfluss auch dann weitergehen, während das Anwendungsprogramm gerade keine Daten aus der Gerätedatei liest.
Wenn das FIFO trotz alledem voll wird, liegt die Ursache meist in einem Fehler beim Systementwurf. Ein häufiger Grund für einen Überlauf ist die Überschätzung der Fähigkeit des Rechners, die Datenrate zu bewältigen.
Insbesondere wenn die Daten in eine Datei auf der Festplatte geschrieben werden (wie mit dem „cat“-Befehl oben), kann die maximale Datenrate geringer sein, als man denkt. Der Grund dafür ist, dass das Betriebssystem oft einen großen Festplattencache besitzt (möglicherweise viele Gigabyte). Wenn die Datenrate der Festplatte mit einer Datenmenge gemessen wird, die kleiner ist als der Festplattencache, sind die Ergebnisse zu optimistisch: Das Betriebssystem tut so, als sei das Schreiben der Daten auf die Festplatte bereits abgeschlossen, obwohl dies in Wirklichkeit noch nicht geschehen ist. In Wahrheit landen die Daten nur im Cache; das eigentliche Schreiben auf die Festplatte geschieht später. Dieser Irrtum zeigt sich erst, wenn eine größere Datenmenge verarbeitet wird.
Entzug der CPU
Leider gibt es eine unvermeidbare Möglichkeit für einen Überlauf (overflow): Das Betriebssystem (Linux oder Windows) darf jedem Prozess im Benutzermodus die CPU für eine unbegrenzte Zeit entziehen. Mit anderen Worten: Das Computerprogramm, das die Daten liest, kann plötzlich für eine gewisse Zeit aufhören zu arbeiten und danach den normalen Betrieb wieder aufnehmen. Für diese Zeitspanne gibt es keine Begrenzung. Jedes Nicht-Echtzeit-Betriebssystem darf Prozesse auf diese Weise willkürlich pausieren.
Dennoch ist Datenerfassung mit diesen Betriebssystemen möglich. Das liegt vor allem daran, dass ein langer CPU-Entzug allgemein als schlechte Eigenschaft gilt. Diese Pausen sind also normalerweise kurz.
Während dieser Pausen füllt der IP-Core weiterhin den RAM-Puffer auf dem Host (per DMA, sodass kein Eingriff des Prozessors erforderlich ist). Wenn das Computerprogramm die CPU zurückbekommt, kann es alle angesammelten Daten schnell konsumieren. Ein RAM-Puffer, der eine Pause von 10 ms ausgleicht, reicht in der Regel aus. Es ist jedoch möglich, bei der Erstellung eines eigenen IP-Cores in der IP Core Factory einen deutlich größeren Puffer anzufordern.
Allerdings besteht weiterhin die Möglichkeit, dass die Pause zu lang ist. Dadurch wird der RAM-Puffer voll, und in der Folge wird auch das FIFO auf dem FPGA voll. Das Ergebnis dieses Überlaufs ist, dass Daten verloren gehen. Das sollte nie passieren, und es wird wahrscheinlich nie passieren. Aber was, wenn es doch passiert?
Erkennen eines Überlaufs
Der vorgeschlagene Lösungsansatz besteht darin, den Datenstrom zu beenden, wenn das FIFO voll wird: Die Logik sendet ein EOF (End-of-File) an den Host, unmittelbar nach dem letzten Element der zusammenhängenden Daten. Betrachten wir also, was passiert, wenn der Host die Daten mit einem „cat“-Befehl konsumiert, wie oben vorgeschlagen:
$ cat /dev/xillybus_read_32 > capture-file.dat
Normalerweise läuft dieser Befehl weiter, bis er mit Strg-C gestoppt wird. Wenn jedoch das FIFO im FPGA voll geworden ist, endet dieser Befehl normal, so wie er nach dem Kopieren einer regulären Datei enden würde. Die Ausgabedatei enthält dann alle Daten, die gesammelt wurden, bevor das FIFO voll wurde.
Fassen wir diese Methode zusammen: Alle Daten, die in capture-file.dat geschrieben werden, sind garantiert fehlerfrei und zusammenhängend. Wenn das Datenerfassungssystem die Kontinuität wegen eines CPU-Entzugs nicht aufrechterhalten kann, ist das Ergebnis eine kürzere Ausgabedatei. Auf den Inhalt der Datei kann man sich jedoch verlassen.
Um diese Lösung umzusetzen, ersetzen Sie die Instanziierung von dualclock_fifo_32 durch Folgendes:
eof_fifo fifo_32
(
.rd_clk(bus_clk),
.rst(!user_r_read_32_open),
.rd_en(user_r_read_32_rden),
.dout(user_r_read_32_data),
.empty(user_r_read_32_empty),
.wr_clk(capture_clk),
.wr_en(capture_en),
.din(capture_data),
.full(),
.eof(user_r_read_32_eof)
);
Die Definition von eof_fifo finden Sie auf einer separaten Seite.
Beachten Sie, dass @user_r_read_32_eof mit dem @eof-Port dieses FIFO verbunden ist. Auf diese Weise sendet die Logik das EOF an den Host, wenn es nötig ist. Beachten Sie außerdem, dass am @full-Port dieses FIFO nichts angeschlossen ist: Es besteht keine Notwendigkeit, dieses Signal weiterhin zu überwachen. Wenn das FIFO voll wird, lässt sich nicht mehr viel tun. Der EOF-Mechanismus sorgt dafür, dass der Host den Datenfluss neu startet, nachdem alle gültigen Daten konsumiert wurden.
Datenwiedergabe (Playback)
Wie steht es um die umgekehrte Richtung? Wie wäre es mit so etwas?
$ cat playback-data.dat > /dev/xillybus_write_32
Das funktioniert nach demselben Prinzip: Der Befehl „cat“ liest aus einer Datei auf der Festplatte und schreibt die Daten in eine Gerätedatei. Im FPGA schreibt der IP-Core diese Daten in ein FIFO. Die Anwendungslogik liest die Daten aus dem FIFO. Gleiche Idee, nur in umgekehrter Richtung.
Dies ist ein vereinfachtes Blockdiagramm, das den Datenfluss vom Anwendungsprogramm auf dem Host zur Anwendungslogik veranschaulicht.
Ähnlich wie bei der Datenerfassung besteht keine Gefahr eines Datenverlusts: Der IP-Core schreibt nicht in das FIFO, wenn es voll (full) ist. Infolgedessen kann auch der Puffer im RAM des Hosts voll werden. Wenn das passiert, wartet das Anwendungsprogramm auf dem Host (indem es schläft), bis die Anwendungslogik genügend Daten aus dem FIFO gelesen hat.
Eine weitere Ähnlichkeit mit der Datenerfassung besteht darin, dass das FIFO niemals leer (empty) wird, solange das Anwendungsprogramm weiterhin schnell genug Daten schreibt. Um das zu gewährleisten, gelten dieselben Überlegungen: Die Spezifikation des IP-Cores sowie das Anwendungsprogramm müssen die erforderliche Datenrate unterstützen.
Wenn diese Bedingungen erfüllt sind, kann die Anwendungslogik bei Bedarf Daten aus dem FIFO konsumieren. Ein Unterlauf (underflow) sollte niemals auftreten.
Asynchrone Streams vs. synchrone Streams
Dieses Thema hängt nicht direkt damit zusammen, verdient aber eine kurze Erörterung.
Bei einer Datenerfassungsanwendung besteht das Hauptziel darin, einen kontinuierlichen Datenfluss aufrechtzuerhalten. Dementsprechend bewegt der IP-Core die Daten so schnell wie möglich vom FIFO in den RAM-Puffer des Hosts. Es spielt keine Rolle, ob das Anwendungsprogramm auf dem Host die Daten gerade anfordert (durch einen Funktionsaufruf wie read() oder Ähnliches): Der Datenfluss läuft weiter, solange die Gerätedatei geöffnet ist und sich Daten im FIFO befinden.
Das bedeutet, dass der Host keine Möglichkeit hat, den Datenfluss vom FPGA zu steuern (außer die Gerätedatei zu öffnen und zu schließen oder auf eine anwendungsspezifische Lösung zurückzugreifen). In den meisten realen Datenerfassungsanwendungen besteht jedoch keine Notwendigkeit, den Datenfluss zu steuern: Es ist in Ordnung, dass der Datenfluss durch das Öffnen der Gerätedatei beginnt. Es ist nicht wichtig, wann genau jedes Datenelement aus dem FIFO gelesen wurde.
Eine Gerätedatei, die sich so verhält, wird in der Terminologie von Xillybus als asynchroner Stream (asynchronous stream) bezeichnet.
In anderen Anwendungen ist jedoch wichtig, wann die Daten erfasst wurden. Zum Beispiel kann die Anwendungslogik im FPGA den Inhalt eines Statusregisters senden, statt Daten aus einem FIFO zu lesen. Das wird im Demopaket mit der Gerätedatei xillybus_mem_8 demonstriert. In diesem Fall ist es sehr wichtig zu steuern, wann die Daten im FPGA erfasst werden: Der Host liest aus der Gerätedatei, um den Status zu diesem Zeitpunkt zu erhalten, und nicht, wie der Status zu einem unbekannten Zeitpunkt in der Vergangenheit war.
Für derartige Anwendungen bietet Xillybus synchrone Streams (synchronous streams): Der IP-Core sammelt vom FPGA immer so wenig Daten wie möglich. Mit anderen Worten: Der IP-Core sammelt Daten nur als Reaktion auf einen Funktionsaufruf wie read() (oder Ähnliches) auf dem Host. Dadurch steuert der Host, wann die Daten vom FPGA geholt werden.
Der Nachteil synchroner Streams sind die Pausen im Datenfluss. Das Hauptproblem dieser Pausen besteht darin, dass das FIFO im FPGA voll werden kann, wenn der Datenfluss vorübergehend angehalten wird. Diese Pausen verringern außerdem die Effizienz des Datenflusses, sodass die maximale Datenrate geringer wird. Diese beiden Nachteile sind jedoch nur für eine Datenerfassungsanwendung von Bedeutung. Eine solche Anwendung sollte ohnehin einen asynchronen Stream verwenden.
Auch bei Gerätedateien in der umgekehrten Richtung gibt es einen Unterschied zwischen asynchronen und synchronen Streams. In dieser Richtung liegt der Unterschied in der Rückkehr des Funktionsaufrufs write(): Bei asynchronen Streams kehrt write() zurück, sobald die Daten in den RAM-Puffer geschrieben wurden. In den meisten Fällen schläft write() also überhaupt nicht. Bei synchronen Streams dagegen wartet write(), bis die Daten am FPGA angeliefert wurden. Das ist wichtig, wenn der Kommunikationskanal zum Senden von Befehlen verwendet wird. Für eine Datenerfassungsanwendung ist das jedoch ebenfalls schlecht.
Im Demopaket ist nur /dev/xillybus_mem_8 ein synchroner Stream. Die anderen vier Gerätedateien sind asynchrone Streams.
In der IP Core Factory hängt die Wahl zwischen synchronem und asynchronem Stream von der Auswahl der Anwendung ab (dem Dropdown-Menü für „Use“). Wenn Sie zum Beispiel „Data acquisition / playback“ wählen, erzeugt das Werkzeug einen asynchronen Stream. Wenn Sie „Command and status“ wählen, erhalten Sie einen synchronen Stream. Sie können das auch manuell auswählen, indem Sie die Option „Autoset internals“ ausschalten.
Weitere Informationen über asynchrone Streams und synchrone Streams finden Sie in Abschnitt 2 des Programmierhandbuchs für Linux (bzw. des Programmierhandbuchs für Windows). Was die IP Core Factory betrifft, lesen Sie den Leitfaden zum Definieren eines eigenen Xillybus-IP-Cores.
Zusammenfassung
Mit Xillybus lässt sich ein einfaches und dennoch praktisch funktionsfähiges Datenerfassungssystem schnell und unkompliziert aufbauen: Die Anwendungssoftware reduziert sich auf die Verwendung eines Standard-Linux-Befehls („cat“). Auf der FPGA-Seite besteht die Interaktion mit dem IP-Core von Xillybus lediglich darin, die Daten in ein FIFO zu schreiben.
Die mit Xillybus erfassten Daten sind garantiert fehlerfrei und zusammenhängend. Aufgrund der Natur des Betriebssystems gibt es jedoch keine Möglichkeit zu garantieren, dass niemals ein Überlauf (overflow) auftritt. Da das unvermeidbar ist, ist der beste Ansatz, die Erkennung eines Überlaufs zu garantieren, falls er doch einmal auftritt. Xillybus bietet dafür einen einfachen Mechanismus, indem ein EOF an den Host gesendet wird.

