FreeRTOS xStreamBufferReceive wartet nicht auf TriggerLevel

OP #7552687
Lesenswert?

Ich nutze FreeRTOS auf einer Datenlogger-Anwendung auf einem ESP32. Grob erklärt kümmert sich die main-Task um das Erfassen der Daten, die andere namesns Logger schickt diese periodisch per FTP an einen Server. Zur Kommunikation zwischen den Tasks und als Zwischenspeicher wird ein StreamBuffer verwendet, die Daten werden von der Main-Task in den Buffer geschrieben, die Logger-Task liest diesen wieder aus, sobald sich genügend Daten im Buffer angesammelt haben.

Zum Testen schreibe ich pro Sekunde eine 16-bit-Zahl in den Streambuffer, die Zahl wird dabei jedesmal um eins hochgezählt. Sobald 300 Zahlen (600 Bytes) erreicht sind, wird der gesamte Block zum Server geschickt. Im Prinzip funktioniert das, die Daten werden korrekt auf dem Server gespeichert. Allerdings wartet xStreamBufferReceive in seltenen Fällen (ca. 2-5%) nicht bis 600 Bytes eingetrudelt sind, sondern kehrt sofort mit nur 2 Bytes zurück. Das geschieht manchmal sogar kurz hintereinander. Danach wartet er wieder korrekt auf die nächsten 600 Bytes. Der Timeout ist auf 360 Sekunden eingestellt, da die Schwelle von 600 Bytes aber schon nach 300 Sekunden erreicht ist, sollte der Timeout eigentlich nie zuschlagen. Im Prinzip ist das nicht wirklich schlimm, es gehen keine Daten verloren. Allerdings führt das kleckerlesweise Schreiben zu einer hohen Last auf dem Server, denn jedesmal wird die FTP-Verbindung auf- und wieder abgebaut.

Interessanterweise liefert die Receive-Funktion manchmal auch nur 0 Bytes zurück, diese kann ich natürlich einfach ignorieren.

Es scheint so zu sein, als ob xStreamBufferReceive manchmal das TriggerLevel missachtet, ich frage mich nur warum und wieso?

Anbei die vereinfachte Struktur des Programms, Infoausgaben und der Austausch des data_buffer-Handles ist hier nicht dargestellt.

Erzeugen des Streambuffer und der Logger-Task

1
#define BUFFER_SIZE    2000
2
#define FTP_CHUNK_SIZE 600  //Trigger Level
3
void app_main(void) {
4
...
5
 StreamBufferHandle_t dataBuffer;
6
 uint16_t c = 0;
7

8
 dataBuffer = xStreamBufferCreate(BUFFER_SIZE, FTP_CHUNK_SIZE); 
9
 xTaskCreate(loggerTask, "Logger", 4096, NULL, 8, NULL);
10
...
11
 while (true) {
12
        xStreamBufferSend(dataBuffer,&c,2,pdMS_TO_TICKS(1000));
13
      c++;
14
      vTaskDelay(pdMS_TO_TICKS(1000)); // wait 1 second
15
 }
16
}

Auslesen in der Logger-Task, die Funktion ftp_writer schreibt den Datensatz über FTP in ein File.

1
void loggerTask(void *pvParameters) {
2
 char* ftp_buffer;
3
 ftp_buffer = (char*)malloc(FTP_CHUNK_SIZE);
4
 ...
5
 while(true) {
6
// wait until FTP_CHUNK_SIZE Bytes have arrived
7
      nData = xStreamBufferReceive(dataBuffer, ftp_buffer, FTP_CHUNK_SIZE, 
8
                                      pdMS_TO_TICKS(600*FTP_CHUNK_SIZE));
9
      if (nData > 0) {
10
          ftp_writer(ftp_buffer, nData); // send the chunk via FTP to the server
11
      }
12
 }
13
}

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