espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.66k stars 7.29k forks source link

xTaskCreateStatic how many memory can use in psram? (IDFGH-10622) #11856

Closed Shaco-Ma closed 1 year ago

Shaco-Ma commented 1 year ago

Answers checklist.

General issue report

idf4.4.4,ubuntu 20.04,idf.py build amd flash,create xTaskCreateStatic use psram,like this: StackType_t mqtt_stack_size = heap_caps_malloc(MQTT_TASK_STACK, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); memset(mqtt_stack_size, 0, MQTT_TASK_STACK); StaticTask_t mqtt_stack_def = malloc(sizeof(StaticTask_t)); memset(app_mqtt_stack_def, 0, sizeof(StaticTask_t)); xTaskCreateStatic(task, "task", MQTT_TASK_STACK, void, TASK_PRI, mqtt_stack_size, mqtt_stack_def); But, when I use uxTaskGetStackHighWaterMark(NULL) is task and ESP_LOGI("%d", uxTaskGetStackHighWaterMark(NULL)) to display the task heap,it's always return wrong,if I put MQTT_TASK_STACK to 1024<<10 in psram,uxTaskGetStackHighWaterMark return 44654,if I put MQTT_TASK_STACK to 2048<<10 in psram, uxTaskGetStackHighWaterMark return near 44000, how many psram can use in xTaskCreateStatic,and any wrong in uxTaskGetStackHighWaterMark return?

Shaco-Ma commented 1 year ago

sometime uxTaskGetStackHighWaterMark return 18352, so I did't know it's xTaskCreateStatic can't use so many memory in external psram,or uxTaskGetStackHighWaterMark return wrong

0xjakob commented 1 year ago

@Shaco-Ma Do you have reproducing code? When I try to re-create this issue, I get plausible values:

uxTaskGetStackHighWaterMark() returns the "stack high water mark", not the heap. The heap is shared between tasks.

Given that the task does the same thing, a different stack size should also lead to different stack high water marks.

Shaco-Ma commented 1 year ago

@0xjakob Hello,uxTaskGetStackHighWaterMark It's mean : task stack had can use stack? the code I use esp-eye,code like https://github.com/InfiniteYuan/esp32-camera-qr-recoginize

0xjakob commented 1 year ago

uxTaskGetStackHighWaterMark It's mean : task stack had can use stack?

uxTaskGetStackHighWaterMark() shows the minimal free amount of stack ever recorded on a task. Example: The task has 4KB stack; during some calculation before 2KB stack has been used, but now just 1KB stack is used. If you now call uxTaskGetStackHighWaterMark(), it will return 2KB (4KB stack - 2K used during the calculation before), even though the current free stack is larger.

0xjakob commented 1 year ago

@Shaco-Ma Since you are using IDF v4.4.4, there is a limitation of uxTaskGetStackHighWaterMark(): it only returns a 16-bit number, which makes it only useful for smaller stacks. Please try to use uxTaskGetStackHighWaterMark2() which uses an unsigned int as return type, which is 32 bit on ESP32. Alternatively, you could also switch to IDF v5.0 or later, which does not have this problem.

0xjakob commented 1 year ago

@Shaco-Ma Sorry, uxTaskGetStackHighWaterMark2() internally uses the 16-bit type, too. I guess the only way to solve this is to switch to IDF version 5.0 then, sorry.

Shaco-Ma commented 1 year ago

@0xjakob Oh,my god,I found the idf in prvTaskCheckFreeStackSpace,it's return uint16_t,thanks!