Forum: Mikrocontroller und Digitale Elektronik PHY am LPC2368 mit uIP / lwIP


von ich (Gast)


Lesenswert?

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.

von Tobias P. (hubertus)


Lesenswert?

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...

von Simon K. (simon) Benutzerseite


Lesenswert?

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 ;)

von ich (Gast)


Lesenswert?

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?

von Simon K. (simon) Benutzerseite


Lesenswert?

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.

von ich (Gast)


Lesenswert?

@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.

von ich (Gast)


Lesenswert?

@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?

von Simon K. (simon) Benutzerseite


Lesenswert?

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).

von Simon K. (simon) Benutzerseite


Lesenswert?

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 ;)).

von ich (Gast)


Lesenswert?

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?

von Simon K. (simon) Benutzerseite


Lesenswert?

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.

von ich (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Simon K. (simon) Benutzerseite


Lesenswert?

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.

von ich (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.