-
Notifications
You must be signed in to change notification settings - Fork 7.6k
NVS/Preferences-lib getString() locks up intermittently #740
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Can you try changing this line to: char buf[len+1];
buf[len] = 0; I doubt this is the issue, but still :) |
Hey @me-no-dev I've tried it, but sadly it did not work. #include <WiFi.h>
const char* ssid = "***";
const char* password = "***";
#define USE_SERIAL Serial
#include <Preferences.h>
Preferences preferences;
#include <HTTPClient.h>
const char* server = "www.howsmyssl.com"; // Server URL
// www.howsmyssl.com root certificate authority, to verify the server
// change it to your server root CA
// SHA1 fingerprint is broken now!
const char* test_root_ca= \
"-----BEGIN CERTIFICATE-----\n" \
"MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\n" \
"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n" \
"DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\n" \
"SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\n" \
"GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\n" \
"AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\n" \
"q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\n" \
"SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\n" \
"Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\n" \
"a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\n" \
"/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\n" \
"AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\n" \
"CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\n" \
"bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\n" \
"c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\n" \
"VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\n" \
"ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\n" \
"MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\n" \
"Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\n" \
"AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\n" \
"uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\n" \
"wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\n" \
"X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\n" \
"PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\n" \
"KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\n" \
"-----END CERTIFICATE-----\n";
void coreTask(void * pvParameters) {
while(1) {
HTTPClient http;
USE_SERIAL.print("[HTTP] begin...\n");
http.begin("https://www.howsmyssl.com/a/check", test_root_ca); //HTTPS
USE_SERIAL.print("[HTTP] GET...\n");
// start connection and send HTTP header
int httpCode = http.GET();
// httpCode will be negative on error
if(httpCode > 0) {
// HTTP header has been send and Server response header has been handled
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
USE_SERIAL.println(payload);
}
} else {
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
delay(1 * 1000);
}
}
void setup() {
preferences.begin("Logger", false);
preferences.putString("facilityId", "qwertz123");
preferences.end();
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
xTaskCreatePinnedToCore(
coreTask, /* Function to implement the task */
"coreTask", /* Name of the task */
10000, /* Stack size in words */
NULL, /* Task input parameter */
10, /* Priority of the task */
NULL, /* Task handle. */
1); /* Core where the task should run */
}
void loop() {
Serial.println("preferences.begin:");
preferences.begin("Logger", true);
Serial.println("preferences.getString:");
String facilityId = preferences.getString("facilityId", "unknown");
Serial.println("preferences.end:");
preferences.end();
Serial.print("facilityId: ");
Serial.println(facilityId);
Serial.print("Uptime: ");
Serial.print(millis()/1000);
Serial.println(" s");
delay(100);
} |
OK, I can confirm this. It seems to break on while |
Strange, using coreTask with priority 1 it works fine here |
@copercini it should work regardless :) |
@me-no-dev I've opened a ticket in esp-idf as well: espressif/esp-idf#1157 |
@Curclamas can you please try the latest code :) just merged IDF last night |
@me-no-dev sadly, after the update my Arduino-IDE throws: |
@me-no-dev after checking out 55289a4 (skipping 4f55293 and 84b8582, those seam to break my build process) getString still freezes. |
I've looked briefly into this, and it seems that the following is happening:
In this situation we have a deadlock, because TLS task never receives any more data, and it doesn't yield to lower-priority task which is doing flash operation. There are a few more possibly interesting things happening in this test, but that's the main part for now. There are two issues to be addressed, one in IDF and another in Arduino.
|
@igrr Thanks for your explanation and nice found! As you said, there is no reason for checking if handshake was done too fast causing this high CPU utilization and power waste, so I PRed a very simple code to slow down the calling of It seems there is the same problem in the mbedtls example of IDF here, but unfortunately I don't have a debugger to see deeply what is happening, how the tasks are scheduled and so on (waiting for 11/11 promotional prices of wrover kit hehe) |
@copercini I've applied the code from you PR and it made the lockup less often. Now it still locks up sometimes after |
@Curclamas Try change this delay(0) by delay(10) |
@copercini This seams indeed to fix it (@iggr 's patch from espressif/esp-idf#1157 also does). Probably both of these precautions should be implemented. Does it make sense to also have the delay in send_ssl_data? |
@copercini I see 14dd44a is now in master. Maybe we should also add a fix for the HTTPclient (https://github.com/espressif/arduino-esp32/blob/master/libraries/HTTPClient/src/HTTPClient.cpp#L997)? |
@Curclamas yes! PRed too, thanks for remember me!
It's a complicated thing, for low datarates it's ok, but for faster transfers maybe it's not adequate have a delay in a transmission function... |
@copercini, I have thought about that too and did not yet come to a
conclusion. When looking at the underlying (networking) functions: Do they
block while sending? I am not that deep into this kind of code, but I don't
see why we would have to busy wait for any incoming data?
…On Mon, Nov 6, 2017 at 5:21 PM, copercini ***@***.***> wrote:
@Curclamas <https://github.com/curclamas> yes! PRed too, thanks for
remember me!
Does it make sense to also have the delay in send_ssl_data?
It's a complicated thing, for low datarates it's ok, but for faster
transfers maybe it's not adequate have a delay in a transmission function...
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#740 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AC_DS403MFYDBFMkP74giaju8Xb5n3ssks5szzH2gaJpZM4P8A-B>
.
|
The fix is for the situation when cache disabling mechanism causes a deadlock with user tasks. Situation is as follows: 1. spi_flash operation is started from low-priority task on CPU0 2. It uses IPC to wake up high-priority IPC1 task on CPU1, preventing all other tasks on CPU1 from running. This is needed to safely disable the cache. 3. While the task which started spi_flash operation is waiting for IPC1 task to acknowledge that CPU1 is not using cache anymore, it is preempted by a higher priority application task ("app0"). 4. Task app0 busy-waits for some operation on CPU1 to complete. But since application tasks are blocked out by IPC1 task, this never happens. Since app0 is busy-waiting, the task doing spi flash operation never runs. The more or less logical soltion to the problem would be to also do cache disabling on CPU0 and the SPI flash operation itself from IPC0 task. However IPC0 task stack would need to be increased to allow doing SPI flash operation (and IPC1 stack as well). This would waste some memory. An alternative approach adopted in this fix is to call FreeRTOS functions to temporary increase the priority of SPI flash operation task to the same level as the IPC task. Fixes espressif/arduino-esp32#740 Fixes espressif/esp-idf#1157
Hardware:
Board: Custom Board
Core Installation/update date: 12.10.2017
IDE name: IDF component
Flash Frequency: 80Mhz
Upload Speed: 115200
Description:
I use Preferences lib to store some information once and read it periodically. Some reads occur every two minutes. After a few hours up to a few days the application will lock itself upon calling
preferences.getString()
.Sketch:
Debug Messages:
In case of the lockup, the last line is missing, implying that
.getString()
locks somehow internally. The task WDT does not always fire upon this lockup, causing the device to freeze until manual reset.The text was updated successfully, but these errors were encountered: