]> granicus.if.org Git - esp-idf/commitdiff
esp32: ets_update_cpu_frequency should set tick scale for both CPUs
authorIvan Grokhotkov <ivan@espressif.com>
Thu, 5 Jan 2017 14:55:38 +0000 (22:55 +0800)
committerIvan Grokhotkov <ivan@espressif.com>
Fri, 6 Jan 2017 07:00:17 +0000 (15:00 +0800)
components/esp32/cpu_freq.c
components/esp32/ld/esp32.rom.ld
components/esp32/test/test_delay.c [new file with mode: 0644]

index 257639cf90e8dd20e987c2afec46228c56f15cfa..7618f147af8fe700cec9ba8ada01303af66e4b36 100644 (file)
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 #include <stdint.h>
+#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;
+}
index 6241ff840ebbf609f84253568c0181f05ae15206..8b5ed5f8dcd02b74dc266bf03ed327f63347fbe7 100644 (file)
@@ -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 (file)
index 0000000..0b6c4aa
--- /dev/null
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/time.h>
+#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);
+}