For reference, this is the code behind the free command:
Code: Select all
/** 'free' command prints available heap memory */
static int free_mem(int argc, char **argv) {
printf("%d\n", esp_get_free_heap_size());
return 0;
}
For refernce, here is the code behind the tasks command
Code: Select all
// The code says that calling uxTaskGetSystemState directly
// rather than VTaskList() is preferred
static int tasks_info(int argc, char **argv) {
const size_t bytes_per_task = 45; /* see vTaskList description */
// config file has max name length = 24
// see component config -> FreeRTOS ->
// status is a single char. one byte
// current priority is at most a two digit number. two bytes.
// StackHighWaterMark is at most four digit numbers. four bytes
// task number is two digits. two bytes
// affinity is sign indicator and one digit. two bytes
// five tabs. five bytes.
// carriage return line feed. two bytes
// 24+1+2+4+2+2+5+2 = 42. Set to 45 just to give some spare
printf("heap size before malloc %d\n", esp_get_free_heap_size());
char *task_list_buffer = malloc(uxTaskGetNumberOfTasks() * bytes_per_task);
if (task_list_buffer == NULL) {
ESP_LOGE(TAG, "failed to allocate buffer for vTaskList output");
return 1;
}
printf("heap size after malloc %d\n", esp_get_free_heap_size());
fputs("Task Name\t\tStatus\tPrio\tHWM\tTask#", stdout);
#ifdef CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID
fputs("\tAffinity", stdout);
#endif
fputs("\n", stdout);
vTaskList(task_list_buffer);
fputs(task_list_buffer, stdout);
free(task_list_buffer);
printf("heap size after free %d\n", esp_get_free_heap_size());
return 0;
}
So what happens when I run this code?
Code: Select all
esp32> free
48776
esp32> tasks
heap size before malloc 48748
heap size after malloc 47960
Task Name Status Prio HWM Task# Affinity
main R 1 4284 5 0
IDLE1 R 0 1604 7 1
IDLE0 R 0 1452 6 0
heartbeat B 10 172 24 0
LedTask B 6 524 12 0
for brevity some of these lines of output are snipped.
esp_timer B 22 3468 1 0
wifi B 23 1220 17 0
ipc0 B 24 596 2 0
heap size after free 48748
esp32> free
48720
esp32>
So there are a few things which are confusing.
1. the difference between first free command and the equivalent in the tasks command differ by 28. .
2. The difference in size between before malloc and after malloc makes sense. The difference agrees with malloc size. In addition the heap size after free() returns to the initial size. This also makes sense. Lastly, the result of free does go down when memory is allocated.
3. Notice that the amount of memory reported at the end of the tasks code is 48748 and the subsquent free command is 48720. A difference of 28 bytes. I tweaked the code so that the tasks command literally did nothing and I still get a 28 bytes loss. Any idea what this loss would be from? I'm guessing it is the command history mechanism saving 28 bytes for each command. However, if that was the case, then simply issuing "free" repeatedly would show a difference of 28 between invocations so I am not sure about that being the reason for the loss of 28 bytes.
Lastly, if I understand correctly, the HWM column is the amount of memory left for each tasks stack. In addition, if any of these tasks have a HWM which is zero, then the task has blown its stack.
Any comments or tips is appreciated. Thanks in advance.