Hi, Nachdem ich mein Board [1] soweit am laufen habe, möchte ich als nächsten Schritt Ethernet nutzen. Hat schon mal jemand mit diesem Board einen TCP/IP Stack, ohne Betriebssystem also bare metal, zum laufen gebracht? Ich brauch eigentlich nur via UDP Pakete empfangen und senden, soll ich da eher den uIP oder lwIP TCP/IP Stack näher ins Auge fassen? Es gibt Beispielcode von Olimex selbst [2] und von ST [3] zum downloaden, muss mir das aber erst genauer anschauen. [1] https://www.olimex.com/Products/ARM/ST/STM32-E407 [2] https://www.olimex.com/Products/ARM/ST/STM32-E407/resources/STM32-E_revB1_demo.zip [3] http://www.st.com/web/en/catalog/tools/FM147/CL1794/SC961/SS1743/PF257906 lG, Max
Ich hab jetzt den uIP Stack erfolgreich implementiert, senden und empfangen von UDP Telegrammen funktioniert also schon mal. Weiss jemand ob man ICMP Ping replies selbst generieren muss oder sollte das uIP selbst machen? Hab diesbezüglich auch nichts in der uip-conf.h gefunden. lG, Max
Markus Manninger schrieb: > Weiss jemand ob man ICMP Ping replies selbst generieren muss oder sollte > das uIP selbst machen? Es gibt kein ICMP Ping. Die entsprechende Netzwerknachricht heißt ICMP ECHO bzw. die Antwort darauf ICMP ECHO REPLY. Beides existiert auch in uIP. ECHO (REPLY) ist übrigens der einzige ICMP-basierte Dienst in uIP. Andere ICMP-Nachrichten werden nicht unterstützt. Das Anwendungsprogramm, mit dem man ICMP ECHO-Anfragen versenden und ICMP ECHO REPLY empfangen kann, heißt auf den meisten Plattformen "ping".
:
Bearbeitet durch User
Jawohl! Die Frage ist nur wie ich den Stack dazu bringe das ICMP ECHO REPLY Telegramm zu verschicken?
Naja, das senden funktioniert doch noch nicht so zuverlässig ... die Telegramme werden sporadisch verschickt. Was muss man ausser "uip_send(ptr, len)" noch machen, damit die Daten via UDP raus gehen? Ich frag mich eigentlich wo man die Destination (Host & Port) angeben muss, mit:
1 | uip_ipaddr(ipaddr, 192, 168, 0, 1); |
2 | uip_setdraddr(ipaddr); |
3 | |
4 | udp_conn = uip_udp_new(&ipaddr, HTONS(5555)); |
5 | |
6 | if (udp_conn != NULL) { |
7 | uip_udp_bind(udp_conn, HTONS(5555)); |
8 | uip_udp_periodic_conn(udp_conn); |
9 | }
|
wartet man ja nur auf eingehende Telegramme von dem Host. Danke, Max
Kann mir jemand weiterhelfen ... bekomms einfach nicht hin einfach ein paar Zeichen via UDP zu verschicken. Ich hab den uIP Stack noch nicht ganz durchblickt ... uip_send() alleine reicht nicht, aber was muss ich noch machen damit das komplette UDP Paket via Ethernet verschickt wird? Muss ich das in der UIP_APPCALL machen? Danke, Max
Ausgehend von diesem [1] code, hab ich folgendes gemacht. Nachdem das Ethernet Interface initialisiert wurde:
1 | clock_init(2); |
2 | |
3 | timer_set(&periodic_timer, CLOCK_SECOND / 2); |
4 | timer_set(&arp_timer, CLOCK_SECOND * 10); |
5 | |
6 | tapdev_init(); |
7 | uip_init(); |
8 | |
9 | uip_ipaddr(ipaddr, 192, 168, 0, 2); |
10 | uip_sethostaddr(ipaddr); |
11 | |
12 | uip_ipaddr(ipaddr, 255, 255, 255, 0); |
13 | uip_setnetmask(ipaddr); |
14 | |
15 | uip_ipaddr(ipaddr, 192, 168, 0, 1); |
16 | uip_setdraddr(ipaddr); |
17 | |
18 | udp_conn = uip_udp_new(&ipaddr, HTONS(5555)); |
19 | |
20 | if (udp_conn != NULL) { |
21 | uip_udp_bind(udp_conn, HTONS(5555)); |
22 | uip_udp_periodic_conn(udp_conn); |
23 | }
|
Will ich jetzt ein Telegramm verschicken, mach ich folgendes:
1 | uip_ipaddr(ipaddr, 192, 168, 0, 1); |
2 | |
3 | char data[] = "Test\r\n"; |
4 | uint8_t len = strlen(data); |
5 | |
6 | uip_ipaddr_copy(&udp_conn->ripaddr, ipaddr); |
7 | |
8 | uip_send(data,len); |
9 | uip_process(UIP_UDP_SEND_CONN); |
10 | tapdev_send( uip_appdata, len); |
Doch leider bekomm ich immer leere Pakete ... niemand eine Idee? sitz schon den ganzen Tag davor, ohne Erfolg. [1] https://github.com/contiki-os/contiki/blob/master/core/net/uip-udp-packet.c lG, Max
Keiner eine Ahnung was das Problem sein könnte? Wenn ich Daten via UDP versenden will, muss ich, denke ich zumindest, folgende zwei uIP-Stackfunktionen aufrufen:
1 | uip_send(data,len); |
2 | uip_process(UIP_UDP_SEND_CONN); |
Doch wo sind die Daten, inkl. TCP/IP Header, die ich dann übers interface rausschicken muss? Mach ich danach ein tapdev_send(uip_appdata,uip_len), fehlt mir der Header und ich sehe im wireshark ein ungültiges Paket das direkt mit "Test", also dem UDP content, beginnt. Gibts denn wirklich niemanden hier der ein bisserl mit uIP Stack zu tun hatte?
:
Bearbeitet durch User
Markus Manninger schrieb: > Gibts denn wirklich niemanden hier der ein bisserl mit uIP Stack zu tun > hatte? ich leider nicht...kann dir also nicht direkt helfen aber falls du nicht weiterkommst und von uIP auf lwIP wechseln willst, da gibts von STM fertige Beispiele dafür hier sind welche von mir für einen UDP-Server : http://mikrocontroller.bplaced.net/wordpress/?page_id=1756 und einen HTTP-Server : http://mikrocontroller.bplaced.net/wordpress/?page_id=1529 vlt kommst du damit schneller klar UB
Ah, danke. Bin eh schon mehrmals über deine Seite gestolpert ... finde sie sehr gut mit vielen praktischen Beispielen. Hab mir auch schon einiges davon abgeschaut! Ich wollte eigentlich beim uIP bleiben, da ich nur UDP Telegramme empfangen und senden muss, und das ganz ohne Zeitstress und da sollte der kleinere uIP schon genügen ... wenn ich aber überhaupt net weiterkomm werd ich mir wohl den lwIP anschaun. Aber ich kann mir nicht vorstellen dass da bei mir noch so viel fehlt. Ich denke ich greife beim verschicken einfach nur auf einen falschen Buffer zu, oder so. Und ich weiss nicht ob ich von jeder Stelle in meinem Source aus was verschicken kann oder ob ich das immer in der APPCALL machen kann. Laut den Beispielen im Netz [1] schauts irgendwie so aus:
1 | uip_len = ethernet_devicedrver_poll(); |
2 | if(uip_len > 0) { |
3 | if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { |
4 | uip_arp_ipin(); |
5 | uip_input(); |
6 | if(uip_len > 0) { |
7 | uip_arp_out(); |
8 | ethernet_devicedriver_send(); |
9 | }
|
10 | } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { |
11 | uip_arp_arpin(); |
12 | if(uip_len > 0) { |
13 | ethernet_devicedriver_send(); |
14 | }
|
15 | }
|
[1] http://www-users.cs.york.ac.uk/~pcc/MCP/examples/html/group__uipdevfunc.html
Eine Alternative ist eventuelle der UDP-Stack den es bei freertos.org gibt. Hat damit schon jemand gearbeitet?
Naja, ich will/brauch eigentlich kein Betriebssystem. Bin grad dabei den lwip in mein projekt einzubauen und steh jetzt beim linken noch vor einer "undefined reference". Ich brauch ein Implementierung der Funktion sys_now(), die vom lwip 1.4.1 benötigt wird. Leider steht irgendswo, was die funktion lieferen soll, aber ich schätze mal die aktuelle Zeit ... aber in welchem Format? Hat vielleicht jemand diese Funktion auf einem STM32F407 umgesetzt? Danke, Max
bei mir ist im File "opt.h" der Define dazu auf "0"
1 | #define LWIP_TCP_TIMESTAMPS 0 |
damit wird "sys_now()" nicht eingebunden Gruss Uwe
Ich hab jetzt den SysTick_Handler() dafür verwendet und die Funktion sys_now() liefert dann die ms seit startup.
So, wieder mal ein paar Fragen. Ich bin jetzt dabei vom uIP auf den lwIP TCP/IP Stack umzustellen. Für lwIP findet man ja auch Beispielcode von ST selbst [1]. Da ich aber einen anderen Ethernet PHY (ks8721bl) hab, muss ich Änderungen am Source vornehmen. Ich denke mal dass davon die Dateien ethernetif.c (im Verzeichnis STM32F4x7_ETH_LwIP_V1.1.0/Utilities/Third_Party/lwip-1.4.1/port/STM32F4x 7/Standalone) und stm32f4x7_eth_bsp.c (im Verzeichnis STM32F4x7_ETH_LwIP_V1.1.0/Project/Standalone/udp_echo_server/src/) betroffen sind. Ich gehe mal davon aus dass die Anschlüsse an den STM32F407 die selben sind, bin sie nur kurz überflogen und da schauts gut aus ... eh klar, der Ethernetcontroller befindet sich ja am Chip ... oder kanns da drotzdem Unterschiede geben? Leider finde ich keine lwIP Beispiel für diesen PHY im Netz. [1] http://www.st.com/web/en/catalog/tools/PF257906 [2] https://www.olimex.com/Products/ARM/ST/STM32-E407/resources/STM32-E_revB1_demo.zip
Hi, eigentlich sind die einzigen Änderungen in stm32f4x7_eth_bsp.c. Hier musst du ggf den GPIO-Pin, über den er PHY seinen Interrupt anzeigt, anpassen ( das passiert in Eth_Link_EXTIConfig ), dann die Anpassungen an die "vendor specific" Register des PHY vornehmen, damit der über Interrupt LinkUp und LinkDown anzeigen kann ( das erfolgt in Eth_Link_PHYITConfig ). Die entsprechenden Register findest du im Datenblatt deines PHY. Der originale code in ...bsp.c ist ja für den DP83848 geschrieben. Ich hab mir das Datenblatt für den und für meinen PHY nebeneinandergelegt und dann stur nach Schema f den entsprechenden Code geändert. Dann musst du noch die EXTI-Interrupt-Routine so anpassen, daß du LinkUp und LinkDown erkennst und aus der Interrupt-Routine entweder netif_set_link_down(&gnetif) oder netif_set_link_up(&gnetif) aufrufen. Entsprechender Code findet sich als "Eth_Link_ITHandler" in ...bsp.c, aber nicht in Form eines IRQ-Handlers. Dann habe ich noch in irgendeinem Olimex-Beispielcode dieses Fragment zur dynamischen Ermittlung der Adresse des PHY gefunden, den hab ich auch eingebaut.
1 | static int ETH_Find_Phy_Address(uint16_t *addr) |
2 | {
|
3 | unsigned int PhyAddr; |
4 | union { |
5 | uint32_t HI_LO; |
6 | struct
|
7 | {
|
8 | uint16_t LO; |
9 | uint16_t HI; |
10 | };
|
11 | } PHYID; |
12 | for(*addr = 0; 32 > *addr; (*addr)++) |
13 | {
|
14 | // datasheet for the SMSC LAN8710A
|
15 | // page 54/55 --> PHY Identifier 1 and 2
|
16 | PHYID.HI = ETH_ReadPHYRegister(*addr,2); // 0x0007 |
17 | PHYID.LO = ETH_ReadPHYRegister(*addr,3) & 0xFFF0; // 0xC0F0 , 4 LSB vary with silicon revision |
18 | if (0x0007C0F0 == PHYID.HI_LO) |
19 | break; |
20 | }
|
21 | |
22 | if(32 < *addr) printf_("Ethernet Phy Not Found\n\r"); |
23 | |
24 | |
25 | return (32 >= *addr); |
26 | }
|
Drei Abende Jugend forscht, aber jetzt rennt's fehlerfrei. Wenn du möchtest, kann ich dir meine stm32f4x7_eth_bsp.c zur Verfügung stellen, die ist jedoch angepasst für einen LAN8710A Gruss, Heinz
Danke für die Antwort aber ich habs mittlerweile auch schon hinbekommen! lG, Max
katastrophenheinz schrieb: > ... kann ich dir meine stm32f4x7_eth_bsp.c zur Verfügung stellen, > die ist jedoch angepasst für einen LAN8710A Darf ich von diesem Angebot gebrauch machen? Dank im voraus.
Mehmet Kendi schrieb: > katastrophenheinz schrieb: >> ... kann ich dir meine stm32f4x7_eth_bsp.c zur Verfügung stellen, >> die ist jedoch angepasst für einen LAN8710A > > Darf ich von diesem Angebot gebrauch machen? > Dank im voraus. Brauchst du meine Datei noch oder bist du mit der von Markus rundum sorglos? Gruss , Rainer
Sorry für die verspaetete Antwort. Erstmal herzlichen Dank an Markus! Schönes Weihnachtsgeschenk :) @Rainer: ich schau' mir die Arbeit von Markus heute Abend mal an. Sollte es irgendwo harzen, werde ich auf Dein Angebot zurückkommen. Mann bin ich froh, dass ich das Ganze nicht auf den LAN8710A anpassen muss \o\ \o/
:
Bearbeitet durch User
Du, Markus, ich hab' jetzt mal die Dateien etwas beschnuppert. Da sehe ich aber was von KS8721, nichts aber von LAN8710A. Sind diese PHYs identisch in ihrer Ansteuerung?
Mehmet Kendi schrieb: > Sind diese PHYs identisch in ihrer Ansteuerung? Schneller Blick in die beiden Datenblätter zeigt: Nein. Sehen zwar ziemlich ähnlich aus, aber unterscheiden sich in kleinen, aber entscheidenden Details, z.B. Interrupt Control/Status Register Gruss, Rainer
Hmm, das war ja der User katastrophenheinz, der mit LAN8710A arbeitet. Als ich die Files sah, kam mir gar nicht in den Sinn, den Absender zu kontrollieren. Naja, dann werde ich nolens volens die Karbidlampe aufsetzen und in den Stollen herabsteigen müssen. Trozden herzlichen Dank für die Hilfsbereitschaft.
Wie oben bereits gesagt: Du kannst von mir die angepasste Version für einen LAN8710A haben. Allerdings habe ich das nun schon für die Tasking Library von Rowley Crossworks erweitert. Den Teil müsstest du dann wieder rauswerfen. Gruss, Rainer
Ich dachte, auch Du haettest das Ganze auf den E407 mit dem KS8721 PHY angepasst. Waere natürlich sehr nett von Dir, wenn Du mir Deine Arbeit zur Verfügung stellen würdest. (Karbidlampe wieder ausgeblasen) :)
Ok. Hier isses - aus dem laufenden Projekt rauskopiert. D.h. du wirst auf jeden Fall anpassen müssen. Gruss, Rainer
Rainer, kannst Du mir bitte auch die stm32f4x7_eth_conf.h Datei zukommen lassen. Zumindest nehme ich an, dass du die PHY Register dort definiert hast. Es geht um die Register PHY_MIFR, PHY_MCSR, ... PHY_MISR_LINK_INT_EN usw. Dank im voraus.
Na klar, sorry. Die C-Datei habe ich auch noch dazu gepackt, weil die bei mir auch ein neueres Änderungsdatum aufweist, ich seh' aber auf den ersten Blick keine Änderungen von mir. Viel Erfolg, Rainer
Danke! Hatte schon damit angefangen beide Datenblaetter vergleichend die entsprechenden defines zu erstellen. Bua! Hast mir schon 'ne heiden Last abgenommen!
;-) Das mit den Register-Mapping geht noch relativ fix. Krude wird es erst, wenn du feststellst, daß der LAN...-PHY keinen Interrupt bei LinkUp auslösen kann. Dafür habe ich das "Autonegotiate Complete" als Interruptursache missbraucht, wie du vllt schon gesehen hast. Kann man bestimmt auch besser lösen, aber tut auch so. Gruss, Rainer
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.