P2 USB Serial is very slow compared to Photon

We run the same code on P2 and Photon
P2 is extremely slow takes 24-25 ms to run this code, while Photon takes 0 ms.
Firmwares:
Photon 1: 2.1.0
P2: 5.1.0

if we commend out:

Serial.println(gps_coordinate, 7); // <-- Low stream speed

Then P2 will also do it in 0 ms.

SYSTEM_THREAD(ENABLED);
//STARTUP(System.enableFeature(FEATURE_DISABLE_LISTENING_MODE));
STARTUP(WiFi.selectAntenna(ANT_INTERNAL));
SYSTEM_MODE(MANUAL);

unsigned long last_check_wifi_ready_millis = 0;
unsigned long boundaries_count = 0;

bool boundaries_parse_basic_settings(const char* p) {
  p = strchr(p, '[') + 1;
  uint max_length = 30;
  /*uint max_length = SIZEOF(boundaries);
  for(unsigned int i = 0; i < max_length; i++) {
    boundaries[i].gps_pos.lat = 0;
    boundaries[i].gps_pos.lng = 0;
  }*/

  boundaries_count = 0;
  
  boolean is_lat = true;
  while(true) {
    if(p[0] == ']')
      break;

    if(boundaries_count >= max_length) {
      for(unsigned int i = 0; i < max_length; i++) {
        //boundaries[i].gps_pos.lat = 0;
        //boundaries[i].gps_pos.lng = 0;
      }

      return false;
    }

    double gps_coordinate = atof(p);

    if(is_lat) {
      //boundaries[boundaries_count].gps_pos.lat = gps_coordinate;
      is_lat = false;
    }
    else {
      //boundaries[boundaries_count].gps_pos.lng = gps_coordinate;
      boundaries_count++;
      is_lat = true;
    }
     
    Serial.println(gps_coordinate, 7); // <-- Low stream speed
    p = strchr(p, '#') + 1;
  }

  return true;
}

void setup() {
    Serial.begin(115200);

    WiFi.on();
    WiFi.connect(WIFI_CONNECT_SKIP_LISTEN);
}

void loop() {
    if(millis() - last_check_wifi_ready_millis > 1000) {
        last_check_wifi_ready_millis = millis();

        /*WiFiAccessPoint ap[5];
        int found = WiFi.getCredentials(ap, 5);
        for (int i = 0; i < found; i++) {
            Serial.printlnf("ssid: %s", ap[i].ssid);
            // security is one of WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA, WLAN_SEC_WPA2, WLAN_SEC_WPA_ENTERPRISE, WLAN_SEC_WPA2_ENTERPRISE
            Serial.printlnf("security: %d", (int) ap[i].security);
            // cipher is one of WLAN_CIPHER_AES, WLAN_CIPHER_TKIP or WLAN_CIPHER_AES_TKIP
            Serial.printlnf("cipher: %d", (int) ap[i].cipher);
        }
        if(!WiFi.ready()) {
            Serial.println("Connect...");
            //WiFi.connect(WIFI_CONNECT_SKIP_LISTEN);
        }

        Serial.printlnf("Connecting... %d", WiFi.connecting());

        Serial.print("WIFI: ");
        Serial.println(WiFi.SSID());

        Serial.print("IP: ");
        Serial.println(WiFi.localIP());
        //print_firmware_version();
        Serial.print("MAC address: ");
        byte mac[6] = {0};
        WiFi.macAddress(mac);
        
        for (int i = 0; i < 6; i++) {
            Serial.printf("%02x%s", mac[i], i != 5 ? ":" : "");
        }
        Serial.println();
        Serial.printlnf("gateway: %s", WiFi.gatewayIP().toString().c_str());*/

        unsigned long m = millis();
        boundaries_parse_basic_settings("8GyOdLExg8;[54.1234567#14.234567#54.1234678#14.234678#54.1234689#14.234689#]*15");
        Serial.printlnf("time: %lu", (millis() - m));
    }
}

Can you please help us out? Thank you so much!

Can you try running this code:

#include "Particle.h"

SYSTEM_THREAD(ENABLED);


void setup() {
    Serial.begin();
}

void loop() {
    static unsigned long lastRun = 0;

    unsigned long start = millis();
    Serial.printlnf("test %lu", lastRun);
    lastRun = millis() - start;
}

This was the simplified test of Serial.printlnf and it’s taking 3 or 4 milliseconds for me on a P2 with Device OS 5.1.0.

test 4
test 3
test 3
test 3
test 3
test 3
test 3
test 4
test 3
test 4
test 3
test 3
test 3
test 3
test 3
test 3
test 4

Thanks for your quick reply.

You have not specified the baud rate in your code, and I am not sure what the default is, but the 3-4 ms, just to print out some data looks incredibly slow.

Thanks!

There is no baud rate for USB serial. Even if you specify it, it is ignored.

It might be slower but the USB serial is typically only used for debugging so I don’t expect that would be a high priority to address.

I am sorry, but in our project we use the USB Serial as well, so for us it is a high priority to address.

As you have seen a basic code from 0 ms with photon, how can be 25 ms and saying it is not priority to address? :frowning:

Are there any other features of P2 which is slower than Photon?

Any solution, you could helps us?

Thanks.

25 milliseconds is very, very slow. If you are getting that with my sample code that would be an issue.

However 3 - 4 milliseconds doesn’t seem that bad. That’s what I was referring to as probably not a high priority.

The USB drivers are completely different between the STM32F205 and the RTL8217D. It’s hard to say where the slowdown is occurring, but if it’s in the Realtek SDK, then there is little that could be done. If it’s in the interface between Device OS and the Realtek SDK, then possibly something could be optimized.

I’m not saying that we won’t fix it, I’m just indicating on the list of priorities, USB serial speed is not a priority so it’s less likely to be fixed immediately.

I think I see why there is a speed difference. On the STM32, there’s a ring buffer between the USB serial calls and the actual USB hardware. It’s instantaneous because it goes into the buffer and goes to the USB host asynchronously. It’s not actually faster, it just returns faster.

On the RTL8721D it actually sends the data to USB before returning.

The easiest workaround if you don’t want to block is just wrap the USB serial with ring buffer.

I implemented a library that replaces Serial and makes the USB CDC Serial writes asynchronous.

The instructions are in the README here: https://github.com/rickkas7/AsyncUSBSerialRK

It makes the writes instantaneous:

test 0
test 0
test 0
test 0
test 0
test 0
test 0

I was mistaken. There is a buffer in the RTL8721D CDC driver. So it should not take 3-4 milliseconds (or more).

However, using the library with the external buffer definitely makes writes much faster, so now I’m not sure what the cause of the slowdown is. But the library would be a reasonable workaround until the actual problem is found.

Hello Rickkas,

Thank you very much for your time and effort.

Can you please make public your github repo AsyncUSBSerialRK?

I am happy that at least, we have found out that there is a misbehaviour. Hopefully your team will find out what cause the problem.

Thank you so much again, we test further P2.

I made the Github repo public. Sorry about that.

Thank you Rickkas