test_tasks_snapshot.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "sdkconfig.h"
  7. #if CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT
  8. #include <stdio.h>
  9. #include "freertos/FreeRTOS.h"
  10. #include "freertos/task.h"
  11. #include "freertos/task_snapshot.h"
  12. #include "esp_cpu.h"
  13. #include "unity.h"
  14. #include "sdkconfig.h"
  15. #define TEST_MAX_TASKS_NUM 32
  16. #define NUM_TASKS_PER_LIST 2
  17. #define TASK_PRIORITY (configMAX_PRIORITIES - 2)
  18. static void ready_task(void *arg)
  19. {
  20. while (1) {
  21. ;
  22. }
  23. }
  24. static void blocked_task(void *arg)
  25. {
  26. // Delay for portMAX_DELAY - 1 as not to go on the suspended list
  27. vTaskDelay(portMAX_DELAY - 1);
  28. }
  29. static void suspended_task(void *arg)
  30. {
  31. vTaskSuspend(NULL);
  32. }
  33. static void setup(TaskHandle_t *task_list, int *num_tasks_ret, UBaseType_t *old_priority_ret)
  34. {
  35. // Raise our priority so that we aren't preempted
  36. *old_priority_ret = uxTaskPriorityGet(NULL);
  37. vTaskPrioritySet(NULL, configMAX_PRIORITIES - 1);
  38. // Create tasks
  39. int num_tasks = 0;
  40. for (int i = 0; i < NUM_TASKS_PER_LIST; i++) {
  41. //Ready task
  42. xTaskCreate(ready_task, "ready", 1024, NULL, TASK_PRIORITY, &(task_list[num_tasks]));
  43. num_tasks++;
  44. //Blocked task
  45. xTaskCreate(blocked_task, "blkd", 1024, NULL, TASK_PRIORITY, &(task_list[num_tasks]));
  46. num_tasks++;
  47. //Suspended task
  48. xTaskCreate(suspended_task, "susp", 1024, NULL, TASK_PRIORITY, &(task_list[num_tasks]));
  49. num_tasks++;
  50. }
  51. *num_tasks_ret = num_tasks;
  52. // Short delay to allow tasks to spin up
  53. vTaskDelay(10);
  54. // Stop preemption on this core, and stall the other core
  55. taskDISABLE_INTERRUPTS();
  56. #if !CONFIG_FREERTOS_UNICORE
  57. esp_cpu_stall(!xPortGetCoreID());
  58. #endif
  59. }
  60. static void check_snapshots(TaskHandle_t *task_list, int num_tasks, TaskSnapshot_t *task_snapshots, UBaseType_t num_snapshots)
  61. {
  62. // Check task snapshots. Every created task should be found in the task snapshot
  63. for (int i = 0; i < num_tasks; i++) {
  64. bool found = false;
  65. for (int j = 0; j < num_snapshots; j++) {
  66. if (task_list[i] == (TaskHandle_t)task_snapshots[j].pxTCB) {
  67. found = true;
  68. break;
  69. }
  70. }
  71. TEST_ASSERT(found);
  72. }
  73. }
  74. static void teardown(TaskHandle_t *task_list, int num_tasks, UBaseType_t old_priority)
  75. {
  76. // Resume other cores and allow preemption
  77. #if !CONFIG_FREERTOS_UNICORE
  78. esp_cpu_unstall(!xPortGetCoreID());
  79. #endif
  80. taskENABLE_INTERRUPTS();
  81. for (int i = 0; i < num_tasks; i++) {
  82. vTaskDelete(task_list[i]);
  83. }
  84. // Restore priority
  85. vTaskPrioritySet(NULL, old_priority);
  86. // Short delay to allow tasks to clean up
  87. vTaskDelay(10);
  88. }
  89. TEST_CASE("Task snapshot: Get all", "[freertos]")
  90. {
  91. // Short delay to allow both cores to spin up
  92. vTaskDelay(10);
  93. TaskHandle_t task_list[TEST_MAX_TASKS_NUM];
  94. int num_tasks;
  95. UBaseType_t old_priority;
  96. setup(task_list, &num_tasks, &old_priority);
  97. // Get task snapshots using uxTaskGetSnapshotAll()
  98. TaskSnapshot_t task_snapshots[TEST_MAX_TASKS_NUM];
  99. UBaseType_t tcb_size;
  100. UBaseType_t num_snapshots;
  101. num_snapshots = uxTaskGetSnapshotAll(task_snapshots, TEST_MAX_TASKS_NUM, &tcb_size);
  102. TEST_ASSERT_LESS_OR_EQUAL(TEST_MAX_TASKS_NUM, num_snapshots);
  103. check_snapshots(task_list, num_tasks, task_snapshots, num_snapshots);
  104. teardown(task_list, num_tasks, old_priority);
  105. }
  106. TEST_CASE("Task snapshot: Iterate", "[freertos]")
  107. {
  108. // Short delay to allow both cores to spin up
  109. vTaskDelay(10);
  110. TaskHandle_t task_list[TEST_MAX_TASKS_NUM];
  111. int num_tasks;
  112. UBaseType_t old_priority;
  113. setup(task_list, &num_tasks, &old_priority);
  114. // Get task snapshots using pxTaskGetNext() and vTaskGetSnapshot()
  115. TaskSnapshot_t task_snapshots[TEST_MAX_TASKS_NUM];
  116. UBaseType_t num_snapshots = 0;
  117. TaskHandle_t cur_task_handle = pxTaskGetNext(NULL);
  118. while (cur_task_handle != NULL) {
  119. // Get the task's snapshot
  120. BaseType_t Result = vTaskGetSnapshot(cur_task_handle, &task_snapshots[num_snapshots]);
  121. TEST_ASSERT_EQUAL(pdTRUE, Result);
  122. num_snapshots++;
  123. cur_task_handle = pxTaskGetNext(cur_task_handle);
  124. }
  125. TEST_ASSERT_LESS_OR_EQUAL(TEST_MAX_TASKS_NUM, num_snapshots);
  126. check_snapshots(task_list, num_tasks, task_snapshots, num_snapshots);
  127. teardown(task_list, num_tasks, old_priority);
  128. }
  129. #endif // CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT