diff --git a/components/esp_system/startup.c b/components/esp_system/startup.c index 0c4ad2d685..d8f4d039d5 100644 --- a/components/esp_system/startup.c +++ b/components/esp_system/startup.c @@ -198,8 +198,7 @@ static void do_core_init(void) app CPU, and when that is not up yet, the memory will be inaccessible and heap_caps_init may fail initializing it properly. */ heap_caps_init(); - esp_setup_syscall_table(); - esp_newlib_locks_init(); + esp_newlib_init(); esp_newlib_time_init(); if (g_spiram_ok) { diff --git a/components/newlib/CMakeLists.txt b/components/newlib/CMakeLists.txt index 670be02dbc..0f869ed475 100644 --- a/components/newlib/CMakeLists.txt +++ b/components/newlib/CMakeLists.txt @@ -6,7 +6,7 @@ set(srcs "pthread.c" "random.c" "reent_init.c" - "syscall_table.c" + "newlib_init.c" "syscalls.c" "termios.c" "time.c") @@ -30,7 +30,7 @@ target_link_libraries(${COMPONENT_LIB} INTERFACE c m gcc "$ #include #include "esp_newlib.h" +#include "esp_attr.h" #include "sdkconfig.h" #include "soc/soc_caps.h" @@ -32,6 +33,8 @@ #include "esp32s2/rom/libc_stubs.h" #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/rom/libc_stubs.h" +#elif CONFIG_IDF_TARGET_ESP32C3 +#include "esp32c3/rom/libc_stubs.h" #endif static struct _reent s_reent; @@ -78,6 +81,18 @@ static struct syscall_stub_table s_stub_table = { ._write_r = (int (*)(struct _reent *r, int, const void *, int)) &_write_r, ._lseek_r = (int (*)(struct _reent *r, int, int, int)) &_lseek_r, ._read_r = (int (*)(struct _reent *r, int, void *, int)) &_read_r, +#if _RETARGETABLE_LOCKING /* TODO: only if RETARGETABLE LOCKING IS IN ROM */ + ._retarget_lock_init = &__retarget_lock_init, + ._retarget_lock_init_recursive = &__retarget_lock_init_recursive, + ._retarget_lock_close = &__retarget_lock_close, + ._retarget_lock_close_recursive = &__retarget_lock_close_recursive, + ._retarget_lock_acquire = &__retarget_lock_acquire, + ._retarget_lock_acquire_recursive = &__retarget_lock_acquire_recursive, + ._retarget_lock_try_acquire = &__retarget_lock_try_acquire, + ._retarget_lock_try_acquire_recursive = &__retarget_lock_try_acquire_recursive, + ._retarget_lock_release = &__retarget_lock_release, + ._retarget_lock_release_recursive = &__retarget_lock_release_recursive, +#else ._lock_init = &_lock_init, ._lock_init_recursive = &_lock_init_recursive, ._lock_close = &_lock_close, @@ -88,6 +103,7 @@ static struct syscall_stub_table s_stub_table = { ._lock_try_acquire_recursive = &_lock_try_acquire_recursive, ._lock_release = &_lock_release, ._lock_release_recursive = &_lock_release_recursive, +#endif #ifdef CONFIG_NEWLIB_NANO_FORMAT ._printf_float = &_printf_float, ._scanf_float = &_scanf_float, @@ -95,15 +111,39 @@ static struct syscall_stub_table s_stub_table = { ._printf_float = NULL, ._scanf_float = NULL, #endif +#ifdef CONFIG_IDF_TARGET_ESP32C3 + /* TODO: mark that this assert failed in ROM, to avoid confusion between IDF & ROM + assertion failures (as function names & source file names will be similar) + */ + .__assert_func = __assert_func, + + /* We don't expect either ROM code or IDF to ever call __sinit, so it's implemented as abort() for now. + + esp_reent_init() does this job inside IDF. + + Kept in the syscall table in case we find a need for it later. + */ + .__sinit = (void *)abort, + ._cleanup_r = &_cleanup_r, +#endif }; -void esp_setup_syscall_table(void) +void esp_newlib_init(void) { +#if CONFIG_IDF_TARGET_ESP32 + syscall_table_ptr_pro = syscall_table_ptr_app = &s_stub_table; +#elif CONFIG_IDF_TARGET_ESP32S2 syscall_table_ptr_pro = &s_stub_table; -#if SOC_CPU_CORES_NUM == 2 - syscall_table_ptr_app = &s_stub_table; +#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 + syscall_table_ptr = &s_stub_table; #endif + _GLOBAL_REENT = &s_reent; + environ = malloc(sizeof(char*)); environ[0] = NULL; + + esp_newlib_locks_init(); } + +void esp_setup_newlib_syscalls(void) __attribute__((alias("esp_newlib_init"))); diff --git a/components/newlib/platform_include/esp_newlib.h b/components/newlib/platform_include/esp_newlib.h index b4aa54e41a..fe06a33486 100644 --- a/components/newlib/platform_include/esp_newlib.h +++ b/components/newlib/platform_include/esp_newlib.h @@ -36,12 +36,16 @@ void esp_reent_init(struct _reent* r); void esp_reent_cleanup(void); /** - * Function which sets up syscall table used by newlib functions in ROM. + * Function which sets up newlib in ROM for use with ESP-IDF + * + * Includes defining the syscall table, setting up any common locks, etc. * * Called from the startup code, not intended to be called from application * code. */ -void esp_setup_syscall_table(void); +void esp_newlib_init(void); + +void esp_setup_syscall_table(void) __attribute__((deprecated("Please call esp_newlib_init() in newer code"))); /** * Update current microsecond time from RTC diff --git a/components/newlib/test/test_newlib.c b/components/newlib/test/test_newlib.c index 69d31bfe60..adca8f9ed3 100644 --- a/components/newlib/test/test_newlib.c +++ b/components/newlib/test/test_newlib.c @@ -141,7 +141,7 @@ TEST_CASE("check if ROM or Flash is used for functions", "[newlib]") #if defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_SPIRAM) TEST_ASSERT(fn_in_rom(atoi)); TEST_ASSERT(fn_in_rom(strtol)); -#elif defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3) +#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C3) /* S3 and C3 always use these from ROM */ TEST_ASSERT(fn_in_rom(atoi)); TEST_ASSERT(fn_in_rom(strtol)); diff --git a/tools/ci/test_build_system.sh b/tools/ci/test_build_system.sh index 780bda49f6..8ffffbd994 100755 --- a/tools/ci/test_build_system.sh +++ b/tools/ci/test_build_system.sh @@ -181,7 +181,7 @@ function run_tests() assert_rebuilt esp32/component_project_vars.mk # pick one each of .c, .cpp, .S that #includes sdkconfig.h # and therefore should rebuild - assert_rebuilt newlib/syscall_table.o + assert_rebuilt newlib/newlib_init.o assert_rebuilt nvs_flash/src/nvs_api.o assert_rebuilt freertos/port/xtensa/xtensa_vectors.o @@ -191,7 +191,7 @@ function run_tests() touch Makefile make # similar to previous test - assert_rebuilt newlib/syscall_table.o + assert_rebuilt newlib/newlib_init.o assert_rebuilt nvs_flash/src/nvs_api.o assert_rebuilt freertos/port/xtensa/xtensa_vectors.o diff --git a/tools/ci/test_build_system_cmake.sh b/tools/ci/test_build_system_cmake.sh index 10794abcb6..2d35ee50b3 100755 --- a/tools/ci/test_build_system_cmake.sh +++ b/tools/ci/test_build_system_cmake.sh @@ -225,7 +225,7 @@ function run_tests() assert_rebuilt config/sdkconfig.h # pick one each of .c, .cpp, .S that #includes sdkconfig.h # and therefore should rebuild - assert_rebuilt esp-idf/newlib/CMakeFiles/${IDF_COMPONENT_PREFIX}_newlib.dir/syscall_table.c.obj + assert_rebuilt esp-idf/newlib/CMakeFiles/${IDF_COMPONENT_PREFIX}_newlib.dir/newlib_init.c.obj assert_rebuilt esp-idf/nvs_flash/CMakeFiles/${IDF_COMPONENT_PREFIX}_nvs_flash.dir/src/nvs_api.cpp.obj assert_rebuilt esp-idf/freertos/CMakeFiles/${IDF_COMPONENT_PREFIX}_freertos.dir/port/xtensa/xtensa_vectors.S.obj mv sdkconfig.bak sdkconfig @@ -240,7 +240,7 @@ function run_tests() idf.py build || failure "Build failed" mv CMakeLists.bak CMakeLists.txt # similar to previous test - assert_rebuilt esp-idf/newlib/CMakeFiles/${IDF_COMPONENT_PREFIX}_newlib.dir/syscall_table.c.obj + assert_rebuilt esp-idf/newlib/CMakeFiles/${IDF_COMPONENT_PREFIX}_newlib.dir/newlib_init.c.obj assert_rebuilt esp-idf/nvs_flash/CMakeFiles/${IDF_COMPONENT_PREFIX}_nvs_flash.dir/src/nvs_api.cpp.obj assert_rebuilt esp-idf/freertos/CMakeFiles/${IDF_COMPONENT_PREFIX}_freertos.dir/port/xtensa/xtensa_vectors.S.obj mv sdkconfig.bak sdkconfig