From c8d4ea1e8c2a46b0f8714604d494a85059d598e3 Mon Sep 17 00:00:00 2001 From: schnittchen Date: Wed, 12 Nov 2025 22:04:09 +0100 Subject: [PATCH 1/2] Add esp.timer_get_time Signed-off-by: schnittchen --- CHANGELOG.md | 1 + libs/eavmlib/src/esp.erl | 13 +++++++- .../esp32/components/avm_sys/platform_nifs.c | 18 +++++++++++ .../test/main/test_erl_sources/CMakeLists.txt | 3 ++ .../test_esp_timer_get_time.erl | 32 +++++++++++++++++++ src/platforms/esp32/test/main/test_main.c | 6 ++++ 6 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/platforms/esp32/test/main/test_erl_sources/test_esp_timer_get_time.erl diff --git a/CHANGELOG.md b/CHANGELOG.md index 87918e9643..949ff41d1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `proc_lib` - Added gen_server support for timeout tuples in callback return actions introduced in OTP-28. - Added `sys` +- Added `esp:timer_get_time/0` ### Changed diff --git a/libs/eavmlib/src/esp.erl b/libs/eavmlib/src/esp.erl index 579bf27181..c744b324ae 100644 --- a/libs/eavmlib/src/esp.erl +++ b/libs/eavmlib/src/esp.erl @@ -61,7 +61,8 @@ task_wdt_deinit/0, task_wdt_add_user/1, task_wdt_reset_user/1, - task_wdt_delete_user/1 + task_wdt_delete_user/1, + timer_get_time/0 ]). -deprecated([ @@ -677,3 +678,13 @@ task_wdt_reset_user(_UserHandle) -> -spec task_wdt_delete_user(UserHandle :: task_wdt_user_handle()) -> ok | {error, any()}. task_wdt_delete_user(_UserHandle) -> erlang:nif_error(undefined). + +%%----------------------------------------------------------------------------- +%% @returns integer +%% @doc Get time in microseconds since boot or wakeup from deep sleep +%% Available with ESP-IDF 5.0 or higher. +%% @end +%%----------------------------------------------------------------------------- +-spec timer_get_time() -> integer(). +timer_get_time() -> + erlang:nif_error(undefined). diff --git a/src/platforms/esp32/components/avm_sys/platform_nifs.c b/src/platforms/esp32/components/avm_sys/platform_nifs.c index 876818168d..22907da009 100644 --- a/src/platforms/esp32/components/avm_sys/platform_nifs.c +++ b/src/platforms/esp32/components/avm_sys/platform_nifs.c @@ -34,6 +34,7 @@ #include "esp_log.h" #include "esp_mac.h" +#include "esp_timer.h" #include #include #include @@ -834,6 +835,13 @@ static term nif_esp_task_wdt_delete_user(Context *ctx, int argc, term argv[]) } #endif +static term nif_esp_timer_get_time(Context *ctx, int argc, term argv[]) +{ + UNUSED(argc); + + return term_make_maybe_boxed_int64(esp_timer_get_time(), &ctx->heap); +} + // // NIF structures and dispatch // @@ -980,6 +988,12 @@ static const struct Nif esp_task_wdt_delete_user_nif = }; #endif +static const struct Nif esp_timer_get_time_nif = +{ + .base.type = NIFFunctionType, + .nif_ptr = nif_esp_timer_get_time +}; + const struct Nif *platform_nifs_get_nif(const char *nifname) { if (strcmp("atomvm:random/0", nifname) == 0) { @@ -1106,6 +1120,10 @@ const struct Nif *platform_nifs_get_nif(const char *nifname) return &esp_task_wdt_delete_user_nif; } #endif + if (strcmp("esp:timer_get_time/0", nifname) == 0) { + TRACE("Resolved platform nif %s ...\n", nifname); + return &esp_timer_get_time_nif; + } const struct Nif *nif = nif_collection_resolve_nif(nifname); if (nif) { return nif; diff --git a/src/platforms/esp32/test/main/test_erl_sources/CMakeLists.txt b/src/platforms/esp32/test/main/test_erl_sources/CMakeLists.txt index e2d67269e8..10dd759a65 100644 --- a/src/platforms/esp32/test/main/test_erl_sources/CMakeLists.txt +++ b/src/platforms/esp32/test/main/test_erl_sources/CMakeLists.txt @@ -38,6 +38,7 @@ function(compile_erlang module_name) endfunction() compile_erlang(test_esp_partition) +compile_erlang(test_esp_timer_get_time) compile_erlang(test_file) compile_erlang(test_wifi_example) compile_erlang(test_list_to_atom) @@ -60,6 +61,7 @@ add_custom_command( COMMAND HostAtomVM-prefix/src/HostAtomVM-build/tools/packbeam/PackBEAM -i esp32_test_modules.avm HostAtomVM-prefix/src/HostAtomVM-build/libs/atomvmlib.avm test_esp_partition.beam + test_esp_timer_get_time.beam test_file.beam test_wifi_example.beam test_list_to_atom.beam @@ -79,6 +81,7 @@ add_custom_command( DEPENDS HostAtomVM "${CMAKE_CURRENT_BINARY_DIR}/test_esp_partition.beam" + "${CMAKE_CURRENT_BINARY_DIR}/test_esp_timer_get_time.beam" "${CMAKE_CURRENT_BINARY_DIR}/test_wifi_example.beam" "${CMAKE_CURRENT_BINARY_DIR}/test_file.beam" "${CMAKE_CURRENT_BINARY_DIR}/test_list_to_atom.beam" diff --git a/src/platforms/esp32/test/main/test_erl_sources/test_esp_timer_get_time.erl b/src/platforms/esp32/test/main/test_erl_sources/test_esp_timer_get_time.erl new file mode 100644 index 0000000000..f8f05108ca --- /dev/null +++ b/src/platforms/esp32/test/main/test_erl_sources/test_esp_timer_get_time.erl @@ -0,0 +1,32 @@ +% +% This file is part of AtomVM. +% +% Copyright 2023 Davide Bettio +% +% 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. +% +% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later +% + +-module(test_esp_timer_get_time). + +-export([start/0]). + +start() -> + T = esp:timer_get_time(), + test_non_neg_int(T). + +test_non_neg_int(X) when is_integer(X) andalso X >= 0 -> + ok; +test_non_neg_int(_X) -> + error. diff --git a/src/platforms/esp32/test/main/test_main.c b/src/platforms/esp32/test/main/test_main.c index 93928c6b74..623c6dc87e 100644 --- a/src/platforms/esp32/test/main/test_main.c +++ b/src/platforms/esp32/test/main/test_main.c @@ -180,6 +180,12 @@ TEST_CASE("test_esp_partition", "[test_run]") TEST_ASSERT(term_to_int(ret_value) == 0); } +TEST_CASE("test_esp_timer_get_time", "[test_run]") +{ + term ret_value = avm_test_case("test_esp_timer_get_time.beam"); + TEST_ASSERT(ret_value == OK_ATOM); +} + // SDMMC works all esp-idf versions for esp32 - still no support c3. // only run in QEMU (eg. OPENETH configured) #if !CONFIG_IDF_TARGET_ESP32C3 && CONFIG_ETH_USE_OPENETH From 2815c5e4dd84890b8b6027a6862223d7d09a1d47 Mon Sep 17 00:00:00 2001 From: schnittchen Date: Thu, 27 Nov 2025 21:50:49 +0100 Subject: [PATCH 2/2] [squash!] final changes Signed-off-by: schnittchen --- src/platforms/esp32/components/avm_sys/platform_nifs.c | 1 + .../test/main/test_erl_sources/test_esp_timer_get_time.erl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platforms/esp32/components/avm_sys/platform_nifs.c b/src/platforms/esp32/components/avm_sys/platform_nifs.c index 22907da009..ae69e3ed00 100644 --- a/src/platforms/esp32/components/avm_sys/platform_nifs.c +++ b/src/platforms/esp32/components/avm_sys/platform_nifs.c @@ -837,6 +837,7 @@ static term nif_esp_task_wdt_delete_user(Context *ctx, int argc, term argv[]) static term nif_esp_timer_get_time(Context *ctx, int argc, term argv[]) { + UNUSED(argv); UNUSED(argc); return term_make_maybe_boxed_int64(esp_timer_get_time(), &ctx->heap); diff --git a/src/platforms/esp32/test/main/test_erl_sources/test_esp_timer_get_time.erl b/src/platforms/esp32/test/main/test_erl_sources/test_esp_timer_get_time.erl index f8f05108ca..e873ce6da9 100644 --- a/src/platforms/esp32/test/main/test_erl_sources/test_esp_timer_get_time.erl +++ b/src/platforms/esp32/test/main/test_erl_sources/test_esp_timer_get_time.erl @@ -1,7 +1,7 @@ % % This file is part of AtomVM. % -% Copyright 2023 Davide Bettio +% Copyright 2025 schnittchen % % Licensed under the Apache License, Version 2.0 (the "License"); % you may not use this file except in compliance with the License.