diff --git a/components/cxx/test/test_cxx.cpp b/components/cxx/test/test_cxx.cpp index 6a27bb0ab0..722c5754d0 100644 --- a/components/cxx/test/test_cxx.cpp +++ b/components/cxx/test/test_cxx.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -324,5 +324,5 @@ template __attribute__((unused)) static void test_binary_operators() } //Add more types here. If any flags cannot pass the build, use FLAG_ATTR in esp_attr.h -#include "driver/timer.h" +#include "driver/timer_types_legacy.h" template void test_binary_operators(); diff --git a/components/esp_event/test/test_default_loop.c b/components/esp_event/test/test_default_loop.c index 9aa34cc23a..1d0ef2d9f8 100644 --- a/components/esp_event/test/test_default_loop.c +++ b/components/esp_event/test/test_default_loop.c @@ -8,8 +8,6 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" -#include "esp_private/periph_ctrl.h" -#include "driver/timer.h" #include "esp_event.h" #include "esp_event_private.h" diff --git a/components/esp_event/test/test_event.c b/components/esp_event/test/test_event.c index 6f13af1787..3faf64f1bc 100644 --- a/components/esp_event/test/test_event.c +++ b/components/esp_event/test/test_event.c @@ -7,8 +7,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" -#include "esp_private/periph_ctrl.h" -#include "driver/timer.h" +#include "driver/gptimer.h" #include "esp_event.h" #include "esp_event_private.h" @@ -302,10 +301,6 @@ static void test_teardown(void) TEST_ESP_OK(esp_event_loop_delete_default()); } -#define TIMER_DIVIDER 16 // Hardware timer clock divider -#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds -#define TIMER_INTERVAL0_SEC (2.0) // sample test interval for the first timer - TEST_CASE("can create and delete event loops", "[event]") { /* this test aims to verify that: @@ -1973,63 +1968,51 @@ static void test_handler_post_from_isr(void* event_handler_arg, esp_event_base_t xSemaphoreGive(*sem); } -void IRAM_ATTR test_event_on_timer_alarm(void* para) +bool test_event_on_timer_alarm(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx) { - /* Retrieve the interrupt status and the counter value - from the timer that reported the interrupt */ - uint64_t timer_counter_value = - timer_group_get_counter_value_in_isr(TIMER_GROUP_0, TIMER_0); - timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0); - timer_counter_value += (uint64_t) (TIMER_INTERVAL0_SEC * TIMER_SCALE); - timer_group_set_alarm_value_in_isr(TIMER_GROUP_0, TIMER_0, timer_counter_value); - - int data = (int) para; + int data = (int)user_ctx; + gptimer_stop(timer); // Posting events with data more than 4 bytes should fail. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_isr_post(s_test_base1, TEST_EVENT_BASE1_EV1, &data, 5, NULL)); // This should succeedd, as data is int-sized. The handler for the event checks that the passed event data // is correct. BaseType_t task_unblocked; TEST_ESP_OK(esp_event_isr_post(s_test_base1, TEST_EVENT_BASE1_EV1, &data, sizeof(data), &task_unblocked)); - if (task_unblocked == pdTRUE) { - portYIELD_FROM_ISR(); - } + return task_unblocked == pdTRUE; } TEST_CASE("can post events from interrupt handler", "[event]") { SemaphoreHandle_t sem = xSemaphoreCreateBinary(); - + gptimer_handle_t gptimer = NULL; /* Select and initialize basic parameters of the timer */ - timer_config_t config = { - .divider = TIMER_DIVIDER, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_PAUSE, - .alarm_en = TIMER_ALARM_EN, - .intr_type = TIMER_INTR_LEVEL, - .auto_reload = false, + gptimer_config_t config = { + .clk_src = GPTIMER_CLK_SRC_APB, + .direction = GPTIMER_COUNT_UP, + .resolution_hz = 1000000, // 1MHz, 1 tick = 1us }; - timer_init(TIMER_GROUP_0, TIMER_0, &config); + TEST_ESP_OK(gptimer_new_timer(&config, &gptimer)); - /* Timer's counter will initially start from value below. - Also, if auto_reload is set, this value will be automatically reload on alarm */ - timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0x00000000ULL); - - /* Configure the alarm value and the interrupt on alarm. */ - timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, TIMER_INTERVAL0_SEC * TIMER_SCALE); - timer_enable_intr(TIMER_GROUP_0, TIMER_0); - timer_isr_register(TIMER_GROUP_0, TIMER_0, test_event_on_timer_alarm, - (void *) sem, ESP_INTR_FLAG_IRAM, NULL); - - timer_start(TIMER_GROUP_0, TIMER_0); + gptimer_alarm_config_t alarm_config = { + .reload_count = 0, + .alarm_count = 500000, + }; + gptimer_event_callbacks_t cbs = { + .on_alarm = test_event_on_timer_alarm + }; + TEST_ESP_OK(gptimer_register_event_callbacks(gptimer, &cbs, sem)); + TEST_ESP_OK(gptimer_set_alarm_action(gptimer, &alarm_config)); + TEST_ESP_OK(gptimer_start(gptimer)); TEST_SETUP(); TEST_ESP_OK(esp_event_handler_register(s_test_base1, TEST_EVENT_BASE1_EV1, - test_handler_post_from_isr, &sem)); + test_handler_post_from_isr, &sem)); xSemaphoreTake(sem, portMAX_DELAY); TEST_TEARDOWN(); + TEST_ESP_OK(gptimer_del_timer(gptimer)); } #endif // CONFIG_ESP_EVENT_POST_FROM_ISR diff --git a/components/esp_hw_support/test/test_intr_alloc.c b/components/esp_hw_support/test/test_intr_alloc.c index f5b41a9bbf..b7ca5e10d3 100644 --- a/components/esp_hw_support/test/test_intr_alloc.c +++ b/components/esp_hw_support/test/test_intr_alloc.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,7 @@ */ #include +#include "sdkconfig.h" #include "esp_types.h" #include "esp_rom_sys.h" #include "freertos/FreeRTOS.h" @@ -16,84 +17,52 @@ #include "freertos/queue.h" #include "unity.h" #include "esp_intr_alloc.h" -#include "esp_private/periph_ctrl.h" -#include "driver/timer.h" +#include "driver/gptimer.h" #include "soc/soc_caps.h" #include "soc/spi_periph.h" #include "hal/spi_ll.h" -#include "sdkconfig.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/gptimer.h" -#define TIMER_DIVIDER (16) /*!< Hardware timer clock divider */ -#define TIMER_SCALE (APB_CLK_FREQ / TIMER_DIVIDER) /*!< used to calculate counter value */ -#define TIMER_INTERVAL0_SEC (3) /*!< test interval for timer 0 */ -#define TIMER_INTERVAL1_SEC (5) /*!< test interval for timer 1 */ - -static void my_timer_init(int timer_group, int timer_idx, uint64_t alarm_value) +static bool on_timer_alarm(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx) { - timer_config_t config = { - .alarm_en = 1, - .auto_reload = 1, - .counter_dir = TIMER_COUNT_UP, - .divider = TIMER_DIVIDER, - }; - /*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, 0); - /*Set alarm value*/ - timer_set_alarm_value(timer_group, timer_idx, alarm_value); - /*Enable timer interrupt*/ - timer_enable_intr(timer_group, timer_idx); -} - -static volatile int count[SOC_TIMER_GROUP_TOTAL_TIMERS] = {0}; - -static void timer_isr(void *arg) -{ - int timer_idx = (int)arg; - int group_id = timer_idx / SOC_TIMER_GROUP_TIMERS_PER_GROUP; - int timer_id = timer_idx % SOC_TIMER_GROUP_TIMERS_PER_GROUP; - count[timer_idx]++; - - timer_group_clr_intr_status_in_isr(group_id, timer_id); - timer_group_enable_alarm_in_isr(group_id, timer_id); + volatile int *count = (volatile int *)user_ctx; + (*count)++; + return false; } static void timer_test(int flags) { - timer_isr_handle_t inth[SOC_TIMER_GROUP_TOTAL_TIMERS]; - for (int i = 0; i < SOC_TIMER_GROUPS; i++) { - for (int j = 0; j < SOC_TIMER_GROUP_TIMERS_PER_GROUP; j++) { - my_timer_init(i, j, 100000 + 10000 * (i * SOC_TIMER_GROUP_TIMERS_PER_GROUP + j + 1)); - } - } - timer_isr_register(0, 0, timer_isr, (void *)0, flags | ESP_INTR_FLAG_INTRDISABLED, &inth[0]); - printf("Interrupts allocated: %d (dis)\r\n", esp_intr_get_intno(inth[0])); + static int count[SOC_TIMER_GROUP_TOTAL_TIMERS] = {0}; + gptimer_handle_t gptimers[SOC_TIMER_GROUP_TOTAL_TIMERS]; + intr_handle_t inth[SOC_TIMER_GROUP_TOTAL_TIMERS]; - for (int j = 1; j < SOC_TIMER_GROUP_TIMERS_PER_GROUP; j++) { - timer_isr_register(0, j, timer_isr, (void *)1, flags, &inth[j]); - printf("Interrupts allocated: %d\r\n", esp_intr_get_intno(inth[j])); - } - for (int i = 1; i < SOC_TIMER_GROUPS; i++) { - for (int j = 0; j < SOC_TIMER_GROUP_TIMERS_PER_GROUP; j++) { - timer_isr_register(i, j, timer_isr, (void *)(i * SOC_TIMER_GROUP_TIMERS_PER_GROUP + j), flags, &inth[i * SOC_TIMER_GROUP_TIMERS_PER_GROUP + j]); - printf("Interrupts allocated: %d\r\n", esp_intr_get_intno(inth[i * SOC_TIMER_GROUP_TIMERS_PER_GROUP + j])); - } - } - for (int i = 0; i < SOC_TIMER_GROUPS; i++) { - for (int j = 0; j < SOC_TIMER_GROUP_TIMERS_PER_GROUP; j++) { - timer_start(i, j); - } - } - - printf("Timer values on start:"); + gptimer_config_t config = { + .clk_src = GPTIMER_CLK_SRC_APB, + .direction = GPTIMER_COUNT_UP, + .resolution_hz = 1000000, + .flags.intr_shared = (flags & ESP_INTR_FLAG_SHARED) == ESP_INTR_FLAG_SHARED, + }; for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { - count[i] = 0; - printf(" %d", count[i]); + TEST_ESP_OK(gptimer_new_timer(&config, &gptimers[i])); + } + gptimer_alarm_config_t alarm_config = { + .reload_count = 0, + .alarm_count = 100000, + .flags.auto_reload_on_alarm = true, + }; + gptimer_event_callbacks_t cbs = { + .on_alarm = on_timer_alarm, + }; + + for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { + TEST_ESP_OK(gptimer_register_event_callbacks(gptimers[i], &cbs, &count[i])); + alarm_config.alarm_count += 10000 * i; + TEST_ESP_OK(gptimer_set_alarm_action(gptimers[i], &alarm_config)); + TEST_ESP_OK(gptimer_start(gptimers[i])); + TEST_ESP_OK(gptimer_get_intr_handle(gptimers[i], &inth[i])); + printf("Interrupts allocated: %d\r\n", esp_intr_get_intno(inth[i])); } - printf("\r\n"); vTaskDelay(1000 / portTICK_PERIOD_MS); printf("Timer values after 1 sec:"); @@ -102,19 +71,13 @@ static void timer_test(int flags) } printf("\r\n"); - TEST_ASSERT(count[0] == 0); - for (int i = 1; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { - TEST_ASSERT(count[i] != 0); + for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { + TEST_ASSERT_NOT_EQUAL(0, count[i]); } - printf("Disabling half of timers' interrupt...\r\n"); - for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS / 2; i++) { - esp_intr_disable(inth[i]); - } - for (int i = SOC_TIMER_GROUP_TOTAL_TIMERS / 2; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { - esp_intr_enable(inth[i]); - } + printf("Disabling timers' interrupt...\r\n"); for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { + esp_intr_disable(inth[i]); count[i] = 0; } @@ -124,38 +87,13 @@ static void timer_test(int flags) printf(" %d", count[i]); } printf("\r\n"); - for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS / 2; i++) { - TEST_ASSERT(count[i] == 0); - } - for (int i = SOC_TIMER_GROUP_TOTAL_TIMERS / 2; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { - TEST_ASSERT(count[i] != 0); + for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { + TEST_ASSERT_EQUAL(0, count[i]); } - printf("Disabling another half...\r\n"); - for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS / 2; i++) { - esp_intr_enable(inth[i]); - } - for (int i = SOC_TIMER_GROUP_TOTAL_TIMERS / 2; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { - esp_intr_disable(inth[i]); - } - for (int x = 0; x < SOC_TIMER_GROUP_TOTAL_TIMERS; x++) { - count[x] = 0; - } - vTaskDelay(1000 / portTICK_PERIOD_MS); - printf("Timer values after 1 sec:"); for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { - printf(" %d", count[i]); - } - printf("\r\n"); - for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS / 2; i++) { - TEST_ASSERT(count[i] != 0); - } - for (int i = SOC_TIMER_GROUP_TOTAL_TIMERS / 2; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { - TEST_ASSERT(count[i] == 0); - } - printf("Done.\n"); - for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { - esp_intr_free(inth[i]); + TEST_ESP_OK(gptimer_stop(gptimers[i])); + TEST_ESP_OK(gptimer_del_timer(gptimers[i])); } } diff --git a/components/esp_pm/test/test_pm.c b/components/esp_pm/test/test_pm.c index 2d7b58d57a..bf055fc4dd 100644 --- a/components/esp_pm/test/test_pm.c +++ b/components/esp_pm/test/test_pm.c @@ -10,9 +10,10 @@ #include "freertos/task.h" #include "freertos/semphr.h" #include "esp_log.h" -#include "driver/timer.h" +#include "driver/gptimer.h" #include "driver/rtc_io.h" #include "soc/rtc.h" +#include "esp_private/gptimer.h" #include "soc/rtc_periph.h" #include "esp_rom_sys.h" #include "esp_private/esp_clk.h" @@ -53,7 +54,8 @@ static void switch_freq(int mhz) }; ESP_ERROR_CHECK( esp_pm_configure(&pm_config) ); printf("Waiting for frequency to be set to %d MHz...\n", mhz); - while (esp_clk_cpu_freq() / MHZ != mhz) { + while (esp_clk_cpu_freq() / MHZ != mhz) + { vTaskDelay(pdMS_TO_TICKS(200)); printf("Frequency is %d MHz\n", esp_clk_cpu_freq() / MHZ); } @@ -70,7 +72,7 @@ TEST_CASE("Can switch frequency using esp_pm_configure", "[pm]") { int orig_freq_mhz = esp_clk_cpu_freq() / MHZ; - for (int i = 0; i < sizeof(test_freqs)/sizeof(int); i++) { + for (int i = 0; i < sizeof(test_freqs) / sizeof(int); i++) { switch_freq(test_freqs[i]); } @@ -125,16 +127,23 @@ static void light_sleep_disable(void) TEST_CASE("Automatic light occurs when tasks are suspended", "[pm]") { - /* To figure out if light sleep takes place, use Timer Group timer. + gptimer_handle_t gptimer = NULL; + /* To figure out if light sleep takes place, use GPTimer * It will stop working while in light sleep. */ - timer_config_t config = { - .counter_dir = TIMER_COUNT_UP, - .divider = 80 /* 1 us per tick */ + gptimer_config_t config = { + .clk_src = GPTIMER_CLK_SRC_APB, + .direction = GPTIMER_COUNT_UP, + .resolution_hz = 1000000, /* 1 us per tick */ }; - timer_init(TIMER_GROUP_0, TIMER_0, &config); - timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0); - timer_start(TIMER_GROUP_0, TIMER_0); + TEST_ESP_OK(gptimer_new_timer(&config, &gptimer)); + TEST_ESP_OK(gptimer_start(gptimer)); + // if GPTimer is clocked from APB, when PM is enabled, the driver will acquire the PM lock + // causing the auto light sleep doesn't take effect + // so we manually release the lock here + esp_pm_lock_handle_t gptimer_pm_lock; + TEST_ESP_OK(gptimer_get_pm_lock(gptimer, &gptimer_pm_lock)); + TEST_ESP_OK(esp_pm_lock_release(gptimer_pm_lock)); light_sleep_enable(); @@ -147,11 +156,10 @@ TEST_CASE("Automatic light occurs when tasks are suspended", "[pm]") /* The following delay should cause light sleep to start */ uint64_t count_start; - timer_get_counter_value(TIMER_GROUP_0, TIMER_0, &count_start); - vTaskDelay(ticks_to_delay); uint64_t count_end; - timer_get_counter_value(TIMER_GROUP_0, TIMER_0, &count_end); - + TEST_ESP_OK(gptimer_get_raw_count(gptimer, &count_start)); + vTaskDelay(ticks_to_delay); + TEST_ESP_OK(gptimer_get_raw_count(gptimer, &count_end)); int timer_diff_us = (int) (count_end - count_start); const int us_per_tick = 1 * portTICK_PERIOD_MS * 1000; @@ -161,6 +169,9 @@ TEST_CASE("Automatic light occurs when tasks are suspended", "[pm]") } light_sleep_disable(); + TEST_ESP_OK(esp_pm_lock_acquire(gptimer_pm_lock)); + TEST_ESP_OK(gptimer_stop(gptimer)); + TEST_ESP_OK(gptimer_del_timer(gptimer)); } #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3) @@ -185,22 +196,22 @@ TEST_CASE("Can wake up from automatic light sleep by GPIO", "[pm][ignore]") rtc_gpio_set_direction(ext1_wakeup_gpio, RTC_GPIO_MODE_INPUT_OUTPUT); rtc_gpio_set_level(ext1_wakeup_gpio, 0); - /* Enable wakeup */ + /* Enable wakeup */ TEST_ESP_OK(esp_sleep_enable_ext1_wakeup(1ULL << ext1_wakeup_gpio, ESP_EXT1_WAKEUP_ANY_HIGH)); /* To simplify test environment, we'll use a ULP program to set GPIO high */ ulp_insn_t ulp_code[] = { - I_DELAY(65535), /* about 8ms, given 8MHz ULP clock */ - I_WR_REG_BIT(RTC_CNTL_HOLD_FORCE_REG, RTC_CNTL_PDAC1_HOLD_FORCE_S, 0), - I_WR_REG_BIT(RTC_GPIO_OUT_REG, ext_rtc_io + RTC_GPIO_OUT_DATA_S, 1), - I_DELAY(1000), - I_WR_REG_BIT(RTC_GPIO_OUT_REG, ext_rtc_io + RTC_GPIO_OUT_DATA_S, 0), - I_WR_REG_BIT(RTC_CNTL_HOLD_FORCE_REG, RTC_CNTL_PDAC1_HOLD_FORCE_S, 1), - I_END(), - I_HALT() + I_DELAY(65535), /* about 8ms, given 8MHz ULP clock */ + I_WR_REG_BIT(RTC_CNTL_HOLD_FORCE_REG, RTC_CNTL_PDAC1_HOLD_FORCE_S, 0), + I_WR_REG_BIT(RTC_GPIO_OUT_REG, ext_rtc_io + RTC_GPIO_OUT_DATA_S, 1), + I_DELAY(1000), + I_WR_REG_BIT(RTC_GPIO_OUT_REG, ext_rtc_io + RTC_GPIO_OUT_DATA_S, 0), + I_WR_REG_BIT(RTC_CNTL_HOLD_FORCE_REG, RTC_CNTL_PDAC1_HOLD_FORCE_S, 1), + I_END(), + I_HALT() }; TEST_ESP_OK(ulp_set_wakeup_period(0, 1000 /* us */)); - size_t size = sizeof(ulp_code)/sizeof(ulp_insn_t); + size_t size = sizeof(ulp_code) / sizeof(ulp_insn_t); TEST_ESP_OK(ulp_process_macros_and_load(0, ulp_code, &size)); light_sleep_enable(); @@ -249,9 +260,9 @@ typedef struct { SemaphoreHandle_t done; } delay_test_arg_t; -static void test_delay_task(void* p) +static void test_delay_task(void *p) { - delay_test_arg_t* arg = (delay_test_arg_t*) p; + delay_test_arg_t *arg = (delay_test_arg_t *) p; vTaskDelay(1); uint64_t start = esp_clk_rtc_time(); @@ -266,9 +277,11 @@ static void test_delay_task(void* p) TEST_CASE("vTaskDelay duration is correct with light sleep enabled", "[pm]") { light_sleep_enable(); + SemaphoreHandle_t done_sem = xSemaphoreCreateBinary(); + TEST_ASSERT_NOT_NULL(done_sem); delay_test_arg_t args = { - .done = xSemaphoreCreateBinary() + .done = done_sem, }; const int delays[] = { 10, 20, 50, 100, 150, 200, 250 }; @@ -278,19 +291,19 @@ TEST_CASE("vTaskDelay duration is correct with light sleep enabled", "[pm]") int delay_ms = delays[i]; args.delay_us = delay_ms * 1000; - xTaskCreatePinnedToCore(test_delay_task, "", 2048, (void*) &args, 3, NULL, 0); - TEST_ASSERT( xSemaphoreTake(args.done, delay_ms * 10 / portTICK_PERIOD_MS) ); + xTaskCreatePinnedToCore(test_delay_task, "", 2048, (void *) &args, 3, NULL, 0); + TEST_ASSERT( xSemaphoreTake(done_sem, delay_ms * 10 / portTICK_PERIOD_MS) ); printf("CPU0: %d %d\n", args.delay_us, args.result); TEST_ASSERT_INT32_WITHIN(1000 * portTICK_PERIOD_MS * 2, args.delay_us, args.result); #if portNUM_PROCESSORS == 2 - xTaskCreatePinnedToCore(test_delay_task, "", 2048, (void*) &args, 3, NULL, 1); - TEST_ASSERT( xSemaphoreTake(args.done, delay_ms * 10 / portTICK_PERIOD_MS) ); + xTaskCreatePinnedToCore(test_delay_task, "", 2048, (void *) &args, 3, NULL, 1); + TEST_ASSERT( xSemaphoreTake(done_sem, delay_ms * 10 / portTICK_PERIOD_MS) ); printf("CPU1: %d %d\n", args.delay_us, args.result); TEST_ASSERT_INT32_WITHIN(1000 * portTICK_PERIOD_MS * 2, args.delay_us, args.result); #endif } - vSemaphoreDelete(args.done); + vSemaphoreDelete(done_sem); light_sleep_disable(); } @@ -312,16 +325,15 @@ TEST_CASE("esp_timer produces correct delays with light sleep", "[pm]") SemaphoreHandle_t done; } test_args_t; - void timer_func(void* arg) - { - test_args_t* p_args = (test_args_t*) arg; + void timer_func(void *arg) { + test_args_t *p_args = (test_args_t *) arg; int64_t t_end = esp_clk_rtc_time(); int32_t ms_diff = (t_end - p_args->t_start) / 1000; printf("timer #%d %dms\n", p_args->cur_interval, ms_diff); p_args->intervals[p_args->cur_interval++] = ms_diff; // Deliberately make timer handler run longer. // We check that this doesn't affect the result. - esp_rom_delay_us(10*1000); + esp_rom_delay_us(10 * 1000); if (p_args->cur_interval == NUM_INTERVALS) { printf("done\n"); TEST_ESP_OK(esp_timer_stop(p_args->timer)); @@ -335,9 +347,9 @@ TEST_CASE("esp_timer produces correct delays with light sleep", "[pm]") test_args_t args = {0}; esp_timer_handle_t timer1; esp_timer_create_args_t create_args = { - .callback = &timer_func, - .arg = &args, - .name = "timer1", + .callback = timer_func, + .arg = &args, + .name = "timer1", }; TEST_ESP_OK(esp_timer_create(&create_args, &timer1)); @@ -365,7 +377,7 @@ TEST_CASE("esp_timer produces correct delays with light sleep", "[pm]") static void timer_cb1(void *arg) { - ++*((int*) arg); + ++*((int *) arg); } TEST_CASE("esp_timer with SKIP_UNHANDLED_EVENTS does not wake up CPU from sleep", "[pm]") @@ -374,10 +386,10 @@ TEST_CASE("esp_timer with SKIP_UNHANDLED_EVENTS does not wake up CPU from sleep" int timer_interval_ms = 50; const esp_timer_create_args_t timer_args = { - .name = "timer_cb1", - .arg = &count_calls, - .callback = &timer_cb1, - .skip_unhandled_events = true, + .name = "timer_cb1", + .arg = &count_calls, + .callback = &timer_cb1, + .skip_unhandled_events = true, }; esp_timer_handle_t periodic_timer; esp_timer_create(&timer_args, &periodic_timer); diff --git a/components/esp_ringbuf/test/test_ringbuf.c b/components/esp_ringbuf/test/test_ringbuf.c index 46a39b2f66..750bcab0e2 100644 --- a/components/esp_ringbuf/test/test_ringbuf.c +++ b/components/esp_ringbuf/test/test_ringbuf.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,7 +11,7 @@ #include "freertos/queue.h" #include "freertos/semphr.h" #include "freertos/ringbuf.h" -#include "driver/timer.h" +#include "driver/gptimer.h" #include "esp_heap_caps.h" #include "esp_spi_flash.h" #include "unity.h" @@ -29,7 +29,8 @@ static const uint8_t small_item[SMALL_ITEM_SIZE] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; static const uint8_t large_item[LARGE_ITEM_SIZE] = { 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}; + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 + }; static RingbufHandle_t buffer_handles[NO_OF_RB_TYPES]; static SemaphoreHandle_t done_sem; @@ -87,9 +88,9 @@ static void receive_check_and_return_item_allow_split(RingbufHandle_t handle, co uint8_t *item1, *item2; BaseType_t ret; if (in_isr) { - ret = xRingbufferReceiveSplitFromISR(handle, (void**)&item1, (void **)&item2, &item_size1, &item_size2); + ret = xRingbufferReceiveSplitFromISR(handle, (void **)&item1, (void **)&item2, &item_size1, &item_size2); } else { - ret = xRingbufferReceiveSplit(handle, (void**)&item1, (void **)&item2, &item_size1, &item_size2, ticks_to_wait); + ret = xRingbufferReceiveSplit(handle, (void **)&item1, (void **)&item2, &item_size1, &item_size2, ticks_to_wait); } TEST_ASSERT_MESSAGE(ret == pdTRUE, "Failed to receive item"); TEST_ASSERT_MESSAGE(item1 != NULL, "Failed to receive item"); @@ -643,7 +644,7 @@ static void queue_set_receiving_task(void *queue_set_handle) //Allow-split buffer receive_check_and_return_item_allow_split(buffer_handles[1], small_item, SMALL_ITEM_SIZE, 0, false); items_rec_count[1] ++; - } else if (xRingbufferCanRead(buffer_handles[2], member) == pdTRUE){ + } else if (xRingbufferCanRead(buffer_handles[2], member) == pdTRUE) { //Byte buffer receive_check_and_return_item_byte_buffer(buffer_handles[2], small_item, SMALL_ITEM_SIZE, 0, false); items_rec_count[2] ++; @@ -653,8 +654,8 @@ static void queue_set_receiving_task(void *queue_set_handle) //Check for completion if (items_rec_count[0] == no_of_items && - items_rec_count[1] == no_of_items && - items_rec_count[2] == no_of_items) { + items_rec_count[1] == no_of_items && + items_rec_count[2] == no_of_items) { done = pdTRUE; } } @@ -676,7 +677,7 @@ TEST_CASE("Test ring buffer with queue sets", "[esp_ringbuf]") } //Create a task to send items to each ring buffer int no_of_items = BUFFER_SIZE / SMALL_ITEM_SIZE; - xTaskCreatePinnedToCore(queue_set_receiving_task, "rec tsk", 2048, (void *)queue_set, UNITY_FREERTOS_PRIORITY + 1 , NULL, 0); + xTaskCreatePinnedToCore(queue_set_receiving_task, "rec tsk", 2048, (void *)queue_set, UNITY_FREERTOS_PRIORITY + 1, NULL, 0); //Send multiple items to each type of ring buffer for (int i = 0; i < no_of_items; i++) { @@ -687,7 +688,7 @@ TEST_CASE("Test ring buffer with queue sets", "[esp_ringbuf]") xSemaphoreTake(done_sem, portMAX_DELAY); vSemaphoreDelete(done_sem); - //Remove and delete ring buffers from queue sets + //Remove and delete ring buffers from queue sets for (int i = 0; i < NO_OF_RB_TYPES; i++) { TEST_ASSERT_MESSAGE(xRingbufferRemoveFromQueueSetRead(buffer_handles[i], queue_set) == pdTRUE, "Failed to remove from read queue set"); vRingbufferDelete(buffer_handles[i]); @@ -703,19 +704,14 @@ TEST_CASE("Test ring buffer with queue sets", "[esp_ringbuf]") * will send then receive an item to a ring buffer. */ -#define TIMER_GROUP 0 -#define TIMER_NUMBER 0 #define ISR_ITERATIONS ((BUFFER_SIZE / SMALL_ITEM_SIZE) * 2) -intr_handle_t ringbuffer_isr_handle; static int buf_type; static int iterations; -static void ringbuffer_isr(void *arg) +static bool on_timer_alarm(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx) { - //Clear timer interrupt - timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0); - timer_group_enable_alarm_in_isr(TIMER_GROUP_0, xPortGetCoreID()); + bool need_yield = false; //Test sending to buffer from ISR from ISR if (buf_type < NO_OF_RB_TYPES) { @@ -740,63 +736,56 @@ static void ringbuffer_isr(void *arg) if (iterations < ISR_ITERATIONS) { iterations++; buf_type = 0; //Reset and iterate through each buffer type again - return; + goto out; } else { //Signal complete BaseType_t task_woken = pdFALSE; xSemaphoreGiveFromISR(done_sem, &task_woken); if (task_woken == pdTRUE) { buf_type++; - portYIELD_FROM_ISR(); + need_yield = true; } } } -} -static void setup_timer(void) -{ - //Setup timer for ISR - int timer_group = TIMER_GROUP; - int timer_idx = TIMER_NUMBER; - timer_config_t config = { - .alarm_en = 1, - .auto_reload = 1, - .counter_dir = TIMER_COUNT_UP, - .divider = 10000, - .intr_type = TIMER_INTR_LEVEL, - .counter_en = TIMER_PAUSE, - }; - timer_init(timer_group, timer_idx, &config); //Configure timer - timer_pause(timer_group, timer_idx); //Stop timer counter - timer_set_counter_value(timer_group, timer_idx, 0x00000000ULL); //Load counter value - timer_set_alarm_value(timer_group, timer_idx, 20); //Set alarm value - timer_enable_intr(timer_group, timer_idx); //Enable timer interrupt - timer_set_auto_reload(timer_group, timer_idx, 1); //Auto Reload - timer_isr_register(timer_group, timer_idx, ringbuffer_isr, NULL, 0, &ringbuffer_isr_handle); //Set ISR handler -} - -static void cleanup_timer(void) -{ - timer_disable_intr(TIMER_GROUP, TIMER_NUMBER); - esp_intr_free(ringbuffer_isr_handle); +out: + return need_yield; } TEST_CASE("Test ring buffer ISR", "[esp_ringbuf]") { + gptimer_handle_t gptimer; for (int i = 0; i < NO_OF_RB_TYPES; i++) { buffer_handles[i] = xRingbufferCreate(BUFFER_SIZE, i); } done_sem = xSemaphoreCreateBinary(); buf_type = 0; iterations = 0; - setup_timer(); - //Start timer to trigger ISR - timer_start(TIMER_GROUP, TIMER_NUMBER); + + //Setup timer for ISR + gptimer_config_t config = { + .clk_src = GPTIMER_CLK_SRC_APB, + .direction = GPTIMER_COUNT_UP, + .resolution_hz = 1000000, + }; + TEST_ESP_OK(gptimer_new_timer(&config, &gptimer)); + gptimer_alarm_config_t alarm_config = { + .reload_count = 0, + .alarm_count = 2000, + .flags.auto_reload_on_alarm = true, + }; + gptimer_event_callbacks_t cbs = { + .on_alarm = on_timer_alarm, + }; + TEST_ESP_OK(gptimer_register_event_callbacks(gptimer, &cbs, NULL)); + TEST_ESP_OK(gptimer_set_alarm_action(gptimer, &alarm_config)); + TEST_ESP_OK(gptimer_start(gptimer)); //Wait for ISR to complete multiple iterations xSemaphoreTake(done_sem, portMAX_DELAY); //Cleanup - cleanup_timer(); + TEST_ESP_OK(gptimer_stop(gptimer)); + TEST_ESP_OK(gptimer_del_timer(gptimer)); vSemaphoreDelete(done_sem); for (int i = 0; i < NO_OF_RB_TYPES; i++) { vRingbufferDelete(buffer_handles[i]); @@ -819,7 +808,8 @@ static const char continuous_data[] = {"A_very_long_string_that_will_be_split_in "items_of_random_lengths_and_sent_to_the_ring_" "buffer._The_maximum_random_length_will_also_" "be_increased_over_multiple_iterations_in_this" - "_test"}; + "_test" + }; #define CONT_DATA_LEN sizeof(continuous_data) //32-bit aligned size that guarantees a wrap around at some point #define CONT_DATA_TEST_BUFF_LEN (((CONT_DATA_LEN/2) + 0x03) & ~0x3) @@ -847,7 +837,7 @@ static void send_to_buffer(RingbufHandle_t buffer, size_t max_item_size) } //Send item - TEST_ASSERT_MESSAGE(xRingbufferSend(buffer, (void *)&(continuous_data[bytes_sent]), next_item_size, TIMEOUT_TICKS) == pdTRUE, "Failed to send an item"); + TEST_ASSERT_MESSAGE(xRingbufferSend(buffer, (void *) & (continuous_data[bytes_sent]), next_item_size, TIMEOUT_TICKS) == pdTRUE, "Failed to send an item"); bytes_sent += next_item_size; } xSemaphoreGive(tx_done); @@ -907,7 +897,7 @@ static void send_task(void *args) //Test sending short length items send_to_buffer(buffer, 1); //Test sending mid length items - send_to_buffer(buffer, max_item_len/2); + send_to_buffer(buffer, max_item_len / 2); //Test sending long length items send_to_buffer(buffer, max_item_len); vTaskDelete(NULL); @@ -921,7 +911,7 @@ static void rec_task(void *args) //Test receiving short length items read_from_buffer(buffer, ((task_args_t *)args)->type, 1); //Test receiving mid length items - read_from_buffer(buffer, ((task_args_t *)args)->type, max_rec_len/2); + read_from_buffer(buffer, ((task_args_t *)args)->type, max_rec_len / 2); //Test receiving long length items read_from_buffer(buffer, ((task_args_t *)args)->type, max_rec_len); @@ -988,10 +978,10 @@ TEST_CASE("Test static ring buffer SMP", "[esp_ringbuf]") //Allocate memory and create semaphores #if CONFIG_SPIRAM_USE_CAPS_ALLOC //When SPIRAM can only be allocated using heap_caps_malloc() buffer_struct = (StaticRingbuffer_t *)heap_caps_malloc(sizeof(StaticRingbuffer_t), MALLOC_CAP_SPIRAM); - buffer_storage = (uint8_t *)heap_caps_malloc(sizeof(uint8_t)*CONT_DATA_TEST_BUFF_LEN, MALLOC_CAP_SPIRAM); + buffer_storage = (uint8_t *)heap_caps_malloc(sizeof(uint8_t) * CONT_DATA_TEST_BUFF_LEN, MALLOC_CAP_SPIRAM); #else //Case where SPIRAM is disabled or when SPIRAM is allocatable through malloc() buffer_struct = (StaticRingbuffer_t *)malloc(sizeof(StaticRingbuffer_t)); - buffer_storage = (uint8_t *)malloc(sizeof(uint8_t)*CONT_DATA_TEST_BUFF_LEN); + buffer_storage = (uint8_t *)malloc(sizeof(uint8_t) * CONT_DATA_TEST_BUFF_LEN); #endif TEST_ASSERT(buffer_struct != NULL && buffer_storage != NULL); diff --git a/components/freemodbus/serial_master/port/port_serial_master.h b/components/freemodbus/serial_master/port/port_serial_master.h index bc7496601b..e389b8198c 100644 --- a/components/freemodbus/serial_master/port/port_serial_master.h +++ b/components/freemodbus/serial_master/port/port_serial_master.h @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: BSD-3-Clause * - * SPDX-FileContributor: 2016-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD */ /* * FreeModbus Libary: ESP32 Port Demo Application @@ -39,7 +39,6 @@ /* ----------------------- Platform includes --------------------------------*/ #include "driver/uart.h" -#include "driver/timer.h" #include "esp_log.h" // for ESP_LOGE macro #include "mb_m.h" #include "port.h" diff --git a/components/freemodbus/serial_slave/port/port_serial_slave.h b/components/freemodbus/serial_slave/port/port_serial_slave.h index 26c13cdce6..880876c11d 100644 --- a/components/freemodbus/serial_slave/port/port_serial_slave.h +++ b/components/freemodbus/serial_slave/port/port_serial_slave.h @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: BSD-3-Clause * - * SPDX-FileContributor: 2016-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD */ /* * FreeModbus Libary: ESP32 Port Demo Application @@ -40,7 +40,6 @@ /* ----------------------- Platform includes --------------------------------*/ #include "driver/uart.h" -#include "driver/timer.h" #include "esp_log.h" #include "port.h" diff --git a/components/freertos/test/test_freertos_eventgroups.c b/components/freertos/test/test_freertos_eventgroups.c index 2ebe6f7dfc..ce5db60a8e 100644 --- a/components/freertos/test/test_freertos_eventgroups.c +++ b/components/freertos/test/test_freertos_eventgroups.c @@ -5,15 +5,9 @@ #include "freertos/semphr.h" #include "freertos/queue.h" #include "freertos/event_groups.h" -#include "driver/timer.h" +#include "driver/gptimer.h" #include "unity.h" -#ifdef CONFIG_IDF_TARGET_ESP32S2 -#define int_clr_timers int_clr -#define update update.update -#define int_st_timers int_st -#endif - #define BIT_CALL (1 << 0) #define BIT_RESPONSE(TASK) (1 << (TASK+1)) #define ALL_RESPONSE_BITS (((1 << NUM_TASKS) - 1) << 1) @@ -72,7 +66,7 @@ TEST_CASE("FreeRTOS Event Groups", "[freertos]") /* Ensure all tasks cleaned up correctly */ for (int c = 0; c < NUM_TASKS; c++) { - TEST_ASSERT( xSemaphoreTake(done_sem, 100/portTICK_PERIOD_MS) ); + TEST_ASSERT( xSemaphoreTake(done_sem, 100 / portTICK_PERIOD_MS) ); } vSemaphoreDelete(done_sem); @@ -117,7 +111,7 @@ TEST_CASE("FreeRTOS Event Group Sync", "[freertos]") /* Ensure all tasks cleaned up correctly */ for (int c = 0; c < NUM_TASKS; c++) { - TEST_ASSERT( xSemaphoreTake(done_sem, 100/portTICK_PERIOD_MS) ); + TEST_ASSERT( xSemaphoreTake(done_sem, 100 / portTICK_PERIOD_MS) ); } vSemaphoreDelete(done_sem); @@ -132,63 +126,27 @@ TEST_CASE("FreeRTOS Event Group Sync", "[freertos]") */ //Use a timer to trigger an ISr -#define TIMER_DIVIDER 10000 -#define TIMER_COUNT 100 -#define TIMER_NUMBER 0 #define BITS 0xAA - -static timer_isr_handle_t isr_handle; +static gptimer_handle_t gptimer; static bool test_set_bits; static bool test_clear_bits; -static void IRAM_ATTR event_group_isr(void *arg) +static bool on_timer_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx) { portBASE_TYPE task_woken = pdFALSE; - timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0); - timer_group_enable_alarm_in_isr(TIMER_GROUP_0, xPortGetCoreID()); - if(test_set_bits){ + gptimer_stop(timer); + + if (test_set_bits) { xEventGroupSetBitsFromISR(eg, BITS, &task_woken); - timer_pause(TIMER_GROUP_0, TIMER_NUMBER); test_set_bits = false; - } else if (test_clear_bits){ + } else if (test_clear_bits) { xEventGroupClearBitsFromISR(eg, BITS); xSemaphoreGiveFromISR(done_sem, &task_woken); - timer_pause(TIMER_GROUP_0, TIMER_NUMBER); test_clear_bits = false; } //Switch context if necessary - if(task_woken == pdTRUE){ - portYIELD_FROM_ISR(); - } -} - -static void setup_timer(void) -{ - //Setup timer for ISR - int timer_group = TIMER_GROUP_0; - int timer_idx = TIMER_NUMBER; - timer_config_t config = { - .alarm_en = 1, - .auto_reload = 1, - .counter_dir = TIMER_COUNT_UP, - .divider = TIMER_DIVIDER, - .intr_type = TIMER_INTR_LEVEL, - .counter_en = TIMER_PAUSE, - }; - timer_init(timer_group, timer_idx, &config); //Configure timer - timer_pause(timer_group, timer_idx); //Stop timer counter - timer_set_counter_value(timer_group, timer_idx, 0x00000000ULL); //Load counter value - timer_set_alarm_value(timer_group, timer_idx, TIMER_COUNT); //Set alarm value - timer_enable_intr(timer_group, timer_idx); //Enable timer interrupt - timer_set_auto_reload(timer_group, timer_idx, 1); //Auto Reload - timer_isr_register(timer_group, timer_idx, event_group_isr, NULL, ESP_INTR_FLAG_IRAM, &isr_handle); //Set ISR handler -} - -static void cleanup_timer(void) -{ - timer_disable_intr(TIMER_GROUP_0, TIMER_NUMBER); - esp_intr_free(isr_handle); + return task_woken == pdTRUE; } TEST_CASE("FreeRTOS Event Group ISR", "[freertos]") @@ -197,23 +155,41 @@ TEST_CASE("FreeRTOS Event Group ISR", "[freertos]") eg = xEventGroupCreate(); test_set_bits = false; test_clear_bits = false; - setup_timer(); //Init timer to trigger ISR + //Setup timer for ISR + gptimer_config_t config = { + .clk_src = GPTIMER_CLK_SRC_APB, + .direction = GPTIMER_COUNT_UP, + .resolution_hz = 1000000, + }; + TEST_ESP_OK(gptimer_new_timer(&config, &gptimer)); + gptimer_alarm_config_t alarm_config = { + .reload_count = 0, + .alarm_count = 200000, + }; + gptimer_event_callbacks_t cbs = { + .on_alarm = on_timer_alarm_cb, + }; + TEST_ESP_OK(gptimer_register_event_callbacks(gptimer, &cbs, NULL)); + TEST_ESP_OK(gptimer_set_alarm_action(gptimer, &alarm_config)); //Test set bits + printf("test set bits\r\n"); test_set_bits = true; - timer_start(TIMER_GROUP_0, TIMER_NUMBER); + TEST_ESP_OK(gptimer_start(gptimer)); TEST_ASSERT_EQUAL(BITS, xEventGroupWaitBits(eg, BITS, pdFALSE, pdTRUE, portMAX_DELAY)); //Let ISR set event group bits //Test clear bits + printf("test clear bits\r\n"); xEventGroupSetBits(eg, BITS); //Set bits to be cleared test_clear_bits = true; - timer_start(TIMER_GROUP_0, TIMER_NUMBER); + TEST_ESP_OK(gptimer_set_raw_count(gptimer, 0)); + TEST_ESP_OK(gptimer_start(gptimer)); xSemaphoreTake(done_sem, portMAX_DELAY); //Wait for ISR to clear bits vTaskDelay(10); //Event group clear bits runs via daemon task, delay so daemon can run TEST_ASSERT_EQUAL(0, xEventGroupGetBits(eg)); //Check bits are cleared //Clean up - cleanup_timer(); + TEST_ESP_OK(gptimer_del_timer(gptimer)); vEventGroupDelete(eg); vSemaphoreDelete(done_sem); vTaskDelay(10); //Give time for idle task to clear up deleted tasks diff --git a/components/freertos/test/test_freertos_task_notify.c b/components/freertos/test/test_freertos_task_notify.c index 5d5168bc04..2a80448a62 100644 --- a/components/freertos/test/test_freertos_task_notify.c +++ b/components/freertos/test/test_freertos_task_notify.c @@ -9,30 +9,20 @@ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include -#include "driver/timer.h" -#ifndef CONFIG_FREERTOS_UNICORE -#include "esp_ipc.h" -#endif +#include "freertos/semphr.h" +#include "driver/gptimer.h" #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 +#define MESSAGE 0xFF static uint32_t send_core_message = 0; -static TaskHandle_t rec_task_handle; +static TaskHandle_t recv_task_handle; static bool isr_give = false; - +static bool test_start = false; +static gptimer_handle_t gptimers[portNUM_PROCESSORS]; static SemaphoreHandle_t trigger_send_semphr; static SemaphoreHandle_t task_delete_semphr; @@ -41,40 +31,77 @@ 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){ +static bool on_alarm_sender_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx) +{ + gptimer_stop(timer); + if (!test_start) { + return false; + } + int curcore = xPortGetCoreID(); + if (isr_give) { //Test vTaskNotifyGiveFromISR() on same core + notifs_sent++; + vTaskNotifyGiveFromISR(recv_task_handle, NULL); + } else { //Test xTaskNotifyFromISR() + notifs_sent++; + xTaskNotifyFromISR(recv_task_handle, (MESSAGE << curcore), eSetValueWithOverwrite, NULL); + } + // always trigger a task switch when exit ISR context + return true; +} + +static void test_gptimer_start(void *arg) +{ + gptimer_handle_t gptimer = (gptimer_handle_t)arg; + gptimer_alarm_config_t alarm_config = { + .reload_count = 0, + .alarm_count = 1000, + }; + TEST_ESP_OK(gptimer_set_raw_count(gptimer, 0)); + gptimer_event_callbacks_t cbs = { + .on_alarm = on_alarm_sender_cb, + }; + TEST_ESP_OK(gptimer_register_event_callbacks(gptimer, &cbs, NULL)); + TEST_ESP_OK(gptimer_set_alarm_action(gptimer, &alarm_config)); + TEST_ESP_OK(gptimer_start(gptimer)); +} + +static void sender_task(void *arg) +{ + gptimer_handle_t gptimer = (gptimer_handle_t)arg; int curcore = xPortGetCoreID(); //Test xTaskNotify xSemaphoreTake(trigger_send_semphr, portMAX_DELAY); notifs_sent++; - xTaskNotify(rec_task_handle, (MESSAGE << curcore), eSetValueWithOverwrite); + xTaskNotify(recv_task_handle, (MESSAGE << curcore), eSetValueWithOverwrite); //Test xTaskNotifyGive xSemaphoreTake(trigger_send_semphr, portMAX_DELAY); notifs_sent++; - xTaskNotifyGive(rec_task_handle); + xTaskNotifyGive(recv_task_handle); //Test xTaskNotifyFromISR xSemaphoreTake(trigger_send_semphr, portMAX_DELAY); isr_give = false; - timer_start(TIMER_GROUP_0, curcore); + test_gptimer_start(gptimer); //Test vTaskNotifyGiveFromISR xSemaphoreTake(trigger_send_semphr, portMAX_DELAY); isr_give = true; - timer_start(TIMER_GROUP_0, curcore); + test_gptimer_start(gptimer); //Delete Task and Semaphores xSemaphoreGive(task_delete_semphr); vTaskDelete(NULL); } -static void receiver_task (void* arg){ +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){ + if (notify_value != send_core_message) { wrong_core = true; } notifs_rec++; @@ -87,7 +114,7 @@ static void receiver_task (void* arg){ //Test xTaskNotifyWait from ISR xSemaphoreGive(trigger_send_semphr); xTaskNotifyWait(0, 0xFFFFFFFF, ¬ify_value, portMAX_DELAY); - if(notify_value != send_core_message){ + if (notify_value != send_core_message) { wrong_core = true; } notifs_rec++; @@ -102,111 +129,62 @@ static void receiver_task (void* arg){ vTaskDelete(NULL); } -static void IRAM_ATTR sender_ISR (void *arg) +static void install_gptimer_on_core(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 = { - .alarm_en = 1, - .auto_reload = 1, - .counter_dir = TIMER_COUNT_UP, - .divider = TIMER_DIVIDER, - .intr_type = TIMER_INTR_LEVEL, - .counter_en = TIMER_PAUSE, + int core_id = (int)arg; + gptimer_config_t timer_config = { + .clk_src = GPTIMER_CLK_SRC_APB, + .direction = GPTIMER_COUNT_UP, + .resolution_hz = 1000000, // 1MHz, 1 tick = 1us }; - - /*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_ESP_OK(gptimer_new_timer(&timer_config, &gptimers[core_id])); + test_gptimer_start(gptimers[core_id]); + xSemaphoreGive(task_delete_semphr); + vTaskDelete(NULL); } 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 - + test_start = false; 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 + task_delete_semphr = xQueueCreateCountingSemaphore(10, 0); + for (int i = 0; i < portNUM_PROCESSORS; i++) { + xTaskCreatePinnedToCore(install_gptimer_on_core, "install_gptimer", 4096, (void *const)i, UNITY_FREERTOS_PRIORITY + 1, NULL, i); + TEST_ASSERT(xSemaphoreTake(task_delete_semphr, pdMS_TO_TICKS(1000))); + } + // wait the gptimer installation done on specific core + vTaskDelay(10); + // test start + test_start = true; + 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); + send_core_message = (0xFF << i); //0xFF if core 0, 0xFF0 if core 1 + // receiver task has higher priority than sender task + xTaskCreatePinnedToCore(receiver_task, "recv task", 1000, NULL, UNITY_FREERTOS_PRIORITY + 2, &recv_task_handle, j); + xTaskCreatePinnedToCore(sender_task, "send task", 1000, gptimers[i], 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) ); + for (int k = 0; k < NO_OF_TASKS; k++) { //Wait for sender and receiver task deletion + TEST_ASSERT(xSemaphoreTake(task_delete_semphr, pdMS_TO_TICKS(2000))); } 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); + TEST_ASSERT_EQUAL(NO_OF_NOTIFS, notifs_sent); + TEST_ASSERT_EQUAL(NO_OF_NOTIFS, notifs_rec); + TEST_ASSERT_EQUAL(false, wrong_core); } } //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 + for (int i = 0; i < portNUM_PROCESSORS; i++) { + TEST_ESP_OK(gptimer_stop(gptimers[i])); + TEST_ESP_OK(gptimer_del_timer(gptimers[i])); + } } diff --git a/components/freertos/test/test_legacy_hooks.c b/components/freertos/test/test_legacy_hooks.c index 1d9690339e..b3bd86fef4 100644 --- a/components/freertos/test/test_legacy_hooks.c +++ b/components/freertos/test/test_legacy_hooks.c @@ -8,7 +8,6 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include -#include "driver/timer.h" #include "unity.h" #include "test_utils.h" diff --git a/components/freertos/test/test_suspend_scheduler.c b/components/freertos/test/test_suspend_scheduler.c index 178bd28f33..02973ef613 100644 --- a/components/freertos/test/test_suspend_scheduler.c +++ b/components/freertos/test/test_suspend_scheduler.c @@ -7,33 +7,24 @@ #include "freertos/queue.h" #include "unity.h" #include "test_utils.h" - -#include "driver/timer.h" +#include "esp_intr_alloc.h" +#include "driver/gptimer.h" +#include "esp_private/gptimer.h" #include "sdkconfig.h" #include "esp_rom_sys.h" -#ifdef CONFIG_IDF_TARGET_ESP32S2 -#define int_clr_timers int_clr -#define update update.update -#define int_st_timers int_st -#endif - static SemaphoreHandle_t isr_semaphore; static volatile unsigned isr_count; /* Timer ISR increments an ISR counter, and signals a mutex semaphore to wake up another counter task */ -static void timer_group0_isr(void *vp_arg) +static bool on_timer_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx) { - timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0); - timer_group_enable_alarm_in_isr(TIMER_GROUP_0, TIMER_0); portBASE_TYPE higher_awoken = pdFALSE; isr_count++; xSemaphoreGiveFromISR(isr_semaphore, &higher_awoken); - if (higher_awoken == pdTRUE) { - portYIELD_FROM_ISR(); - } + return higher_awoken == pdTRUE; } typedef struct { @@ -45,7 +36,7 @@ static void counter_task_fn(void *vp_config) { counter_config_t *config = (counter_config_t *)vp_config; printf("counter_task running...\n"); - while(1) { + while (1) { xSemaphoreTake(config->trigger_sem, portMAX_DELAY); config->counter++; } @@ -59,9 +50,11 @@ static void counter_task_fn(void *vp_config) TEST_CASE("Scheduler disabled can handle a pending context switch on resume", "[freertos]") { isr_count = 0; - isr_semaphore = xSemaphoreCreateBinary(); TaskHandle_t counter_task; - intr_handle_t isr_handle = NULL; + gptimer_handle_t gptimer = NULL; + intr_handle_t intr_handle = NULL; + isr_semaphore = xSemaphoreCreateBinary(); + TEST_ASSERT_NOT_NULL(isr_semaphore); counter_config_t count_config = { .trigger_sem = isr_semaphore, @@ -71,25 +64,26 @@ TEST_CASE("Scheduler disabled can handle a pending context switch on resume", "[ &count_config, UNITY_FREERTOS_PRIORITY + 1, &counter_task, UNITY_FREERTOS_CPU); - /* Configure timer ISR */ - const timer_config_t timer_config = { - .alarm_en = 1, - .auto_reload = 1, - .counter_dir = TIMER_COUNT_UP, - .divider = 2, //Range is 2 to 65536 - .intr_type = TIMER_INTR_LEVEL, - .counter_en = TIMER_PAUSE, + gptimer_config_t timer_config = { + .clk_src = GPTIMER_CLK_SRC_APB, + .direction = GPTIMER_COUNT_UP, + .resolution_hz = 1000000, // 1MHz, 1 tick=1us }; - /* Configure timer */ - timer_init(TIMER_GROUP_0, TIMER_0, &timer_config); - timer_pause(TIMER_GROUP_0, TIMER_0); - timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0); - timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 1000); - timer_enable_intr(TIMER_GROUP_0, TIMER_0); - timer_isr_register(TIMER_GROUP_0, TIMER_0, timer_group0_isr, NULL, 0, &isr_handle); - timer_start(TIMER_GROUP_0, TIMER_0); + TEST_ESP_OK(gptimer_new_timer(&timer_config, &gptimer)); + gptimer_alarm_config_t alarm_config = { + .reload_count = 0, + .alarm_count = 1000, // alarm period 1ms + .flags.auto_reload_on_alarm = true, + }; + gptimer_event_callbacks_t cbs = { + .on_alarm = on_timer_alarm_cb, + }; + TEST_ESP_OK(gptimer_register_event_callbacks(gptimer, &cbs, NULL)); + TEST_ESP_OK(gptimer_set_alarm_action(gptimer, &alarm_config)); + TEST_ESP_OK(gptimer_start(gptimer)); + TEST_ESP_OK(gptimer_get_intr_handle(gptimer, &intr_handle)); - vTaskDelay(5); + vTaskDelay(pdMS_TO_TICKS(20)); // Check some counts have been triggered via the ISR TEST_ASSERT(count_config.counter > 10); @@ -104,24 +98,22 @@ TEST_CASE("Scheduler disabled can handle a pending context switch on resume", "[ // scheduler off on this CPU... esp_rom_delay_us(20 * 1000); - //TEST_ASSERT_NOT_EQUAL(no_sched_isr, isr_count); TEST_ASSERT_EQUAL(count_config.counter, no_sched_task); // disable timer interrupts - timer_disable_intr(TIMER_GROUP_0, TIMER_0); + esp_intr_disable(intr_handle); // When we resume scheduler, we expect the counter task // will preempt and count at least one more item esp_intr_noniram_enable(); - timer_enable_intr(TIMER_GROUP_0, TIMER_0); + esp_intr_enable(intr_handle); xTaskResumeAll(); TEST_ASSERT_NOT_EQUAL(count_config.counter, no_sched_task); } - esp_intr_free(isr_handle); - timer_disable_intr(TIMER_GROUP_0, TIMER_0); - + TEST_ESP_OK(gptimer_stop(gptimer)); + TEST_ESP_OK(gptimer_del_timer(gptimer)); vTaskDelete(counter_task); vSemaphoreDelete(isr_semaphore); } @@ -132,7 +124,7 @@ TEST_CASE("Scheduler disabled can handle a pending context switch on resume", "[ */ TEST_CASE("Scheduler disabled can wake multiple tasks on resume", "[freertos]") { - #define TASKS_PER_PROC 4 +#define TASKS_PER_PROC 4 TaskHandle_t tasks[portNUM_PROCESSORS][TASKS_PER_PROC] = { 0 }; counter_config_t counters[portNUM_PROCESSORS][TASKS_PER_PROC] = { 0 }; @@ -169,7 +161,7 @@ TEST_CASE("Scheduler disabled can wake multiple tasks on resume", "[freertos]") for (int t = 0; t < TASKS_PER_PROC; t++) { xSemaphoreGive(counters[p][t].trigger_sem); } - } + } esp_rom_delay_us(200); /* Let the other CPU do some things */ @@ -207,7 +199,7 @@ static void suspend_scheduler_5ms_task_fn(void *ignore) { vTaskSuspendAll(); sched_suspended = true; - for (int i = 0; i <5; i++) { + for (int i = 0; i < 5; i++) { esp_rom_delay_us(1000); } xTaskResumeAll(); @@ -237,7 +229,7 @@ TEST_CASE("Scheduler disabled on CPU B, tasks on A can wake", "[freertos]") /* counter task is now blocked on other CPU, waiting for wake_sem, and we expect that this CPU's scheduler will be suspended for 5ms shortly... */ - while(!sched_suspended) { } + while (!sched_suspended) { } xSemaphoreGive(wake_sem); esp_rom_delay_us(1000); @@ -247,7 +239,7 @@ TEST_CASE("Scheduler disabled on CPU B, tasks on A can wake", "[freertos]") TEST_ASSERT(sched_suspended); /* wait for the rest of the 5ms... */ - while(sched_suspended) { } + while (sched_suspended) { } esp_rom_delay_us(100); TEST_ASSERT_EQUAL(1, count_config.counter); // when scheduler resumes, counter task should immediately count diff --git a/components/freertos/test/test_task_suspend_resume.c b/components/freertos/test/test_task_suspend_resume.c index 17d0faee38..5ffbf56798 100644 --- a/components/freertos/test/test_task_suspend_resume.c +++ b/components/freertos/test/test_task_suspend_resume.c @@ -9,22 +9,13 @@ #include "freertos/queue.h" #include "unity.h" #include "test_utils.h" - -#include "driver/timer.h" - +#include "driver/gptimer.h" #ifndef CONFIG_FREERTOS_UNICORE #include "esp_ipc.h" #endif #include "esp_freertos_hooks.h" - #include "esp_rom_sys.h" -#ifdef CONFIG_IDF_TARGET_ESP32S2 -#define int_clr_timers int_clr -#define update update.update -#define int_st_timers int_st -#endif - /* Counter task counts a target variable forever */ static void task_count(void *vp_counter) { @@ -116,33 +107,29 @@ TEST_CASE("Suspend the current running task", "[freertos]") } -volatile bool timer_isr_fired; +static volatile bool timer_isr_fired; +static gptimer_handle_t gptimer = NULL; /* Timer ISR clears interrupt, sets flag, then resumes the task supplied in the * callback argument. */ -void IRAM_ATTR timer_group0_isr(void *vp_arg) +bool on_timer_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx) { - // Clear interrupt - timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0); - - timer_isr_fired = true; - - TaskHandle_t handle = vp_arg; + TaskHandle_t handle = user_ctx; BaseType_t higherPriorityTaskWoken = pdFALSE; + gptimer_stop(timer); + timer_isr_fired = true; higherPriorityTaskWoken = xTaskResumeFromISR(handle); - if (higherPriorityTaskWoken == pdTRUE) { - portYIELD_FROM_ISR(); - } + return higherPriorityTaskWoken == pdTRUE; } /* Task suspends itself, then sets parameter value to the current timer group counter and deletes itself */ -static void task_suspend_self_with_timer(void *vp_resumed) +static IRAM_ATTR void task_suspend_self_with_timer(void *vp_resumed) { volatile uint64_t *resumed_counter = vp_resumed; *resumed_counter = 0; vTaskSuspend(NULL); - timer_get_counter_value(TIMER_GROUP_0, TIMER_0, vp_resumed); + gptimer_get_raw_count(gptimer, (uint64_t *)resumed_counter); vTaskDelete(NULL); } @@ -157,49 +144,40 @@ static void test_resume_task_from_isr(int target_core) xTaskCreatePinnedToCore(task_suspend_self_with_timer, "suspend_self", 2048, (void *)&resumed_counter, UNITY_FREERTOS_PRIORITY + 1, &suspend_task, target_core); - + // delay to make the task has resumed itself vTaskDelay(1); TEST_ASSERT_EQUAL(0, resumed_counter); - const unsigned APB_CYCLES_PER_TICK = TIMER_BASE_CLK / configTICK_RATE_HZ; - const unsigned TEST_TIMER_DIV = 2; - const unsigned TEST_TIMER_CYCLES_PER_TICK = APB_CYCLES_PER_TICK / TEST_TIMER_DIV; - const unsigned TEST_TIMER_CYCLES_PER_MS = TIMER_BASE_CLK / 1000 / TEST_TIMER_DIV; - const unsigned TEST_TIMER_ALARM = TEST_TIMER_CYCLES_PER_TICK / 2; // half an RTOS tick - /* Configure timer ISR */ - timer_isr_handle_t isr_handle; - const timer_config_t config = { - .alarm_en = 1, - .auto_reload = 0, - .counter_dir = TIMER_COUNT_UP, - .divider = TEST_TIMER_DIV, - .intr_type = TIMER_INTR_LEVEL, - .counter_en = TIMER_PAUSE, + gptimer_config_t timer_config = { + .clk_src = GPTIMER_CLK_SRC_APB, + .direction = GPTIMER_COUNT_UP, + .resolution_hz = 1000000, // 1MHz, 1 tick = 1us }; - /*Configure timer*/ - ESP_ERROR_CHECK( timer_init(TIMER_GROUP_0, TIMER_0, &config) ); - ESP_ERROR_CHECK( timer_pause(TIMER_GROUP_0, TIMER_0) ); - ESP_ERROR_CHECK( timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0) ); - ESP_ERROR_CHECK( timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, TEST_TIMER_ALARM) ); - ESP_ERROR_CHECK( timer_enable_intr(TIMER_GROUP_0, TIMER_0) ); - ESP_ERROR_CHECK( timer_isr_register(TIMER_GROUP_0, TIMER_0, timer_group0_isr, (void*)suspend_task, ESP_INTR_FLAG_IRAM, &isr_handle) ); + TEST_ESP_OK(gptimer_new_timer(&timer_config, &gptimer)); timer_isr_fired = false; vTaskDelay(1); // Make sure we're at the start of a new tick - - ESP_ERROR_CHECK( timer_start(TIMER_GROUP_0, TIMER_0) ); - - vTaskDelay(1); // We expect timer group will fire half-way through this delay - + gptimer_alarm_config_t alarm_config = { + .alarm_count = 1000000 / configTICK_RATE_HZ / 2, + .reload_count = 0, + }; + gptimer_event_callbacks_t cbs = { + .on_alarm = on_timer_alarm_cb, + }; + TEST_ESP_OK(gptimer_register_event_callbacks(gptimer, &cbs, suspend_task)); + TEST_ESP_OK(gptimer_set_alarm_action(gptimer, &alarm_config)); + TEST_ESP_OK(gptimer_start(gptimer)); + // wait the timer interrupt fires up + vTaskDelay(2); TEST_ASSERT_TRUE(timer_isr_fired); + // check the task was resumed TEST_ASSERT_NOT_EQUAL(0, resumed_counter); // The task should have woken within 500us of the timer interrupt event (note: task may be a flash cache miss) - printf("alarm value %u task resumed at %u\n", TEST_TIMER_ALARM, (unsigned)resumed_counter); - TEST_ASSERT_UINT32_WITHIN(TEST_TIMER_CYCLES_PER_MS/2, TEST_TIMER_ALARM, (unsigned)resumed_counter); + printf("alarm value %llu task resumed at %u\n", alarm_config.alarm_count, (unsigned)resumed_counter); + TEST_ASSERT_UINT32_WITHIN(100, alarm_config.alarm_count, (unsigned)resumed_counter); // clean up - timer_deinit(TIMER_GROUP_0, TIMER_0); - ESP_ERROR_CHECK( esp_intr_free(isr_handle) ); + TEST_ESP_OK(gptimer_del_timer(gptimer)); } TEST_CASE("Resume task from ISR (same core)", "[freertos]") @@ -216,7 +194,7 @@ TEST_CASE("Resume task from ISR (other core)", "[freertos]") static volatile bool block; static bool suspend_both_cpus; -static void IRAM_ATTR suspend_scheduler_while_block_set(void* arg) +static void IRAM_ATTR suspend_scheduler_while_block_set(void *arg) { vTaskSuspendAll(); diff --git a/components/spi_flash/test/test_spi_flash.c b/components/spi_flash/test/test_spi_flash.c index dd5a5f69a2..38837d07ff 100644 --- a/components/spi_flash/test/test_spi_flash.c +++ b/components/spi_flash/test/test_spi_flash.c @@ -7,7 +7,6 @@ #include #include #include -#include "driver/timer.h" #include "esp_intr_alloc.h" #include "test_utils.h" #include "ccomp_timer.h" @@ -117,88 +116,6 @@ TEST_CASE("flash write and erase work both on PRO CPU and on APP CPU", "[spi_fla vSemaphoreDelete(done); } - - -typedef struct { - size_t buf_size; - uint8_t* buf; - size_t flash_addr; - size_t repeat_count; - SemaphoreHandle_t done; -} read_task_arg_t; - - -typedef struct { - size_t delay_time_us; - size_t repeat_count; -} block_task_arg_t; - -#ifdef CONFIG_IDF_TARGET_ESP32S2 -#define int_clr_timers int_clr -#endif - -static void IRAM_ATTR timer_isr(void* varg) { - block_task_arg_t* arg = (block_task_arg_t*) varg; - timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0); - timer_group_enable_alarm_in_isr(TIMER_GROUP_0, TIMER_0); - esp_rom_delay_us(arg->delay_time_us); - arg->repeat_count++; -} - -static void read_task(void* varg) { - read_task_arg_t* arg = (read_task_arg_t*) varg; - for (size_t i = 0; i < arg->repeat_count; ++i) { - ESP_ERROR_CHECK( spi_flash_read(arg->flash_addr, arg->buf, arg->buf_size) ); - } - xSemaphoreGive(arg->done); - vTaskDelay(1); - vTaskDelete(NULL); -} - -TEST_CASE("spi flash functions can run along with IRAM interrupts", "[spi_flash][esp_flash]") -{ - const size_t size = 128; - read_task_arg_t read_arg = { - .buf_size = size, - .buf = (uint8_t*) malloc(size), - .flash_addr = 0, - .repeat_count = 1000, - .done = xSemaphoreCreateBinary() - }; - - timer_config_t config = { - .alarm_en = true, - .counter_en = false, - .intr_type = TIMER_INTR_LEVEL, - .counter_dir = TIMER_COUNT_UP, - .auto_reload = true, - .divider = 80 - }; - - block_task_arg_t block_arg = { - .repeat_count = 0, - .delay_time_us = 100 - }; - - ESP_ERROR_CHECK( timer_init(TIMER_GROUP_0, TIMER_0, &config) ); - timer_pause(TIMER_GROUP_0, TIMER_0); - ESP_ERROR_CHECK( timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 120) ); - intr_handle_t handle; - ESP_ERROR_CHECK( timer_isr_register(TIMER_GROUP_0, TIMER_0, &timer_isr, &block_arg, ESP_INTR_FLAG_IRAM, &handle) ); - timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0); - timer_enable_intr(TIMER_GROUP_0, TIMER_0); - timer_start(TIMER_GROUP_0, TIMER_0); - - xTaskCreatePinnedToCore(read_task, "r", 2048, &read_arg, 3, NULL, portNUM_PROCESSORS - 1); - xSemaphoreTake(read_arg.done, portMAX_DELAY); - - timer_pause(TIMER_GROUP_0, TIMER_0); - timer_disable_intr(TIMER_GROUP_0, TIMER_0); - esp_intr_free(handle); - vSemaphoreDelete(read_arg.done); - free(read_arg.buf); -} - #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3) // TODO ESP32-S3 IDF-2021 diff --git a/components/vfs/test/test_vfs_eventfd.c b/components/vfs/test/test_vfs_eventfd.c index 0d051008f1..6e5c40a004 100644 --- a/components/vfs/test/test_vfs_eventfd.c +++ b/components/vfs/test/test_vfs_eventfd.c @@ -1,26 +1,16 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License - -#include "esp_vfs_eventfd.h" +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include - -#include "driver/timer.h" -#include "esp_vfs.h" #include "freertos/FreeRTOS.h" #include "unity.h" +#include "driver/gptimer.h" +#include "esp_vfs.h" +#include "esp_vfs_eventfd.h" TEST_CASE("eventfd create and close", "[vfs][eventfd]") { @@ -217,13 +207,14 @@ TEST_CASE("eventfd signal from task", "[vfs][eventfd]") TEST_ESP_OK(esp_vfs_eventfd_unregister()); } -static void eventfd_select_test_isr(void *arg) +static bool eventfd_select_test_isr(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx) { - int fd = *((int *)arg); + gptimer_stop(timer); + int fd = *((int *)user_ctx); uint64_t val = 1; - timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0); int ret = write(fd, &val, sizeof(val)); assert(ret == sizeof(val)); + return true; } TEST_CASE("eventfd signal from ISR", "[vfs][eventfd]") @@ -234,22 +225,23 @@ TEST_CASE("eventfd signal from ISR", "[vfs][eventfd]") int fd = eventfd(0, EFD_SUPPORT_ISR); TEST_ASSERT_GREATER_OR_EQUAL(0, fd); - timer_config_t timer_config = { - .divider = 16, - .counter_dir = TIMER_COUNT_UP, - .counter_en = TIMER_PAUSE, - .alarm_en = TIMER_ALARM_EN, - .auto_reload = false, + gptimer_handle_t gptimer = NULL; + gptimer_config_t timer_config = { + .clk_src = GPTIMER_CLK_SRC_APB, + .direction = GPTIMER_COUNT_UP, + .resolution_hz = 1000000, }; - TEST_ESP_OK(timer_init(TIMER_GROUP_0, TIMER_0, &timer_config)); - - TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0x00000000ULL)); - - TEST_ESP_OK(timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, TIMER_BASE_CLK / 16)); - TEST_ESP_OK(timer_enable_intr(TIMER_GROUP_0, TIMER_0)); - TEST_ESP_OK(timer_isr_register(TIMER_GROUP_0, TIMER_0, eventfd_select_test_isr, - &fd, ESP_INTR_FLAG_LOWMED, NULL)); - TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0)); + TEST_ESP_OK(gptimer_new_timer(&timer_config, &gptimer)); + gptimer_alarm_config_t alarm_config = { + .reload_count = 0, + .alarm_count = 200000, + }; + gptimer_event_callbacks_t cbs = { + .on_alarm = eventfd_select_test_isr, + }; + TEST_ESP_OK(gptimer_register_event_callbacks(gptimer, &cbs, &fd)); + TEST_ESP_OK(gptimer_set_alarm_action(gptimer, &alarm_config)); + TEST_ESP_OK(gptimer_start(gptimer)); struct timeval wait_time; fd_set read_fds, write_fds, error_fds; @@ -264,9 +256,9 @@ TEST_CASE("eventfd signal from ISR", "[vfs][eventfd]") int ret = select(fd + 1, &read_fds, &write_fds, &error_fds, &wait_time); TEST_ASSERT_EQUAL(1, ret); TEST_ASSERT(FD_ISSET(fd, &read_fds)); - timer_deinit(TIMER_GROUP_0, TIMER_0); TEST_ASSERT_EQUAL(0, close(fd)); TEST_ESP_OK(esp_vfs_eventfd_unregister()); + TEST_ESP_OK(gptimer_del_timer(gptimer)); } static void close_task(void *arg) diff --git a/tools/ci/check_copyright_config.yaml b/tools/ci/check_copyright_config.yaml index bc536ecb73..b00aea17c7 100644 --- a/tools/ci/check_copyright_config.yaml +++ b/tools/ci/check_copyright_config.yaml @@ -57,6 +57,14 @@ examples_and_unit_tests: - CC0-1.0 license_for_new_files: Unlicense OR CC0-1.0 +freemodbus_component: + include: + - 'components/freemodbus/**' + allowed_licenses: + - Apache-2.0 + - BSD-3-Clause + license_for_new_files: Apache-2.0 + # files matching this section do not perform the check # file patterns starting with ! are negated, meaning files matching them won't match the section. ignore: diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index d16fc5be1c..4202f94256 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -944,7 +944,6 @@ components/freertos/test/test_task_priorities.c components/freertos/test/test_task_suspend_resume.c components/freertos/test/test_tasks_snapshot.c components/freertos/test/test_thread_local.c -components/freertos/test/test_timers.c components/freertos/test/test_xtensa_loadstore_handler.c components/hal/aes_hal.c components/hal/cpu_hal.c @@ -2106,7 +2105,6 @@ components/vfs/include/esp_vfs_eventfd.h components/vfs/include/esp_vfs_semihost.h components/vfs/test/test_vfs_access.c components/vfs/test/test_vfs_append.c -components/vfs/test/test_vfs_eventfd.c components/vfs/test/test_vfs_fd.c components/vfs/test/test_vfs_lwip.c components/vfs/test/test_vfs_paths.c diff --git a/tools/unit-test-app/components/test_utils/ref_clock_impl_timergroup.c b/tools/unit-test-app/components/test_utils/ref_clock_impl_timergroup.c index 513d667112..8b1143257f 100644 --- a/tools/unit-test-app/components/test_utils/ref_clock_impl_timergroup.c +++ b/tools/unit-test-app/components/test_utils/ref_clock_impl_timergroup.c @@ -1,41 +1,36 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "test_utils.h" -#include "esp_private/periph_ctrl.h" -#include "soc/periph_defs.h" -#include "hal/timer_hal.h" -#include "hal/timer_ll.h" +#include "unity_config.h" +#include "driver/gptimer.h" -#define TIMER_GROUP_ID (1) -#define TIMER_ID (0) -static timer_hal_context_t timer_hal; +static gptimer_handle_t ts_gptimer; void ref_clock_init(void) { - periph_module_enable(PERIPH_TIMG1_MODULE); - timer_hal_init(&timer_hal, TIMER_GROUP_ID, TIMER_ID); - timer_ll_set_clock_source(timer_hal.dev, TIMER_ID, GPTIMER_CLK_SRC_XTAL); // Select XTAL, so ref_clock is independent of the APL clock - timer_ll_enable_counter(timer_hal.dev, TIMER_ID, false); // stop timer from running - timer_ll_set_clock_prescale(timer_hal.dev, TIMER_ID, 40); // Resolution is configured to 1MHz - timer_ll_set_count_direction(timer_hal.dev, timer_hal.timer_id, GPTIMER_COUNT_UP); // increase mode - timer_hal_set_counter_value(&timer_hal, 0); // initial count value to zero - timer_ll_enable_intr(timer_hal.dev, TIMER_LL_EVENT_ALARM(TIMER_ID), false); // disable interrupt - timer_ll_enable_alarm(timer_hal.dev, TIMER_ID, false); // alarm event is not needed - timer_ll_enable_auto_reload(timer_hal.dev, TIMER_ID, false); - timer_ll_enable_counter(timer_hal.dev, TIMER_ID, true); // start counter + gptimer_config_t timer_config = { + .clk_src = GPTIMER_CLK_SRC_XTAL, + .direction = GPTIMER_COUNT_UP, + .resolution_hz = 1000000, // Resolution is configured to 1MHz + }; + TEST_ESP_OK(gptimer_new_timer(&timer_config, &ts_gptimer)); + TEST_ESP_OK(gptimer_start(ts_gptimer)); } void ref_clock_deinit(void) { - timer_ll_enable_counter(timer_hal.dev, TIMER_ID, false); // stop timer from running - periph_module_disable(PERIPH_TIMG1_MODULE); + TEST_ESP_OK(gptimer_stop(ts_gptimer)); + TEST_ESP_OK(gptimer_del_timer(ts_gptimer)); + ts_gptimer = NULL; } uint64_t ref_clock_get(void) { - return timer_ll_get_counter_value(timer_hal.dev, timer_hal.timer_id); + uint64_t ts; + gptimer_get_raw_count(ts_gptimer, &ts); + return ts; }