| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- /*
- Test of FreeRTOS task notifications. This test creates a sender and receiver
- task under different core permutations. For each permutation, the sender task
- will test the xTaskNotify(), xTaskNotifyGive(), xTaskNotifyFromISR(), and
- vTaskNotifyGiveFromISR(), whereas the receiver task will test
- xTaskNotifyWait() and ulTaskNotifyTake().
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include <freertos/semphr.h>
- #include "driver/timer.h"
- #ifndef CONFIG_FREERTOS_UNICORE
- #include "esp_ipc.h"
- #endif
- #include "unity.h"
- #include "test_utils.h"
- #ifdef CONFIG_IDF_TARGET_ESP32S2
- #define int_clr_timers int_clr
- #define update update.update
- #define int_st_timers int_st
- #endif
- #define NO_OF_NOTIFS 4
- #define NO_OF_TASKS 2 //Sender and receiver
- #define TIMER_DIVIDER 10000
- #define TIMER_COUNT 100
- #define MESSAGE 0xFF
- static uint32_t send_core_message = 0;
- static TaskHandle_t rec_task_handle;
- static bool isr_give = false;
- static SemaphoreHandle_t trigger_send_semphr;
- static SemaphoreHandle_t task_delete_semphr;
- //Test tracking vars
- static volatile uint32_t notifs_sent = 0;
- static volatile uint32_t notifs_rec = 0;
- static bool wrong_core = false;
- static void sender_task (void* arg){
- int curcore = xPortGetCoreID();
- //Test xTaskNotify
- xSemaphoreTake(trigger_send_semphr, portMAX_DELAY);
- notifs_sent++;
- xTaskNotify(rec_task_handle, (MESSAGE << curcore), eSetValueWithOverwrite);
- //Test xTaskNotifyGive
- xSemaphoreTake(trigger_send_semphr, portMAX_DELAY);
- notifs_sent++;
- xTaskNotifyGive(rec_task_handle);
- //Test xTaskNotifyFromISR
- xSemaphoreTake(trigger_send_semphr, portMAX_DELAY);
- isr_give = false;
- timer_start(TIMER_GROUP_0, curcore);
- //Test vTaskNotifyGiveFromISR
- xSemaphoreTake(trigger_send_semphr, portMAX_DELAY);
- isr_give = true;
- timer_start(TIMER_GROUP_0, curcore);
- //Delete Task and Semaphores
- xSemaphoreGive(task_delete_semphr);
- vTaskDelete(NULL);
- }
- static void receiver_task (void* arg){
- uint32_t notify_value;
- //Test xTaskNotifyWait from task
- xTaskNotifyWait(0, 0xFFFFFFFF, ¬ify_value, portMAX_DELAY);
- if(notify_value != send_core_message){
- wrong_core = true;
- }
- notifs_rec++;
- //Test ulTaskNotifyTake from task
- xSemaphoreGive(trigger_send_semphr);
- ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
- notifs_rec++;
- //Test xTaskNotifyWait from ISR
- xSemaphoreGive(trigger_send_semphr);
- xTaskNotifyWait(0, 0xFFFFFFFF, ¬ify_value, portMAX_DELAY);
- if(notify_value != send_core_message){
- wrong_core = true;
- }
- notifs_rec++;
- //Test ulTaskNotifyTake from ISR
- xSemaphoreGive(trigger_send_semphr);
- ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
- notifs_rec++;
- //Test complete, stop timer and delete task
- xSemaphoreGive(task_delete_semphr);
- vTaskDelete(NULL);
- }
- static void IRAM_ATTR sender_ISR (void *arg)
- {
- int curcore = xPortGetCoreID();
- timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, curcore);
- timer_group_set_counter_enable_in_isr(TIMER_GROUP_0, curcore, TIMER_PAUSE);
- //Re-enable alarm
- timer_group_enable_alarm_in_isr(TIMER_GROUP_0, curcore);
- if(isr_give){ //Test vTaskNotifyGiveFromISR() on same core
- notifs_sent++;
- vTaskNotifyGiveFromISR(rec_task_handle, NULL);
- }
- else { //Test xTaskNotifyFromISR()
- notifs_sent++;
- xTaskNotifyFromISR(rec_task_handle, (MESSAGE << curcore), eSetValueWithOverwrite, NULL);
- }
- portYIELD_FROM_ISR();
- return;
- }
- static void timerg0_init(void *isr_handle)
- {
- int timer_group = TIMER_GROUP_0;
- int timer_idx = xPortGetCoreID();
- timer_config_t config;
- config.alarm_en = 1;
- config.auto_reload = 1;
- config.counter_dir = TIMER_COUNT_UP;
- config.divider = TIMER_DIVIDER;
- config.intr_type = TIMER_INTR_LEVEL;
- config.counter_en = TIMER_PAUSE;
- /*Configure timer*/
- timer_init(timer_group, timer_idx, &config);
- /*Stop timer counter*/
- timer_pause(timer_group, timer_idx);
- /*Load counter value */
- timer_set_counter_value(timer_group, timer_idx, 0x00000000ULL);
- /*Set alarm value*/
- timer_set_alarm_value(timer_group, timer_idx, TIMER_COUNT);
- /*Enable timer interrupt*/
- timer_enable_intr(timer_group, timer_idx);
- //Auto Reload
- timer_set_auto_reload(timer_group, timer_idx, 1);
- /*Set ISR handler*/
- timer_isr_register(timer_group, timer_idx, sender_ISR, NULL, ESP_INTR_FLAG_IRAM, (intr_handle_t *)isr_handle);
- }
- static void timerg0_deinit(void* isr_handle)
- {
- int timer_group = TIMER_GROUP_0;
- int timer_idx = xPortGetCoreID();
- intr_handle_t handle = *((intr_handle_t *) isr_handle);
- //Pause timer then free registered ISR
- timer_pause(timer_group, timer_idx);
- esp_intr_free(handle);
- }
- TEST_CASE("Test Task_Notify", "[freertos]")
- {
- //Initialize and pause timers. Used to trigger ISR
- intr_handle_t isr_handle_0 = NULL;
- timerg0_init(&isr_handle_0); //Core 0 timer
- #ifndef CONFIG_FREERTOS_UNICORE
- intr_handle_t isr_handle_1 = NULL;
- esp_ipc_call(1, timerg0_init, &isr_handle_1); //Core 1 timer
- #endif
- trigger_send_semphr = xSemaphoreCreateBinary();
- task_delete_semphr = xQueueCreateCountingSemaphore(NO_OF_TASKS, 0);
- for(int i = 0; i < portNUM_PROCESSORS; i++){ //Sending Core
- for(int j = 0; j < portNUM_PROCESSORS; j++){ //Receiving Core
- //Reset Values
- notifs_sent = 0;
- notifs_rec = 0;
- wrong_core = false;
- send_core_message = (0xFF << i); //0xFF if core 0, 0xFF0 if core 1
- xTaskCreatePinnedToCore(receiver_task, "rec task", 1000, NULL, UNITY_FREERTOS_PRIORITY + 2, &rec_task_handle, j);
- xTaskCreatePinnedToCore(sender_task, "send task", 1000, NULL, UNITY_FREERTOS_PRIORITY + 1, NULL, i);
- vTaskDelay(5); //Wait for task creation to complete
- xSemaphoreGive(trigger_send_semphr); //Trigger sender task
- for(int k = 0; k < NO_OF_TASKS; k++){ //Wait for sender and receiver task deletion
- TEST_ASSERT( xSemaphoreTake(task_delete_semphr, 1000 / portTICK_PERIOD_MS) );
- }
- vTaskDelay(5); //Give time tasks to delete
- TEST_ASSERT(notifs_sent == NO_OF_NOTIFS);
- TEST_ASSERT(notifs_rec == NO_OF_NOTIFS);
- TEST_ASSERT(wrong_core == false);
- }
- }
- //Delete Semaphroes and timer ISRs
- vSemaphoreDelete(trigger_send_semphr);
- vSemaphoreDelete(task_delete_semphr);
- timerg0_deinit(&isr_handle_0);
- isr_handle_0 = NULL;
- #ifndef CONFIG_FREERTOS_UNICORE
- esp_ipc_call(1, timerg0_deinit, &isr_handle_1);
- isr_handle_1 = NULL;
- #endif
- }
|