Closed v-c closed 4 years ago
Hello v-c,
ESP32 v1 is a dual-core processor. There are functions that can only be executed on one of the cores (if I remember well, e.g. deepsleep / wakeup must use core 1 and not core 0). You cannot control this with SETUP() and LOOP(), because then always core 1 will be used.
You can check the core within LOOP() with:
Serial.print("Setup: Executing on core ");
Serial.println(xPortGetCoreID());
To use core 0 explicitly, you have to use xTaskCreatePinnedToCore in SETUP():
define a global task handle:
TaskHandle_t handleAutoConnect;
write your code which have to be pinned to a core (same as your coding in LOOP)
void taskAutoConnect(void *optionalArgs)
{
for (;;)
{
// some code, e.g. AutoConnect::begin
delay(1000);
}
}
start the task within SETUP():
// create task TaskAC: function = taskAutoConnect, handle = handleAutoConnect, core = 0, priority = 1, stack = 10000, parameters = NULL
xTaskCreatePinnedToCore(taskAutoConnect, "TaskAutoConnect", 10000, NULL, 1, &handleAutoConnect, 0);
The function taskAutoConnect
is bound to core = 0
and all subroutines called and all objects generated by this function now also are bound to this core. That means that you cannot have the AutoConnect portal on core 0 and a part of it (OTA update) running on core 1 (and I don't think it would be a good idea to implement task handling into this library).
(If you need the power of an ESP32 but don't need the two cores, the new ESP32 v2 may be more attractive to you :-))
Kind regards, Tom
Thanks for the detailed response, Tom. Like you say, it may not be desirable to have the OTA update to run on core 0.
That said, I'm surprised that this situation happens on the ESP32CAM but OTA Update with the AutoConnect library works on other ESP32s (v1).
I'll do some more investigation as to the cause of the problem on this specific board.
After more digging it appears that perhaps it has to do with the partition sizes and the size of the sketch that is causing a kernel panic on the ESP32CAM. Here's the debug log:
abort() was called at PC 0x4014d965 on core 1
Backtrace: 0x400913ec:0x3ffb17b0 0x4009161d:0x3ffb17d0 0x4014d965:0x3ffb17f0 0x4008a463:0x3ffb1810 0x400eb589:0x3ffb1830 0x4015b596:0x3ffb1850 0x4015b7b9:0x3ffb1870 0x400e4319:0x3ffb1890 0x400dc855:0x3ffb18b0 0x400e4cb2:0x3ffb18f0 0x400de7a5:0x3ffb1920 0x400dfb0d:0x3ffb1940 0x400d8c35:0x3ffb1a00 0x400d9da9:0x3ffb1a20 0x400de7a5:0x3ffb1a50 0x401594ad:0x3ffb1a70 0x400d5d55:0x3ffb1aa0 0x400d7011:0x3ffb1ae0 0x400d847e:0x3ffb1cf0 0x400d53ba:0x3ffb1f20 0x400db2cd:0x3ffb1f70 0x400d1f9e:0x3ffb1f90 0x400edf4d:0x3ffb1fb0 0x4008db35:0x3ffb1fd0 **#0 0x400913ec:0x3ffb17b0 in invoke_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c:707
(inlined by) void std::_Mem_fn_base<void (AutoConnectUploadHandler::*)(String const&, HTTPUpload const&), true>::operator()<AutoConnectOTA*&, String const&, HTTPUpload const&, void>(AutoConnectOTA*&, String const&, HTTPUpload const&) const at c:\users\v-c-dev\.platformio\packages\toolchain-xtensa32\xtensa-esp32-elf\include\c++\5.2.0/functional:610
(inlined by) void std::_Bind<std::_Mem_fn<void (AutoConnectUploadHandler::*)(String const&, HTTPUpload const&)> (AutoConnectOTA*, std::_Placeholder<1>, std::_Placeholder<2>)>::__call<void, String const&, HTTPUpload const&, 0u, 1u, 2u>(std::tuple<String const&, HTTPUpload const&>&&, std::_Index_tuple<0u, 1u, 2u>) at c:\users\v-c-dev\.platformio\packages\toolchain-xtensa32\xtensa-esp32-elf\include\c++\5.2.0/functional:1074
(inlined by) void std::_Bind<std::_Mem_fn<void (AutoConnectUploadHandler::*)(String const&, HTTPUpload const&)> (AutoConnectOTA*, std::_Placeholder<1>, std::_Placeholder<2>)>::operator()<String const&, HTTPUpload
const&, void>(String const&, HTTPUpload const&) at c:\users\v-c-dev.platformio\packages\toolchain-xtensa32\xtensa-esp32-elf\include\c++\5.2.0/functional:1133 (inlined by) std::_Function_handler<void (String const&, HTTPUpload const&), std::_Bind<std::_Mem_fn<void (AutoConnectUploadHandler::)(String const&, HTTPUpload const&)> (AutoConnectOTA, std::_Placeholder<1>, std::_Placeholder<2>)> >::_M_invoke(std::_Any_data const&, String const&, HTTPUpload const&) at c:\users\v-c-dev.platformio\packages\toolchain-xtensa32\xtensa-esp32-elf\include\c++\5.2.0/functional:1871
(inlined by) void std::_Bind<std::_Mem_fn<void (AutoConnect::*)(String const&, HTTPUpload const&)> (AutoConnect*, std::_Placeholder<1>, std::_Placeholder<2>)>::__call<void, String const&, HTTPUpload const&, 0u, 1u, 2u>(std::tuple<String const&, HTTPUpload const&>&&, std::_Index_tuple<0u, 1u, 2u>) at c:\users\v-c-dev\.platformio\packages\toolchain-xtensa32\xtensa-esp32-elf\include\c++\5.2.0/functional:1074
(inlined by) void std::_Bind<std::_Mem_fn<void (AutoConnect::*)(String const&, HTTPUpload const&)> (AutoConnect*, std::_Placeholder<1>, std::_Placeholder<2>)>::operator()<String const&, HTTPUpload const&, void>(String const&, HTTPUpload const&) at c:\users\v-c-dev\.platformio\packages\toolchain-xtensa32\xtensa-esp32-elf\include\c++\5.2.0/functional:1133
(inlined by) std::_Function_handler<void (String const&, HTTPUpload const&), std::_Bind<std::_Mem_fn<void (AutoConnect::*)(String const&, HTTPUpload const&)> (AutoConnect*, std::_Placeholder<1>, std::_Placeholder<2>)> >::_M_invoke(std::_Any_data const&, String const&, HTTPUpload const&) at c:\users\v-c-dev\.platformio\packages\toolchain-xtensa32\xtensa-esp32-elf\include\c++\5.2.0/functional:1871
Rebooting... ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:2 load:0x3fff0018,len:4 load:0x3fff001c,len:1044 load:0x40078000,len:8896 load:0x40080400,len:5828 entry 0x400806ac
Any suggestions, Tom?
It turns out the problem was the memory available to the OTA. I was able to use a different partition map to get past this problem.
;# Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x5000, otadata, data, ota, 0xe000, 0x2000, app0, app, ota_0, 0x10000, 0x1E0000, app1, app, ota_1, 0x1F0000, 0x1E0000, spiffs, data, spiffs, 0x3D0000, 0x30000,
Documenting how I was able to debug this: 1) Set the options below in platformio.ini (Note the debug build, debug level, and the monitor_filter options to use the esp32_exceptions_decoder) 2) I needed to use a newer version of the espressif32 idf than the current stable version to be able to use the esp_exceptions_decoder
[env:esp32cam] platform = https://github.com/platformio/platform-espressif32.git ; espressif32 board = esp32cam board_build.partitions = esp32cam_partitions.csv framework = arduino ;board_build.partitions = customparts.csv upload_port = COM3 monitor_speed = 115200 ; upload_port = 192.168.0.109 monitor_filters = esp32_exception_decoder build_flags = -DCORE_DEBUG_LEVEL=5 -DBOARD_HAS_PSRAM=TRUE -mfix-esp32-psram-cache-issue lib_deps = AutoConnect build_type = debug
@v-c Thank you for reporting your valuable investigation results.
The partition definition as your solution increases OTA reserved area than the default. So, I think your diagnosis may identify the phenomenon induced by the mismatch of sketch size and reserved area for OTA.
One of the causes of this problem is that the object size of the AutoConnect library is too large, but the average user may not have many opportunities to care for it. Therefore, if they encounter this phenomenon once, it may be difficult to solve it by self-help. Should I document some guidance based on your results?
[EDIT] I added descriptions for the partition table to the documentation in v1.2.0. But its description lacks association with this phenomenon caused by insufficient OTA space.
@Hieromon -- It doesn't hurt to document this the debugging solution. When I initially ran into the problem, the abort had insufficient information for me to consider changing the partition size.
OTA updates from a web browser fails when using the AutoConnect library on a ESP32CAM board. The only diagnostic available is this printed in the serial monitor:
abort() was called at PC 0x4013fb01 on core 1
I believe this is the same as reported here:
https://github.com/espressif/arduino-esp32/issues/3937
Is there a way to specify which core of the ESP32 to run the part of the code that does the OTA Update?