lwIP UDP Pakete senden

OP #5247795
Lesenswert?

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(&ETH_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);

}
#5247829
Lesenswert?

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
OP #5247914
Lesenswert?

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(&ETH_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);

}
#5248071
Lesenswert?

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
(Firma: keine) #5248128
Lesenswert?

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.
OP #5248601
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren