堆栈大小问题?
Posted: Sun Apr 28, 2024 9:52 am
ESP32 IDF 版本:v5.2.1
硬件开发板:ESP32-LyraTD-MSC , ESP32 v1.0
一个很简单的跟https服务器交互的简单应用,以官方的esp_http_client参考代码为样本进行简单改造:
app_main代码如下,创建task的堆栈为8192(8K),应该足够?
Task的入口函数如下:
主要调用函数talk_to_server的代码如下
如果MACRO(MAX_HTTP_OUTPUT_BUFFER)定义为1024,则会发生Stack overflow错误:
#define MAX_HTTP_OUTPUT_BUFFER 1024
***ERROR*** A stack overflow in task talk_to_server_task has been detected.
Backtrace: 0x40081796:0x3ffcdf00 0x40089091:0x3ffcdf20 0x40089f8a:0x3ffcdf40 0x4008b273:0x3ffcdfc0 0x4008a094:0x3ffcdfe0 0x4008a046:0x00000000 |<-CORRUPTED
0x40081796: panic_abort at C:/Users/hyuan/esp/esp-idf/components/esp_system/panic.c:472
0x40089091: esp_system_abort at C:/Users/hyuan/esp/esp-idf/components/esp_system/port/esp_system_chip.c:93
0x40089f8a: vApplicationStackOverflowHook at C:/Users/hyuan/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:553
0x4008b273: vTaskSwitchContext at C:/Users/hyuan/esp/esp-idf/components/freertos/FreeRTOS-Kernel/tasks.c:3630 (discriminator 7)
0x4008a094: _frxt_dispatch at C:/Users/hyuan/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/portasm.S:451
0x4008a046: _frxt_int_exit at C:/Users/hyuan/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/portasm.S:246
如果减小MAX_HTTP_OUTPUT_BUFFER定义为512,则应用正常跑完,也能获得服务器的数据
#define MAX_HTTP_OUTPUT_BUFFER 512
如果进一步增加MAX_HTTP_OUTPUT_BUFFER到2048,则体现为HEAP被破坏,跑飞crash.
============================================================================
#define MAX_HTTP_OUTPUT_BUFFER 512 时编译后的内存占用信息及HEAP信息如下:
Total sizes:
Used static DRAM: 33852 bytes ( 146884 remain, 18.7% used)
.data size: 15348 bytes
.bss size: 18504 bytes
Used static IRAM: 91606 bytes ( 39466 remain, 69.9% used)
.text size: 90579 bytes
.vectors size: 1027 bytes
Used Flash size : 847223 bytes
.text: 623595 bytes
.rodata: 223372 bytes
Total image size: 954177 bytes (.bin may be padded larger)
I (492) cpu_start: ESP-IDF: v5.2.1
I (497) cpu_start: Min chip rev: v0.0
I (502) cpu_start: Max chip rev: v3.99
I (507) cpu_start: Chip rev: v1.0
I (512) heap_init: Initializing. RAM available for dynamic allocation:
I (519) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (525) heap_init: At 3FFB8440 len 00027BC0 (158 KiB): DRAM
I (531) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (537) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (544) heap_init: At 400965D8 len 00009A28 (38 KiB): IRAM
I (552) spi_flash: detected chip: generic
I (555) spi_flash: flash io: dio
I (560) main_task: Started on CPU0
I (570) main_task: Calling app_main()
#define KIMI_MAX_HTTP_OUTPUT_BUFFER 1024 时编译后的内存占用信息及HEAP信息如下:
Total sizes:
Used static DRAM: 33852 bytes ( 146884 remain, 18.7% used)
.data size: 15348 bytes
.bss size: 18504 bytes
Used static IRAM: 91606 bytes ( 39466 remain, 69.9% used)
.text size: 90579 bytes
.vectors size: 1027 bytes
Used Flash size : 847179 bytes
.text: 623551 bytes
.rodata: 223372 bytes
Total image size: 954133 bytes (.bin may be padded larger)
I (492) cpu_start: ESP-IDF: v5.2.1
I (497) cpu_start: Min chip rev: v0.0
I (502) cpu_start: Max chip rev: v3.99
I (507) cpu_start: Chip rev: v1.0
I (512) heap_init: Initializing. RAM available for dynamic allocation:
I (519) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (525) heap_init: At 3FFB8440 len 00027BC0 (158 KiB): DRAM
I (531) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (537) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (544) heap_init: At 400965D8 len 00009A28 (38 KiB): IRAM
I (551) spi_flash: detected chip: generic
I (554) spi_flash: flash io: dio
I (559) main_task: Started on CPU0
I (569) main_task: Calling app_main()
============================================================================
应该是函数talk_to_server中定义的局部变量local_response_buffer大小会影响内存分布导致要么Stack overflow, 要么heap被破坏:
void talk_to_server(void)
{
char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER+1] = {0};
.....
}
请教一下这种情况应该如何调整配置?
硬件开发板:ESP32-LyraTD-MSC , ESP32 v1.0
一个很简单的跟https服务器交互的简单应用,以官方的esp_http_client参考代码为样本进行简单改造:
app_main代码如下,创建task的堆栈为8192(8K),应该足够?
Code: Select all
void app_main(void)
{
//Initialize NVS
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
if(ESP_OK!=connect_wifi()){
ESP_LOGE(TALKTAG,"Connect to Wifi is fail, aborting...");
} else{
ESP_LOGI(TALKTAG, "Connected to Wifi, starting the application...");
xTaskCreate(&app_task, "app_task", 8192, NULL, 5, NULL);
}
}
Code: Select all
static void app_task(void *pvparameters)
{
talk_to_server();
ESP_LOGI(TALKTAG, "Finish talking to server.");
for (int countdown = 10; countdown >= 0; countdown--) {
ESP_LOGI(TALKTAG, "%d...", countdown);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
vTaskDelete(NULL);
}
Code: Select all
void talk_to_server(void)
{
char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER+1] = {0};
esp_http_client_config_t config = {
.url = SERVER_WEB_URL,
.event_handler = _http_event_handler,
.crt_bundle_attach = esp_crt_bundle_attach,
.user_data = local_response_buffer,
//.method = HTTP_METHOD_POST,
};
esp_http_client_handle_t client = esp_http_client_init(&config);
...
//中间代码略
...
esp_http_client_cleanup(client);
}
#define MAX_HTTP_OUTPUT_BUFFER 1024
***ERROR*** A stack overflow in task talk_to_server_task has been detected.
Backtrace: 0x40081796:0x3ffcdf00 0x40089091:0x3ffcdf20 0x40089f8a:0x3ffcdf40 0x4008b273:0x3ffcdfc0 0x4008a094:0x3ffcdfe0 0x4008a046:0x00000000 |<-CORRUPTED
0x40081796: panic_abort at C:/Users/hyuan/esp/esp-idf/components/esp_system/panic.c:472
0x40089091: esp_system_abort at C:/Users/hyuan/esp/esp-idf/components/esp_system/port/esp_system_chip.c:93
0x40089f8a: vApplicationStackOverflowHook at C:/Users/hyuan/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:553
0x4008b273: vTaskSwitchContext at C:/Users/hyuan/esp/esp-idf/components/freertos/FreeRTOS-Kernel/tasks.c:3630 (discriminator 7)
0x4008a094: _frxt_dispatch at C:/Users/hyuan/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/portasm.S:451
0x4008a046: _frxt_int_exit at C:/Users/hyuan/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/portasm.S:246
如果减小MAX_HTTP_OUTPUT_BUFFER定义为512,则应用正常跑完,也能获得服务器的数据
#define MAX_HTTP_OUTPUT_BUFFER 512
如果进一步增加MAX_HTTP_OUTPUT_BUFFER到2048,则体现为HEAP被破坏,跑飞crash.
============================================================================
#define MAX_HTTP_OUTPUT_BUFFER 512 时编译后的内存占用信息及HEAP信息如下:
Total sizes:
Used static DRAM: 33852 bytes ( 146884 remain, 18.7% used)
.data size: 15348 bytes
.bss size: 18504 bytes
Used static IRAM: 91606 bytes ( 39466 remain, 69.9% used)
.text size: 90579 bytes
.vectors size: 1027 bytes
Used Flash size : 847223 bytes
.text: 623595 bytes
.rodata: 223372 bytes
Total image size: 954177 bytes (.bin may be padded larger)
I (492) cpu_start: ESP-IDF: v5.2.1
I (497) cpu_start: Min chip rev: v0.0
I (502) cpu_start: Max chip rev: v3.99
I (507) cpu_start: Chip rev: v1.0
I (512) heap_init: Initializing. RAM available for dynamic allocation:
I (519) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (525) heap_init: At 3FFB8440 len 00027BC0 (158 KiB): DRAM
I (531) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (537) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (544) heap_init: At 400965D8 len 00009A28 (38 KiB): IRAM
I (552) spi_flash: detected chip: generic
I (555) spi_flash: flash io: dio
I (560) main_task: Started on CPU0
I (570) main_task: Calling app_main()
#define KIMI_MAX_HTTP_OUTPUT_BUFFER 1024 时编译后的内存占用信息及HEAP信息如下:
Total sizes:
Used static DRAM: 33852 bytes ( 146884 remain, 18.7% used)
.data size: 15348 bytes
.bss size: 18504 bytes
Used static IRAM: 91606 bytes ( 39466 remain, 69.9% used)
.text size: 90579 bytes
.vectors size: 1027 bytes
Used Flash size : 847179 bytes
.text: 623551 bytes
.rodata: 223372 bytes
Total image size: 954133 bytes (.bin may be padded larger)
I (492) cpu_start: ESP-IDF: v5.2.1
I (497) cpu_start: Min chip rev: v0.0
I (502) cpu_start: Max chip rev: v3.99
I (507) cpu_start: Chip rev: v1.0
I (512) heap_init: Initializing. RAM available for dynamic allocation:
I (519) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (525) heap_init: At 3FFB8440 len 00027BC0 (158 KiB): DRAM
I (531) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (537) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (544) heap_init: At 400965D8 len 00009A28 (38 KiB): IRAM
I (551) spi_flash: detected chip: generic
I (554) spi_flash: flash io: dio
I (559) main_task: Started on CPU0
I (569) main_task: Calling app_main()
============================================================================
应该是函数talk_to_server中定义的局部变量local_response_buffer大小会影响内存分布导致要么Stack overflow, 要么heap被破坏:
void talk_to_server(void)
{
char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER+1] = {0};
.....
}
请教一下这种情况应该如何调整配置?