-
Notifications
You must be signed in to change notification settings - Fork 7.6k
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
HTTPS failure with low free heap memory? #2175
Comments
|
Thank, actually I've tried to allocate memory to see this limit. It seem that it start to fails if free heap is about 100k. the code in the loop is:
The result is:
I've repeated this test multiple times changing the memory allocated at each iteration: 5k/10k/20k were tested leading to the same result. |
I see the same issues with a WROVER module. See my referenced thread I posted in ESP32 forums. I have almost 4MB of heap available, but it says memory allocation failed. Any help is greatly appreciated. |
Only because you have 4MB free heap it does not means that all can be used in all situations of for all components. |
@czuvich Depending on the SDK version @fabiuz7 using http.getString() multiple times in a loop will eventually consume all available heap, Arduino Strings are evil :D I've had the same issues in my own project, and upon @chegewara's suggestion I moved all String() statements to const char* and could eventually use ps_malloc instead of malloc. Consequently you'll have to use streaming with HTTP. // get this outside your loop !
HTTPClient http;
http.setReuse(true);
// assuming 'step' is a power of 2 (e.g. 512, 1024, 2048)
byte* buff = (byte*)ps_malloc(step); // only malloc/ps_malloc during setup() !!
// (...)
// modify your loop as follows:
WiFiClient * stream = http.getStreamPtr();
// (...)
if(httpCode == HTTP_CODE_OK) {
while(http.connected() && (len > 0 || len == -1)) {
// get available data size
size_t size = stream->available();
if(size) {
// read up to 'step' bytes
int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
// write it to SD, Serial or any other resource
Serial.write(buff, c);
//SD.write(buff, c);
if(len-c >= 0) {
len -= c;
}
}
}
} If you're using a SD Card there's also the possibility to SD-load certificate data directly to the psram: bonus in sketch size and maintainability as it unlocks the possibility to have the certificate stored in psram. |
Thanks for the helpful responses! I am getting the error on startup of the chip. If I call BLEDevice::init() followed by the HTTPS call it reports that error. If I omit BLEDevice::init() it’s fine. So, how could I get that working in Arduino (without omitting one or the other)? Is the error reported to be expected since it sounds like it forces internal allocation? I’m looking at Perhaps? I assume to get that working I’d need to recompile the SDK libs right? |
@czuvich maybe Ongoing scans can eat up to 256 bytes per detected device so it can affect your heap differently depending on how long your scan is. |
@czuvich Could you try revert order, first https calls and then ble? |
@chegewara Switching order allows me to execute WiFi and then BLE scans; however, I can't run WiFi afterwards. So, here's what I'm seeing: BLE then WiFi (fails) Shouldn't mbed use spiram in the Arduino environment? If not, I'm wondering if there needs to be some other configuration. Here's the full log from the other thread. 12:59:27.190 -> [V][ssl_client.cpp:53] start_ssl_client(): Free heap before TLS 4182376 |
@czuvich on the Wrover kit + SDK-rc1 I had to run psramInit() manually before being able to use it, which is odd as it's supposed to be automatically initialized. |
@tobozo Thanks for suggestion, but that doesn't seem to work either. I am currently running v3.2-dev-39-gaaf12390 with the WROVER DEV Kit 4.1. I think I may open up my own github issue for this problem. I don't think it's anything on my end, but I'll try to create a repo. Just curious, are you using the WROVER DEV Kit for your project? Did you end up getting your own board designed with a WROVER chip? I am currently using the WROVER Dev kit; however, I don't need all of the extra "stuff". |
@czuvich I have the Wrover Dev Kit v4.1 too (playing with this project) without doing simultaneous WiFi/BLE though. Not sure what the v3.2 you mention is, I'm on the arduino-esp32-1.0.1-rc2 of Arduino IDE 1.8.7 and using the 1.22.0-80-g6c4433a-5.2.0 xtensa. |
Arduino 1.0.1? Either that's a typo or you may want to update :) I'm on Arduino IDE 1.8.7. The SDK version I printed out was from Also, thank you for linking your project. I can't release the source for mine, but I'm building a BLE->WiFi gateway using the WROVER dev kit for now. I'm leveraging the SD Card and an external RTC (DS3231). |
@czuvich In my project I have a use case for downloading HTTPS content between two BLE scans, what should I do in my scan loop to replicate your issue ? btw on my build the RTC module wants to run on core 1 or it dies miserably. |
@tobozo I setup 2 tasks. One task is for BLEScanning and the other task is for posting data to an HTTPS backend. For the repo, I was going to use only 1 task and call BLEDevice::init() in setup since I am getting an error without scanning. I am using the following base class for executing tasks: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/Task.h So something like this in the setup() function: BLEDevice::init(); Then, inside of the That should be enough to replicate the issue. I've tried different stack allocations, but it always fails if BLEDevice::init() is invoked first. To work around the issue, I just "schedule" the HTTPS POST. If the program detects that it's time to run the POST, it resets the board, executes the POST first, and resets the board again. I keep a persistent variable that tells me the next time to execute the POST (hence the RTC). |
So if you try to call the RTCLib.now() (not sure which RTCLib you're using) function on core 0 it will fail? |
@czuvich yep RTCLib.now() fails on core 0, returns 165:165:65 unless it runs on core 1, I haven't figured out why I wont be able to test BLE+TLS on Arduino until a couple of days, currently it won't compile because other libraries of my app already use too much space, I'll update this comment with the progress. |
check the task priority. I found issues with task starvation because of interrupt priority inversion. A high priority task waiting for a semaphore held by a low priority task that never gets any cpu cycles. Chuck. |
Ok... So I took out both BLE and WiFi out of task execution and put them in the loop(), and I'm able to execute WiFi after BLE once; however, it fails the second time with the memory allocation error. I've configured my tasks as follows: Maybe I have my tasks configured incorrectly? I'm using the Task.h base class to execute the tasks from: |
2 things:
|
@chegewara Thank you for finding that!
What was leaking? I am not allocating a new Task(), but instead I have a global task in the sketch that I re-use. |
In my example the issue was when i am using this example to connect and disconnect multiple times. Every connect/disconnect procedure takes about 3kB memory and cant free it: |
@chegewara The Task.h wrapper is not really doing much, so I'd be surprised if that's the cause of the leak. I'll try to re-work my tasks then to see if that's where one of the issues is at, but even taking out the tasks I still get memory allocation failed on a WROVER. In theory, I shouldn't be running into an allocation issue on this chip after 2 executions. |
I thought exactly the same, its just a task wrapper. But as soon as i switched in this example to normal freeRTOS task there is no longer memory leaks. |
Got it. I think I may need to just wait until 1.0.1 is officially released. I'm running into several issues with the WROVER dev kit and BLE using the latest dev branch. I'll post findings as I move along. |
@chegewara FYI, I think the leak in the Task.cpp is in line 84 - Task::stop(). void Task::stop() { |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
This stale issue has been automatically closed. Thank you for your contributions. |
What's wrong with Esp32? Why in 8266 I can establish 2 https connections with only 40-50Kb free heap and at esp32 it's falling all with 400+Kb?! Firmware size in flash is about 2Mb - wtf? It's soo unoptimized or what? May be switching to it at work project is going to be the greatest failure( |
yet there are countless devices out there running on ESP32... maybe something you are doing wrong? |
Hardware:
Board: Lolin D32
Core Installation/update date: commit: 884e417 06/dec/2018
IDE name: Arduino IDE
Flash Frequency: 40Mhz
PSRAM enabled: no
Upload Speed: 921600
Computer OS: Windows 10
Description:
I was testing the HTTPS functionality and it works perfectly. Last week I've added the BLE library, but it cause the failure of HTTPS calls. Actually Bluetooth is just instantiated BLEDevice::init(""); and never used, but it seems enough to make fail https calls. I think that the problem is the huge amount of ram stole by BLE library, but I'm not so confident about that.
This is what I get on serial port and it represent the common behaviour, everything works fine (even if there is that socket error) , you can see the huge (normal) amount of free heap:
This is what I get when BLE is initialized (NOTE low free heap quantity):
My questions are:
The text was updated successfully, but these errors were encountered: