1 /* Heap Task Tracking Example
2 
3    This example code is in the Public Domain (or CC0 licensed, at your option.)
4 
5    Unless required by applicable law or agreed to in writing, this
6    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
7    CONDITIONS OF ANY KIND, either express or implied.
8 */
9 #include <stdio.h>
10 #include "freertos/FreeRTOS.h"
11 #include "freertos/task.h"
12 #include "esp_heap_task_info.h"
13 #include "esp_log.h"
14 
15 
16 #define MAX_TASK_NUM 20                         // Max number of per tasks info that it can store
17 #define MAX_BLOCK_NUM 20                        // Max number of per block info that it can store
18 
19 static size_t s_prepopulated_num = 0;
20 static heap_task_totals_t s_totals_arr[MAX_TASK_NUM];
21 static heap_task_block_t s_block_arr[MAX_BLOCK_NUM];
22 
esp_dump_per_task_heap_info(void)23 static void esp_dump_per_task_heap_info(void)
24 {
25     heap_task_info_params_t heap_info = {0};
26     heap_info.caps[0] = MALLOC_CAP_8BIT;        // Gets heap with CAP_8BIT capabilities
27     heap_info.mask[0] = MALLOC_CAP_8BIT;
28     heap_info.caps[1] = MALLOC_CAP_32BIT;       // Gets heap info with CAP_32BIT capabilities
29     heap_info.mask[1] = MALLOC_CAP_32BIT;
30     heap_info.tasks = NULL;                     // Passing NULL captures heap info for all tasks
31     heap_info.num_tasks = 0;
32     heap_info.totals = s_totals_arr;            // Gets task wise allocation details
33     heap_info.num_totals = &s_prepopulated_num;
34     heap_info.max_totals = MAX_TASK_NUM;        // Maximum length of "s_totals_arr"
35     heap_info.blocks = s_block_arr;             // Gets block wise allocation details. For each block, gets owner task, address and size
36     heap_info.max_blocks = MAX_BLOCK_NUM;       // Maximum length of "s_block_arr"
37 
38     heap_caps_get_per_task_info(&heap_info);
39 
40     for (int i = 0 ; i < *heap_info.num_totals; i++) {
41         printf("Task: %s -> CAP_8BIT: %d CAP_32BIT: %d\n",
42                 heap_info.totals[i].task ? pcTaskGetTaskName(heap_info.totals[i].task) : "Pre-Scheduler allocs" ,
43                 heap_info.totals[i].size[0],    // Heap size with CAP_8BIT capabilities
44                 heap_info.totals[i].size[1]);   // Heap size with CAP32_BIT capabilities
45     }
46 
47     printf("\n\n");
48 }
49 
example_task(void * args)50 static void example_task(void *args)
51 {
52     uint32_t size = 0;
53     const char *TAG = "example_task";
54     while (1) {
55         /*
56          * Allocate random amount of memory for demonstration
57          */
58         size = (esp_random() % 1000);
59         void *ptr = malloc(size);
60         if (ptr == NULL) {
61             ESP_LOGE(TAG, "Could not allocate heap memory");
62             abort();
63         }
64         esp_dump_per_task_heap_info();
65         free(ptr);
66         vTaskDelay(pdMS_TO_TICKS(2000));
67     }
68 }
69 
70 
app_main(void)71 void app_main(void)
72 {
73     /*
74      *  Create example task to demonstrate heap_task_tracking
75      */
76     xTaskCreate(&example_task, "example_task", 3072, NULL, 5, NULL);
77 }
78