LwIP + TCP + RTOS + netconn - unerwartetes Verhalten

Gast #5111315
Moin zusammen,

vielleicht ist jemand schlauer als ich (ganz bestimmt!).

Ich habe ein Task in RTOS der zyklisch Daten sendet, aus den Speicher 
ueber TCP. Sieht mehr oder weniger so aus (abgekuerzt):
1
while(1)
2
{
3

4
netconn_write(server_conn, (const unsigned char*)data_2, 136000, NETCONN_NOCOPY);
5

6
/** Delay ist ~ 100 ms. **/
7

8
vTaskDelay(xDelay);
9
}

Laeuft alles so gut, und TCP kann die Daten wieder aufbauen bei 
verlorene Pakete.

Nun, wenn ich eine kleine for-Schleife hinzufuege, bevor ich die Daten 
wegschicke, bricht alles ab und wird sehr langsam, als in, 10-fach 
langsamer:
1
while(1)
2
{
3
  for(i = 0; i < 10; i++){
4
    data[340 * i] = HAL_GetTick();
5
    data[340 * i + 1] = seqNumber;
6
    seqNumber++;
7
  }
8

9
  netconn_write(server_conn, (const unsigned char*)data_2, 136000, NETCONN_NOCOPY);
10

11
  vTaskDelay(xDelay);
12
}

Das wuerde mich wunder wenn die Schleife sehr gross waere, allerdings 
bei 10 finde ich das sehr komisch.

Irgendwelchen Optimierungen die da vielleicht ins Spiel kommen? Momentan 
ist die Optimierung auf Debug. Ich werde ein bisschen weiter testen.

Cheers,

Albert
Gast #5112360
Aber die Schleife ist im gleichen Task wie die Datenuebertragung. Ein 
yield() wuerde dann beides verlangsamern.

Mittlererweile habe ich mit den Optimierungs-Settings gespielt, das 
aendert auch manches. Manchmal besser, manchmal nicht so...

Cheers,

Albert
#5112645
Albert F. schrieb:
> Aber die Schleife ist im gleichen Task wie die Datenuebertragung. Ein
> yield() wuerde dann beides verlangsamern.

Das stimmt, wenn dein netconn_write() synchron ist. Es kann aber auch 
sein, dass dein Netzwerktreiber (bzw. IP-Stack) in einem separaten Task 
läuft und dein netconn_write() einfach nur die Übertragung anstößt. Ich 
kenne dein System nicht.

Andere Idee: Tritt das Problem auch auf, wenn du HAL_GetTick() nicht 
aufrufst? Vielleicht ist diese Funktion einfach nur sehr langsam. Im 
Zweifelsfall kannst du mal die Zeit messen, die deine Funktion insgesamt 
braucht.
Gast #5112657
Albert F. schrieb:
> while(1)
> {
>   for(i = 0; i < 10; i++){
>     data[340 * i] = HAL_GetTick();
>     data[340 * i + 1] = seqNumber;
>     seqNumber++;
>   }
>
>   netconn_write(server_conn, (const unsigned char*)data_2, 136000,
> NETCONN_NOCOPY);
>
>   vTaskDelay(xDelay);
> }

wie groß ist data in beiden versuchen ?

in erstem fall ... ein paar bytes .. in zweitem fall ein paar tausend

je nach sendepuffer des lwip kann das ungemein ausbremsen
Gast #5112660
Albert F. schrieb:
> while(1)
> {
>   for(i = 0; i < 10; i++){
>     data[340 * i] = HAL_GetTick();
>     data[340 * i + 1] = seqNumber;
>     seqNumber++;
>   }
>
>   netconn_write(server_conn, (const unsigned char*)data_2, 136000,
> NETCONN_NOCOPY);
>
>   vTaskDelay(xDelay);
> }

zumald diese schleife keinen sinn macht ...
oder sollte es heißen :
1
while(1)
2
{
3
  for(i = 0; i < 10; i++){
4
    data[340] = HAL_GetTick();
5
    data[340 + 1] = seqNumber;
6
    seqNumber++;
7
  netconn_write(server_conn, (const unsigned char*)data_2, 136000,     NETCONN_NOCOPY);
8
  }
9

10
  vTaskDelay(xDelay);
11
}
#5112692
458iu7888766687 schrieb:
> zumald diese schleife keinen sinn macht ...

Nun ja, deine Schleife macht dann aber irgendwie überhaupt gar keinen 
Sinn...

Abgesehen davon stellt sich mir die Frage, warum anscheinend data 
beschrieben und data_2 weggeschickt wird?

Ansonsten scheint mir netconn_write() lediglich die Daten in eine 
Output-Queue zu stellen (per Referenz wg. NOCOPY). Das geht also 
wahrscheinlich ziemlich flott, die eigentliche Arbeit (verschicken) 
passiert woanders.

... und nochwas: der Code scheint keine Synchronisierung zu enthalten, 
d.h. falls das nicht irgendwo im nicht gezeigten Code passiert, kann es 
sein, daß Du (für den nächsten Durchgang) an den Daten rumfummelst 
obwohl sie noch gar nicht abgeschickt sind...
Gast #5113538
Vielen Dank fuer die Antworten.

Stimmt, die Schleife macht wenig Sinn (oder keinen), die war da um diese 
Verzoegerung zu erzeugen. Wenn die Schleife weg ist (sinnvoll oder 
nicht), ging alles OK.

Im Moment ist dieses Task nicht synchronisiert, das wuerde das auch 
erklaeren. Allerdings habe ich auch festgestellt dass wenn ich die 
Optimierung auf O3 (statt Og) setze, laeuft das alles flott.

Ich werde jetzt versuchen sicherzustellen dass die Daten nicht geloescht 
werden.

Cheers,

Albert
Gast #5113583
Albert F. schrieb:
> Allerdings habe ich auch festgestellt dass wenn ich die
> Optimierung auf O3 (statt Og) setze, laeuft das alles flott.

SW4 von STM?
Cube projekt?
STMF4 oder F7?

stell auf O2 und die debug auf -g1

dann vermeide structs mit "__packed" oder
mit vielen unterschiedlichen datentypen
sortiere die, das immer 32bit voll sind ..
zur not dummy uint8_t reinwerfen

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.