Forum: Mikrocontroller und Digitale Elektronik LwIP TCP: pbuf definieren und/oder leeren?


von Daniel F. (lmdaniel999)


Lesenswert?

Hi,

ich habe ein Problem (scheinbar mit dem Buffer?) einer LwIP TCP 
Verbindung.

Dazu hatte ich schonmal einen anderen Thread gemacht, allerdings ging es 
da mehr um die netconn API...
Hier möchte ich direkt auf den Buffer selbst eingehen, in diesem Fall 
aber bei der RAW API.

Ich kann aktuell mit der RAW API und den TCP Funktionen eine Verbindung 
aufbauen, Daten senden und Daten empfangen. Allerdings nur eine 
begrenzte Menge.

Hier der Code:
1
struct netif gnetif;
2
struct tcp_pcb *testClient_pcb;
3
uint8_t dataToSend[14];
4
int i;
5
6
int main(void)
7
{
8
  /* STM32F4xx HAL library initialization:
9
       - Configure the Flash prefetch, instruction and Data caches
10
       - Configure the Systick to generate an interrupt each 1 msec
11
       - Set NVIC Group Priority to 4
12
       - Global MSP (MCU Support Package) initialization
13
     */
14
  HAL_Init();  
15
  
16
  /* Configure the system clock to 180 MHz */
17
  SystemClock_Config();
18
     
19
  /* Initialize the LwIP stack */
20
  lwip_init();
21
  
22
  /* Configure the Network interface */
23
  Netif_Config();
24
  
25
  /* Notify user about the network interface config */
26
  User_notification(&gnetif);
27
28
  HAL_Delay(1000);
29
  ip_addr_t DestIPaddr;
30
31
  /* create new tcp pcb */
32
  testClient_pcb = tcp_new();
33
34
  if (testClient_pcb != NULL)
35
  {
36
    IP4_ADDR( &DestIPaddr, DEST_IP_ADDR0, DEST_IP_ADDR1, DEST_IP_ADDR2, DEST_IP_ADDR3 );
37
38
    /* connect to destination address/port */
39
    LCD_UsrLog ("  Connecting...\n");
40
    tcp_connect(testClient_pcb,&DestIPaddr,DEST_PORT,testConnected);
41
  }
42
  else{
43
    LCD_UsrLog ("Error while creating - no PCB!\n");
44
  }
45
46
  /* Infinite loop */
47
  while (1)
48
  {  
49
    /* Read a received packet from the Ethernet buffers and send it 
50
       to the lwIP for handling */
51
    ethernetif_input(&gnetif);
52
53
    /* Handle timeouts */
54
    sys_check_timeouts();
55
  }
56
}
57
58
static err_t testConnected(void *arg, struct tcp_pcb *tpcb, err_t err) {
59
  LCD_UsrLog ("Connected!\n");
60
  testSender();
61
  return ERR_OK;
62
}
63
64
void testSender() {
65
  LCD_UsrLog ("  Sending ...\n");
66
  tcp_write(testClient_pcb, dataToSend, 14, TCP_WRITE_FLAG_COPY);
67
  tcp_sent(testClient_pcb, testSent);
68
}
69
70
static err_t testSent(void *arg, struct tcp_pcb *tpcb, u16_t len) {
71
   LCD_UsrLog ("Sended!\n");
72
73
     /* initialize LwIP tcp_recv callback function */
74
     tcp_recv(tpcb, testReceiver);
75
     tcp_err(tpcb, testErrorCallback);
76
     return ERR_OK;
77
}
78
79
static err_t testReceiver(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err){
80
  i++;
81
  LCD_UsrLog ("Received: %d bytes, Nr.%d\n", p->tot_len, i);
82
  LCD_UsrLog ("%d\n",err);
83
  /* Acknowledge data reception */
84
  u16_t len = p->tot_len;
85
        pbuf_free(p);
86
        p = NULL;
87
  tcp_recved(tpcb, len);
88
  return ERR_OK;
89
}
90
91
static void testErrorCallback(void *arg, err_t err) {
92
  LCD_UsrLog ("Error!\n");
93
  LCD_UsrLog ("%d\n",err);
94
}

Der Kommunikationspartner sendet zyklisch Daten, nachdem ich ihm einen 
Befehl geschickt habe. Das klappt soweit.

Bevor ich diese Zeilen eingefügt hatte...
1
        pbuf_free(p);
2
        p = NULL;
... konnte ich nur genau 8 Nachrichten empfangen.
Das habe ich durch die Variable "i" gesehen.
Es kam kein Fehler!

Ich habe sogar in der lwip/opt.h Datei versucht, die Memory 
Einstellungen zu ändern. Leider ohne Erfolg. Immer nur 8 Nachrichten.

