Experiences with the ESP32 serial interface

I wanted to optimize the runtime of my functions for receiving and analyzing data from a GNSS receiver.
To do this, I replaced all string commands with char arrays, which, for example, reduced the analysis of the NMEA dataset from 328 µs to 40 µs (oscilloscope measurement).

However, reading the 83-byte RMC dataset with the ESP32 functions avaiable() and read() took about 1.8 ms.
This is obviously due to the FreeRTOS operating system, which manages the ESP32's serial interfaces.

The combination of avaiable() and readBytes() brought about a big improvement from 1.8 ms to 27.4 µs !
The data buffered by the operating system is provided in larger blocks anyway.

A disadvantage of this block-by-block reading is that readBytes() could return multiple or incomplete records. This means that at the end of the received block there is an incomplete record that is only completed with the next call. However, this can be managed with little additional code.

A simplified version of both methods is shown below:

//   Board: ESP32 / ESP32 Dev Module

#define TestPin     12                  // Test-Output
HardwareSerial SerialGNSS(1);           // serial interface to the GNSS-Receiver

//---------------------------------------------------------
void setup() {
  Serial.begin(115200);
  delay(2000);

  pinMode(TestPin, OUTPUT);
  digitalWrite(TestPin, LOW);     // for time measurement
  SerialGNSS.setRxBufferSize(1024);
  SerialGNSS.begin(115200, SERIAL_8N1, 13, 14);
}

//---------------------------------------------------------
void loop() {
  int cnt;

  if (SerialGNSS.available()) {
    digitalWrite(TestPin, HIGH);      // start time measurement

    //cnt = receiveRec1();              // serial receiving byte by byte    
    cnt = receiveRec2();              // serial receiving block by block

    digitalWrite(TestPin, LOW);       // stop time measurement
    Serial.print(" " + String(cnt));    // number of received chars
  }
  delay(10);
}

//---------------------------------------------------------
int receiveRec1() {                   // run time: 1,78ms
  char rc;
  int i = 0;
  
  while (SerialGNSS.available()) {    // if chars received
    rc = SerialGNSS.read();           //    get one char
    if (rc == '\n') return i;         //    and check it
    i++;
  }
  return -i;
}

//---------------------------------------------------------
int receiveRec2() {                   // runtime 27,4µs
  char rc;
  int i = 0;
  char buf[256];

  int cnt = SerialGNSS.available();
  if (cnt <= 0) return 0;             // exit, if nothing received

  SerialGNSS.readBytes(buf, cnt);     // get all received chars
  for (i=0; i<cnt; i++) {
    rc = buf[i];
    if (rc == '\n') return i;         // and check them
  }
  return -i;
}

So you have a sketch that has 0 time spent waiting? If it does not, then speeding up one statement has NO effect on throughput. You might want to consider spending your time more productively.
p.s. I once held the world record for transactions per minute.

What baud rate is the GNSS receiver sending at?

Dave, have a look to the code:

Oops, sorry. I should have looked at the code.