Ich habe einen LPC2368 mit einem Micrel PHY KSZ8721BLI und würde das gerne mit uIP betreiben. Ich habe hier noch ein paar Verständnissprobleme bezüglich der Kommunikation untereinander. Also, es gibt den Netzwerkstecker, den stecke ich ein, dann ist der PHY mit Netzwerk verbunden. Zuvor habe ich den PHY initialisiert. Jetzt ist mir nicht ganz klar was passiert, bzw. passieren soll. Im PHY ISR Register sehe ich, dass ein Datenpaket angekommen ist, aber der LPC registriert das irgendwie nicht und die Daten werden auch nicht über das RMII Interface übertragen. Wie sage ich dem Netzwerk dass mein Controller die IP Adresse 192.168.1.10 haben soll, bzw wenn ich vom PC aus dort hin ein Datenpaket schicke, dass mein PHY es empfängt und meiner CPU überträgt? Kann mir bitte jemad die Augen öffnen wie das gehen soll? Das geht doch sicher in wenigen Sätzen, ohne dass ich gleich die Paketstruktur von TCP/IP & Co kennen muss. Ich bin neuling auf dem Ethernet gebiet und es ist auch möglich dass in meinen Quellen noch ein Fehler drin ist. Ich habe die emac.c vom Code Bundle aus www.standardics.nxp.com geladen.
Dein MAC (im LPC2368) hat ne MAC Adresse (ich bin mir nich sicher, ob da schon fest eine vorgegeben ist oder ob du die selber einprogrammieren musst). Um dann eine Zuordnung von MAC- zu IP-Adressen vorzunehmen, muss du das ARP (Address Resolution Protocol) implementieren, siehe Wikipedia. Wenn z.B. dein PC an die IP 192.168.1.1 ein Paket senden will, dann generiert er erst mal ein ARP-Paket, das er an den Router versendet. Der Router löst dann die IP auf und gibt deinem PC die MAC-Adresse zurück. Dein PC generiert erst dann das eigentliche Datenpaket, wo er dann die MAC-Adresse reinpackt, die der Router ihm verraten hat. Damit kannst du aber noch nicht so viel anfangen; Damit du wirklich mit deinem Controller kommunizieren kannst musst du noch ICMP (ping) implementieren (z.B.) oder TCP/IP oder UDP. Sonst lässt sich nicht viel sinnvolles damit anfangen...
ich wrote: > Das geht doch sicher in wenigen Sätzen, ohne dass ich gleich die > Paketstruktur von TCP/IP & Co kennen muss. Ganz ehrlich? Nein geht es nicht. Nicht mit uIP/lwIP. Auf einem PC mit genügend Abstraktion zwischen den Netzwerksachen und der tatsächlichen Programmierung geht es vielleicht noch. Aber hier hast du keine Chance. Lies dir ein paar Grundlagen zu TCP/IP, Ethernet und ARP an, versuche zu verstehen wie die Kommunikation von statten gehen und welche Protokolle für genau welchen Zweck zuständig sind. Alles andere kann sehr schnell in Frust und Frickelei ausarten ;)
Also, muss mein LPC2368 erst mal ein Paket generieren, das dem Switch sagt: Hallo, ich habe Macadresse x.x.x.x.x.x und die IP x.x.x.x Und das als ARP Paket verpackt? Also dem Switch mitteilen dass an diesem Port mein LPC hängt?
ich wrote: > Also, muss mein LPC2368 erst mal ein Paket generieren, das dem Switch > sagt: > > Hallo, ich habe Macadresse x.x.x.x.x.x und die IP x.x.x.x > > Und das als ARP Paket verpackt? > Also dem Switch mitteilen dass an diesem Port mein LPC hängt? Nein, das macht uIP/lwIP.
@Simon: Also aus dem FreeRTOS Demo, da ist es ganz einfach: uIP_Init() uIP_SetAddr(...) httpd_init() EMAC_Init() Und dann in einer Schleife die Daten abholen und schicken. Das Senden und Empfangen mit der HW ist in der emac.c drin. Das sieht doch enorm einfach aus? Natürlich muss mann sich erst richtig einarbeiten, wenn man jedes Bytes eines TCP/IP Stackst und den anderen wissen möchte, mich interessiert aber nur das Ergebnis. Ähnlich wie bei USB, die ganze Header bits macht halt hier die Hardware, so dachte ich mir, das macht bei TCP/IP uIP.
@Simon, die Texte überschneiden sich... Dann fehlt mir der Teil, wo dieser automatismus von uIP auch auf den EMAC/LPC überträgt? Also Irgend eine Routine wird noch von uIP aufgerufen, die ich noch nicht programmiert habe?
ich wrote: > @Simon, die Texte überschneiden sich... > > Dann fehlt mir der Teil, wo dieser automatismus von uIP auch auf den > EMAC/LPC überträgt? Also Irgend eine Routine wird noch von uIP > aufgerufen, die ich noch nicht programmiert habe? Beim uIP/lwIP sind auch Beispiele, sowie Dokumentationen dabei. Du musst dich nur um das Empfangen und das Senden der Pakete kümmern. Diese liegen dabei immer in einem globalen Puffer (im Falle von uIP).
ich wrote: > @Simon: > Also aus dem FreeRTOS Demo, da ist es ganz einfach: > uIP_Init() > uIP_SetAddr(...) > httpd_init() > > EMAC_Init() > > Und dann in einer Schleife die Daten abholen und schicken. > Das Senden und Empfangen mit der HW ist in der emac.c drin. > > Das sieht doch enorm einfach aus? Okay, ich kenne mich mit den Mikroprozessoren von NXP nicht aus. Scheint als gäbe es da schon vorhandenen Quellcode. > Natürlich muss mann sich erst richtig einarbeiten, wenn man jedes Bytes > eines TCP/IP Stackst und den anderen wissen möchte, mich interessiert > aber nur das Ergebnis. Ähnlich wie bei USB, die ganze Header bits macht > halt hier die Hardware, so dachte ich mir, das macht bei TCP/IP uIP. Ja, die Headersachen macht prinzipiell jemand anders für dich (uIP). Aber wenn du auch selber Applikationen für den Stack schreiben möchtest (und nicht nur den mitgelieferten HTTP-Dienst benutzen willst, fängt die Sache schon gut an ;)).
Bei uIP müsste er doch alle Nase lang die Funktion "UIP_APPCALL()" aufrufen, oder nicht? bzw. wenn uip_periodic() aufgerugen wird, dann sollte auch eine uip_len mit einer Zahl zurück kommen, die die Anzahl der zu sendenden Bytes zurück gibt?
ich wrote: > Bei uIP müsste er doch alle Nase lang die Funktion "UIP_APPCALL()" > aufrufen, oder nicht? Nein, diese Funktion darf nur der Stack aufrufen. > bzw. wenn uip_periodic() aufgerugen wird, dann sollte auch eine uip_len > mit einer Zahl zurück kommen, die die Anzahl der zu sendenden Bytes > zurück gibt? Je nachdem, ob neue Daten gesendet werden müssen oder nicht.
Ich habe mich falsch ausgedrücht, sorry:
> Nein, diese Funktion darf nur der Stack aufrufen.
Ich meinte, der Stack müsste diese funktion alle Nase lang aufrufen...
Also mal ganz von vorne...
- Die Initialisierung:
1 | EMACInit(); |
2 | EMAC_RxEnable(); |
3 | EMAC_TxEnable(); |
4 | uip_init(); // Initialisierung |
5 | uip_setethaddr(xAddr); // MAC-Adresse |
6 | uip_sethostaddr(ipaddr); // 192.168.1.10 |
7 | uip_arp_init(); |
8 | uip_listen(HTONS(80)); |
- Die Endlosschleife:
1 | uip_len = EMACReceive( (void *)uip_buf ); |
2 | if(uip_len > 0) |
3 | {
|
4 | uip_input(); |
5 | uip_arp_ipin(); |
6 | if(uip_len > 0) |
7 | {
|
8 | uip_arp_out(); |
9 | EMACSend((void*)uip_buf, uip_len); |
10 | }
|
11 | } else { |
12 | // Zyklischer Aufruf
|
13 | if (TimerPuls1Sekunde) |
14 | {
|
15 | for( i = 0; i < UIP_CONNS; i++ ) |
16 | {
|
17 | uip_periodic( i ); |
18 | if( uip_len > 0 ) |
19 | {
|
20 | uip_arp_out(); |
21 | EMACSend((void*)uip_buf, uip_len); |
22 | }
|
23 | }
|
24 | }
|
25 | }
|
Hier fehlt doch noch was, also ich meine die Initialisierung müsste doch ein Paket generieren, das ich schicken müsste? Das ganze ist wie ein Puzzle... Im Anhang ist meine uIP_Task.c wo alles nochmal genauer drin steht, hier nur der Auszug (kurzform). Der Task wird bei mir bei jedem Main-Loop aufgerufen.
ich wrote: > Ich habe mich falsch ausgedrücht, sorry: >> Nein, diese Funktion darf nur der Stack aufrufen. > Ich meinte, der Stack müsste diese funktion alle Nase lang aufrufen... Der Stack ruft die Funktion auch periodisch auf, das ist richtig. > Hier fehlt doch noch was, also ich meine die Initialisierung müsste doch > ein Paket generieren, das ich schicken müsste? > Das ganze ist wie ein Puzzle... Nein die Initialisierung muss kein Paket generieren. Wenn du den kleinen einmal ans Netz hängst, wird erst mal niemand wissen, dass er da ist. Sobald jemand eine ARP-Anfrage (mit der Ziel-IP des Mikrocontrollers) ins Netz stellt, muss dieser aber antworten. > Im Anhang ist meine uIP_Task.c wo alles nochmal genauer drin steht, hier > nur der Auszug (kurzform). Der Task wird bei mir bei jedem Main-Loop > aufgerufen. So wie es in dem Sourcecode ist, wird deine Applikation ständig aufgerufen, das ist richtig. Du hast nämlich die Zeitbasis im Moment nicht im Code eingebaut. Normalerweise reicht es wenn uip_periodic (und somit die Applikation für jede Verbindung) alle 100ms aufgerufen wird.
uip_periodic() wird jede Sekunde aufgerufen, ich habe hier eine Ausgabe auf den COM Port, das ist es so. In meinem Quellcode heist es im Original "tPuls1s", diese Variable wird durch den Timer-Task für genau einen Main-Loop Zyklus jede Sekunde gesetzt. Wenn ich Sie richtig verstanden habe, passiert erstmal gar nichts. Erst wenn ich z.B. über meinen IE auf 192.168.1.10 los gehe, dann sucht der Explorer nach der Broad-Cast Methode (Port 80) ob da jemand antwortet (dabei blinkt auch die grüne LED an meinem LPC2368-Board, angesteuert vom PHY). Und dann müsste das Paket doch irgendwie in mein LPC2368 gelangen, ich habe auf der LCD Anzeige das Interrupt-Register des PHYs angezeigt, es kommt aber nichts. Wie sollte es denn sein?
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.