| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- /*
- Unit tests for FreeRTOS preemption
- */
- #include <esp_types.h>
- #include <stdio.h>
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/semphr.h"
- #include "freertos/queue.h"
- #include "unity.h"
- #include "soc/cpu.h"
- #include "hal/cpu_hal.h"
- #include "test_utils.h"
- #include "sdkconfig.h"
- static volatile bool trigger;
- static volatile bool flag;
- /* Task:
- - Waits for 'trigger' variable to be set
- - Reads the cycle count on this CPU
- - Pushes it into a queue supplied as a param
- - Busy-waits until the main task terminates it
- */
- static void task_send_to_queue(void *param)
- {
- QueueHandle_t queue = (QueueHandle_t) param;
- uint32_t ccount;
- while(!trigger) {}
- ccount = cpu_hal_get_cycle_count();
- flag = true;
- xQueueSendToBack(queue, &ccount, 0);
- /* This is to ensure that higher priority task
- won't wake anyhow, due to this task terminating.
- The task runs until terminated by the main task.
- */
- while(1) {}
- }
- TEST_CASE("Yield from lower priority task, same CPU", "[freertos]")
- {
- /* Do this 3 times, mostly for the benchmark value - the first
- run includes a cache miss so uses more cycles than it should. */
- for (int i = 0; i < 3; i++) {
- TaskHandle_t sender_task;
- QueueHandle_t queue = xQueueCreate(1, sizeof(uint32_t));
- flag = false;
- trigger = false;
- /* "yield" task sits on our CPU, lower priority to us */
- xTaskCreatePinnedToCore(task_send_to_queue, "YIELD", 2048, (void *)queue, UNITY_FREERTOS_PRIORITY - 1, &sender_task, UNITY_FREERTOS_CPU);
- vTaskDelay(1); /* make sure everything is set up */
- trigger = true;
- uint32_t yield_ccount, now_ccount, delta;
- TEST_ASSERT( xQueueReceive(queue, &yield_ccount, 100 / portTICK_PERIOD_MS) );
- now_ccount = cpu_hal_get_cycle_count();
- TEST_ASSERT( flag );
- delta = now_ccount - yield_ccount;
- printf("Yielding from lower priority task took %u cycles\n", delta);
- TEST_ASSERT(delta < 10000);
- vTaskDelete(sender_task);
- vQueueDelete(queue);
- }
- }
- #if (portNUM_PROCESSORS == 2) && !CONFIG_FREERTOS_TASK_FUNCTIONS_INTO_FLASH
- TEST_CASE("Yield from lower priority task, other CPU", "[freertos]")
- {
- uint32_t trigger_ccount, yield_ccount, now_ccount, delta;
- /* Do this 3 times, mostly for the benchmark value - the first
- run includes a cache miss so uses more cycles than it should. */
- for (int i = 0; i < 3; i++) {
- TaskHandle_t sender_task;
- QueueHandle_t queue = xQueueCreate(1, sizeof(uint32_t));
- trigger = false;
- flag = false;
- /* "send_to_queue" task sits on the other CPU, lower priority to us */
- xTaskCreatePinnedToCore(task_send_to_queue, "YIELD", 2048, (void *)queue, UNITY_FREERTOS_PRIORITY - 1,
- &sender_task, !UNITY_FREERTOS_CPU);
- vTaskDelay(2); /* make sure everything is set up */
- trigger = true;
- trigger_ccount = cpu_hal_get_cycle_count();
- // yield_ccount is not useful in this test as it's the other core's CCOUNT
- // so we use trigger_ccount instead
- TEST_ASSERT( xQueueReceive(queue, &yield_ccount, 100 / portTICK_PERIOD_MS) );
- now_ccount = cpu_hal_get_cycle_count();
- TEST_ASSERT( flag );
- delta = now_ccount - trigger_ccount;
- printf("Yielding from task on other core took %u cycles\n", delta);
- TEST_ASSERT(delta < 10000);
- vQueueDelete(queue);
- vTaskDelete(sender_task);
- }
- }
- #endif
|