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.
Wo kann ich sehen wie genau struct tcp_pcb deklariert ist, um meine empfangenen Daten auslesen zu können? Die müssten ja dort abgespeichert sein oder?
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.
ok danke... das mit dem pbuf hab ich mitlerweile auch gefunden aber da meine c Kenntnisse nicht die besten sind... wie kann ich da drauf zu greifen?
1 | unsigned char x; |
2 | x = p->payload |
funktioniert nicht? Das struct sieht ja volgendermaßen aus:
1 | struct pbuf { |
2 | void *payload; |
3 | ...
|
4 | ...
|
5 | }
|
müsste da mein pointer p nicht auf das erste Byte zeigen und in x speichern? Wie gesagt c ist bei mir schon ne weile her...
*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 | unsigned int count=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:
1 | err_t tcp_write(struct tcp_pcb * pcb, void * dataptr, u16_t len, |
2 | u8_t apiflags) |
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
Schau dir mal auf http://magazin.c-plusplus.de/artikel/Sockets%20und%20das%20HTTP-Protokoll die Funktion SendAll unter Punkt 5.2 an. Das sollte hier auch möglich sein.
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
ML ist nur ein Namenszusatz und wird in der Regel für Boards mit Virtex Chip benutzt. Das Xapp1026 ist grundsätzlich für alle Xilinx Boards brauchbar.
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.