test_task_tracking.c 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Unlicense OR CC0-1.0
  5. */
  6. #include "unity.h"
  7. #include "stdio.h"
  8. #include "freertos/FreeRTOS.h"
  9. #include "freertos/task.h"
  10. #include "esp_heap_caps.h"
  11. #include "esp_heap_task_info.h"
  12. // This test only apply when task tracking is enabled
  13. #if defined(CONFIG_HEAP_TASK_TRACKING)
  14. #define MAX_TASK_NUM 10 // Max number of per tasks info that it can store
  15. #define MAX_BLOCK_NUM 10 // Max number of per block info that it can store
  16. #define ALLOC_BYTES 36
  17. static void check_heap_task_info(TaskHandle_t taskHdl)
  18. {
  19. size_t num_totals = 0;
  20. heap_task_totals_t s_totals_arr[MAX_TASK_NUM];
  21. heap_task_block_t s_block_arr[MAX_BLOCK_NUM];
  22. heap_task_info_params_t heap_info = {0};
  23. heap_info.caps[0] = MALLOC_CAP_32BIT; // Gets heap info with CAP_32BIT capabilities
  24. heap_info.mask[0] = MALLOC_CAP_32BIT;
  25. heap_info.tasks = NULL; // Passing NULL captures heap info for all tasks
  26. heap_info.num_tasks = 0;
  27. heap_info.totals = s_totals_arr; // Gets task wise allocation details
  28. heap_info.num_totals = &num_totals;
  29. heap_info.max_totals = MAX_TASK_NUM; // Maximum length of "s_totals_arr"
  30. heap_info.blocks = s_block_arr; // Gets block wise allocation details. For each block, gets owner task, address and size
  31. heap_info.max_blocks = MAX_BLOCK_NUM; // Maximum length of "s_block_arr"
  32. heap_caps_get_per_task_info(&heap_info);
  33. bool task_found = false;
  34. for (int i = 0 ; i < *heap_info.num_totals; i++) {
  35. // the prescheduler allocs and free are stored as a
  36. // task with a handle set to 0, avoid calling pcTaskGetName
  37. // in that case.
  38. if (heap_info.totals[i].task != 0 && (uint32_t*)(heap_info.totals[i].task) == (uint32_t*)taskHdl) {
  39. task_found = true;
  40. // check the number of byte allocated according to the task tracking feature
  41. // and make sure it matches the expected value. The size returned by the
  42. // heap_caps_get_per_task_info includes the size of the block owner (4 bytes)
  43. TEST_ASSERT(heap_info.totals[i].size[0] == ALLOC_BYTES + 4);
  44. }
  45. }
  46. TEST_ASSERT_TRUE(task_found);
  47. }
  48. static void test_task(void *args)
  49. {
  50. void *ptr = heap_caps_malloc(ALLOC_BYTES, MALLOC_CAP_32BIT);
  51. if (ptr == NULL) {
  52. abort();
  53. }
  54. // unlock main too check task tracking feature
  55. xTaskNotifyGive((TaskHandle_t)args);
  56. // wait for main to delete this task
  57. ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
  58. }
  59. /* This test will create a task, wait for the task to allocate / free memory
  60. * so it is added to the task tracking info in the heap component and then
  61. * call heap_caps_get_per_task_info() and make sure a task with the name test_task
  62. * is in the list, and that the right ALLOC_BYTES are shown.
  63. *
  64. * Note: The memory allocated in the task is not freed for the sake of the test
  65. * so it is normal that memory leak will be reported by the test environment. It
  66. * shouldn't be more than the byte allocated by the task + associated metadata
  67. */
  68. TEST_CASE("heap task tracking reports created task", "[heap]")
  69. {
  70. TaskHandle_t test_task_handle;
  71. xTaskCreate(&test_task, "test_task", 3072, (void *)xTaskGetCurrentTaskHandle(), 5, &test_task_handle);
  72. // wait for task to allocate memory and give the hand back to the test
  73. ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
  74. // check that the task is referenced in the list of task
  75. // by the task tracking feature. Check the number of bytes
  76. // the task has allocated and make sure it is matching the
  77. // expected value.
  78. check_heap_task_info(test_task_handle);
  79. // delete the task.
  80. vTaskDelete(test_task_handle);
  81. }
  82. #endif // CONFIG_HEAP_TASK_TRACKING