From 1cbc2fa046f4c1afd96054eb2987859c265ec361 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 5 Jan 2017 22:55:38 +0800 Subject: [PATCH] esp32: ets_update_cpu_frequency should set tick scale for both CPUs --- components/esp32/cpu_freq.c | 8 +++++ components/esp32/ld/esp32.rom.ld | 4 ++- components/esp32/test/test_delay.c | 58 ++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 components/esp32/test/test_delay.c diff --git a/components/esp32/cpu_freq.c b/components/esp32/cpu_freq.c index 257639cf9..7618f147a 100644 --- a/components/esp32/cpu_freq.c +++ b/components/esp32/cpu_freq.c @@ -13,6 +13,7 @@ // limitations under the License. #include +#include "esp_attr.h" #include "rom/ets_sys.h" #include "rom/uart.h" #include "sdkconfig.h" @@ -66,3 +67,10 @@ void esp_set_cpu_freq(void) ets_update_cpu_frequency(freq_mhz); } +void IRAM_ATTR ets_update_cpu_frequency(uint32_t ticks_per_us) +{ + extern uint32_t g_ticks_per_us_pro; // g_ticks_us defined in ROM for PRO CPU + extern uint32_t g_ticks_per_us_app; // same defined for APP CPU + g_ticks_per_us_pro = ticks_per_us; + g_ticks_per_us_app = ticks_per_us; +} diff --git a/components/esp32/ld/esp32.rom.ld b/components/esp32/ld/esp32.rom.ld index 6241ff840..8b5ed5f8d 100644 --- a/components/esp32/ld/esp32.rom.ld +++ b/components/esp32/ld/esp32.rom.ld @@ -202,7 +202,7 @@ PROVIDE ( ets_timer_init = 0x400084e8 ); PROVIDE ( ets_timer_setfn = 0x40008350 ); PROVIDE ( ets_unpack_flash_code = 0x40007018 ); PROVIDE ( ets_unpack_flash_code_legacy = 0x4000694c ); -PROVIDE ( ets_update_cpu_frequency = 0x40008550 ); +/* PROVIDE ( ets_update_cpu_frequency = 0x40008550 ); */ /* Updates g_ticks_per_us on the current CPU only; not on the other core */ PROVIDE ( ets_waiti0 = 0x400067d8 ); PROVIDE ( exc_cause_table = 0x3ff991d0 ); PROVIDE ( _exit_r = 0x4000bd28 ); @@ -1725,6 +1725,8 @@ PROVIDE ( xthal_memcpy = 0x4000c0bc ); PROVIDE ( xthal_set_ccompare = 0x4000c058 ); PROVIDE ( xthal_set_intclear = 0x4000c1ec ); PROVIDE ( _xtos_set_intlevel = 0x4000bfdc ); +PROVIDE ( g_ticks_per_us_pro = 0x3ffe01e0 ); +PROVIDE ( g_ticks_per_us_app = 0x3ffe40f0 ); /* These functions are xtos-related (or call xtos-related functions) and do not play well with multicore FreeRTOS. Where needed, we provide alternatives that are multicore diff --git a/components/esp32/test/test_delay.c b/components/esp32/test/test_delay.c new file mode 100644 index 000000000..0b6c4aaf9 --- /dev/null +++ b/components/esp32/test/test_delay.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include "unity.h" +#include "rom/ets_sys.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +typedef struct { + int delay_us; + int method; +} delay_test_arg_t; + +static void test_delay_task(void* p) +{ + const delay_test_arg_t* arg = (delay_test_arg_t*) p; + struct timeval tv_start, tv_stop; + gettimeofday(&tv_start, NULL); + switch (arg->method) { + case 0: + ets_delay_us(arg->delay_us); + break; + case 1: + vTaskDelay(arg->delay_us / portTICK_PERIOD_MS / 1000); + break; + default: + TEST_FAIL(); + } + gettimeofday(&tv_stop, NULL); + int real_delay_us = (tv_stop.tv_sec - tv_start.tv_sec) * 1000000 + + tv_stop.tv_usec - tv_start.tv_usec; + printf("%s core=%d expected=%d actual=%d\n", arg->method ? "vTaskDelay" : "ets_delay_us", + xPortGetCoreID(), arg->delay_us, real_delay_us); + TEST_ASSERT_TRUE(abs(real_delay_us - arg->delay_us) < 1000); + vTaskDelay(1); + vTaskDelete(NULL); +} + +TEST_CASE("ets_delay produces correct delay on both CPUs", "[delay]") +{ + int delay_ms = 50; + const delay_test_arg_t args = { .delay_us = delay_ms * 1000, .method = 0 }; + xTaskCreatePinnedToCore(test_delay_task, "", 2048, (void*) &args, 3, NULL, 0); + vTaskDelay(delay_ms / portTICK_PERIOD_MS + 1); + xTaskCreatePinnedToCore(test_delay_task, "", 2048, (void*) &args, 3, NULL, 1); + vTaskDelay(delay_ms / portTICK_PERIOD_MS + 1); +} + +TEST_CASE("vTaskDelay produces correct delay on both CPUs", "[delay]") +{ + int delay_ms = 50; + const delay_test_arg_t args = { .delay_us = delay_ms * 1000, .method = 1 }; + xTaskCreatePinnedToCore(test_delay_task, "", 2048, (void*) &args, 3, NULL, 0); + vTaskDelay(delay_ms / portTICK_PERIOD_MS + 1); + xTaskCreatePinnedToCore(test_delay_task, "", 2048, (void*) &args, 3, NULL, 1); + vTaskDelay(delay_ms / portTICK_PERIOD_MS + 1); +}