Mit dieser Library kann man mit dem STM32F4-Discovery-Board und einem extern angeschlossenen PHY (von Texas Instruments “DP83848C”) und einer RJ45-Buchse einen UDP-Server erstellen.
Für nähere Infos von wegen Ethernet, bitte bei der HTTP-Server-Lib nachlesen.
Der Server kann Strings per UDP versenden und empfangen. Zum Test habe ich ein kostenloses PC-Terminal Programm aus dem Internet benutzt, das auch UDP kann.
(Man kann auch das von mir geschriebene PC-Programm benutzen)
Die HOST Adresse muss im H-File eingestellt werden. Wahrscheinlich können auch mehrere CPUs verbunden werden…das habe ich aber nicht getestet.
Das Flag zum erkennen ob ein UDP-String empfangen wurde, habe ich in die
“UB_UDP_Server_Do-Funktion” reingepackt, die muss eh zyklisch aufgerufen werden.
Das Beispiel-Programm sendet nach dem Initialisieren einen Test-String per UDP und beantwortet ab dann alle ankommende Strings mit einem Echo.
Beispielbild :
Benutzte Pins :
1 2 3 4 5 6 7 | PA1 = RMII_Ref_Clk PC1 = ETH_MDC PA2 = ETH_MDIO PC4 = RMII_RXD0 PA7 = RMII_CRS_DV PC5 = RMII_RXD1 PB11 = RMII_TX_EN PB12 = RMII_TXD0 PB13 = RMII_TXD1 PB14 = RMII_INT |
Voraussetzungen :
1 2 | Benutzte Module der CooCox-IDE : GPIO, SYSCFG, EXTI, MISC Benutzte Librarys : keine |
Enumerationen :
1 2 3 4 5 | typedef enum { UDP_INIT_OK =0, // kein Fehler beim Init UDP_INIT_ETH_MACDMA_ERR, // Fehler beim init vom MAC UDP_INIT_ETH_PHYINT_ERR // Fehler beim init vom PHY }UDP_INIT_STATUS_t; |
:
1 2 3 4 5 6 7 8 | typedef enum { UDP_CONNECT_OK =0, // Verbindung ist ok UDP_INIT_ERR, // Server noch nicht initialisiert UDP_RUNNING, // Server läuft schon UDP_NO_LINK, // keine Verbindung zum LAN UDP_ERR1, // Error Nr. 1 UDP_ERR2 // Error Nr. 2 }UDP_SERVER_CONNECT_t; |
:
1 2 3 4 5 | typedef enum { UDP_SERVER_OFFLINE =0, // UDP-Server ist offline UDP_REVEICE_EMPTY, // UDP RX-Puffer ist leer UDP_RECEIVE_READY // UDP RX-Puffer ist voll }UDP_RECEIVE_t; |
Funktionen :
1 2 3 4 5 | UDP_INIT_STATUS_t UB_UDP_Server_Init(void); // zum init vom UDP-Server UDP_SERVER_CONNECT_t UB_UDP_Server_Connect(void); // Connect vom Server void UB_UDP_Server_Disconnect(void); // Disconnect vom Server ErrorStatus UB_UDP_Server_SendString(char *ptr); // zum senden von Strings per UDP UDP_RECEIVE_t UB_UDP_Server_Do(char *ptr); // muss zyklisch aufgerufen werden |
Beispiel :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | //-------------------------------------------------------------- // File : main.c // Datum : 31.05.2013 // Version : 1.0 // Autor : UB // EMail : mc-4u(@)t-online.de // Web : www.mikrocontroller-4u.de // CPU : STM32F4 // IDE : CooCox CoIDE 1.7.0 // Module : CMSIS_BOOT, M4_CMSIS_CORE // Funktion : Demo der UPD-Server-Library // Hinweis : Diese zwei Files muessen auf 8MHz stehen // "cmsis_boot/stm32f4xx.h" // "cmsis_boot/system_stm32f4xx.c" //-------------------------------------------------------------- #include "main.h" #include "stm32_ub_udp_server.h" #include "stm32_ub_led.h" int main(void) { UDP_INIT_STATUS_t init_check; UDP_RECEIVE_t rec_check; char rx_buf[UDP_RX_BUFFER_SIZE]; SystemInit(); // Quarz Einstellungen aktivieren // LEDs initialisieren UB_Led_Init(); // UDP-Server initialisieren init_check=UB_UDP_Server_Init(); if(init_check==UDP_INIT_OK) { // wenn initialisierung ok UB_Led_On(LED_GREEN); // Server starten if(UB_UDP_Server_Connect()==UDP_CONNECT_OK) { // wenn der Server läuft // einmal einen Text per UDP senden UB_UDP_Server_SendString("UDP Server ok"); } } else { // bei einem Fehler UB_Led_On(LED_RED); } while(1) { // UDP-Server zyklisch aufrufen // und check ob Daten empfangen wurden rec_check=UB_UDP_Server_Do(rx_buf); if(rec_check==UDP_SERVER_OFFLINE) { // UDP-Server ist Offline UB_Led_Off(LED_BLUE); } else { // UDP-Server ist Online UB_Led_On(LED_BLUE); if(rec_check==UDP_RECEIVE_READY) { // wenn Daten per UDP empfangen wurde UB_Led_Toggle(LED_ORANGE); // als Echo zurücksenden UB_UDP_Server_SendString(rx_buf); } } } } |
Hier die Library zum Download :
Hier der komplette CooCox-Projektordner zum Download :
Hier der Link zu dem PC-Programm :
Hallo Uwe,
es wäre eine coole Sache wenn du UDP mit deinem Show02 Projekt verbinden würdest.
Dann ließe sich per USB oder UDP steuern.
Jörg
Ja, da sehe ich kein Problem. Ich setz das mal auf die Liste.
Hi Uwe,
ich habe dieses Projekt mit der CoIDE kompiliert und mit dem externen Board (TI DP83848C) laufen lassen. Angeschlossen wurde das ganze an eine Fritzbox. Als Gegenstelle habe ich ein selbst geschriebens C# Programm verwendet, dass in Verbindung mit anderen Endgeräten problemlos UDP-Nachrichten versendet und empfängt. Bei dem Discoveryboard kamen jedoch zusätzlich verwirrende Zeichen nach der eigentlichen Nachricht mit zurück. Lag dieser Fehler bei dir auch vor?
Ich habe versucht den LwIP-Stack auf die neuste Version 1.4.1 in deinem Projekt zu aktualisieren. Das hat leider nicht ganz wie geplant funktioniert. Könntest du versuchen dies umzusetzen?
ST hat ja die Standard Peripheral Library durch den STM32F4xx_HAL_Driver in Verbindung mit der Software STM32Cube ersetzt. Portierst du deine Projekte auf die neue Library?
Danke & Gruß,
Thomas
Ersetzt wurde Gott sei Dank nicht, es gibt auch die Std Lib in neuer Version. 1.31. Das ist aber nur für die neuen CPUs relevant.
Ob sich Cube wirklich durchsetzt bleibt abzuwarten. Der Aufwand umzustellen ist doch erheblich. Ein Tool was automatisch auf HAL portiert wäre da hilfreich.
Echt nicht? Ich dachte ich hätte dies im “Getting Started” zum Cube so gelesen. Wo hast du die Version 1.31 gefunden? Der folgende Link http://www.st.com/web/en/catalog/tools/PF257901 macht eher den Eindruck, als ob ST die Standard Library auslaufen lässt.
Na mal gut das ich es erst vor ein paar Tagen herunter geladen hatte.
Ich finde die auch nicht mehr…
Ich such nun schon seit längerem, aber kann mir jemand sagen wo direkt in der udp_sendto_if() die Nachricht weggeschickt wird? Irgendwie kann ich dem Weg der Nutzdaten nicht mehr folgen.
Ich würde gerne ein fest definierten Datensatz schicken. Kann ich da einfach die Bytes im String verändern, oder kriegt man die Nachrichten noch kürzer ohne Stringdeklaration?
Ich habe derzeit auch das Probelm, dass wenn ich einen eigenen String verschicke, als Callback, die zugeschickte Nachricht (rx_buf) noch hinten ran gehängt wird.
char testar[4]={48,49,57,57};
UB_UDP_Server_SendString(rx_buf);
UB_UDP_Server_SendString(testar); <– mien zusätzlicher String
Ich hoffe es war nicht zu unverständlich erklärt.
MfG
Jo
dein Array ist KEIN String…ein String endet mit 0×00
Ah ok. Dann bekomme ich anscheinen schonmal die Nutzdaten gechickt. Allerdings wird mir in meinem UDP Program (SocketTest) das immer als String angezeigt. Aber das liegt wohl an der Autovervollständigung!?
Hast du auch einen Idee warum rx_buf immer angehängt wird?
Was noch interessant wäre, wenn so einen String:
UB_UDP_Server_SendString(“beispiel”);
sende, dann hängt er mir nichts an!
mein Kommentar sollte eigentlich ein Wink mit dem Zaunpfahl sein…ist aber anscheindend nicht angekommen. Also nochmal zum mitschreiben
1. Die Funktion “Server_SendString” erwartet als Übergabeparameter einen String
2. Du übergibst ein Array das kein String ist
3. Die Software sucht im Array nach einer Stringendekennung und sendet solange zeichen aus dem Speicher bis sie eine findet -> BUG !!!
4. Lösung : EINEN STRING ÜBERGEBEN
probier mal das hier
char testar[5]={48,49,57,57,0};
Das hatte ich dann auch ausprobiert. Klappt natürlich. Der Rest Nutzdaten wird dann ja mir 00 gefüllt. So lange bis die Minimallänge erreicht ist!? Oder gibt es eine Möglichkeit das zu kürzen.
Das sollte dann auch erst einmal genug der Fragerei sein.
Und… danke für die schnellen Antworten!
die minimal Länge vom Ethernet-Frame sind 64 Bytes. Vermutlich wird ein zu kurzes UDP-Data-Field verlängert, bis die 64 Bytes erreicht sind.
Wenn ich das noch richtig in Erinnerung habe sind das minimal 18 Bytes Nutzdaten bei UDP. Da wirst du nichts dran ändern können.
18 Byte waren richtig, glaub ich.
Das Problem bei mir ist derzeit, das ich auch 0-Werte schicken muss… Ich finds einfach nicht wo in dem Array nach der 0 geschaut wird. Das wird ja wohl mit einer Schleife gemacht, die ich fest definieren würde um immer die gleiche Framelänge zu verschicken. In meinem Fall dann 18 Byte oder so.
Und dann hoffentlich Ende der Fragerei…
probier mal das hier :
ErrorStatus UB_UDP_Server_SendArray(char *ptr, uint16_t len)
{
ErrorStatus ret_wert=ERROR;
struct pbuf *p;
if(len==0) return(ERROR);
// nur senden, wenn Server laeuft
if(UDP_SERVER.status==UDP_SERVER_RUNNING) {
// Puffer einrichten
p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_POOL);
if (p == NULL) return(ERROR);
// Array kopieren
pbuf_take(p, (char*)ptr, len);
// Daten per UDP an HOST senden
udp_sendto(upcb_server,p,&HostIPaddr,HOST_UDP_PORT);
// Puffer wieder loeschen
pbuf_free(p);
ret_wert=SUCCESS;
}
return(ret_wert);
}
ungetestet !!
hi
i used your code.stm32f4 receiving data & when i check rx_buf the data is correct.but don’t sending any thing to pc
the UB_UDP_Server_SendString(rx_buf) ;
command not work?
why?
after starting the board the string “UDP Server ok” musst be send to the client.
red led must be OFF, blue and green led must be ON.
please verify that the orange led toggles every time you send a string to the cpu.
what program do you use on the pc side ?
my board is stm32f407 DISCOVERY & a Base Board for it
i use hercules setup utility(
mudule ip:192.168.10
port:65100
local port:65100
)
-after starting the board i don’t recieve the string “UDP Server ok”
-blue and green led in my board is on & red led is OFF
-when i send a frame from pc to arm the orange led toggles every time & recieved frame in rx_buf is correct.
-but it don’t sending or returning any frame to pc by the command UB_UDP_Server_SendString(rx_buf) ;
why my udp is only send fram from pc to arm and pc cann’t recieve anythings
Modul IP is “192.168.0.10″ !!!
i have testet the file again and it works. Can you PING “192.168.0.10″ ?
Try this :
1. Power-On the Discovery-Board (green and blue LED)
2. Start the Hercules-Utility
3. Switch to “UDP”
4. IP = “192.168.0.10″ , Port=”65100″ , Local=”65100″
5. Press Button “Listen”
6. Press the Reset-Button on the Discovery-Board
7. After 5 Sek the String “UDP Server ok” must be received
8. Send a String (or single chars) and a echo must be received
hi
after starting the board.blue and green led is on & red led is OFF
[IMG]http://i59.tinypic.com/1zwj32v.jpg[/IMG]
when i ping the 192.160.0.10 this message is show
[IMG]http://i57.tinypic.com/33jgww1.jpg[/IMG]
when i Start the Hercules-Utility and Press Button “Listen” & after it i Press the Reset-Button on the my Discovery-Board.but i don’t receive the string “UDP Server ok”
[IMG]http://i62.tinypic.com/mwtwck.jpg[/IMG]
when i send “13″ charecter.the received frame in rx_buf is correct & orange led toggle
[IMG]http://i61.tinypic.com/15mbjpf.jpg[/IMG]
[IMG]http://i58.tinypic.com/k54bcl.jpg[/IMG]
but echo don’t receive?
[IMG]http://i60.tinypic.com/bijvia.jpg[/IMG]
ok…funny error :
how is your LAN connection to the board realised ? Directly with a ethernet cable to the PC or is a switch/router involved ? Can you deactivate the firewall (or check if port 65100 is not blocked). I have no idea what kind of problem this is. And a last test : please download my UDP-Server from here “http://mikrocontroller.bplaced.net/wordpress/?page_id=1179#P05″ and try this on your pc.
Hi,
Did you solved the problem you had ? If yes can you share how you did it. I have the same problem. My Devkit407 is not communicating with the PC although the blue and green lights are ON. When i press reset button the orange light does not toggles.
hi
i need your udp-sever code in keil version for stm32f429(2M flash).COOCOX IDE not support stm32f429(2M flash).
so, feel free to port it to keil. And have a look at the remark from “miros”
(from 7. März 2014) he posted a link for the 2MB support under CoIDE.
http://mikrocontroller.bplaced.net/wordpress/?page_id=2708#comment-1445
hi
i used two stm32f407 board’s as udp server that connected to one client
pc(as client)(ethernet hub switch)|server-1(stm32f407 as udp server)
ip=192.168.0.3,port=1200)
|server-2(stm32f407 as udp server)
ip=192.168.0.4,port=2302)
when i connect them to a ethernet hub switch .server-1 & server-2 not work correct but when i connect them to router with gateway address (192.168.0.1 ).two servers work Properly
pc(as client)( router “192.168.0.1″)|server-1(stm32f407 as udp server)
ip=192.168.0.3,port=1200)
|server-2(stm32f407 as udp server)
ip=192.168.0.4,port=2302)
do need ethernet communication between 2 STMf407 devices need to router modem?
sorry, i dont know
Hallo Uwe,
zunächst einmal vielen Dank für deine umfangreichen Libraries insbesondere mit LwIP. Ist eine geniale Sache so ein Demoprogramm. Ich arbeite gerade mit deinem Demo und alles funktioniert wie gewünscht. Einzig dauert es bei mir sehr lange (> 1 Minute) bis der UDP Server nach einem Reprogramming wieder erreichbar ist. (ICMP ergo Ping). Hast du eine Idee wo ich den Fehler suchen könnte?
stell mal eine feste IP ein und schalte DHCP ab.
Hallo Uwe,
perfekt das war es – tausend Dank !
Gruß Michael
Hi,
gibt es denn eine Möglichkeit die IP Adresse des Moduls zur Laufzeit auf dem STM32 zu ermitteln?
Dankeschön, Michael
es gibt mit sicherheit eine Struktur in der die IP drinsteht. Aber die kenne ich jetzt nicht auswendig. Such mal in der Doku vom LwIp.
Hi,
I checked you implementation of UDP server on STM32F407 + STM32F4-BB where (LAN 8720A chip is used). The server setup runs (green and blue LEDs are ON) but I can’t reach any communication on RX, TX. I tried to ping 192.168.0.10 and no response for this IP. Could you advice me what to do or check?
I am sure that port 65100 is not blocked by firewall. The boart is connected directly to PC without any router or switch. I use Coocox IDE for compilation.
Did you test your code with STM32F4-BaseBoard, too?
for your PHY (LAN8720) you must use another files. you can find C+H Files in this HTTP-Project : http://mikrocontroller.bplaced.net/wordpress/?page_id=2434
Hi,
Thank you for advice, I used the adeqaute files and it works correctly.
So big thank you for your support and your source codes, it helped and saved me lot of “days”
Hi,
I have the same problem. What do you mean by adequate files which you copied ?
what PHY do you use ?
if “LAN8720″ then download “Show_04_Webserver” and use
LAN8720 Files from “stm_lolevel” directory.
and add the define “F4D”
Hi admin_ub,
I am unable to make communication between the device and my pc. Below are the details of my settings.
Module IP:192.168.0.10
Module mask:255.255.255.0
Gateway:0.0.0.0 (because my device is directly connected to my pc through an extra lan card)
Ports(65100 for both)
Host Ip(PC):192.168.0.15, mask as above and no gateway selected.
I hope the above settings are correct.
Hi admin_ub,
I did not understand which files do i need to copy from “Show_04_Webserver”.
Do you mean to copy all the files like
“LAN8720_stm32f4x7_eth.c”
“LAN8720_stm32f4x7_eth_bsp.c”
“stm32f4x7_eth.c”
“stm32f4x7_eth.h”
“stm32f4x7_eth_bsp.h”
“stm32f4x7_eth_bsp.h”
In the above files i changed the
#include “stm32_ub_http_server.h” to
#include “stm32_ub_udp_server.h” for the Project 44.
Thanks and waiting for reply.
replace:
stm32f4x7_eth_bsp.c
stm32f4x7_eth.c
with
LAN8720_stm32f4x7_eth_bsp.c
LAN8720_stm32f4x7_eth.c
replace also stm32f4x7_eth_conf.h.
edit the lines that says “stm32_ub_http_server.h” and replace with stm32_ub_udp_server.h
replace the last function of “stm32_ub_udp_server.h
” with:
#ifdef F4D
#else
//————————————————————–
// ISR von Ext-Interrupt (PB14)
//————————————————————–
void EXTI15_10_IRQHandler(void)
{
// check welcher Ext-Interrupt (10 bis 15) aufgetreten ist
if(EXTI_GetITStatus(ETH_LINK_EXTI_LINE) != RESET)
{
// wenn es der Interrupt vom LINK-Status war
// Interrupt Handler starten
Eth_Link_ITHandler(DP83848_PHY_ADDRESS);
// ISR-Flag löschen
EXTI_ClearITPendingBit(ETH_LINK_EXTI_LINE);
}
}
#endif