Hallo,
ich würde gerne eine Verbindung mit einem FPGA und einem PC über
Ethernet herstellen. Hierzu hab ich mir die app1024 von Xilinx
angeschaut und das referenz Design auf meinem Board implementiert
(ML505).
Ich sehe nun im Terminalprogramm die beschriebene Ausgabe, kann aber
keine Verbindung zum Board aufbauen. Wenn ich im command window
ipconfig/all eingebe wird mir folgendes angezeigt:
IP-Adresse: 168.254.72.76
Subnetzmaske: 255.255.0.0
Standardgatway: nix
-> ist es richtig das das Board hier nicht auftaucht???
Dementsprechent hab ich in der main.c folgendes eingetragen:
IP4_ADDR(&ipaddr, 168, 254, 72, 77);
IP4_ADDR(&netmask, 255, 255, 0, 0);
IP4_ADDR(&gw, 168, 254, 72, 1);
Die MAC Adresse hab ich unverändert gelassen. Ist dies korrekt, oder
müsste der MAC nicht eine bestimmte MAC adresse haben. Wenn ja wie komm
ich an diese?
Wenn ich nun über CMD window versuche den Echo Server zu testen kommt
folgender fehler.
telnet 168.254.72.77 1024
Verbindungsaufbau zu 168.254.72.77...Es konnte keine Verbindung mit dem
Host her
gestellt werden, auf Port 1024: Verbinden fehlgeschlagen
Hat eventuell noch jemand eine Idee, was ich falsch mache?
Danke
matzunami
matzunami schrieb:> Hierzu hab ich mir die app1024 von Xilinx> angeschaut und das referenz Design auf meinem Board implementiert
Nur fürs Protokoll, du wirst wohl die xapp1026 meinen.
matzunami schrieb:> ipconfig/all eingebe wird mir folgendes angezeigt:> IP-Adresse: 168.254.72.76> Subnetzmaske: 255.255.0.0> Standardgatway: nix
Du hast deinem PC wohl keine IP zugewiesen, denn das scheint eine
Standardadresse zu sein, die Windows setzt, wenn die Netzwerkkarte noch
nicht konfiguriert und auch kein DHCP Server im Netz gefunden wurde.
Änder die IP lieber auf z.B. 192.168.0.xxx, damit du auf der sicheren
Seite bist. Gib deinem Board eine entsprechende IP aus dem selben Netz.
matzunami schrieb:> -> ist es richtig das das Board hier nicht auftaucht???
Mit dem Kommando "ipconfig \all" wird nur die Konfiguration der
Netzwerkinterfaces angezeigt, die in deinem PC sind und nicht, davon,
was noch so alles im Netz rumschwirrt.
matzunami schrieb:> Dementsprechent hab ich in der main.c folgendes eingetragen:> IP4_ADDR(&ipaddr, 168, 254, 72, 77);> IP4_ADDR(&netmask, 255, 255, 0, 0);> IP4_ADDR(&gw, 168, 254, 72, 1);
Wie gesagt, beweg dich lieber im 192.168.0.xxx'er Netz mit der passenden
Netzmask 255.255.255.0.
matzunami schrieb:> Die MAC Adresse hab ich unverändert gelassen. Ist dies korrekt, oder> müsste der MAC nicht eine bestimmte MAC adresse haben. Wenn ja wie komm> ich an diese?
In der nähe der RJ45'er Netzwerkbuchsen müsste ein Aufkleber sein, auf
dem die MAC Adresse drauf steht. Die solltest du natürlich auch
benutzen.
matzunami schrieb:> telnet 168.254.72.77 1024> Verbindungsaufbau zu 168.254.72.77...Es konnte keine Verbindung mit dem> Host her> gestellt werden, auf Port 1024: Verbinden fehlgeschlagen>> Hat eventuell noch jemand eine Idee, was ich falsch mache?
Vermutlich ists eine Folge der oben genannten Dinge. Zudem ist die
Frage, obs auch der richtige Port ist? Sollte der so in der
Dokumentation und vorallem auch im Code stehen, dann ists natürlich
richtig.
Danke für die Antwort. Ich hab mit wireshark mein Datentransfer mal
beobachtet und bemerkt, dass ich bei der IP Adresse einen Fehler gemacht
habe. Diese ist nicht 168.254.72.76 sondern 169.254.72.76 und dies muss
auch beim Standardgateway eingetragen werden.
Es funktioniert jetzt alles :)
Gruß
matzunammi
Hallo,
nach dem ich den kompletten Programmaufbau durchgeschaut hab, muss ich
feststellen das es doch etwas komplizierter ist als ich gehofft habe.
Mein Ziel ist es Daten aus dem Speicher auszulesen und über UDP oder TCP
an einen Rechner zu schicken. Ich habe gehofft das ich an hand des
Echo_Server Beispiels funktionen finde die mir die Übertragung über TCP
ermöglichen (sowas wie TCP_Send oder so). Das Programm schickt ja auch
die empfangenen Daten zurück, ich habe da allerdings noch nicht ganz den
durchblick, wo dies genau geschieht.
Eventuell kann mir da vielleicht noch jemand unter die Arme greifen und
mir etwas behilflich sein. Wäre sehr dankbar.
Gruß
matzunami
Mir ging/geht es da nicht anders als dir, weswegen ich weg von der RAW
hin zur Socket API gegangen bin, weil die doch deutlich intuitiver ist.
Bezogen auf die Durchsatzrate ist sie natürlich schwächer als die RAW
API (Meine Beispielkonfiguration bei Fast Ethernet: 66Mbit/s mit der
RAW, 26 Mbit/s mit der Socket API) aber wenn du nur reine
Controllinginformationen verschicken willst und nicht irgendwelche
megagroßen Datenblöcke, dann wäre es eine Überlegung wert, die API zu
wechseln.
Ich hab mit dem Xilinx Kernel noch keine Erfahrungen gemacht und soll
die Schnittstelle auch in ein bestehendes Projekt integrieren, was
ebenfals ohne den Kernel läuft. Dementsprechent weiß ich nicht wie
sinvoll es ist auf die Socket Variante umzusteigen, die diesen ja
benötigt??? Existiert nicht irgend ein Dokument, wie die "Xilinx Device
Drivers Documentation", in der ich alle mir zur Verfügung stehenden
Funktionen mit einer kurzen Beschreibung finde? Oder ein besser
erläutertes Beispiel?
Ok, wenn das ganze komplett ohne Xilkernel laufen soll, dann wirst du an
der RAW API nicht vorbei kommen. Eine kleine Übersicht, über die zur
Verfügung stehenden Funktionen findest du in der "rawapi.txt", die du,
zumindest in der EDK 10.1 im Verzeichnis
\EDK\sw\ThirdParty\sw_services\lwip130_v1_00_a\src\lwip-1.3.0\doc
findest. Ansonsten kannst du auch nochmal schaun, ob dir das hier hilft
http://lwip.wikia.com/wiki/Raw/TCP
ok ich nehm mal an das ich sicher noch ein paar Fragen dies bezüglich
hab, aber ich werd mir das noch mal alles anschaun und mal sehn, ob ich
was zu stande bekomme, schon mal vielen Dank für die Hilfe
Wäre es für deine Anwendungen ausreichend komplett auf den TCP Krempel
zu verzichten und einfach RAW kommunikation zu machen?
Ich habe hier TEMAC mit LocalLink über SGMII am laufen und baue mir die
Pakete manuell zusammen sowohl auf Software als auch auf Hardwareseite,
das funktioniert ganz gut
Sollte das mit der RAW API doch all zu nervig und zeitintensiv werden,
dann ist es vielleicht doch eine Überlegung wert mit dem Xilkernel. Den
bindest du über eine #include- Anweisung und einen Funktionsaufruf in
deinen bestehenden Code ein und kannst sonst arbeiten, wie in einer
standalone Anwendung. Wie gesagt, ich würde ihn mir zur Not einfach mal
anschaun und wenn du eh schon das EDK hast, dann kannst du den auch
problem- und kostenlos nutzen. Aber das ist natürlich alles
projektspezifisch, ob man das will/braucht/nutzen kann.
ja Danke ich will noch nicht aufgeben, aber wenn ichs absolut nicht
hinbekomme dann schau ich mir das auch auf jeden Fall an...
Wenn ich etwas empfange wird ja eine Callback Fkt. aufgerufen
(recv_callback), in der ein struct übergeben wird -> struct tcp_pcb
*tpcb. In diesem müssten doch meine empfangenen Daten stehen, die ich
doch in den Speicher schreiben kann oder was auch immer... seh ich das
richtig?
Kuck dir das Telnet Echo Server Example im SDK an. Da wird eine TCP
Verbindung auf den Port 7 (Telnet Echo Port) gebunden. Und in der
Callback Funktion err_t recv_callback(void *arg, struct tcp_pcb *tpcb,
struct pbuf *p, err_t err)
wird auf die Daten (payload) so zugegriffen: p->payload und p->len. Das
Paket ist meiner Meinung nach also im pbuf p. tcp_pcb ist nur die
Session?
>ich würde die TCP funktionalität schon gerne nutzen>und verstehen :)
Also. TCP bedeutet eine gesicherte Verbindung. Dh man kann ein Paket
senden, viel groesser wie die Blockgroesse, dabei koennen die
Teilpackete auf verschiedenen Wegen transportiert werden und das
Protokoll setzt die Bloecke wieder zusammen, alles is CRC geschuetzt,
mit Retries, Acknowledge und so. Dh die Daten die ankommen stimmen.
Alternativ kann man UDP verwenden. Da fallen die Retries weg. Die
Verbindung ist nicht gesichert. Der CRC ist zwar da, wird gerechnet,
aber die Neuanforderung muss man selbst machen. Dadurch ist UDP viel
schneller.
Eine Datenuebertragung macht man in TCP, eine Musikuebertragung mit UDP.
*p ist ein Pointer vom Typ void. Damit ist das ein Typenloser Pointer
der nun in diesem Fall auf den Anfang der Nutzdaten zeigt. Wieviele Byte
Nutzdaten da gekommen sind steht in p->len.
Ich vergleiche die angekommenen Daten z.b. Byte für Byte auf ein
MagicWord. Wurde das Zauberwort erhalten, beendet sich der Server:
1
unsignedintcount=0;
2
for(i=0;i<(p->len);i++)// compare each byte
3
{
4
if(pcompare_data[i]==((char*)(p->payload))[i])
5
{
6
count++;// do_something();
7
}
8
...
Hier siehst du wie in der if Abfrage der void Pointer implizit
Typkonvertiert wird um ihn mit einem Chararray vergleichen zu können.
Wie groß das Chararray sein muss? Gute Frage, selber implementieren. Ich
nehme an es gibt nicht etwas wie "msg = malloc(size);". Wenn du
voraussagen kannst dass p->len nie größer als xy Bytes ist, dann kannst
dir ja entsprechend einen char buffer[xy]; im voraus erstellen.
Mahlzeit
So ich habs fast alles am laufen. Aber eine Frage hät ich noch. Wenn ich
größere Datenmengen verschicken will (einige MB), muss ich mir diese
selbst zerteilen? Mit der funktion:
kann ich ja nur Daten mit der maximalen länge von der größe meines
TCP_SND_BUF verschiecken. Muss ich somit bei einer größeren Datenmänge
diese Funktion mehrmals aufrufen???
Gruß matzunami
Meine Fkt. tcp_write gibt mir aber nicht die Zahl der gesendeten Bytes
zurück. Und wenn "len" größer wie der TCP_SND_BUF wird, wird garnix mehr
gesendet (ich nehm mal an dann gibt die Funktion ERR_MEM zurück).
Hallo ich bins noch mal... meine Ethernet Verbindung läuft "fast" wie
gewünscht. Ich habe noch ein Problem bei dem ich noch hoffentlich etwas
Hilfe bekomme. Und zwar:
Wenn ich mit dem Xilinx Beispielprogramm (aus xapp1024) ein iperf Test
laufen lasse, übertrage ich Daten mit einer Geschwindigkeit von über
100Mbits/sec (in beide Richtungen). Nach dem ich das Programm für meine
Zwecke leicht abgeändert habe übertrage ich meine 100kByte (meine
Nutzdaten) in 21 sekunden??? Warum dauert das so lange? Wenn ich mir mit
WireShark den Datentransfer anschaue, sehe ich, dass der PC ja jedes
Packet mit einem ACK bestädigt. Dieses Bestätigen dauert bei dem Xilinx
Beispielprogramm wenige µs (wenn es 100µs sind, sind es viel). Bei
meiner Applikation dauert es ganze 300ms bis ich mein ACK empfange.
Woher kommen diese unterschiede? Da ich mein nächstes Datenpaket (anders
wie beim Xilinx Programm) erst nach dem Empfang des ACK's los schicke
ist mir auch klar warum das alles so lange dauert, ich verstehe nur
nicht warum das ACK in meinem Fall so spät kommt???
wäre sehr dankbar, wenn einer eine Idee hätte woran es liegen könnte
Gruß
matzunami
ich habe festgestellt, dass wenn ich es so mache wie Xilinx und einfach
den Buffer mit meinen Daten voll stopfe, ich auf die gewünschte
Datenrate komme. Mir ist aber nicht klar warum die Übertragung dann so
wesentlich schneller ist? Zuerst hab ich auf das ACK gewartet, was mir
auch meldet wieviel Bytes erfolgreich ankamen hab um diese Zahl meine
Adresse erhöht und den nächsten Frame gesendet. Das scheint eine
schlechte vorgehensweise zu sein.
Hallo,
Ich bin recht neu in der fpga welt. habe ein einfaches sender/empfänger
system implementiert und würde gerne daten von dem empfänger fpga auf
den pc übertragen. ich habe allerdings ein virtex 4 board. in der
xapp1026 steht ausdrücklich für ML oder Sparten Boards. Gibts es
ähnliches Dokument oder Hilfe für Ethernet Übertragung zwischen PC und
Virtex 4 Boards?
Danke und Grüße,
Rone
matzunami schrieb:> Zuerst hab ich auf das ACK gewartet, was mir> auch meldet wieviel Bytes erfolgreich ankamen hab um diese Zahl meine> Adresse erhöht und den nächsten Frame gesendet
Das Tcp protokoll ist darauf ausgelegt, deinen Datenstrom in Pakete
aufzuteilen, die quasi Parallel unterwegs sind, je nach Netztopologie
können zwei Pakete einen völlig anderen Weg nehmen und damit sie am Ende
richtig zusammengesetzt werden, sind sie nummeriert. Die Pakete werden
quasi bündelweise verschickt und die ACKs kommen ebenso in Bündeln
zurück. Du musst theoretisch jedes Frame, was du schickst solange
aufheben, bis du weist, dass es sicher angekommen ist, gleichzeitig aber
auch schon neue losschicken, um den gewünschten Durchsatz zu kommen,
also brauchst du ne Menge Ram, damit du ein fehlerhaftes Frame evtl
nochmal senden kannst. Oder du scheisst einfach drauf, schliesslich
werden die Meisten Fehler per CRC korrigiert und sobald dein Paket mal
in einem Switch gelandet ist, ist es meistens auch sicher aufgehoben.