console example, tasks and free command

netskink
Posts: 1
Joined: Thu Dec 26, 2019 7:21 pm

console example, tasks and free command

Postby netskink » Thu Dec 26, 2019 8:04 pm

Hello, I'm working on an existing esp32 IDF based project. I don't have a JTAG debugger so I am trying to use the console example to debug why this project has intermittent behavior. With that said, I'm curious about the behavior I am seeing with the console example.


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;
}
I modified the tasks command to print the result of esp_get_free_head_size() result before it allocs the fputs buffer which is filled with the vTasksInfo() call, after the malloc and then after the free.

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.

Who is online

Users browsing this forum: Baidu [Spider], Google [Bot] and 85 guests