Hallo, alle miteinander. Ich versuche, kontinuierlich Daten von meinem XMC4500 Relax Kit via UDP an meinen PC zu senden. Der Sendevorgang findet in der Interrupt-Service-Routine eines Timers statt. Ich benutze Dave V4 und die ETH_lwIP App. Ich brauche eure Hilfe, weil der Übertragungsprozess nicht funktioniert. Mein Quellcode: #include <DAVE.h> //Declarations from DAVE Code Generation (includes SFR declaration) #define TRANSMIT_PORT_DESTINATION (45175) #define LOCAL_PORT_TRANSMIT (45174) int main(void) { DAVE_Init(); // Initialization of DAVE Apps //Start the lwIP stack ETH_LWIP_STATUS_t init_status; init_status = ETH_LWIP_Init(Ð_LWIP_0); while(1) { /*Function called below, checks for timeout of different protocol timers and executes relevant handler functions */ sys_check_timeouts(); } } void UserIRQHandler(void) { ip_addr_t ip_computer; IP4_ADDR(&ip_computer,192,168,0,40); struct udp_pcb *pcb_tr; pcb_tr = udp_new(); udp_bind(pcb_tr,IP4_ADDR_ANY,LOCAL_PORT_TRANSMIT); char msg1[]="testingUDPtransmit"; struct pbuf *ppp; ppp = pbuf_alloc(PBUF_TRANSPORT,sizeof(msg1),PBUF_RAM); memcpy (ppp->payload, msg1, sizeof(msg1)); udp_sendto(pcb_tr,ppp,&ip_computer,TRANSMIT_PORT_DESTINATION); pbuf_free(ppp); }
Hallo, was funktioniert denn nicht? Ein paar Punkte die mir auffallen ... 1.sollte man das nicht innerhalb einer ISR versenden 2.dein Socket solltest du am Ende schließen, oder besser noch in der Main nur 1 Mal anlegen und für alle Vorgänge nutzen 3.ein Bind brauchst du nur wenn du auch empfangen willst, und auch hier kannst du ein Bind auf einen Port nur 1x ausführen, ohne das Socket freizugeben wird jedes weitere Bind auf den selben Port zu einem Fehler führen Sascha
Vielen Dank schonmal für die Antwort. Ein paar deiner Vorschläge habe ich jetzt berücksichtigt und die UDP Pakete werden bei jedem Aufruf der ISR versendet. Welche Möglichkeit besteht denn, abgesehen von einer ISR, Daten im Sekundentakt per UDP zu versenden? Für weitere Anmerkungen und Verbesserungsvorschläge bin ich sehr dankbar, da ich zum ersten mal mit UDP arbeite. Mein aktueller, angepasster Quellcode: #include <DAVE.h> //Declarations from DAVE Code Generation (includes SFR declaration) #define TRANSMIT_PORT_DESTINATION (45175) struct udp_pcb *pcb_tr; char msg1[]="testingUDPtransmit"; struct pbuf *ppp; ip_addr_t ip_computer; int main(void) { DAVE_Init(); // Initialization of DAVE Apps //Start the lwIP stack ETH_LWIP_STATUS_t init_status; init_status = ETH_LWIP_Init(Ð_LWIP_0); pcb_tr = udp_new(); IP4_ADDR(&ip_computer,192,168,0,40); while(1) { /*Function called below, checks for timeout of different protocol timers and executes relevant handler functions */ sys_check_timeouts(); } } void UserIRQHandler(void) { ppp = pbuf_alloc(PBUF_TRANSPORT,sizeof(msg1),PBUF_RAM); memcpy (ppp->payload, msg1, sizeof(msg1)); udp_sendto(pcb_tr,ppp,&ip_computer,TRANSMIT_PORT_DESTINATION); pbuf_free(ppp); }
Wilhelm R. schrieb: > Vielen Dank schonmal für die Antwort. Ein paar deiner Vorschläge habe > ich jetzt berücksichtigt und die UDP Pakete werden bei jedem Aufruf der > ISR versendet. das sieht ja schon mal gut aus > Welche Möglichkeit besteht denn, abgesehen von einer ISR, > Daten im Sekundentakt per UDP zu versenden? in dem du in der ISR nur ein Flag setzt und dieses in der Main-loop abfragst. Es geht ja primär darum die Bearbeitungsdauer der ISR auf das notwendigste zu begrenzen. Auch wenn das vielleicht jetzt bei einem Aufruf pro Sekunde kein Problem zu sein scheint, so kann das je nach Architektur des Controllers in Verbindung mit anderen zeitkritischen ISRs zu Problemen führen. Beim AVR z.B. unterbrechen sich ISRs (wenn man es nicht erzwingt) nicht gegenseitig. Wenn nun die eine ISR ein Mal pro Sekunde10ms dauert eine zweite jedoch jede Millisekunde einen Zähler erhöhen soll "verliert" diese wenigstens 9 Aufrufe pro Sekunde. > Für weitere Anmerkungen und Verbesserungsvorschläge bin ich sehr > dankbar, da ich zum ersten mal mit UDP arbeite. Auch den Puffer brauchst du nur 1x mit der größt möglichen Länge der Nachricht anzulegen. Das hat aber alles nichts speziell mit dem versenden von UDP-Paketen zu tun. Sascha
Wilhelm R. schrieb: > Welche Möglichkeit besteht denn, abgesehen von einer ISR, > Daten im Sekundentakt per UDP zu versenden? Arbeitest Du mit einem RTOS? Die übliche Vorgehensweise dort ist, eine Sendetask suspendiert zu halten und periodisch aufzuwecken (Stichtwort Signal oder Event, oft durch Semaphoren realisiert). Der Timer ISR setzt das Signal, womit das RTOS die Task aufweckt. Eine andere sehr typische (ähnliche, aber nicht identische) Implementationsweise ist über eine Message Pump - dort würden nicht nur Signale des Timer ISR, sondern auch andere events abgearbeitet werden. Man kann Netzwerksoftware ohne RTOS benutzen (lwip ist sogar explizit dafür vorgesehen), aber typischerweise macht ein System mehr als nur über das Netzwerk zu kommunizieren. In solchen Fällen macht ein RTOS sehr schnell Sinn. Wie schon vorher gesagt ist das Aufrufen von Netzwerkfunktionen im ISR in aller Regel ein absolutes No-no - u.A. deshalb, weil Funktionen wie udp_sendto in der Regel so realisiert sind, dass sie in verschiedenen Szenarien den Aufrufer suspendieren können, und das ist in ISRs nicht möglich, Punkt.
Ruediger A. schrieb: > Arbeitest Du mit einem RTOS? Die übliche Vorgehensweise dort ist, eine > Sendetask suspendiert zu halten und periodisch aufzuwecken (Stichtwort > Signal oder Event, oft durch Semaphoren realisiert). Der Timer ISR setzt > das Signal, womit das RTOS die Task aufweckt. > Ich arbeitet nicht mit einem RTOS. Die Aufgabe meines Mikrocontrollers soll darin bestehen Messwerte mit Hilfe einer FFT zu analysieren und die berechneten Werte anschließend per UDP an MATLAB (R2016b) zu senden. MATLAB ist vorerst nur zur grafischen Auswertung dieser Daten zuständig.
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.