Forum: Mikrocontroller und Digitale Elektronik FreeRTOS xStreamBufferReceive wartet nicht auf TriggerLevel


von Fritz G. (fritz65)


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
}

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.