Nachdem ich nun die Zeilen oben ergänzt habe, kann ich mehr empfangen, 
allerdings nicht "flüssig". Es kommen 8 Nachrichten, dann eine kurze 
Pause, dann nochmal 3, dann nochmal eine kurze Pause, dann nochmal ein 
paar. Nach 16 oder 17 Nachrichten kommt nun die Fehlernummer "-14" durch 
die Error-Callback-Funktion, was einem "Connection reset" entspricht.

Ich verstehe die pbufs noch nicht so ganz.
Weiß LwIP nur durch die opt.h Datei, wie die buffer aussehen?
Wofür ist dann die "pbuf API" von LwIP?
Kann ich den pbuf "p" aus dem obigen Code noch anpassen  ändern  
optimieren?

Vielen Dank vorab!

von Hansi (Gast)


Lesenswert?

Hallo,

Daniel F. schrieb:
> Bevor ich diese Zeilen eingefügt hatte...        pbuf_free(p);
>         p = NULL;
> ... konnte ich nur genau 8 Nachrichten empfangen.
> Das habe ich durch die Variable "i" gesehen.
> Es kam kein Fehler!


Du solltest nicht p = NULL setzen, dadurch greifst du in den internen 
Memory Management von LWIP ein und es kann zu Memory Leaks kommen, was 
dazu führt, dass das Memory ausgeht.

Um mehr Daten zu empfangen, kannst du folgendes machen:

tcp_recved(tpcb, p->len);
pbuf_free(p);
pbuf_free(p->next);
pbuf_free(p->next->next);
pbuf_free(p->next->next->next);

ich mache die nächsten pBufs frei sicherheitshalber, aber die erste 
Zeile signalisiert dem Sender, dass man wieder mehr Daten empfangen 
kann.

Außerdem kannst Du in LWIP-opts.h auch die TCP_WND, TCP_MSS und 
PBUF_POOL_SIZE und PBUF Buffergrößte ändern bzw. vergrößern.

Das sollte helfen.

von Daniel F. (lmdaniel999)


Lesenswert?

Hi,
danke für die Antwort.
"tcp_recved(tpcb, p->len);" hatte ich ja genutzt...
Das hatte nichts gebracht.

Mittlerweile hab ich das Problem "indirekt" gelöst:
Der Fehler trat nur auf dem Dev-Board von ST auf. Sobald das Programm 
auf dem eigenen Board war, war der Fehler weg und es lief tadellos!

Ich weiß nicht, ob auf dem Dev-Board etwas anders sein kann. Es ist zwar 
mehr Hardware dran, aber da Programm ist das selbe...

Leider verstehe ich noch nicht so genau, warum, aber immerhin geht es! 
:-)
Das ist erstmal die Hauptsache.
Werde da bei Gelegenheit nochmal nachforschen, beim nächsten Projekt...

von Mahmud F. (mf1988)


Lesenswert?

Hallo, im Rahmen meiner Studienarbeit muss ich über Cube mx mit LwIP 
Daten an den Mikrocontroller senden. Ich bin darin ein Anfänger und wäre 
dankbar, wenn ihr mir da helfen könnt.

Frage:

1. Wie sende ich eine TCP/IP an den Controller?
2. Wie können die Low-Level Netzwerkfunktionen des Controllers getestet 
werden?
3. Einfache Implementierung eines Low-Level Tests.


Ich muss mit st cube mx arbeiten... es soll für Frage 1 einen LwIP Code 
geben..

Danke im voraus!

: Bearbeitet durch User
von Johannes S. (Gast)


Lesenswert?

Für ‚mach mir meine Studienarbeit‘ einen Thread kapern? Kommt hier gar 
nicht gut.
Da dürft ihr schon einen Codegenerator nutzen und dann immer noch zu 
faul mal ein Tutorium dazu anzusehen? Coronastress?

von Rath Geba (Gast)


Lesenswert?

Mahmud F. schrieb:
> Ich muss mit st cube mx arbeiten... es soll für Frage 1 einen LwIP Code
> geben..

Es soll - dunkle Gerüchte verbreiten diese Meinung - ein Wiki
zu LWIP geben. Aber das ist sehr geheim, Suchmascheinen ver-
weigern die Auskunft ....

Wenn man dann durch langjährige Suche darauf gestossen ist
könnte man dort sogar Beispielcode finden.

Und wenn man noch ein paar Jahre sucht (das ist natürlich nur
für ganz harte Jungs) findet man sogar im LWIP package Code
Beispiele.

Mahmud F. schrieb:
> Danke im voraus!

Für Unterstützung im Wenig- bzw. Nichtstun?

Beitrag #6194642 wurde vom Autor gelöscht.
von Daniel F. (lmdaniel999)


Lesenswert?

Johannes S. schrieb:
> Für ‚mach mir meine Studienarbeit‘ einen Thread kapern? Kommt hier gar
> nicht gut.
--> Und dann auch noch einen, der eigentlich was ganz anderes zum Inhalt 
hat! ^^

Mahmud F. schrieb:
> im Rahmen meiner Studienarbeit muss ich über Cube mx mit LwIP
> Daten an den Mikrocontroller senden.

Du willst von Cube mx über LwIP Daten an den µC schicken?
Oder willst du den µC mit Cube mx prgrammieren, dabei dann LwIP nutzen, 
damit du Daten per Ethernet empfangen kannst?

Mahmud F. schrieb:
> Frage:
>
> 1. Wie sende ich eine TCP/IP an den Controller?
> 2. Wie können die Low-Level Netzwerkfunktionen des Controllers getestet
> werden?
> 3. Einfache Implementierung eines Low-Level Tests.

Antwort zu 1: Gibt viele Möglichkeiten: Zum Testen z.B. auch mit 
RealTerm auf dem PC.

Gegenfrage zu 2:
Was willst du genau testen? Ob dein Code funktioniert? Ob die Hardware 
i.O. ist?

Gegenfrage zu 3:
Was ist deine Frage?

Mahmud F. schrieb:
> Ich muss mit st cube mx arbeiten... es soll für Frage 1 einen LwIP Code
> geben..

Ja, es gibt nen Haufen Beispiele.
In deinem User Ordner auf der Festplatte findest du einen Ordner 
"STM32Cube", darin das "Repository", darin die Firmware der 
installierten Controller. Darin findest du unter "Projects" und deinem 
Board dann den Ordner "Applications", wo auch einige Beispiele zu "LwIP" 
sind.
Unter anderem TCP und UDP Server und Clients. Auch ein HTTP Server...

Du könntest dir nun die Application "LwIP_TCP_Echo_Server" ansehen, wo 
in der Readme genau erklärt ist, was du machen musst!

Ich habe selbst damals länger gebraucht, bis ich die ganzen Examples 
gefunden habe. Wenn man die aber mal gefunden hat, ist es nur noch ein 
"Nachbauen" und "Zusammenkopieren"....

von Rath Geba (Gast)


Lesenswert?

Daniel F. schrieb:
> Antwort zu 1: Gibt viele Möglichkeiten:

Hier eine ganz nützliche:

https://packetsender.com/

von Mahmud F. (mf1988)


Lesenswert?

Zu Frage 1: Ich möchte erstmal nur Testdaten an den Controller senden 
mit TCP/IP. Also nur zum üben wie man so etwas macht.

zu Frage2: Es soll ein Konzept sein wie man low-level Netzwerkfunktion 
des Controllers testet. Ich denke, ob meine Funktion 
funktioniert....Genaueres muss ich noch mal nachfragen.

zu Frage 3: nur Grundlagen wie man low-Level Funktion implementiert.
Ich werde hierzu noch genaueres nachfragen.

Ich danke dir für deine Hilfe...werde mal reinschauen was du mir 
geschickt hast...

Als Alnfänger ist es etwas schwierig zurecht zu finden.

: Bearbeitet durch User
Beitrag #6196336 wurde vom Autor gelöscht.
von Mahmud F. (mf1988)


Lesenswert?

Du willst von Cube mx über LwIP Daten an den µC schicken?
Oder willst du den µC mit Cube mx prgrammieren, dabei dann LwIP nutzen,
damit du Daten per Ethernet empfangen kannst?

Von Cube mx über LWIP Daten an den µC schicken.

von Daniel F. (lmdaniel999)


Lesenswert?

Mahmud F. schrieb:
> Du willst von Cube mx über LwIP Daten an den µC schicken?
> Oder willst du den µC mit Cube mx prgrammieren, dabei dann LwIP nutzen,
> damit du Daten per Ethernet empfangen kannst?
>
> Von Cube mx über LWIP Daten an den µC schicken.

Das versteh ich nicht....

Vielleicht kann mich mal jemand aufklären! :-)

Cube mx (und die IDE) wird genutzt, um den µC zu programmieren.
LwIP ist eine Bibliothek, die genutzt wird, um eine 
Netzwerkfunktionalität auf dem µC zu realisieren.

Meines Wissens nach kann man VON Cube mx keine Daten ÜBER LwIP AN den µC 
schicken. Interpretiere ich was falsch, oder hast du einfach noch keine 
Ahnung davon?

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.