mirror of
https://github.com/espressif/esp-idf.git
synced 2025-12-26 21:29:33 +00:00
Merge branch 'feature/update-toolchain-to-esp-15.2.0_20250929.4-6d3fdb7' into 'master'
Make Picolibc the default libc See merge request espressif/esp-idf!43620
This commit is contained in:
@@ -25,19 +25,33 @@ check_public_headers:
|
||||
- .host_test_template
|
||||
- .rules:build:check
|
||||
script:
|
||||
- IDF_TARGET=esp32 python tools/ci/check_public_headers.py --jobs 4 --prefix xtensa-esp32-elf-
|
||||
- IDF_TARGET=esp32s2 python tools/ci/check_public_headers.py --jobs 4 --prefix xtensa-esp32s2-elf-
|
||||
- IDF_TARGET=esp32s3 python tools/ci/check_public_headers.py --jobs 4 --prefix xtensa-esp32s3-elf-
|
||||
- IDF_TARGET=esp32c3 python tools/ci/check_public_headers.py --jobs 4 --prefix riscv32-esp-elf-
|
||||
- IDF_TARGET=esp32c2 python tools/ci/check_public_headers.py --jobs 4 --prefix riscv32-esp-elf-
|
||||
- IDF_TARGET=esp32c6 python tools/ci/check_public_headers.py --jobs 4 --prefix riscv32-esp-elf-
|
||||
- IDF_TARGET=esp32c5 python tools/ci/check_public_headers.py --jobs 4 --prefix riscv32-esp-elf-
|
||||
- IDF_TARGET=esp32h2 python tools/ci/check_public_headers.py --jobs 4 --prefix riscv32-esp-elf-
|
||||
- IDF_TARGET=esp32p4 python tools/ci/check_public_headers.py --jobs 4 --prefix riscv32-esp-elf-
|
||||
- IDF_TARGET=esp32c61 python tools/ci/check_public_headers.py --jobs 4 --prefix riscv32-esp-elf-
|
||||
- IDF_TARGET=esp32h21 python tools/ci/check_public_headers.py --jobs 4 --prefix riscv32-esp-elf-
|
||||
- IDF_TARGET=esp32h4 python tools/ci/check_public_headers.py --jobs 4 --prefix riscv32-esp-elf-
|
||||
- IDF_TARGET=esp32s31 python tools/ci/check_public_headers.py --jobs 4 --prefix riscv32-esp-elf-
|
||||
- |
|
||||
targets="esp32 \
|
||||
esp32s2 \
|
||||
esp32s3 \
|
||||
esp32c3 \
|
||||
esp32c2 \
|
||||
esp32c6 \
|
||||
esp32c5 \
|
||||
esp32h2 \
|
||||
esp32p4 \
|
||||
esp32c61 \
|
||||
esp32h21 \
|
||||
esp32h4 \
|
||||
esp32s31"
|
||||
for libc in newlib picolibc; do
|
||||
for target in ${targets}; do
|
||||
case "${target}" in
|
||||
esp32|esp32s2|esp32s3)
|
||||
PREFIX="xtensa-${target}-elf-"
|
||||
;;
|
||||
*)
|
||||
PREFIX="riscv32-esp-elf-"
|
||||
;;
|
||||
esac
|
||||
IDF_TARGET=${target} python tools/ci/check_public_headers.py --jobs 4 --prefix ${PREFIX} --libc-type ${libc}
|
||||
done
|
||||
done
|
||||
|
||||
test_nvs_coverage:
|
||||
extends:
|
||||
|
||||
@@ -78,11 +78,22 @@ else()
|
||||
list(APPEND cxx_compile_options "-fno-exceptions")
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_CXX_RTTI)
|
||||
list(APPEND cxx_compile_options "-frtti")
|
||||
else()
|
||||
list(APPEND cxx_compile_options "-fno-rtti")
|
||||
list(APPEND link_options "-fno-rtti") # used to invoke correct multilib variant (no-rtti) during linking
|
||||
if(CONFIG_IDF_TOOLCHAIN_GCC)
|
||||
if(CONFIG_COMPILER_CXX_RTTI)
|
||||
idf_toolchain_remove_flags(CXX_COMPILE_OPTIONS "-fno-rtti"
|
||||
LINK_OPTIONS "-fno-rtti")
|
||||
else()
|
||||
idf_toolchain_add_flags(CXX_COMPILE_OPTIONS "-fno-rtti"
|
||||
LINK_OPTIONS "-fno-rtti")
|
||||
endif()
|
||||
idf_toolchain_rerun_abi_detection()
|
||||
else() # TODO IDF-14338
|
||||
if(CONFIG_COMPILER_CXX_RTTI)
|
||||
list(APPEND cxx_compile_options "-frtti")
|
||||
else()
|
||||
list(APPEND cxx_compile_options "-fno-rtti")
|
||||
list(APPEND link_options "-fno-rtti") # used to invoke correct multilib variant (no-rtti) during linking
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_SAVE_RESTORE_LIBCALLS)
|
||||
|
||||
1
Kconfig
1
Kconfig
@@ -794,7 +794,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
||||
- CONFIG_ESP_WIFI_EAP_TLS1_3
|
||||
- CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
|
||||
- CONFIG_USB_HOST_EXT_PORT_RESET_ATTEMPTS
|
||||
- CONFIG_LIBC_PICOLIBC
|
||||
- CONFIG_GDMA_ENABLE_WEIGHTED_ARBITRATION
|
||||
- CONFIG_I3C_MASTER_ENABLED
|
||||
- CONFIG_ESPTOOLPY_FAST_REFLASHING
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "sys/queue.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
|
||||
#include <tinycrypt/ecc.h>
|
||||
#include <tinycrypt/ecc_platform_specific.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
idf_build_get_property(target IDF_TARGET)
|
||||
|
||||
# Note: Almost all source files in this component include console_stdio_private.h.
|
||||
# This header only affects LIBC_PICOLIBC builds, not LIBC_NEWLIB builds.
|
||||
# It enables thread-local stdio streams, which are required for console functionality in some cases.
|
||||
set(srcs "commands.c"
|
||||
"esp_console_common.c"
|
||||
"split_argv.c"
|
||||
@@ -43,6 +46,14 @@ idf_component_register(SRCS ${srcs}
|
||||
esp_usb_cdc_rom_console
|
||||
)
|
||||
|
||||
if(CONFIG_LIBC_PICOLIBC)
|
||||
list(APPEND srcs_include_stdio_private ${srcs})
|
||||
list(APPEND srcs_include_stdio_private ${argtable_srcs})
|
||||
list(REMOVE_ITEM srcs_include_stdio_private "esp_console_repl_chip.c" "esp_console_repl_linux.c")
|
||||
set_source_files_properties(${srcs_include_stdio_private}
|
||||
PROPERTIES COMPILE_FLAGS "--include=console_stdio_private.h")
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # TODO IDF-10085
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-analyzer")
|
||||
endif()
|
||||
|
||||
@@ -30,6 +30,19 @@ esp_err_t esp_console_setup_prompt(const char *prompt, esp_console_repl_com_t *r
|
||||
snprintf(repl_com->prompt, CONSOLE_PROMPT_MAX_LEN - 1, LOG_COLOR_I "%s " LOG_RESET_COLOR, prompt_temp);
|
||||
|
||||
/* Figure out if the terminal supports escape sequences */
|
||||
/* TODO IDF-14901: It is not appropriate to probe the current thread's console here.
|
||||
* The esp_console_repl_task can open its own stdin/stdout for use.
|
||||
* However, linenoiseProbe() cannot be moved to esp_console_repl_task
|
||||
* to preserve user expectations. Consider the following usage pattern:
|
||||
* esp_console_start_repl(repl);
|
||||
* printf("!!!ready!!!");
|
||||
* Users expect that when "!!!ready!!!" is printed, the console is already available.
|
||||
* If linenoiseProbe() were moved to esp_console_repl_task, race conditions
|
||||
* between threads combined with usleep() calls inside linenoiseProbe() could
|
||||
* change this behavior. Currently, there is already a race between threads,
|
||||
* but since esp_console_repl_task does not call any sleep functions, everything
|
||||
* works as users expect.
|
||||
*/
|
||||
int probe_status = linenoiseProbe();
|
||||
if (probe_status) {
|
||||
/* zero indicates success */
|
||||
@@ -159,7 +172,6 @@ void esp_console_repl_task(void *args)
|
||||
{
|
||||
esp_console_repl_universal_t *repl_conf = (esp_console_repl_universal_t *) args;
|
||||
esp_console_repl_com_t *repl_com = &repl_conf->repl_com;
|
||||
const int uart_channel = repl_conf->uart_channel;
|
||||
|
||||
/* Waiting for task notify. This happens when `esp_console_start_repl()`
|
||||
* function is called. */
|
||||
@@ -172,6 +184,16 @@ void esp_console_repl_task(void *args)
|
||||
/* Change standard input and output of the task if the requested UART is
|
||||
* NOT the default one. This block will replace stdin, stdout and stderr.
|
||||
*/
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
// TODO IDF-14901
|
||||
if (repl_com->_stdin) {
|
||||
stdin = repl_com->_stdin;
|
||||
stdout = stderr = repl_com->_stdout;
|
||||
} else {
|
||||
linenoise_init_with_global_stdio();
|
||||
}
|
||||
#else
|
||||
const int uart_channel = repl_conf->uart_channel;
|
||||
if (uart_channel != CONFIG_ESP_CONSOLE_UART_NUM) {
|
||||
char path[CONSOLE_PATH_MAX_LEN] = { 0 };
|
||||
snprintf(path, CONSOLE_PATH_MAX_LEN, "/dev/uart/%d", uart_channel);
|
||||
@@ -180,6 +202,7 @@ void esp_console_repl_task(void *args)
|
||||
stdout = fopen(path, "w");
|
||||
stderr = stdout;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Disable buffering on stdin of the current task.
|
||||
* If the console is ran on a different UART than the default one,
|
||||
@@ -231,6 +254,10 @@ void esp_console_repl_task(void *args)
|
||||
linenoiseFree(line);
|
||||
}
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
linenoise_close_stdio();
|
||||
#endif
|
||||
|
||||
if (repl_com->state_mux != NULL) {
|
||||
xSemaphoreGive(repl_com->state_mux);
|
||||
}
|
||||
|
||||
@@ -252,9 +252,42 @@ esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_con
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC // TODO IDF-14901
|
||||
#if !CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
#define tls_stdin linenoise_stdin
|
||||
#define tls_stdout linenoise_stdout
|
||||
#endif
|
||||
extern __thread FILE *tls_stdin;
|
||||
extern __thread FILE *tls_stdout;
|
||||
|
||||
// Workaround for Picolibc to use thread-local stdio streams when the console is not the default one.
|
||||
// Need to set linenoise_stdin/linenoise_stdout to correct values that will be used by the esp_console_repl_task
|
||||
// before esp_console_setup_prompt() call, because it uses them. After that, we can restore the original values.
|
||||
if (dev_config->channel != CONFIG_ESP_CONSOLE_UART_NUM) {
|
||||
char path[CONSOLE_PATH_MAX_LEN] = { 0 };
|
||||
snprintf(path, CONSOLE_PATH_MAX_LEN, "/dev/uart/%d", dev_config->channel);
|
||||
uart_repl->repl_com._stdin = fopen(path, "r");
|
||||
uart_repl->repl_com._stdout = fopen(path, "w");
|
||||
}
|
||||
FILE *tmp_stdin = stdin;
|
||||
FILE *tmp_stdout = stdout;
|
||||
if (uart_repl->repl_com._stdin) {
|
||||
tls_stdin = uart_repl->repl_com._stdin;
|
||||
tls_stdout = uart_repl->repl_com._stdout;
|
||||
}
|
||||
#endif
|
||||
|
||||
// setup prompt
|
||||
esp_console_setup_prompt(repl_config->prompt, &uart_repl->repl_com);
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC // TODO IDF-14901
|
||||
if (uart_repl->repl_com._stdin) {
|
||||
// Restore the original values of tls_stdin and tls_stdout just in case.
|
||||
tls_stdin = tmp_stdin;
|
||||
tls_stdout = tmp_stdout;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Fill the structure here as it will be used directly by the created task. */
|
||||
uart_repl->uart_channel = dev_config->channel;
|
||||
uart_repl->repl_com.state = CONSOLE_REPL_STATE_INIT;
|
||||
|
||||
@@ -124,6 +124,14 @@
|
||||
#include <sys/param.h>
|
||||
#include <assert.h>
|
||||
#include "linenoise.h"
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
#include <stdio-bufio.h>
|
||||
#endif
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC && !CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
__thread FILE *linenoise_stdin;
|
||||
__thread FILE *linenoise_stdout;
|
||||
#endif
|
||||
|
||||
#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
|
||||
#define LINENOISE_DEFAULT_MAX_LINE 4096
|
||||
|
||||
@@ -31,6 +31,10 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
esp_console_repl_t repl_core; // base class
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
FILE *_stdin;
|
||||
FILE *_stdout;
|
||||
#endif
|
||||
char prompt[CONSOLE_PROMPT_MAX_LEN]; // Prompt to be printed before each line
|
||||
repl_state_t state;
|
||||
SemaphoreHandle_t state_mux;
|
||||
|
||||
79
components/console/private_include/console_stdio_private.h
Normal file
79
components/console/private_include/console_stdio_private.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/**
|
||||
* This file provides thread-local storage for stdin/stdout streams when using
|
||||
* picolibc to have thread-local stdio streams instead of global ones.
|
||||
* It enables per-thread stdio redirection by:
|
||||
* - Defining thread-local FILE* variables (tls_stdin, tls_stdout)
|
||||
* - Redefining standard I/O macros (stdin, stdout, printf, scanf, etc.) to use TLS streams
|
||||
* - Providing initialization and cleanup functions for TLS stdio streams
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stdio.h>
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC && !CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
#define tls_stdin linenoise_stdin
|
||||
#define tls_stdout linenoise_stdout
|
||||
#endif
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
extern __thread FILE *tls_stdin;
|
||||
extern __thread FILE *tls_stdout;
|
||||
#endif
|
||||
|
||||
static inline void linenoise_init_with_global_stdio(void)
|
||||
{
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
tls_stdin = stdin;
|
||||
tls_stdout = stdout;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void linenoise_close_stdio(void)
|
||||
{
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
if (tls_stdin != stdin) {
|
||||
fclose(tls_stdin);
|
||||
}
|
||||
if (tls_stdout != stdout) {
|
||||
fclose(tls_stdout);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
#undef stdin
|
||||
#define stdin tls_stdin
|
||||
|
||||
#undef stdout
|
||||
#define stdout tls_stdout
|
||||
|
||||
#define printf(...) fprintf(tls_stdout, __VA_ARGS__)
|
||||
#define vprintf(fmt, ap) vfprintf(tls_stdout, fmt, ap)
|
||||
#ifdef putchar
|
||||
#undef putchar
|
||||
#endif
|
||||
#define putchar(c) fputc((c), tls_stdout)
|
||||
#define puts(s) fputs((s), tls_stdout)
|
||||
|
||||
#define scanf(...) fscanf(tls_stdin, __VA_ARGS__)
|
||||
#define vscanf(fmt, ap) vfscanf(tls_stdin, fmt, ap)
|
||||
#ifdef getchar
|
||||
#undef getchar
|
||||
#endif
|
||||
#define getchar() fgetc(tls_stdin)
|
||||
#define gets(buf) fgets((buf), sizeof(buf), tls_stdin)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,4 +1,10 @@
|
||||
set(priv_requires unity console)
|
||||
|
||||
if(NOT CONFIG_IDF_TARGET_LINUX)
|
||||
list(APPEND priv_requires esp_driver_uart)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "test_app_main.c" "test_console.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES unity console
|
||||
PRIV_REQUIRES ${priv_requires}
|
||||
WHOLE_ARCHIVE)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -8,6 +8,9 @@
|
||||
#include "unity_test_runner.h"
|
||||
#include "unity_test_utils_memory.h"
|
||||
#include <sys/time.h>
|
||||
#if !CONFIG_IDF_TARGET_LINUX
|
||||
#include "driver/uart.h"
|
||||
#endif
|
||||
|
||||
// Some resources are lazy allocated (newlib locks) in the console code, the threshold is left for that case
|
||||
#define TEST_MEMORY_LEAK_THRESHOLD_DEFAULT (150)
|
||||
@@ -36,6 +39,15 @@ void app_main(void)
|
||||
struct timeval tv = { 0 };
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
#if !CONFIG_IDF_TARGET_LINUX
|
||||
/* Preallocate UART1 memory */
|
||||
fileno(stdin);
|
||||
uart_driver_install(UART_NUM_1, 256, 0, 0, NULL, 0);
|
||||
FILE *f = fopen("/dev/uart/1", "rw");
|
||||
fclose(f);
|
||||
uart_driver_delete(UART_NUM_1);
|
||||
#endif
|
||||
|
||||
printf("Running console component tests\n");
|
||||
unity_run_menu();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#if !CONFIG_IDF_TARGET_LINUX
|
||||
#include "driver/uart.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NOTE: Most of these unit tests DO NOT work standalone. They require pytest to control
|
||||
@@ -152,7 +155,7 @@ static esp_console_cmd_t s_quit_cmd = {
|
||||
ran separately in test_console_repl */
|
||||
TEST_CASE("esp console repl test", "[console][ignore]")
|
||||
{
|
||||
set_leak_threshold(416);
|
||||
set_leak_threshold(248);
|
||||
|
||||
s_test_console_mutex = xSemaphoreCreateMutexStatic(&s_test_console_mutex_buf);
|
||||
TEST_ASSERT_NOT_NULL(s_test_console_mutex);
|
||||
@@ -189,7 +192,7 @@ TEST_CASE("esp console repl test", "[console][ignore]")
|
||||
|
||||
TEST_CASE("esp console repl deinit", "[console][ignore]")
|
||||
{
|
||||
set_leak_threshold(416);
|
||||
set_leak_threshold(248);
|
||||
|
||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
||||
@@ -404,3 +407,33 @@ TEST_CASE("esp console re-register commands", "[console][ignore]")
|
||||
TEST_ESP_OK(esp_console_start_repl(s_repl));
|
||||
vTaskDelay(pdMS_TO_TICKS(5000));
|
||||
}
|
||||
|
||||
#if !CONFIG_IDF_TARGET_LINUX
|
||||
|
||||
TEST_CASE("esp console repl custom_uart test", "[console][ignore]")
|
||||
{
|
||||
set_leak_threshold(248);
|
||||
|
||||
printf("Running repl on UART1\n");
|
||||
|
||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
||||
uart_config.channel = UART_NUM_1; // Set UART1 for repl task
|
||||
|
||||
TEST_ESP_OK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
||||
|
||||
TEST_ESP_OK(esp_console_cmd_register(&s_quit_cmd));
|
||||
|
||||
TEST_ESP_OK(esp_console_start_repl(s_repl));
|
||||
|
||||
/* Wait a little for repl console initialization on UART1 */
|
||||
vTaskDelay(pdMS_TO_TICKS(300));
|
||||
|
||||
TEST_ESP_OK(esp_console_stop_repl(s_repl));
|
||||
|
||||
/* Let scheduler clean task internals */
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
|
||||
printf("ByeBye\r\n");
|
||||
}
|
||||
#endif // !CONFIG_IDF_TARGET_LINUX
|
||||
|
||||
@@ -19,7 +19,7 @@ def do_test_repl_deinit(dut: Dut) -> None:
|
||||
|
||||
def do_test_help_generic(dut: Dut, registration_order: str) -> None:
|
||||
dut.expect_exact('Press ENTER to see the list of tests')
|
||||
dut.confirm_write('"esp console help command - {} registration"'.format(registration_order), expect_str='esp>')
|
||||
dut.confirm_write(f'"esp console help command - {registration_order} registration"', expect_str='esp>')
|
||||
|
||||
dut.confirm_write('help', expect_str='aaa')
|
||||
|
||||
@@ -269,3 +269,21 @@ def test_console_help_re_register(dut: Dut, test_on: str) -> None:
|
||||
|
||||
dut.expect_exact('should appear last in help')
|
||||
dut.expect_exact('should appear first in help')
|
||||
|
||||
|
||||
@idf_parametrize('config', ['defaults'], indirect=['config'])
|
||||
@idf_parametrize(
|
||||
'target,test_on,markers',
|
||||
[
|
||||
('esp32', 'target', (pytest.mark.generic,)),
|
||||
('esp32c3', 'target', (pytest.mark.generic,)),
|
||||
('esp32', 'qemu', (pytest.mark.host_test, pytest.mark.qemu)),
|
||||
],
|
||||
indirect=['target'],
|
||||
)
|
||||
def test_console_custom_uart_repl(dut: Dut, test_on: str) -> None:
|
||||
dut.expect_exact('Press ENTER to see the list of tests')
|
||||
dut.confirm_write('"esp console repl custom_uart test"', expect_str='Running repl on UART1')
|
||||
|
||||
# make sure that global stdout has not been changed
|
||||
dut.expect_exact('ByeBye')
|
||||
|
||||
@@ -29,6 +29,11 @@ extern "C" size_t __cxx_eh_arena_size_get(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" void __esp_idf_pthread_rwlock_lazy_allocation(void)
|
||||
{
|
||||
/* TODO IDF-14862: remove */
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy function used to force linking this file.
|
||||
* This works via -u __cxx_init_dummy flag in CMakeLists.txt
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "unity_test_utils.h"
|
||||
#include "soc/soc.h"
|
||||
#include <chrono>
|
||||
#include <shared_mutex>
|
||||
#include <thread>
|
||||
#include "esp_timer.h"
|
||||
|
||||
@@ -343,6 +344,25 @@ TEST_CASE("test std::this_thread::sleep_for basic functionality", "[misc]")
|
||||
TEST_ASSERT_GREATER_OR_EQUAL(long_sleep.count(), elapsed_us);
|
||||
}
|
||||
|
||||
TEST_CASE("test std::shared_mutex memory leaks", "[misc]")
|
||||
{
|
||||
/* TODO IDF-14862:
|
||||
* check if PTHREAD_RWLOCK_INITIALIZER is still defined to not break user's code
|
||||
*/
|
||||
pthread_rwlock_t m = PTHREAD_RWLOCK_INITIALIZER;
|
||||
TEST_ASSERT_NOT_EQUAL_UINT(NULL, m);
|
||||
|
||||
std::shared_mutex* mutex_not_initialized = new std::shared_mutex();
|
||||
delete mutex_not_initialized;
|
||||
|
||||
/* A locked mutex can't be destroyed, don't test it here */
|
||||
|
||||
std::shared_mutex* mutex_unlocked = new std::shared_mutex();
|
||||
mutex_unlocked->lock();
|
||||
mutex_unlocked->unlock();
|
||||
delete mutex_unlocked;
|
||||
}
|
||||
|
||||
extern "C" void app_main(void)
|
||||
{
|
||||
s_testTLS.foo(); /* allocates memory that will be reused */
|
||||
|
||||
@@ -14,6 +14,7 @@ extern "C" {
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "sdkconfig.h"
|
||||
|
||||
bool esp_coex_common_env_is_chip_wrapper(void);
|
||||
|
||||
|
||||
@@ -224,6 +224,37 @@ FORCE_INLINE_ATTR __attribute__((pure)) void *esp_cpu_pc_to_addr(uint32_t pc)
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the current CPU core's thread pointer
|
||||
*
|
||||
* Sets the thread pointer register to the given value.
|
||||
*
|
||||
* @param threadptr Pointer to the thread-local storage area
|
||||
*/
|
||||
FORCE_INLINE_ATTR void esp_cpu_set_threadptr(void * threadptr)
|
||||
{
|
||||
#ifdef __XTENSA__
|
||||
xt_utils_set_threadptr(threadptr);
|
||||
#else
|
||||
rv_utils_set_threadptr(threadptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current CPU core's thread pointer
|
||||
*
|
||||
* @return thread pointer register value
|
||||
*/
|
||||
FORCE_INLINE_ATTR void *esp_cpu_get_threadptr(void)
|
||||
{
|
||||
#ifdef __XTENSA__
|
||||
return xt_utils_get_threadptr();
|
||||
#else
|
||||
return rv_utils_get_threadptr();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------- CPU Interrupts ----------------------------------------------------
|
||||
*
|
||||
* ------------------------------------------------------------------------------------------------------------------ */
|
||||
|
||||
@@ -64,7 +64,11 @@ else()
|
||||
list(APPEND srcs
|
||||
"src/picolibc/picolibc_init.c"
|
||||
"src/picolibc/rand.c"
|
||||
"src/picolibc/open_memstream.c")
|
||||
"src/picolibc/open_memstream.c"
|
||||
"src/picolibc/errno.c")
|
||||
if(CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY)
|
||||
list(APPEND srcs "src/picolibc/getreent.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(ldfragments "")
|
||||
|
||||
@@ -2,15 +2,46 @@ menu "LibC"
|
||||
|
||||
choice LIBC
|
||||
prompt "LibC to build application with"
|
||||
default LIBC_NEWLIB
|
||||
default LIBC_NEWLIB if IDF_TOOLCHAIN_CLANG
|
||||
default LIBC_PICOLIBC
|
||||
|
||||
config LIBC_NEWLIB
|
||||
bool "NewLib"
|
||||
config LIBC_PICOLIBC
|
||||
bool "Picolibc (EXPERIMENTAL)"
|
||||
depends on !IDF_TOOLCHAIN_CLANG && IDF_EXPERIMENTAL_FEATURES
|
||||
bool "Picolibc"
|
||||
depends on !IDF_TOOLCHAIN_CLANG
|
||||
endchoice
|
||||
|
||||
config LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
bool "Provides limited interoperability with libraries built using Newlib headers"
|
||||
default y
|
||||
depends on LIBC_PICOLIBC
|
||||
help
|
||||
This option provides limited compatibility with libraries built using Newlib headers by:
|
||||
|
||||
Enabling hidden system-header inclusions that exist in Newlib.
|
||||
Adding tls_stdio, tls_stdout, and tls_stderr variables to Thread Local Storage
|
||||
to allow prebuilt libraries to access them via getreent().
|
||||
Providing an implementation of getreent() that returns the value of the thread-pointer register.
|
||||
|
||||
Limitations:
|
||||
|
||||
1. If your application or an external prebuilt library accesses Newlib "struct _reent" implicitly,
|
||||
this may cause memory corruption on the task stack. You have two options:
|
||||
|
||||
- Use libc API calls instead of directly accessing "struct _reent" fields.
|
||||
- Switch ESP-IDF to use the Newlib implementation by setting CONFIG_LIBC_NEWLIB=y in sdkconfig.
|
||||
|
||||
2. If your application uses a prebuilt library built with Newlib headers, you may encounter
|
||||
unexpected behavior when overriding stdin, stdout, and stderr. External prebuilt libraries
|
||||
can only read these streams, so overriding them will not affect as it was for Newlib.
|
||||
You have two options to fix this:
|
||||
|
||||
- Rebuild the library with Picolibc headers that follow POSIX-standardized stdin, stdout,
|
||||
and stderr declarations.
|
||||
- Switch ESP-IDF to use the Newlib implementation by setting CONFIG_LIBC_NEWLIB=y in sdkconfig.
|
||||
|
||||
|
||||
config LIBC_MISC_IN_IRAM
|
||||
bool "Place misc libc functions (abort/assert/stdatomics) in IRAM" if SPI_FLASH_AUTO_SUSPEND
|
||||
default y
|
||||
@@ -18,7 +49,6 @@ menu "LibC"
|
||||
config LIBC_LOCKS_PLACE_IN_IRAM
|
||||
bool "Place lock API in IRAM"
|
||||
default y
|
||||
depends on LIBC_NEWLIB
|
||||
help
|
||||
Enable this option to include be able to call the lock API from
|
||||
code that runs while cache is disabled, e.g. IRAM interrupts.
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include_next <stdio.h>
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include_next <stdio.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
#include <stddef.h>
|
||||
void flockfile(FILE *);
|
||||
void funlockfile(FILE *);
|
||||
FILE *open_memstream(char **, size_t *);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#if CONFIG_LIBC_NEWLIB
|
||||
#include_next <stdio_ext.h>
|
||||
#else
|
||||
#endif
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
#include <stdio-bufio.h>
|
||||
#endif
|
||||
|
||||
12
components/esp_libc/platform_include/sys/cdefs.h
Normal file
12
components/esp_libc/platform_include/sys/cdefs.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include_next <sys/cdefs.h>
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
13
components/esp_libc/platform_include/sys/fcntl.h
Normal file
13
components/esp_libc/platform_include/sys/fcntl.h
Normal file
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include_next <sys/fcntl.h>
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
@@ -1,9 +1,13 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_LIBC_NEWLIB
|
||||
/* Newlib sys/time.h defines timerisset, timerclear, timercmp, timeradd, timersub macros
|
||||
for __CYGWIN__ and __rtems__. We want to define these macros in IDF as well.
|
||||
Since we wish to use un-modified newlib headers until a patched newlib version is
|
||||
@@ -20,3 +24,10 @@
|
||||
#define __rtems__
|
||||
#include_next <sys/time.h>
|
||||
#undef __rtems__
|
||||
#else // CONFIG_LIBC_NEWLIB
|
||||
#include_next <sys/time.h>
|
||||
#endif // CONFIG_LIBC_NEWLIB
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -7,6 +7,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#include_next <sys/unistd.h>
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ if(CONFIG_IDF_TOOLCHAIN_GCC)
|
||||
else()
|
||||
idf_toolchain_remove_flags(LINK_OPTIONS "--specs=nano.specs")
|
||||
endif()
|
||||
|
||||
idf_toolchain_rerun_abi_detection()
|
||||
else() # TODO IDF-14338
|
||||
if(CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND)
|
||||
idf_build_set_property(COMPILE_OPTIONS "-mdisable-hardware-atomics" APPEND)
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
name: 'newlib'
|
||||
version: '4.5.0'
|
||||
cpe: cpe:2.3:a:newlib_project:newlib:{}:*:*:*:*:*:*:*
|
||||
name: 'esp_libc'
|
||||
supplier: 'Organization: Espressif Systems (Shanghai) CO LTD'
|
||||
originator: 'Organization: Red Hat Incorporated'
|
||||
originator: 'Organization: Espressif Systems (Shanghai) CO LTD'
|
||||
description: An open-source C standard library implementation with additional features and patches from Espressif.
|
||||
cve-exclude-list:
|
||||
- cve: CVE-2024-30949
|
||||
reason: A vulnerability was discovered in the gettimeofday system call implementation within the RISC-V libgloss component of Newlib. ESP-IDF does not link against libgloss for RISC-V, hence the issue is not directly applicable. Still, the relevant fix has been patched through https://github.com/espressif/newlib-esp32/commit/047ba47013c2656a1e7838dc86cbc75aeeaa67a7
|
||||
virtpackages:
|
||||
- sbom_newlibc.yml
|
||||
- sbom_picolibc.yml
|
||||
|
||||
10
components/esp_libc/sbom_newlibc.yml
Normal file
10
components/esp_libc/sbom_newlibc.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
if: 'LIBC_NEWLIB'
|
||||
name: 'newlib'
|
||||
version: '4.5.0'
|
||||
cpe: cpe:2.3:a:newlib_project:newlib:{}:*:*:*:*:*:*:*
|
||||
supplier: 'Organization: Espressif Systems (Shanghai) CO LTD'
|
||||
originator: 'Organization: Red Hat Incorporated'
|
||||
description: Newlib is a small C standard library for embedded systems
|
||||
cve-exclude-list:
|
||||
- cve: CVE-2024-30949
|
||||
reason: A vulnerability was discovered in the gettimeofday system call implementation within the RISC-V libgloss component of Newlib. ESP-IDF does not link against libgloss for RISC-V, hence the issue is not directly applicable. Still, the relevant fix has been patched through https://github.com/espressif/newlib-esp32/commit/047ba47013c2656a1e7838dc86cbc75aeeaa67a7
|
||||
6
components/esp_libc/sbom_picolibc.yml
Normal file
6
components/esp_libc/sbom_picolibc.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
if: 'LIBC_PICOLIBC'
|
||||
name: 'picolib'
|
||||
version: '1.8.10'
|
||||
supplier: 'Organization: Espressif Systems (Shanghai) CO LTD'
|
||||
originator: 'Organization: keithp.com/picolibc'
|
||||
description: C Libraries for Smaller Embedded Systems
|
||||
@@ -17,9 +17,9 @@
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_LIBC_LOCKS_PLACE_IN_IRAM
|
||||
#define NEWLIB_LOCKS_IRAM_ATTR IRAM_ATTR
|
||||
#define LIBC_LOCKS_IRAM_ATTR IRAM_ATTR
|
||||
#else
|
||||
#define NEWLIB_LOCKS_IRAM_ATTR
|
||||
#define LIBC_LOCKS_IRAM_ATTR
|
||||
#endif
|
||||
|
||||
/* Notes on our newlib lock implementation:
|
||||
@@ -50,7 +50,7 @@ static portMUX_TYPE lock_init_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
Called by _lock_init*, also called by _lock_acquire* to lazily initialize locks that might have
|
||||
been initialised (to zero only) before the RTOS scheduler started.
|
||||
*/
|
||||
static void NEWLIB_LOCKS_IRAM_ATTR lock_init_generic(_lock_t *lock, uint8_t mutex_type)
|
||||
static void LIBC_LOCKS_IRAM_ATTR lock_init_generic(_lock_t *lock, uint8_t mutex_type)
|
||||
{
|
||||
portENTER_CRITICAL(&lock_init_spinlock);
|
||||
if (*lock) {
|
||||
@@ -81,13 +81,13 @@ static void NEWLIB_LOCKS_IRAM_ATTR lock_init_generic(_lock_t *lock, uint8_t mute
|
||||
portEXIT_CRITICAL(&lock_init_spinlock);
|
||||
}
|
||||
|
||||
void NEWLIB_LOCKS_IRAM_ATTR _lock_init(_lock_t *lock)
|
||||
void LIBC_LOCKS_IRAM_ATTR _lock_init(_lock_t *lock)
|
||||
{
|
||||
*lock = 0; // In case lock's memory is uninitialized
|
||||
lock_init_generic(lock, queueQUEUE_TYPE_MUTEX);
|
||||
}
|
||||
|
||||
void NEWLIB_LOCKS_IRAM_ATTR _lock_init_recursive(_lock_t *lock)
|
||||
void LIBC_LOCKS_IRAM_ATTR _lock_init_recursive(_lock_t *lock)
|
||||
{
|
||||
*lock = 0; // In case lock's memory is uninitialized
|
||||
lock_init_generic(lock, queueQUEUE_TYPE_RECURSIVE_MUTEX);
|
||||
@@ -103,7 +103,7 @@ void NEWLIB_LOCKS_IRAM_ATTR _lock_init_recursive(_lock_t *lock)
|
||||
re-initialised if it is used again. Caller has to avoid doing
|
||||
this!
|
||||
*/
|
||||
void NEWLIB_LOCKS_IRAM_ATTR _lock_close(_lock_t *lock)
|
||||
void LIBC_LOCKS_IRAM_ATTR _lock_close(_lock_t *lock)
|
||||
{
|
||||
portENTER_CRITICAL(&lock_init_spinlock);
|
||||
if (*lock) {
|
||||
@@ -122,7 +122,7 @@ void _lock_close_recursive(_lock_t *lock) __attribute__((alias("_lock_close")));
|
||||
/* Acquire the mutex semaphore for lock. wait up to delay ticks.
|
||||
mutex_type is queueQUEUE_TYPE_RECURSIVE_MUTEX or queueQUEUE_TYPE_MUTEX
|
||||
*/
|
||||
static int NEWLIB_LOCKS_IRAM_ATTR lock_acquire_generic(_lock_t *lock, uint32_t delay, uint8_t mutex_type)
|
||||
static int LIBC_LOCKS_IRAM_ATTR lock_acquire_generic(_lock_t *lock, uint32_t delay, uint8_t mutex_type)
|
||||
{
|
||||
SemaphoreHandle_t h = (SemaphoreHandle_t)(*lock);
|
||||
if (!h) {
|
||||
@@ -164,22 +164,22 @@ static int NEWLIB_LOCKS_IRAM_ATTR lock_acquire_generic(_lock_t *lock, uint32_t d
|
||||
return (success == pdTRUE) ? 0 : -1;
|
||||
}
|
||||
|
||||
void NEWLIB_LOCKS_IRAM_ATTR _lock_acquire(_lock_t *lock)
|
||||
void LIBC_LOCKS_IRAM_ATTR _lock_acquire(_lock_t *lock)
|
||||
{
|
||||
lock_acquire_generic(lock, portMAX_DELAY, queueQUEUE_TYPE_MUTEX);
|
||||
}
|
||||
|
||||
void NEWLIB_LOCKS_IRAM_ATTR _lock_acquire_recursive(_lock_t *lock)
|
||||
void LIBC_LOCKS_IRAM_ATTR _lock_acquire_recursive(_lock_t *lock)
|
||||
{
|
||||
lock_acquire_generic(lock, portMAX_DELAY, queueQUEUE_TYPE_RECURSIVE_MUTEX);
|
||||
}
|
||||
|
||||
int NEWLIB_LOCKS_IRAM_ATTR _lock_try_acquire(_lock_t *lock)
|
||||
int LIBC_LOCKS_IRAM_ATTR _lock_try_acquire(_lock_t *lock)
|
||||
{
|
||||
return lock_acquire_generic(lock, 0, queueQUEUE_TYPE_MUTEX);
|
||||
}
|
||||
|
||||
int NEWLIB_LOCKS_IRAM_ATTR _lock_try_acquire_recursive(_lock_t *lock)
|
||||
int LIBC_LOCKS_IRAM_ATTR _lock_try_acquire_recursive(_lock_t *lock)
|
||||
{
|
||||
return lock_acquire_generic(lock, 0, queueQUEUE_TYPE_RECURSIVE_MUTEX);
|
||||
}
|
||||
@@ -187,7 +187,7 @@ int NEWLIB_LOCKS_IRAM_ATTR _lock_try_acquire_recursive(_lock_t *lock)
|
||||
/* Release the mutex semaphore for lock.
|
||||
mutex_type is queueQUEUE_TYPE_RECURSIVE_MUTEX or queueQUEUE_TYPE_MUTEX
|
||||
*/
|
||||
static void NEWLIB_LOCKS_IRAM_ATTR lock_release_generic(_lock_t *lock, uint8_t mutex_type)
|
||||
static void LIBC_LOCKS_IRAM_ATTR lock_release_generic(_lock_t *lock, uint8_t mutex_type)
|
||||
{
|
||||
if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) {
|
||||
return; /* locking is a no-op before scheduler is up */
|
||||
@@ -213,12 +213,12 @@ static void NEWLIB_LOCKS_IRAM_ATTR lock_release_generic(_lock_t *lock, uint8_t m
|
||||
}
|
||||
}
|
||||
|
||||
void NEWLIB_LOCKS_IRAM_ATTR _lock_release(_lock_t *lock)
|
||||
void LIBC_LOCKS_IRAM_ATTR _lock_release(_lock_t *lock)
|
||||
{
|
||||
lock_release_generic(lock, queueQUEUE_TYPE_MUTEX);
|
||||
}
|
||||
|
||||
void NEWLIB_LOCKS_IRAM_ATTR _lock_release_recursive(_lock_t *lock)
|
||||
void LIBC_LOCKS_IRAM_ATTR _lock_release_recursive(_lock_t *lock)
|
||||
{
|
||||
lock_release_generic(lock, queueQUEUE_TYPE_RECURSIVE_MUTEX);
|
||||
}
|
||||
@@ -291,69 +291,69 @@ static StaticSemaphore_t s_common_recursive_mutex;
|
||||
#define MAYBE_OVERRIDE_LOCK(_lock, _lock_to_use_instead)
|
||||
#endif // ROM_NEEDS_MUTEX_OVERRIDE
|
||||
|
||||
void NEWLIB_LOCKS_IRAM_ATTR __retarget_lock_init(_LOCK_T *lock)
|
||||
void LIBC_LOCKS_IRAM_ATTR __retarget_lock_init(_LOCK_T *lock)
|
||||
{
|
||||
*lock = NULL; /* In case lock's memory is uninitialized */
|
||||
lock_init_generic(lock, queueQUEUE_TYPE_MUTEX);
|
||||
}
|
||||
|
||||
void NEWLIB_LOCKS_IRAM_ATTR __retarget_lock_init_recursive(_LOCK_T *lock)
|
||||
void LIBC_LOCKS_IRAM_ATTR __retarget_lock_init_recursive(_LOCK_T *lock)
|
||||
{
|
||||
*lock = NULL; /* In case lock's memory is uninitialized */
|
||||
lock_init_generic(lock, queueQUEUE_TYPE_RECURSIVE_MUTEX);
|
||||
}
|
||||
|
||||
void NEWLIB_LOCKS_IRAM_ATTR __retarget_lock_close(_LOCK_T lock)
|
||||
void LIBC_LOCKS_IRAM_ATTR __retarget_lock_close(_LOCK_T lock)
|
||||
{
|
||||
_lock_close(&lock);
|
||||
}
|
||||
|
||||
void NEWLIB_LOCKS_IRAM_ATTR __retarget_lock_close_recursive(_LOCK_T lock)
|
||||
void LIBC_LOCKS_IRAM_ATTR __retarget_lock_close_recursive(_LOCK_T lock)
|
||||
{
|
||||
_lock_close_recursive(&lock);
|
||||
}
|
||||
|
||||
/* Separate function, to prevent generating multiple assert strings */
|
||||
static void NEWLIB_LOCKS_IRAM_ATTR check_lock_nonzero(_LOCK_T lock)
|
||||
static void LIBC_LOCKS_IRAM_ATTR check_lock_nonzero(_LOCK_T lock)
|
||||
{
|
||||
assert(lock != NULL && "Uninitialized lock used");
|
||||
}
|
||||
|
||||
void NEWLIB_LOCKS_IRAM_ATTR __retarget_lock_acquire(_LOCK_T lock)
|
||||
void LIBC_LOCKS_IRAM_ATTR __retarget_lock_acquire(_LOCK_T lock)
|
||||
{
|
||||
check_lock_nonzero(lock);
|
||||
MAYBE_OVERRIDE_LOCK(lock, &s_common_mutex);
|
||||
_lock_acquire(&lock);
|
||||
}
|
||||
|
||||
void NEWLIB_LOCKS_IRAM_ATTR __retarget_lock_acquire_recursive(_LOCK_T lock)
|
||||
void LIBC_LOCKS_IRAM_ATTR __retarget_lock_acquire_recursive(_LOCK_T lock)
|
||||
{
|
||||
check_lock_nonzero(lock);
|
||||
MAYBE_OVERRIDE_LOCK(lock, &s_common_recursive_mutex);
|
||||
_lock_acquire_recursive(&lock);
|
||||
}
|
||||
|
||||
int NEWLIB_LOCKS_IRAM_ATTR __retarget_lock_try_acquire(_LOCK_T lock)
|
||||
int LIBC_LOCKS_IRAM_ATTR __retarget_lock_try_acquire(_LOCK_T lock)
|
||||
{
|
||||
check_lock_nonzero(lock);
|
||||
MAYBE_OVERRIDE_LOCK(lock, &s_common_mutex);
|
||||
return _lock_try_acquire(&lock);
|
||||
}
|
||||
|
||||
int NEWLIB_LOCKS_IRAM_ATTR __retarget_lock_try_acquire_recursive(_LOCK_T lock)
|
||||
int LIBC_LOCKS_IRAM_ATTR __retarget_lock_try_acquire_recursive(_LOCK_T lock)
|
||||
{
|
||||
check_lock_nonzero(lock);
|
||||
MAYBE_OVERRIDE_LOCK(lock, &s_common_recursive_mutex);
|
||||
return _lock_try_acquire_recursive(&lock);
|
||||
}
|
||||
|
||||
void NEWLIB_LOCKS_IRAM_ATTR __retarget_lock_release(_LOCK_T lock)
|
||||
void LIBC_LOCKS_IRAM_ATTR __retarget_lock_release(_LOCK_T lock)
|
||||
{
|
||||
check_lock_nonzero(lock);
|
||||
_lock_release(&lock);
|
||||
}
|
||||
|
||||
void NEWLIB_LOCKS_IRAM_ATTR __retarget_lock_release_recursive(_LOCK_T lock)
|
||||
void LIBC_LOCKS_IRAM_ATTR __retarget_lock_release_recursive(_LOCK_T lock)
|
||||
{
|
||||
check_lock_nonzero(lock);
|
||||
_lock_release_recursive(&lock);
|
||||
|
||||
22
components/esp_libc/src/picolibc/errno.c
Normal file
22
components/esp_libc/src/picolibc/errno.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
* Picolibc does not initialize 'errno' and places it in the TBSS section.
|
||||
*
|
||||
* To allow convenient initialization and support interoperability with Newlib,
|
||||
* 'errno' is defined in the TDATA section. The linker script ensures that
|
||||
* it is positioned at the beginning of the TDATA segment.
|
||||
*/
|
||||
__thread int errno __attribute__((section(".tdata.errno"))) = 0;
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
int *__errno(void)
|
||||
{
|
||||
return &errno;
|
||||
}
|
||||
#endif
|
||||
19
components/esp_libc/src/picolibc/getreent.c
Normal file
19
components/esp_libc/src/picolibc/getreent.c
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include "esp_cpu.h"
|
||||
|
||||
void *__getreent(void)
|
||||
{
|
||||
/*
|
||||
* The linker script provides the basic _reent fields
|
||||
* used to access errno and stdin/stdout/stderr.
|
||||
*
|
||||
* Note: if code accesses other fields in struct _reent
|
||||
* that are not intended to be "public," data corruption may occur.
|
||||
*/
|
||||
return esp_cpu_get_threadptr();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -33,21 +33,59 @@ static void esp_cleanup_r(struct _reent *rptr)
|
||||
#endif
|
||||
|
||||
#if ESP_ROM_HAS_RETARGETABLE_LOCKING
|
||||
static int __retarget_lock_try_acquire(struct __lock * p)
|
||||
{
|
||||
__retarget_lock_acquire(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __retarget_lock_try_acquire_recursive(struct __lock *p)
|
||||
{
|
||||
__retarget_lock_acquire_recursive(p);
|
||||
return 0;
|
||||
}
|
||||
int __retarget_lock_try_acquire(struct __lock * p);
|
||||
int __retarget_lock_try_acquire_recursive(struct __lock *p);
|
||||
#endif
|
||||
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
struct _reent_stub {
|
||||
int _errno;
|
||||
__FILE *_stdin, *_stdout, *_stderr;
|
||||
int _inc;
|
||||
char *_emergency;
|
||||
int _reserved_0;
|
||||
int _reserved_1;
|
||||
struct __locale_t *_locale;
|
||||
void *_mp;
|
||||
void (*__cleanup)(struct _reent *);
|
||||
int _gamma_signgam;
|
||||
int _cvtlen;
|
||||
char *_cvtbuf;
|
||||
struct _rand48 *_r48;
|
||||
#if 0 /* unlikely used fields in ROM implementation */
|
||||
struct __tm *_localtime_buf;
|
||||
char *_asctime_buf;
|
||||
void (** _sig_func)(int);
|
||||
struct _atexit *_reserved_6;
|
||||
struct _atexit _reserved_7;
|
||||
struct _glue _reserved_8;
|
||||
__FILE *__sf;
|
||||
struct _misc_reent *_misc;
|
||||
char *_signal_buf;
|
||||
#endif
|
||||
};
|
||||
|
||||
void *__getreent_rom_stub(void)
|
||||
{
|
||||
static struct _reent_stub reent_stub;
|
||||
return &reent_stub;
|
||||
}
|
||||
#endif // SECURE_ENABLE_TEE
|
||||
|
||||
static struct syscall_stub_table s_stub_table = {
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
/*
|
||||
* ESP-TEE uses snprintf() from ROM, which requires at least a fake __getreent stub.
|
||||
*
|
||||
* NOTE: If floating-point variables are intended to be used,
|
||||
* the following fields must be specified in the syscall_stub_table:
|
||||
* ._printf_float =
|
||||
* ._scanf_float =
|
||||
*/
|
||||
.__getreent = (void *)__getreent_rom_stub,
|
||||
#else
|
||||
.__getreent = (void *)abort,
|
||||
#endif
|
||||
._malloc_r = (void *)abort,
|
||||
._free_r = (void *)abort,
|
||||
._realloc_r = (void *)abort,
|
||||
@@ -143,20 +181,10 @@ void esp_reent_cleanup(void)
|
||||
return;
|
||||
}
|
||||
|
||||
#if CONFIG_VFS_SUPPORT_IO
|
||||
FILE *stdin;
|
||||
FILE *stdout;
|
||||
FILE *stderr;
|
||||
void esp_libc_init_global_stdio(const char *stdio_dev)
|
||||
{
|
||||
stdin = fopen(stdio_dev, "r");
|
||||
stdout = fopen(stdio_dev, "w");
|
||||
assert(stdin);
|
||||
assert(stdout);
|
||||
setlinebuf(stdout);
|
||||
stderr = stdout;
|
||||
}
|
||||
#else /* CONFIG_VFS_SUPPORT_IO */
|
||||
/*
|
||||
* Initialize stdin, stdout, and stderr using static memory allocation.
|
||||
* Creating them with fopen() would call malloc() internally.
|
||||
*/
|
||||
static char write_buf[BUFSIZ];
|
||||
static char read_buf[BUFSIZ];
|
||||
|
||||
@@ -166,10 +194,28 @@ static struct __file_bufio __stdout = FDEV_SETUP_BUFIO(1, write_buf, BUFSIZ, rea
|
||||
FILE *stdin = &__stdin.xfile.cfile.file;
|
||||
FILE *stdout = &__stdout.xfile.cfile.file;
|
||||
FILE *stderr = &__stdout.xfile.cfile.file;
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
__thread FILE* tls_stdin = &__stdin.xfile.cfile.file;
|
||||
__thread FILE* tls_stdout = &__stdout.xfile.cfile.file;
|
||||
__thread FILE* tls_stderr = &__stdout.xfile.cfile.file;
|
||||
#endif
|
||||
|
||||
#if CONFIG_VFS_SUPPORT_IO
|
||||
void esp_libc_init_global_stdio(const char *stdio_dev)
|
||||
{
|
||||
int stdin_fd = open(stdio_dev, O_RDONLY);
|
||||
assert(stdin_fd > 0);
|
||||
__stdin.ptr = (void *)(intptr_t)(stdin_fd);
|
||||
|
||||
int stdout_fd = open(stdio_dev, O_WRONLY);
|
||||
assert(stdout_fd > 0);
|
||||
__stdout.ptr = (void *)(intptr_t)(stdout_fd);
|
||||
}
|
||||
#else /* CONFIG_VFS_SUPPORT_IO */
|
||||
void esp_libc_init_global_stdio(void)
|
||||
{
|
||||
__lock_init_recursive(stdin->lock);
|
||||
__lock_init_recursive(stdout->lock);
|
||||
/* Nothing to do. */
|
||||
}
|
||||
#endif /* CONFIG_VFS_SUPPORT_IO */
|
||||
|
||||
|
||||
@@ -110,6 +110,10 @@ int fcntl(int fd, int cmd, ...)
|
||||
return _fcntl_r(__getreent(), fd, cmd, arg);
|
||||
}
|
||||
|
||||
int getpid()
|
||||
{
|
||||
return _getpid_r(__getreent());
|
||||
}
|
||||
#endif // CONFIG_LIBC_PICOLIBC
|
||||
|
||||
void _exit(int __status)
|
||||
|
||||
@@ -162,7 +162,7 @@ if(CONFIG_ESP_PHY_ENABLED)
|
||||
add_custom_command(
|
||||
OUTPUT ${phy_init_data_bin}
|
||||
DEPENDS ${CMAKE_CURRENT_LIST_DIR}/${idf_target}/phy_init_data.c
|
||||
COMMAND ${CMAKE_C_COMPILER} -c ${CMAKE_CURRENT_LIST_DIR}/${idf_target}/phy_init_data.c
|
||||
COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} -c ${CMAKE_CURRENT_LIST_DIR}/${idf_target}/phy_init_data.c
|
||||
-I ${esp_common_dir}/include -I ${CMAKE_CURRENT_LIST_DIR}/include
|
||||
-I ${CMAKE_CURRENT_LIST_DIR}/${idf_target}/include -I ${esp_rom_dir}/include
|
||||
-I ${soc_dir}/${idf_target}/include -I ${esp_libc_dir}/platform_include
|
||||
|
||||
@@ -145,7 +145,7 @@ endif()
|
||||
|
||||
if(ESP_TEE_BUILD)
|
||||
rom_linker_script("heap")
|
||||
if(CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT)
|
||||
if(CONFIG_LIBC_NEWLIB AND CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT)
|
||||
rom_linker_script("newlib-nano")
|
||||
endif()
|
||||
rom_linker_script("libc")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -22,18 +22,12 @@ bzero = 0x4000c1f4;
|
||||
div = 0x40056348;
|
||||
__dummy_lock = 0x4000c728;
|
||||
__dummy_lock_try = 0x4000c730;
|
||||
isalnum = 0x40000f04;
|
||||
isalpha = 0x40000f18;
|
||||
isascii = 0x4000c20c;
|
||||
isblank = 0x40000f2c;
|
||||
iscntrl = 0x40000f50;
|
||||
isdigit = 0x40000f64;
|
||||
isgraph = 0x40000f94;
|
||||
islower = 0x40000f78;
|
||||
isprint = 0x40000fa8;
|
||||
ispunct = 0x40000fc0;
|
||||
isspace = 0x40000fd4;
|
||||
isupper = 0x40000fe8;
|
||||
__itoa = 0x40056678;
|
||||
itoa = 0x400566b4;
|
||||
labs = 0x40056370;
|
||||
@@ -49,19 +43,15 @@ memset = 0x4000c44c;
|
||||
qsort = 0x40056424;
|
||||
__sccl = 0x4000c498;
|
||||
setjmp = 0x40056268;
|
||||
strcasecmp = 0x400011cc;
|
||||
strcasestr = 0x40001210;
|
||||
strcat = 0x4000c518;
|
||||
strchr = 0x4000c53c;
|
||||
strcmp = 0x40001274;
|
||||
strcoll = 0x40001398;
|
||||
strcpy = 0x400013ac;
|
||||
strcspn = 0x4000c558;
|
||||
strlcat = 0x40001470;
|
||||
strlcpy = 0x4000c584;
|
||||
strlen = 0x400014c0;
|
||||
strlwr = 0x40001524;
|
||||
strncasecmp = 0x40001550;
|
||||
strncat = 0x4000c5c4;
|
||||
strncmp = 0x4000c5f4;
|
||||
strncpy = 0x400015d4;
|
||||
@@ -70,10 +60,7 @@ strrchr = 0x40001708;
|
||||
strsep = 0x40001734;
|
||||
strspn = 0x4000c648;
|
||||
strstr = 0x4000c674;
|
||||
strupr = 0x4000174c;
|
||||
__submore = 0x40058f3c;
|
||||
toascii = 0x4000c720;
|
||||
tolower = 0x40001868;
|
||||
toupper = 0x40001884;
|
||||
__utoa = 0x400561f0;
|
||||
utoa = 0x40056258;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -59,3 +59,16 @@ __sinit_lock_release = 0x40001e2c;
|
||||
__env_lock = 0x40001fd4;
|
||||
__env_unlock = 0x40001fe0;
|
||||
_getenv_r = 0x40001fbc;
|
||||
tolower = 0x40001868;
|
||||
toupper = 0x40001884;
|
||||
isalnum = 0x40000f04;
|
||||
isalpha = 0x40000f18;
|
||||
isdigit = 0x40000f64;
|
||||
islower = 0x40000f78;
|
||||
isspace = 0x40000fd4;
|
||||
isupper = 0x40000fe8;
|
||||
strcasecmp = 0x400011cc;
|
||||
strcoll = 0x40001398;
|
||||
strlwr = 0x40001524;
|
||||
strncasecmp = 0x40001550;
|
||||
strupr = 0x4000174c;
|
||||
|
||||
@@ -9,41 +9,28 @@ strlen = 0x400004a8;
|
||||
strstr = 0x400004ac;
|
||||
bzero = 0x400004b0;
|
||||
sbrk = 0x400004b8;
|
||||
isalnum = 0x400004bc;
|
||||
isalpha = 0x400004c0;
|
||||
isascii = 0x400004c4;
|
||||
isblank = 0x400004c8;
|
||||
iscntrl = 0x400004cc;
|
||||
isdigit = 0x400004d0;
|
||||
islower = 0x400004d4;
|
||||
isgraph = 0x400004d8;
|
||||
isprint = 0x400004dc;
|
||||
ispunct = 0x400004e0;
|
||||
isspace = 0x400004e4;
|
||||
isupper = 0x400004e8;
|
||||
toupper = 0x400004ec;
|
||||
tolower = 0x400004f0;
|
||||
toascii = 0x400004f4;
|
||||
memccpy = 0x400004f8;
|
||||
memchr = 0x400004fc;
|
||||
memrchr = 0x40000500;
|
||||
strcasecmp = 0x40000504;
|
||||
strcasestr = 0x40000508;
|
||||
strcat = 0x4000050c;
|
||||
strchr = 0x40000514;
|
||||
strcspn = 0x40000518;
|
||||
strcoll = 0x4000051c;
|
||||
strlcat = 0x40000520;
|
||||
strlcpy = 0x40000524;
|
||||
strlwr = 0x40000528;
|
||||
strncasecmp = 0x4000052c;
|
||||
strncat = 0x40000530;
|
||||
strnlen = 0x40000538;
|
||||
strrchr = 0x4000053c;
|
||||
strsep = 0x40000540;
|
||||
strspn = 0x40000544;
|
||||
strtok_r = 0x40000548;
|
||||
strupr = 0x4000054c;
|
||||
longjmp = 0x40000550;
|
||||
setjmp = 0x40000554;
|
||||
abs = 0x40000558;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -63,3 +63,16 @@ puts = 0x4000065c;
|
||||
putc = 0x40000660;
|
||||
putchar = 0x40000664;
|
||||
__errno = 0x40000670;
|
||||
toupper = 0x400004ec;
|
||||
tolower = 0x400004f0;
|
||||
isalnum = 0x400004bc;
|
||||
isalpha = 0x400004c0;
|
||||
isdigit = 0x400004d0;
|
||||
islower = 0x400004d4;
|
||||
isspace = 0x400004e4;
|
||||
isupper = 0x400004e8;
|
||||
strcasecmp = 0x40000504;
|
||||
strcoll = 0x4000051c;
|
||||
strlwr = 0x40000528;
|
||||
strncasecmp = 0x4000052c;
|
||||
strupr = 0x4000054c;
|
||||
|
||||
@@ -9,41 +9,28 @@ strlen = 0x40000374;
|
||||
strstr = 0x40000378;
|
||||
bzero = 0x4000037c;
|
||||
sbrk = 0x40000384;
|
||||
isalnum = 0x40000388;
|
||||
isalpha = 0x4000038c;
|
||||
isascii = 0x40000390;
|
||||
isblank = 0x40000394;
|
||||
iscntrl = 0x40000398;
|
||||
isdigit = 0x4000039c;
|
||||
islower = 0x400003a0;
|
||||
isgraph = 0x400003a4;
|
||||
isprint = 0x400003a8;
|
||||
ispunct = 0x400003ac;
|
||||
isspace = 0x400003b0;
|
||||
isupper = 0x400003b4;
|
||||
toupper = 0x400003b8;
|
||||
tolower = 0x400003bc;
|
||||
toascii = 0x400003c0;
|
||||
memccpy = 0x400003c4;
|
||||
memchr = 0x400003c8;
|
||||
memrchr = 0x400003cc;
|
||||
strcasecmp = 0x400003d0;
|
||||
strcasestr = 0x400003d4;
|
||||
strcat = 0x400003d8;
|
||||
strchr = 0x400003e0;
|
||||
strcspn = 0x400003e4;
|
||||
strcoll = 0x400003e8;
|
||||
strlcat = 0x400003ec;
|
||||
strlcpy = 0x400003f0;
|
||||
strlwr = 0x400003f4;
|
||||
strncasecmp = 0x400003f8;
|
||||
strncat = 0x400003fc;
|
||||
strnlen = 0x40000404;
|
||||
strrchr = 0x40000408;
|
||||
strsep = 0x4000040c;
|
||||
strspn = 0x40000410;
|
||||
strtok_r = 0x40000414;
|
||||
strupr = 0x40000418;
|
||||
longjmp = 0x4000041c;
|
||||
setjmp = 0x40000420;
|
||||
abs = 0x40000424;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -35,3 +35,16 @@ PROVIDE( _fwalk = 0x40000464 );
|
||||
PROVIDE( _fwalk_reent = 0x40000468 );
|
||||
PROVIDE( __swbuf_r = 0x40000474 );
|
||||
__swbuf = 0x40000478;
|
||||
toupper = 0x400003b8;
|
||||
tolower = 0x400003bc;
|
||||
isalnum = 0x40000388;
|
||||
isalpha = 0x4000038c;
|
||||
isdigit = 0x4000039c;
|
||||
islower = 0x400003a0;
|
||||
isspace = 0x400003b0;
|
||||
isupper = 0x400003b4;
|
||||
strcasecmp = 0x400003d0;
|
||||
strcoll = 0x400003e8;
|
||||
strlwr = 0x400003f4;
|
||||
strncasecmp = 0x400003f8;
|
||||
strupr = 0x40000418;
|
||||
|
||||
@@ -24,41 +24,28 @@ strlen = 0x400004d8;
|
||||
strstr = 0x400004dc;
|
||||
bzero = 0x400004e0;
|
||||
sbrk = 0x400004e8;
|
||||
isalnum = 0x400004ec;
|
||||
isalpha = 0x400004f0;
|
||||
isascii = 0x400004f4;
|
||||
isblank = 0x400004f8;
|
||||
iscntrl = 0x400004fc;
|
||||
isdigit = 0x40000500;
|
||||
islower = 0x40000504;
|
||||
isgraph = 0x40000508;
|
||||
isprint = 0x4000050c;
|
||||
ispunct = 0x40000510;
|
||||
isspace = 0x40000514;
|
||||
isupper = 0x40000518;
|
||||
toupper = 0x4000051c;
|
||||
tolower = 0x40000520;
|
||||
toascii = 0x40000524;
|
||||
memccpy = 0x40000528;
|
||||
memchr = 0x4000052c;
|
||||
memrchr = 0x40000530;
|
||||
strcasecmp = 0x40000534;
|
||||
strcasestr = 0x40000538;
|
||||
strcat = 0x4000053c;
|
||||
strchr = 0x40000544;
|
||||
strcspn = 0x40000548;
|
||||
strcoll = 0x4000054c;
|
||||
strlcat = 0x40000550;
|
||||
strlcpy = 0x40000554;
|
||||
strlwr = 0x40000558;
|
||||
strncasecmp = 0x4000055c;
|
||||
strncat = 0x40000560;
|
||||
strnlen = 0x40000568;
|
||||
strrchr = 0x4000056c;
|
||||
strsep = 0x40000570;
|
||||
strspn = 0x40000574;
|
||||
strtok_r = 0x40000578;
|
||||
strupr = 0x4000057c;
|
||||
longjmp = 0x40000580;
|
||||
setjmp = 0x40000584;
|
||||
abs = 0x40000588;
|
||||
|
||||
@@ -37,3 +37,16 @@ __swhatbuf_r = 0x400005d4;
|
||||
__swbuf_r = 0x400005d8;
|
||||
__swbuf = 0x400005dc;
|
||||
__swsetup_r = 0x400005e0;
|
||||
toupper = 0x4000051c;
|
||||
tolower = 0x40000520;
|
||||
isalnum = 0x400004ec;
|
||||
isalpha = 0x400004f0;
|
||||
isdigit = 0x40000500;
|
||||
islower = 0x40000504;
|
||||
isspace = 0x40000514;
|
||||
isupper = 0x40000518;
|
||||
strcasecmp = 0x40000534;
|
||||
strcoll = 0x4000054c;
|
||||
strlwr = 0x40000558;
|
||||
strncasecmp = 0x4000055c;
|
||||
strupr = 0x4000057c;
|
||||
|
||||
@@ -9,41 +9,28 @@ strlen = 0x400004c8;
|
||||
strstr = 0x400004cc;
|
||||
bzero = 0x400004d0;
|
||||
sbrk = 0x400004d8;
|
||||
isalnum = 0x400004dc;
|
||||
isalpha = 0x400004e0;
|
||||
isascii = 0x400004e4;
|
||||
isblank = 0x400004e8;
|
||||
iscntrl = 0x400004ec;
|
||||
isdigit = 0x400004f0;
|
||||
islower = 0x400004f4;
|
||||
isgraph = 0x400004f8;
|
||||
isprint = 0x400004fc;
|
||||
ispunct = 0x40000500;
|
||||
isspace = 0x40000504;
|
||||
isupper = 0x40000508;
|
||||
toupper = 0x4000050c;
|
||||
tolower = 0x40000510;
|
||||
toascii = 0x40000514;
|
||||
memccpy = 0x40000518;
|
||||
memchr = 0x4000051c;
|
||||
memrchr = 0x40000520;
|
||||
strcasecmp = 0x40000524;
|
||||
strcasestr = 0x40000528;
|
||||
strcat = 0x4000052c;
|
||||
strchr = 0x40000534;
|
||||
strcspn = 0x40000538;
|
||||
strcoll = 0x4000053c;
|
||||
strlcat = 0x40000540;
|
||||
strlcpy = 0x40000544;
|
||||
strlwr = 0x40000548;
|
||||
strncasecmp = 0x4000054c;
|
||||
strncat = 0x40000550;
|
||||
strnlen = 0x40000558;
|
||||
strrchr = 0x4000055c;
|
||||
strsep = 0x40000560;
|
||||
strspn = 0x40000564;
|
||||
strtok_r = 0x40000568;
|
||||
strupr = 0x4000056c;
|
||||
longjmp = 0x40000570;
|
||||
setjmp = 0x40000574;
|
||||
abs = 0x40000578;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -39,3 +39,16 @@ __swhatbuf_r = 0x400005c4;
|
||||
__swbuf_r = 0x400005c8;
|
||||
__swbuf = 0x400005cc;
|
||||
__swsetup_r = 0x400005d0;
|
||||
toupper = 0x4000050c;
|
||||
tolower = 0x40000510;
|
||||
isalnum = 0x400004dc;
|
||||
isalpha = 0x400004e0;
|
||||
isdigit = 0x400004f0;
|
||||
islower = 0x400004f4;
|
||||
isspace = 0x40000504;
|
||||
isupper = 0x40000508;
|
||||
strcasecmp = 0x40000524;
|
||||
strcoll = 0x4000053c;
|
||||
strlwr = 0x40000548;
|
||||
strncasecmp = 0x4000054c;
|
||||
strupr = 0x4000056c;
|
||||
|
||||
@@ -9,41 +9,28 @@ strlen = 0x400004d8;
|
||||
strstr = 0x400004dc;
|
||||
bzero = 0x400004e0;
|
||||
sbrk = 0x400004e8;
|
||||
isalnum = 0x400004ec;
|
||||
isalpha = 0x400004f0;
|
||||
isascii = 0x400004f4;
|
||||
isblank = 0x400004f8;
|
||||
iscntrl = 0x400004fc;
|
||||
isdigit = 0x40000500;
|
||||
islower = 0x40000504;
|
||||
isgraph = 0x40000508;
|
||||
isprint = 0x4000050c;
|
||||
ispunct = 0x40000510;
|
||||
isspace = 0x40000514;
|
||||
isupper = 0x40000518;
|
||||
toupper = 0x4000051c;
|
||||
tolower = 0x40000520;
|
||||
toascii = 0x40000524;
|
||||
memccpy = 0x40000528;
|
||||
memchr = 0x4000052c;
|
||||
memrchr = 0x40000530;
|
||||
strcasecmp = 0x40000534;
|
||||
strcasestr = 0x40000538;
|
||||
strcat = 0x4000053c;
|
||||
strchr = 0x40000544;
|
||||
strcspn = 0x40000548;
|
||||
strcoll = 0x4000054c;
|
||||
strlcat = 0x40000550;
|
||||
strlcpy = 0x40000554;
|
||||
strlwr = 0x40000558;
|
||||
strncasecmp = 0x4000055c;
|
||||
strncat = 0x40000560;
|
||||
strnlen = 0x40000568;
|
||||
strrchr = 0x4000056c;
|
||||
strsep = 0x40000570;
|
||||
strspn = 0x40000574;
|
||||
strtok_r = 0x40000578;
|
||||
strupr = 0x4000057c;
|
||||
longjmp = 0x40000580;
|
||||
setjmp = 0x40000584;
|
||||
abs = 0x40000588;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -39,3 +39,16 @@ __swhatbuf_r = 0x400005d4;
|
||||
__swbuf_r = 0x400005d8;
|
||||
__swbuf = 0x400005dc;
|
||||
__swsetup_r = 0x400005e0;
|
||||
toupper = 0x4000051c;
|
||||
tolower = 0x40000520;
|
||||
isalnum = 0x400004ec;
|
||||
isalpha = 0x400004f0;
|
||||
isdigit = 0x40000500;
|
||||
islower = 0x40000504;
|
||||
isspace = 0x40000514;
|
||||
isupper = 0x40000518;
|
||||
strcasecmp = 0x40000534;
|
||||
strcoll = 0x4000054c;
|
||||
strlwr = 0x40000558;
|
||||
strncasecmp = 0x4000055c;
|
||||
strupr = 0x4000057c;
|
||||
|
||||
@@ -9,41 +9,28 @@ strlen = 0x400004c0;
|
||||
strstr = 0x400004c4;
|
||||
bzero = 0x400004c8;
|
||||
sbrk = 0x400004d0;
|
||||
isalnum = 0x400004d4;
|
||||
isalpha = 0x400004d8;
|
||||
isascii = 0x400004dc;
|
||||
isblank = 0x400004e0;
|
||||
iscntrl = 0x400004e4;
|
||||
isdigit = 0x400004e8;
|
||||
islower = 0x400004ec;
|
||||
isgraph = 0x400004f0;
|
||||
isprint = 0x400004f4;
|
||||
ispunct = 0x400004f8;
|
||||
isspace = 0x400004fc;
|
||||
isupper = 0x40000500;
|
||||
toupper = 0x40000504;
|
||||
tolower = 0x40000508;
|
||||
toascii = 0x4000050c;
|
||||
memccpy = 0x40000510;
|
||||
memchr = 0x40000514;
|
||||
memrchr = 0x40000518;
|
||||
strcasecmp = 0x4000051c;
|
||||
strcasestr = 0x40000520;
|
||||
strcat = 0x40000524;
|
||||
strchr = 0x4000052c;
|
||||
strcspn = 0x40000530;
|
||||
strcoll = 0x40000534;
|
||||
strlcat = 0x40000538;
|
||||
strlcpy = 0x4000053c;
|
||||
strlwr = 0x40000540;
|
||||
strncasecmp = 0x40000544;
|
||||
strncat = 0x40000548;
|
||||
strnlen = 0x40000550;
|
||||
strrchr = 0x40000554;
|
||||
strsep = 0x40000558;
|
||||
strspn = 0x4000055c;
|
||||
strtok_r = 0x40000560;
|
||||
strupr = 0x40000564;
|
||||
longjmp = 0x40000568;
|
||||
setjmp = 0x4000056c;
|
||||
abs = 0x40000570;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -39,3 +39,16 @@ __swhatbuf_r = 0x400005bc;
|
||||
__swbuf_r = 0x400005c0;
|
||||
__swbuf = 0x400005c4;
|
||||
__swsetup_r = 0x400005c8;
|
||||
toupper = 0x40000504;
|
||||
tolower = 0x40000508;
|
||||
isalnum = 0x400004d4;
|
||||
isalpha = 0x400004d8;
|
||||
isdigit = 0x400004e8;
|
||||
islower = 0x400004ec;
|
||||
isspace = 0x400004fc;
|
||||
isupper = 0x40000500;
|
||||
strcasecmp = 0x4000051c;
|
||||
strcoll = 0x40000534;
|
||||
strlwr = 0x40000540;
|
||||
strncasecmp = 0x40000544;
|
||||
strupr = 0x40000564;
|
||||
|
||||
@@ -9,41 +9,28 @@ strlen = 0x400004b8;
|
||||
strstr = 0x400004bc;
|
||||
bzero = 0x400004c0;
|
||||
sbrk = 0x400004c8;
|
||||
isalnum = 0x400004cc;
|
||||
isalpha = 0x400004d0;
|
||||
isascii = 0x400004d4;
|
||||
isblank = 0x400004d8;
|
||||
iscntrl = 0x400004dc;
|
||||
isdigit = 0x400004e0;
|
||||
islower = 0x400004e4;
|
||||
isgraph = 0x400004e8;
|
||||
isprint = 0x400004ec;
|
||||
ispunct = 0x400004f0;
|
||||
isspace = 0x400004f4;
|
||||
isupper = 0x400004f8;
|
||||
toupper = 0x400004fc;
|
||||
tolower = 0x40000500;
|
||||
toascii = 0x40000504;
|
||||
memccpy = 0x40000508;
|
||||
memchr = 0x4000050c;
|
||||
memrchr = 0x40000510;
|
||||
strcasecmp = 0x40000514;
|
||||
strcasestr = 0x40000518;
|
||||
strcat = 0x4000051c;
|
||||
strchr = 0x40000524;
|
||||
strcspn = 0x40000528;
|
||||
strcoll = 0x4000052c;
|
||||
strlcat = 0x40000530;
|
||||
strlcpy = 0x40000534;
|
||||
strlwr = 0x40000538;
|
||||
strncasecmp = 0x4000053c;
|
||||
strncat = 0x40000540;
|
||||
strnlen = 0x40000548;
|
||||
strrchr = 0x4000054c;
|
||||
strsep = 0x40000550;
|
||||
strspn = 0x40000554;
|
||||
strtok_r = 0x40000558;
|
||||
strupr = 0x4000055c;
|
||||
longjmp = 0x40000560;
|
||||
setjmp = 0x40000564;
|
||||
abs = 0x40000568;
|
||||
|
||||
@@ -39,3 +39,16 @@ __swhatbuf_r = 0x400005b4;
|
||||
__swbuf_r = 0x400005b8;
|
||||
__swbuf = 0x400005bc;
|
||||
__swsetup_r = 0x400005c0;
|
||||
toupper = 0x400004fc;
|
||||
tolower = 0x40000500;
|
||||
isalnum = 0x400004cc;
|
||||
isalpha = 0x400004d0;
|
||||
isdigit = 0x400004e0;
|
||||
islower = 0x400004e4;
|
||||
isspace = 0x400004f4;
|
||||
isupper = 0x400004f8;
|
||||
strcasecmp = 0x40000514;
|
||||
strcoll = 0x4000052c;
|
||||
strlwr = 0x40000538;
|
||||
strncasecmp = 0x4000053c;
|
||||
strupr = 0x4000055c;
|
||||
|
||||
@@ -31,41 +31,28 @@ strlen = 0x400004b8;
|
||||
strstr = 0x400004bc;
|
||||
bzero = 0x400004c0;
|
||||
sbrk = 0x400004c4;
|
||||
isalnum = 0x400004c8;
|
||||
isalpha = 0x400004cc;
|
||||
isascii = 0x400004d0;
|
||||
isblank = 0x400004d4;
|
||||
iscntrl = 0x400004d8;
|
||||
isdigit = 0x400004dc;
|
||||
islower = 0x400004e0;
|
||||
isgraph = 0x400004e4;
|
||||
isprint = 0x400004e8;
|
||||
ispunct = 0x400004ec;
|
||||
isspace = 0x400004f0;
|
||||
isupper = 0x400004f4;
|
||||
toupper = 0x400004f8;
|
||||
tolower = 0x400004fc;
|
||||
toascii = 0x40000500;
|
||||
memccpy = 0x40000504;
|
||||
memchr = 0x40000508;
|
||||
memrchr = 0x4000050c;
|
||||
strcasecmp = 0x40000510;
|
||||
strcasestr = 0x40000514;
|
||||
strcat = 0x40000518;
|
||||
strchr = 0x4000051c;
|
||||
strcspn = 0x40000520;
|
||||
strcoll = 0x40000524;
|
||||
strlcat = 0x40000528;
|
||||
strlcpy = 0x4000052c;
|
||||
strlwr = 0x40000530;
|
||||
strncasecmp = 0x40000534;
|
||||
strncat = 0x40000538;
|
||||
strnlen = 0x4000053c;
|
||||
strrchr = 0x40000540;
|
||||
strsep = 0x40000544;
|
||||
strspn = 0x40000548;
|
||||
strtok_r = 0x4000054c;
|
||||
strupr = 0x40000550;
|
||||
longjmp = 0x40000554;
|
||||
setjmp = 0x40000558;
|
||||
abs = 0x4000055c;
|
||||
|
||||
@@ -37,3 +37,16 @@ __swhatbuf_r = 0x40000484;
|
||||
__swbuf_r = 0x40000488;
|
||||
__swbuf = 0x4000048c;
|
||||
__swsetup_r = 0x40000490;
|
||||
toupper = 0x400004f8;
|
||||
tolower = 0x400004fc;
|
||||
isalnum = 0x400004c8;
|
||||
isalpha = 0x400004cc;
|
||||
isdigit = 0x400004dc;
|
||||
islower = 0x400004e0;
|
||||
isspace = 0x400004f0;
|
||||
isupper = 0x400004f4;
|
||||
strcasecmp = 0x40000510;
|
||||
strcoll = 0x40000524;
|
||||
strlwr = 0x40000530;
|
||||
strncasecmp = 0x40000534;
|
||||
strupr = 0x40000550;
|
||||
|
||||
@@ -9,41 +9,28 @@ strlen = 0x4fc00288;
|
||||
strstr = 0x4fc0028c;
|
||||
bzero = 0x4fc00290;
|
||||
sbrk = 0x4fc00298;
|
||||
isalnum = 0x4fc0029c;
|
||||
isalpha = 0x4fc002a0;
|
||||
isascii = 0x4fc002a4;
|
||||
isblank = 0x4fc002a8;
|
||||
iscntrl = 0x4fc002ac;
|
||||
isdigit = 0x4fc002b0;
|
||||
islower = 0x4fc002b4;
|
||||
isgraph = 0x4fc002b8;
|
||||
isprint = 0x4fc002bc;
|
||||
ispunct = 0x4fc002c0;
|
||||
isspace = 0x4fc002c4;
|
||||
isupper = 0x4fc002c8;
|
||||
toupper = 0x4fc002cc;
|
||||
tolower = 0x4fc002d0;
|
||||
toascii = 0x4fc002d4;
|
||||
memccpy = 0x4fc002d8;
|
||||
memchr = 0x4fc002dc;
|
||||
memrchr = 0x4fc002e0;
|
||||
strcasecmp = 0x4fc002e4;
|
||||
strcasestr = 0x4fc002e8;
|
||||
strcat = 0x4fc002ec;
|
||||
strchr = 0x4fc002f4;
|
||||
strcspn = 0x4fc002f8;
|
||||
strcoll = 0x4fc002fc;
|
||||
strlcat = 0x4fc00300;
|
||||
strlcpy = 0x4fc00304;
|
||||
strlwr = 0x4fc00308;
|
||||
strncasecmp = 0x4fc0030c;
|
||||
strncat = 0x4fc00310;
|
||||
strnlen = 0x4fc00318;
|
||||
strrchr = 0x4fc0031c;
|
||||
strsep = 0x4fc00320;
|
||||
strspn = 0x4fc00324;
|
||||
strtok_r = 0x4fc00328;
|
||||
strupr = 0x4fc0032c;
|
||||
longjmp = 0x4fc00330;
|
||||
setjmp = 0x4fc00334;
|
||||
abs = 0x4fc00338;
|
||||
|
||||
@@ -39,3 +39,16 @@ __swhatbuf_r = 0x4fc00384;
|
||||
__swbuf_r = 0x4fc00388;
|
||||
__swbuf = 0x4fc0038c;
|
||||
__swsetup_r = 0x4fc00390;
|
||||
toupper = 0x4fc002cc;
|
||||
tolower = 0x4fc002d0;
|
||||
isalnum = 0x4fc0029c;
|
||||
isalpha = 0x4fc002a0;
|
||||
isdigit = 0x4fc002b0;
|
||||
islower = 0x4fc002b4;
|
||||
isspace = 0x4fc002c4;
|
||||
isupper = 0x4fc002c8;
|
||||
strcasecmp = 0x4fc002e4;
|
||||
strcoll = 0x4fc002fc;
|
||||
strlwr = 0x4fc00308;
|
||||
strncasecmp = 0x4fc0030c;
|
||||
strupr = 0x4fc0032c;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -17,18 +17,12 @@ PROVIDE ( __assert = 0x4001a430 );
|
||||
PROVIDE ( __assert_func = 0x4001a408 );
|
||||
bzero = 0x400078c8;
|
||||
div = 0x40000620;
|
||||
isalnum = 0x400078d8;
|
||||
isalpha = 0x400078e8;
|
||||
isascii = 0x4001aaec;
|
||||
isblank = 0x400078f8;
|
||||
iscntrl = 0x40007918;
|
||||
isdigit = 0x40007930;
|
||||
isgraph = 0x40007968;
|
||||
islower = 0x40007948;
|
||||
isprint = 0x40007980;
|
||||
ispunct = 0x40007994;
|
||||
isspace = 0x400079ac;
|
||||
isupper = 0x400079c4;
|
||||
labs = 0x40000648;
|
||||
ldiv = 0x40000650;
|
||||
longjmp = 0x400005a4;
|
||||
@@ -44,14 +38,11 @@ setjmp = 0x40000540;
|
||||
strcat = 0x4001ad90;
|
||||
strchr = 0x4001adb0;
|
||||
strcmp = 0x40007be4;
|
||||
strcoll = 0x40007ce8;
|
||||
strcpy = 0x40007cfc;
|
||||
strcspn = 0x4001adcc;
|
||||
strlcat = 0x40007db8;
|
||||
strlcpy = 0x4001adf8;
|
||||
strlen = 0x40007e08;
|
||||
strlwr = 0x40007e68;
|
||||
strncasecmp = 0x40007e94;
|
||||
strncat = 0x4001ae34;
|
||||
strncmp = 0x4001ae64;
|
||||
strncpy = 0x40007f20;
|
||||
@@ -62,7 +53,4 @@ strspn = 0x4001aebc;
|
||||
strstr = 0x4001aee8;
|
||||
__strtok_r = 0x4001af18;
|
||||
strtok_r = 0x4001af7c;
|
||||
strupr = 0x40008084;
|
||||
toascii = 0x4001af90;
|
||||
tolower = 0x40008158;
|
||||
toupper = 0x40008174;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -50,3 +50,15 @@ __locale_ctype_ptr_l = 0x40001c24;
|
||||
__locale_mb_cur_max = 0x40001c0c;
|
||||
strcasecmp = 0x40007b38;
|
||||
strcasestr = 0x40007b7c;
|
||||
tolower = 0x40008158;
|
||||
toupper = 0x40008174;
|
||||
isalnum = 0x400078d8;
|
||||
isalpha = 0x400078e8;
|
||||
isdigit = 0x40007930;
|
||||
islower = 0x40007948;
|
||||
isspace = 0x400079ac;
|
||||
isupper = 0x400079c4;
|
||||
strcoll = 0x40007ce8;
|
||||
strlwr = 0x40007e68;
|
||||
strncasecmp = 0x40007e94;
|
||||
strupr = 0x40008084;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -16,41 +16,28 @@ strlen = 0x40001248;
|
||||
strstr = 0x40001254;
|
||||
bzero = 0x40001260;
|
||||
sbrk = 0x40001278;
|
||||
isalnum = 0x40001284;
|
||||
isalpha = 0x40001290;
|
||||
isascii = 0x4000129c;
|
||||
isblank = 0x400012a8;
|
||||
iscntrl = 0x400012b4;
|
||||
isdigit = 0x400012c0;
|
||||
islower = 0x400012cc;
|
||||
isgraph = 0x400012d8;
|
||||
isprint = 0x400012e4;
|
||||
ispunct = 0x400012f0;
|
||||
isspace = 0x400012fc;
|
||||
isupper = 0x40001308;
|
||||
toupper = 0x40001314;
|
||||
tolower = 0x40001320;
|
||||
toascii = 0x4000132c;
|
||||
memccpy = 0x40001338;
|
||||
memchr = 0x40001344;
|
||||
memrchr = 0x40001350;
|
||||
strcasecmp = 0x4000135c;
|
||||
strcasestr = 0x40001368;
|
||||
strcat = 0x40001374;
|
||||
strchr = 0x4000138c;
|
||||
strcspn = 0x40001398;
|
||||
strcoll = 0x400013a4;
|
||||
strlcat = 0x400013b0;
|
||||
strlcpy = 0x400013bc;
|
||||
strlwr = 0x400013c8;
|
||||
strncasecmp = 0x400013d4;
|
||||
strncat = 0x400013e0;
|
||||
strnlen = 0x400013f8;
|
||||
strrchr = 0x40001404;
|
||||
strsep = 0x40001410;
|
||||
strspn = 0x4000141c;
|
||||
strtok_r = 0x40001428;
|
||||
strupr = 0x40001434;
|
||||
longjmp = 0x40001440;
|
||||
setjmp = 0x4000144c;
|
||||
abs = 0x40001458;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -29,3 +29,16 @@ PROVIDE( _fwalk = 0x40001518 );
|
||||
PROVIDE( _fwalk_reent = 0x40001524 );
|
||||
PROVIDE( __swbuf_r = 0x40001548 );
|
||||
__swbuf = 0x40001554;
|
||||
toupper = 0x40001314;
|
||||
tolower = 0x40001320;
|
||||
isalnum = 0x40001284;
|
||||
isalpha = 0x40001290;
|
||||
isdigit = 0x400012c0;
|
||||
islower = 0x400012cc;
|
||||
isspace = 0x400012fc;
|
||||
isupper = 0x40001308;
|
||||
strcasecmp = 0x4000135c;
|
||||
strcoll = 0x400013a4;
|
||||
strlwr = 0x400013c8;
|
||||
strncasecmp = 0x400013d4;
|
||||
strupr = 0x40001434;
|
||||
|
||||
@@ -69,7 +69,9 @@
|
||||
* And so forth...
|
||||
*/
|
||||
*(.rela.*)
|
||||
#if CONFIG_LIBC_NEWLIB
|
||||
*(.got .got.plt) /* TODO: GCC-382 */
|
||||
#endif
|
||||
#if !EH_FRAME_LINKING_ENABLED
|
||||
*(.eh_frame_hdr)
|
||||
*(.eh_frame)
|
||||
|
||||
@@ -395,12 +395,14 @@ SECTIONS
|
||||
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
|
||||
*/
|
||||
ALIGNED_SYMBOL(4, __preinit_array_start)
|
||||
ALIGNED_SYMBOL(4, __bothinit_array_start)
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = ABSOLUTE(.);
|
||||
ALIGNED_SYMBOL(4, __init_array_start)
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors.*)))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
__bothinit_array_end = ABSOLUTE(.);
|
||||
|
||||
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
|
||||
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
|
||||
@@ -428,12 +430,24 @@ SECTIONS
|
||||
|
||||
/* TLS data. */
|
||||
ALIGNED_SYMBOL(4, _thread_local_start)
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
_picolibc_reent_stub_start = ABSOLUTE(.);
|
||||
KEEP(*(.tdata.errno))
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
/* Reproduce the public fields from struct _reent. */
|
||||
KEEP(*(.tdata.tls_stdin))
|
||||
KEEP(*(.tdata.tls_stdout))
|
||||
KEEP(*(.tdata.tls_stderr))
|
||||
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
_picolibc_reent_stub_end = ABSOLUTE(.);
|
||||
#endif // CONFIG_LIBC_PICOLIBC
|
||||
*(.tdata)
|
||||
*(.tdata.*)
|
||||
*(.tbss)
|
||||
*(.tbss.*)
|
||||
_thread_local_end = ABSOLUTE(.);
|
||||
} > default_rodata_seg
|
||||
ASSERT_PICOLIBC_REENT_STUB()
|
||||
|
||||
_flash_rodata_align = ALIGNOF(.flash.rodata);
|
||||
|
||||
|
||||
@@ -217,6 +217,9 @@ SECTIONS
|
||||
|
||||
mapping[flash_rodata]
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
*(.got .got.plt) /* TODO: GCC-439 */
|
||||
#endif
|
||||
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
@@ -228,12 +231,14 @@ SECTIONS
|
||||
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
|
||||
*/
|
||||
ALIGNED_SYMBOL(4, __preinit_array_start)
|
||||
ALIGNED_SYMBOL(4, __bothinit_array_start)
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = ABSOLUTE(.);
|
||||
ALIGNED_SYMBOL(4, __init_array_start)
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
__bothinit_array_end = ABSOLUTE(.);
|
||||
|
||||
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
|
||||
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
|
||||
@@ -288,24 +293,42 @@ SECTIONS
|
||||
|
||||
.flash.tdata :
|
||||
{
|
||||
/* Keep tdata and tbss sections contiguous (no gaps between them).
|
||||
* The TLS runtime code calculates offsets assuming these sections are
|
||||
* adjacent. Gaps would cause incorrect address calculations, leading
|
||||
* to accessing wrong memory.
|
||||
*
|
||||
* Storing all TLS structures in flash increases binary size, but avoids
|
||||
* runtime issues and reduces TLS allocations on the stack.
|
||||
*/
|
||||
/* tdata sections */
|
||||
_thread_local_data_start = ABSOLUTE(.);
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
_picolibc_reent_stub_start = ABSOLUTE(.);
|
||||
KEEP(*(.tdata.errno))
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
/* Reproduce the public fields from struct _reent. */
|
||||
KEEP(*(.tdata.tls_stdin))
|
||||
KEEP(*(.tdata.tls_stdout))
|
||||
KEEP(*(.tdata.tls_stderr))
|
||||
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
_picolibc_reent_stub_end = ABSOLUTE(.);
|
||||
#endif // CONFIG_LIBC_PICOLIBC
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.tbss));
|
||||
_thread_local_data_end = ABSOLUTE(.);
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
|
||||
|
||||
.flash.tbss (NOLOAD) :
|
||||
{
|
||||
/* tbss sections */
|
||||
_thread_local_bss_start = ABSOLUTE(.);
|
||||
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
|
||||
_thread_local_bss_end = ABSOLUTE(.);
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.rodata_noload));
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload)
|
||||
ASSERT(_thread_local_data_end == _thread_local_bss_start,
|
||||
"tdata and tbss must be contiguous.")
|
||||
ASSERT_PICOLIBC_REENT_STUB()
|
||||
|
||||
/**
|
||||
* This section contains all the rodata that is not used
|
||||
@@ -318,7 +341,7 @@ SECTIONS
|
||||
* driver to maintain the virtual address.
|
||||
* NOLOAD rodata may not be included in this section.
|
||||
*/
|
||||
_rodata_reserved_end = ADDR(.flash.tbss);
|
||||
_rodata_reserved_end = .;
|
||||
|
||||
mapping[rodata_noload]
|
||||
|
||||
|
||||
@@ -346,6 +346,9 @@ SECTIONS
|
||||
|
||||
mapping[flash_rodata]
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
*(.got .got.plt) /* TODO: GCC-439 */
|
||||
#endif
|
||||
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
@@ -357,12 +360,14 @@ SECTIONS
|
||||
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
|
||||
*/
|
||||
ALIGNED_SYMBOL(4, __preinit_array_start)
|
||||
ALIGNED_SYMBOL(4, __bothinit_array_start)
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = ABSOLUTE(.);
|
||||
ALIGNED_SYMBOL(4, __init_array_start)
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
__bothinit_array_end = ABSOLUTE(.);
|
||||
|
||||
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
|
||||
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
|
||||
@@ -417,24 +422,42 @@ SECTIONS
|
||||
|
||||
.flash.tdata :
|
||||
{
|
||||
/* Keep tdata and tbss sections contiguous (no gaps between them).
|
||||
* The TLS runtime code calculates offsets assuming these sections are
|
||||
* adjacent. Gaps would cause incorrect address calculations, leading
|
||||
* to accessing wrong memory.
|
||||
*
|
||||
* Storing all TLS structures in flash increases binary size, but avoids
|
||||
* runtime issues and reduces TLS allocations on the stack.
|
||||
*/
|
||||
/* tdata sections */
|
||||
_thread_local_data_start = ABSOLUTE(.);
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
_picolibc_reent_stub_start = ABSOLUTE(.);
|
||||
KEEP(*(.tdata.errno))
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
/* Reproduce the public fields from struct _reent. */
|
||||
KEEP(*(.tdata.tls_stdin))
|
||||
KEEP(*(.tdata.tls_stdout))
|
||||
KEEP(*(.tdata.tls_stderr))
|
||||
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
_picolibc_reent_stub_end = ABSOLUTE(.);
|
||||
#endif // CONFIG_LIBC_PICOLIBC
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.tbss));
|
||||
_thread_local_data_end = ABSOLUTE(.);
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
|
||||
|
||||
.flash.tbss (NOLOAD) :
|
||||
{
|
||||
/* tbss sections */
|
||||
_thread_local_bss_start = ABSOLUTE(.);
|
||||
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
|
||||
_thread_local_bss_end = ABSOLUTE(.);
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.rodata_noload));
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload)
|
||||
ASSERT(_thread_local_data_end == _thread_local_bss_start,
|
||||
"tdata and tbss must be contiguous.")
|
||||
ASSERT_PICOLIBC_REENT_STUB()
|
||||
|
||||
/**
|
||||
* This section contains all the rodata that is not used
|
||||
@@ -447,7 +470,7 @@ SECTIONS
|
||||
* driver to maintain the virtual address.
|
||||
* NOLOAD rodata may not be included in this section.
|
||||
*/
|
||||
_rodata_reserved_end = ADDR(.flash.tbss);
|
||||
_rodata_reserved_end = .;
|
||||
|
||||
mapping[rodata_noload]
|
||||
|
||||
|
||||
@@ -402,6 +402,9 @@ SECTIONS
|
||||
|
||||
mapping[flash_rodata]
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
*(.got .got.plt) /* TODO: GCC-439 */
|
||||
#endif
|
||||
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
@@ -413,12 +416,14 @@ SECTIONS
|
||||
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
|
||||
*/
|
||||
ALIGNED_SYMBOL(4, __preinit_array_start)
|
||||
ALIGNED_SYMBOL(4, __bothinit_array_start)
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = ABSOLUTE(.);
|
||||
ALIGNED_SYMBOL(4, __init_array_start)
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
__bothinit_array_end = ABSOLUTE(.);
|
||||
|
||||
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
|
||||
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
|
||||
@@ -473,32 +478,48 @@ SECTIONS
|
||||
|
||||
.flash.tdata :
|
||||
{
|
||||
/* Keep tdata and tbss sections contiguous (no gaps between them).
|
||||
* The TLS runtime code calculates offsets assuming these sections are
|
||||
* adjacent. Gaps would cause incorrect address calculations, leading
|
||||
* to accessing wrong memory.
|
||||
*
|
||||
* Storing all TLS structures in flash increases binary size, but avoids
|
||||
* runtime issues and reduces TLS allocations on the stack.
|
||||
*/
|
||||
/* tdata sections */
|
||||
_thread_local_data_start = ABSOLUTE(.);
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
_picolibc_reent_stub_start = ABSOLUTE(.);
|
||||
KEEP(*(.tdata.errno))
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
/* Reproduce the public fields from struct _reent. */
|
||||
KEEP(*(.tdata.tls_stdin))
|
||||
KEEP(*(.tdata.tls_stdout))
|
||||
KEEP(*(.tdata.tls_stderr))
|
||||
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
_picolibc_reent_stub_end = ABSOLUTE(.);
|
||||
#endif // CONFIG_LIBC_PICOLIBC
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
_thread_local_data_end = ABSOLUTE(.);
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.tbss));
|
||||
/* tbss sections */
|
||||
_thread_local_bss_start = ABSOLUTE(.);
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
_thread_local_bss_end = ABSOLUTE(.);
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.rodata_noload));
|
||||
#if CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
|
||||
/* Align the end of flash rodata region as per PMP granularity to allow using the
|
||||
* page alignment gap created while mapping the flash region into the PSRAM memory.
|
||||
*/
|
||||
. = ALIGN(_esp_pmp_align_size);
|
||||
#endif // CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
|
||||
|
||||
_thread_local_data_end = ABSOLUTE(.);
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
|
||||
|
||||
.flash.tbss (NOLOAD) :
|
||||
{
|
||||
_thread_local_bss_start = ABSOLUTE(.);
|
||||
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
|
||||
_thread_local_bss_end = ABSOLUTE(.);
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload)
|
||||
ASSERT(_thread_local_data_end == _thread_local_bss_start,
|
||||
"tdata and tbss must be contiguous.")
|
||||
ASSERT_PICOLIBC_REENT_STUB()
|
||||
|
||||
/**
|
||||
* This section contains all the rodata that is not used
|
||||
@@ -511,7 +532,7 @@ SECTIONS
|
||||
* driver to maintain the virtual address.
|
||||
* NOLOAD rodata may not be included in this section.
|
||||
*/
|
||||
_rodata_reserved_end = ADDR(.flash.tbss);
|
||||
_rodata_reserved_end = .;
|
||||
|
||||
mapping[rodata_noload]
|
||||
|
||||
|
||||
@@ -398,6 +398,9 @@ SECTIONS
|
||||
|
||||
mapping[flash_rodata]
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
*(.got .got.plt) /* TODO: GCC-439 */
|
||||
#endif
|
||||
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
@@ -409,12 +412,14 @@ SECTIONS
|
||||
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
|
||||
*/
|
||||
ALIGNED_SYMBOL(4, __preinit_array_start)
|
||||
ALIGNED_SYMBOL(4, __bothinit_array_start)
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = ABSOLUTE(.);
|
||||
ALIGNED_SYMBOL(4, __init_array_start)
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
__bothinit_array_end = ABSOLUTE(.);
|
||||
|
||||
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
|
||||
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
|
||||
@@ -469,24 +474,42 @@ SECTIONS
|
||||
|
||||
.flash.tdata :
|
||||
{
|
||||
/* Keep tdata and tbss sections contiguous (no gaps between them).
|
||||
* The TLS runtime code calculates offsets assuming these sections are
|
||||
* adjacent. Gaps would cause incorrect address calculations, leading
|
||||
* to accessing wrong memory.
|
||||
*
|
||||
* Storing all TLS structures in flash increases binary size, but avoids
|
||||
* runtime issues and reduces TLS allocations on the stack.
|
||||
*/
|
||||
/* tdata sections */
|
||||
_thread_local_data_start = ABSOLUTE(.);
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
_picolibc_reent_stub_start = ABSOLUTE(.);
|
||||
KEEP(*(.tdata.errno))
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
/* Reproduce the public fields from struct _reent. */
|
||||
KEEP(*(.tdata.tls_stdin))
|
||||
KEEP(*(.tdata.tls_stdout))
|
||||
KEEP(*(.tdata.tls_stderr))
|
||||
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
_picolibc_reent_stub_end = ABSOLUTE(.);
|
||||
#endif // CONFIG_LIBC_PICOLIBC
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.tbss));
|
||||
_thread_local_data_end = ABSOLUTE(.);
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
|
||||
|
||||
.flash.tbss (NOLOAD) :
|
||||
{
|
||||
/* tbss sections */
|
||||
_thread_local_bss_start = ABSOLUTE(.);
|
||||
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
|
||||
_thread_local_bss_end = ABSOLUTE(.);
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.rodata_noload));
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload)
|
||||
ASSERT(_thread_local_data_end == _thread_local_bss_start,
|
||||
"tdata and tbss must be contiguous.")
|
||||
ASSERT_PICOLIBC_REENT_STUB()
|
||||
|
||||
/**
|
||||
* This section contains all the rodata that is not used
|
||||
@@ -499,7 +522,7 @@ SECTIONS
|
||||
* driver to maintain the virtual address.
|
||||
* NOLOAD rodata may not be included in this section.
|
||||
*/
|
||||
_rodata_reserved_end = ADDR(.flash.tbss);
|
||||
_rodata_reserved_end = .;
|
||||
|
||||
mapping[rodata_noload]
|
||||
|
||||
|
||||
@@ -244,6 +244,9 @@ SECTIONS
|
||||
|
||||
mapping[flash_rodata]
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
*(.got .got.plt) /* TODO: GCC-439 */
|
||||
#endif
|
||||
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
@@ -255,6 +258,7 @@ SECTIONS
|
||||
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
|
||||
*/
|
||||
ALIGNED_SYMBOL(4, __preinit_array_start)
|
||||
ALIGNED_SYMBOL(4, __bothinit_array_start)
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = ABSOLUTE(.);
|
||||
|
||||
@@ -262,6 +266,7 @@ SECTIONS
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
__bothinit_array_end = ABSOLUTE(.);
|
||||
|
||||
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
|
||||
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
|
||||
@@ -316,32 +321,48 @@ SECTIONS
|
||||
|
||||
.flash.tdata :
|
||||
{
|
||||
/* Keep tdata and tbss sections contiguous (no gaps between them).
|
||||
* The TLS runtime code calculates offsets assuming these sections are
|
||||
* adjacent. Gaps would cause incorrect address calculations, leading
|
||||
* to accessing wrong memory.
|
||||
*
|
||||
* Storing all TLS structures in flash increases binary size, but avoids
|
||||
* runtime issues and reduces TLS allocations on the stack.
|
||||
*/
|
||||
/* tdata sections */
|
||||
_thread_local_data_start = ABSOLUTE(.);
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
_picolibc_reent_stub_start = ABSOLUTE(.);
|
||||
KEEP(*(.tdata.errno))
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
/* Reproduce the public fields from struct _reent. */
|
||||
KEEP(*(.tdata.tls_stdin))
|
||||
KEEP(*(.tdata.tls_stdout))
|
||||
KEEP(*(.tdata.tls_stderr))
|
||||
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
_picolibc_reent_stub_end = ABSOLUTE(.);
|
||||
#endif // CONFIG_LIBC_PICOLIBC
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
_thread_local_data_end = ABSOLUTE(.);
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.tbss));
|
||||
/* tbss sections */
|
||||
_thread_local_bss_start = ABSOLUTE(.);
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
_thread_local_bss_end = ABSOLUTE(.);
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.rodata_noload));
|
||||
#if CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
|
||||
/* Align the end of flash rodata region as per PMP granularity to allow using the
|
||||
* page alignment gap created while mapping the flash region into the PSRAM memory.
|
||||
*/
|
||||
. = ALIGN(_esp_pmp_align_size);
|
||||
#endif // CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
|
||||
|
||||
_thread_local_data_end = ABSOLUTE(.);
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
|
||||
|
||||
.flash.tbss (NOLOAD) :
|
||||
{
|
||||
_thread_local_bss_start = ABSOLUTE(.);
|
||||
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
|
||||
_thread_local_bss_end = ABSOLUTE(.);
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload)
|
||||
ASSERT(_thread_local_data_end == _thread_local_bss_start,
|
||||
"tdata and tbss must be contiguous.")
|
||||
ASSERT_PICOLIBC_REENT_STUB()
|
||||
|
||||
/**
|
||||
* This section contains all the rodata that is not used
|
||||
@@ -354,7 +375,7 @@ SECTIONS
|
||||
* driver to maintain the virtual address.
|
||||
* NOLOAD rodata may not be included in this section.
|
||||
*/
|
||||
_rodata_reserved_end = ADDR(.flash.tbss);
|
||||
_rodata_reserved_end = .;
|
||||
|
||||
mapping[rodata_noload]
|
||||
|
||||
|
||||
@@ -400,6 +400,9 @@ SECTIONS
|
||||
|
||||
mapping[flash_rodata]
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
*(.got .got.plt) /* TODO: GCC-439 */
|
||||
#endif
|
||||
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
@@ -411,12 +414,14 @@ SECTIONS
|
||||
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
|
||||
*/
|
||||
ALIGNED_SYMBOL(4, __preinit_array_start)
|
||||
ALIGNED_SYMBOL(4, __bothinit_array_start)
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = ABSOLUTE(.);
|
||||
ALIGNED_SYMBOL(4, __init_array_start)
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
__bothinit_array_end = ABSOLUTE(.);
|
||||
|
||||
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
|
||||
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
|
||||
@@ -471,24 +476,42 @@ SECTIONS
|
||||
|
||||
.flash.tdata :
|
||||
{
|
||||
/* Keep tdata and tbss sections contiguous (no gaps between them).
|
||||
* The TLS runtime code calculates offsets assuming these sections are
|
||||
* adjacent. Gaps would cause incorrect address calculations, leading
|
||||
* to accessing wrong memory.
|
||||
*
|
||||
* Storing all TLS structures in flash increases binary size, but avoids
|
||||
* runtime issues and reduces TLS allocations on the stack.
|
||||
*/
|
||||
/* tdata sections */
|
||||
_thread_local_data_start = ABSOLUTE(.);
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
_picolibc_reent_stub_start = ABSOLUTE(.);
|
||||
KEEP(*(.tdata.errno))
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
/* Reproduce the public fields from struct _reent. */
|
||||
KEEP(*(.tdata.tls_stdin))
|
||||
KEEP(*(.tdata.tls_stdout))
|
||||
KEEP(*(.tdata.tls_stderr))
|
||||
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
_picolibc_reent_stub_end = ABSOLUTE(.);
|
||||
#endif // CONFIG_LIBC_PICOLIBC
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.tbss));
|
||||
_thread_local_data_end = ABSOLUTE(.);
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
|
||||
|
||||
.flash.tbss (NOLOAD) :
|
||||
{
|
||||
/* tbss sections */
|
||||
_thread_local_bss_start = ABSOLUTE(.);
|
||||
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
|
||||
_thread_local_bss_end = ABSOLUTE(.);
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.rodata_noload));
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload)
|
||||
ASSERT(_thread_local_data_end == _thread_local_bss_start,
|
||||
"tdata and tbss must be contiguous.")
|
||||
ASSERT_PICOLIBC_REENT_STUB()
|
||||
|
||||
/**
|
||||
* This section contains all the rodata that is not used
|
||||
@@ -501,7 +524,7 @@ SECTIONS
|
||||
* driver to maintain the virtual address.
|
||||
* NOLOAD rodata may not be included in this section.
|
||||
*/
|
||||
_rodata_reserved_end = ADDR(.flash.tbss);
|
||||
_rodata_reserved_end = .;
|
||||
|
||||
mapping[rodata_noload]
|
||||
|
||||
|
||||
@@ -389,6 +389,9 @@ SECTIONS
|
||||
|
||||
mapping[flash_rodata]
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
*(.got .got.plt) /* TODO: GCC-439 */
|
||||
#endif
|
||||
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
@@ -400,12 +403,14 @@ SECTIONS
|
||||
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
|
||||
*/
|
||||
ALIGNED_SYMBOL(4, __preinit_array_start)
|
||||
ALIGNED_SYMBOL(4, __bothinit_array_start)
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = ABSOLUTE(.);
|
||||
ALIGNED_SYMBOL(4, __init_array_start)
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
__bothinit_array_end = ABSOLUTE(.);
|
||||
|
||||
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
|
||||
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
|
||||
@@ -460,24 +465,42 @@ SECTIONS
|
||||
|
||||
.flash.tdata :
|
||||
{
|
||||
/* Keep tdata and tbss sections contiguous (no gaps between them).
|
||||
* The TLS runtime code calculates offsets assuming these sections are
|
||||
* adjacent. Gaps would cause incorrect address calculations, leading
|
||||
* to accessing wrong memory.
|
||||
*
|
||||
* Storing all TLS structures in flash increases binary size, but avoids
|
||||
* runtime issues and reduces TLS allocations on the stack.
|
||||
*/
|
||||
/* tdata sections */
|
||||
_thread_local_data_start = ABSOLUTE(.);
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
_picolibc_reent_stub_start = ABSOLUTE(.);
|
||||
KEEP(*(.tdata.errno))
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
/* Reproduce the public fields from struct _reent. */
|
||||
KEEP(*(.tdata.tls_stdin))
|
||||
KEEP(*(.tdata.tls_stdout))
|
||||
KEEP(*(.tdata.tls_stderr))
|
||||
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
_picolibc_reent_stub_end = ABSOLUTE(.);
|
||||
#endif // CONFIG_LIBC_PICOLIBC
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.tbss));
|
||||
_thread_local_data_end = ABSOLUTE(.);
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
|
||||
|
||||
.flash.tbss (NOLOAD) :
|
||||
{
|
||||
/* tbss sections */
|
||||
_thread_local_bss_start = ABSOLUTE(.);
|
||||
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
|
||||
_thread_local_bss_end = ABSOLUTE(.);
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.rodata_noload));
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload)
|
||||
ASSERT(_thread_local_data_end == _thread_local_bss_start,
|
||||
"tdata and tbss must be contiguous.")
|
||||
ASSERT_PICOLIBC_REENT_STUB()
|
||||
|
||||
/**
|
||||
* This section contains all the rodata that is not used
|
||||
@@ -490,7 +513,7 @@ SECTIONS
|
||||
* driver to maintain the virtual address.
|
||||
* NOLOAD rodata may not be included in this section.
|
||||
*/
|
||||
_rodata_reserved_end = ADDR(.flash.tbss);
|
||||
_rodata_reserved_end = .;
|
||||
|
||||
mapping[rodata_noload]
|
||||
|
||||
|
||||
@@ -218,6 +218,9 @@ SECTIONS
|
||||
|
||||
mapping[flash_rodata]
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
*(.got .got.plt) /* TODO: GCC-439 */
|
||||
#endif
|
||||
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
@@ -229,12 +232,14 @@ SECTIONS
|
||||
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
|
||||
*/
|
||||
ALIGNED_SYMBOL(4, __preinit_array_start)
|
||||
ALIGNED_SYMBOL(4, __bothinit_array_start)
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = ABSOLUTE(.);
|
||||
ALIGNED_SYMBOL(4, __init_array_start)
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
__bothinit_array_end = ABSOLUTE(.);
|
||||
|
||||
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
|
||||
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
|
||||
@@ -289,24 +294,42 @@ SECTIONS
|
||||
|
||||
.flash.tdata :
|
||||
{
|
||||
/* Keep tdata and tbss sections contiguous (no gaps between them).
|
||||
* The TLS runtime code calculates offsets assuming these sections are
|
||||
* adjacent. Gaps would cause incorrect address calculations, leading
|
||||
* to accessing wrong memory.
|
||||
*
|
||||
* Storing all TLS structures in flash increases binary size, but avoids
|
||||
* runtime issues and reduces TLS allocations on the stack.
|
||||
*/
|
||||
/* tdata sections */
|
||||
_thread_local_data_start = ABSOLUTE(.);
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
_picolibc_reent_stub_start = ABSOLUTE(.);
|
||||
KEEP(*(.tdata.errno))
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
/* Reproduce the public fields from struct _reent. */
|
||||
KEEP(*(.tdata.tls_stdin))
|
||||
KEEP(*(.tdata.tls_stdout))
|
||||
KEEP(*(.tdata.tls_stderr))
|
||||
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
_picolibc_reent_stub_end = ABSOLUTE(.);
|
||||
#endif // CONFIG_LIBC_PICOLIBC
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.tbss));
|
||||
_thread_local_data_end = ABSOLUTE(.);
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
|
||||
|
||||
.flash.tbss (NOLOAD) :
|
||||
{
|
||||
/* tbss sections */
|
||||
_thread_local_bss_start = ABSOLUTE(.);
|
||||
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
|
||||
_thread_local_bss_end = ABSOLUTE(.);
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.rodata_noload));
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload)
|
||||
ASSERT(_thread_local_data_end == _thread_local_bss_start,
|
||||
"tdata and tbss must be contiguous.")
|
||||
ASSERT_PICOLIBC_REENT_STUB()
|
||||
|
||||
/**
|
||||
* This section contains all the rodata that is not used
|
||||
@@ -319,7 +342,7 @@ SECTIONS
|
||||
* driver to maintain the virtual address.
|
||||
* NOLOAD rodata may not be included in this section.
|
||||
*/
|
||||
_rodata_reserved_end = ADDR(.flash.tbss);
|
||||
_rodata_reserved_end = .;
|
||||
|
||||
mapping[rodata_noload]
|
||||
|
||||
|
||||
@@ -426,6 +426,9 @@ SECTIONS
|
||||
|
||||
mapping[flash_rodata]
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
*(.got .got.plt) /* TODO: GCC-439 */
|
||||
#endif
|
||||
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
@@ -443,12 +446,14 @@ SECTIONS
|
||||
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
|
||||
*/
|
||||
ALIGNED_SYMBOL(4, __preinit_array_start)
|
||||
ALIGNED_SYMBOL(4, __bothinit_array_start)
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = ABSOLUTE(.);
|
||||
ALIGNED_SYMBOL(4, __init_array_start)
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
__bothinit_array_end = ABSOLUTE(.);
|
||||
|
||||
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
|
||||
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
|
||||
@@ -503,32 +508,48 @@ SECTIONS
|
||||
|
||||
.flash.tdata :
|
||||
{
|
||||
/* Keep tdata and tbss sections contiguous (no gaps between them).
|
||||
* The TLS runtime code calculates offsets assuming these sections are
|
||||
* adjacent. Gaps would cause incorrect address calculations, leading
|
||||
* to accessing wrong memory.
|
||||
*
|
||||
* Storing all TLS structures in flash increases binary size, but avoids
|
||||
* runtime issues and reduces TLS allocations on the stack.
|
||||
*/
|
||||
/* tdata sections */
|
||||
_thread_local_data_start = ABSOLUTE(.);
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
_picolibc_reent_stub_start = ABSOLUTE(.);
|
||||
KEEP(*(.tdata.errno))
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
/* Reproduce the public fields from struct _reent. */
|
||||
KEEP(*(.tdata.tls_stdin))
|
||||
KEEP(*(.tdata.tls_stdout))
|
||||
KEEP(*(.tdata.tls_stderr))
|
||||
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
_picolibc_reent_stub_end = ABSOLUTE(.);
|
||||
#endif // CONFIG_LIBC_PICOLIBC
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
_thread_local_data_end = ABSOLUTE(.);
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.tbss));
|
||||
/* tbss sections */
|
||||
_thread_local_bss_start = ABSOLUTE(.);
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
_thread_local_bss_end = ABSOLUTE(.);
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.rodata_noload));
|
||||
#if CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
|
||||
/* Align the end of flash rodata region as per PMP granularity to allow using the
|
||||
* page alignment gap created while mapping the flash region into the PSRAM memory.
|
||||
*/
|
||||
. = ALIGN(_esp_pmp_align_size);
|
||||
#endif // CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
|
||||
|
||||
_thread_local_data_end = ABSOLUTE(.);
|
||||
} > rodata_seg_low
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
|
||||
|
||||
.flash.tbss (NOLOAD) :
|
||||
{
|
||||
_thread_local_bss_start = ABSOLUTE(.);
|
||||
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
|
||||
_thread_local_bss_end = ABSOLUTE(.);
|
||||
} > rodata_seg_low
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload)
|
||||
ASSERT(_thread_local_data_end == _thread_local_bss_start,
|
||||
"tdata and tbss must be contiguous.")
|
||||
ASSERT_PICOLIBC_REENT_STUB()
|
||||
|
||||
/**
|
||||
* This section contains all the rodata that is not used
|
||||
@@ -541,7 +562,7 @@ SECTIONS
|
||||
* driver to maintain the virtual address.
|
||||
* NOLOAD rodata may not be included in this section.
|
||||
*/
|
||||
_rodata_reserved_end = ADDR(.flash.tbss);
|
||||
_rodata_reserved_end = .;
|
||||
|
||||
arrays[rodata_noload]
|
||||
|
||||
|
||||
@@ -388,6 +388,9 @@ SECTIONS
|
||||
arrays[flash_rodata]
|
||||
mapping[flash_rodata]
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
*(.got .got.plt) /* TODO: GCC-439 */
|
||||
#endif
|
||||
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
@@ -405,12 +408,14 @@ SECTIONS
|
||||
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
|
||||
*/
|
||||
ALIGNED_SYMBOL(4, __preinit_array_start)
|
||||
ALIGNED_SYMBOL(4, __bothinit_array_start)
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = ABSOLUTE(.);
|
||||
ALIGNED_SYMBOL(4, __init_array_start)
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
__bothinit_array_end = ABSOLUTE(.);
|
||||
|
||||
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
|
||||
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
|
||||
@@ -460,11 +465,37 @@ SECTIONS
|
||||
|
||||
.flash.tdata :
|
||||
{
|
||||
/* Keep tdata and tbss sections contiguous (no gaps between them).
|
||||
* The TLS runtime code calculates offsets assuming these sections are
|
||||
* adjacent. Gaps would cause incorrect address calculations, leading
|
||||
* to accessing wrong memory.
|
||||
*
|
||||
* Storing all TLS structures in flash increases binary size, but avoids
|
||||
* runtime issues and reduces TLS allocations on the stack.
|
||||
*/
|
||||
/* tdata sections */
|
||||
_thread_local_data_start = ABSOLUTE(.);
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
_picolibc_reent_stub_start = ABSOLUTE(.);
|
||||
KEEP(*(.tdata.errno))
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
/* Reproduce the public fields from struct _reent. */
|
||||
KEEP(*(.tdata.tls_stdin))
|
||||
KEEP(*(.tdata.tls_stdout))
|
||||
KEEP(*(.tdata.tls_stderr))
|
||||
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
_picolibc_reent_stub_end = ABSOLUTE(.);
|
||||
#endif // CONFIG_LIBC_PICOLIBC
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
_thread_local_data_end = ABSOLUTE(.);
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.tbss));
|
||||
/* tbss sections */
|
||||
_thread_local_bss_start = ABSOLUTE(.);
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
_thread_local_bss_end = ABSOLUTE(.);
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.rodata_noload));
|
||||
|
||||
#if CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
|
||||
/* Align the end of flash rodata region as per PMP granularity to allow using the
|
||||
@@ -472,20 +503,11 @@ SECTIONS
|
||||
*/
|
||||
. = ALIGN(_esp_pmp_align_size);
|
||||
#endif // CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
|
||||
|
||||
_thread_local_data_end = ABSOLUTE(.);
|
||||
} > rodata_seg_low
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
|
||||
|
||||
.flash.tbss (NOLOAD) :
|
||||
{
|
||||
_thread_local_bss_start = ABSOLUTE(.);
|
||||
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
|
||||
_thread_local_bss_end = ABSOLUTE(.);
|
||||
} > rodata_seg_low
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload)
|
||||
ASSERT(_thread_local_data_end == _thread_local_bss_start,
|
||||
"tdata and tbss must be contiguous.")
|
||||
ASSERT_PICOLIBC_REENT_STUB()
|
||||
|
||||
/**
|
||||
* This section contains all the rodata that is not used
|
||||
@@ -498,7 +520,7 @@ SECTIONS
|
||||
* driver to maintain the virtual address.
|
||||
* NOLOAD rodata may not be included in this section.
|
||||
*/
|
||||
_rodata_reserved_end = ADDR(.flash.tbss);
|
||||
_rodata_reserved_end = .;
|
||||
|
||||
arrays[rodata_noload]
|
||||
mapping[rodata_noload]
|
||||
|
||||
@@ -397,12 +397,14 @@ SECTIONS
|
||||
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
|
||||
*/
|
||||
ALIGNED_SYMBOL(4, __preinit_array_start)
|
||||
ALIGNED_SYMBOL(4, __bothinit_array_start)
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = ABSOLUTE(.);
|
||||
ALIGNED_SYMBOL(4, __init_array_start)
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors.*)))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
__bothinit_array_end = ABSOLUTE(.);
|
||||
|
||||
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
|
||||
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
|
||||
@@ -430,12 +432,24 @@ SECTIONS
|
||||
|
||||
/* TLS data. */
|
||||
ALIGNED_SYMBOL(4, _thread_local_start)
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
_picolibc_reent_stub_start = ABSOLUTE(.);
|
||||
KEEP(*(.tdata.errno))
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
/* Reproduce the public fields from struct _reent. */
|
||||
KEEP(*(.tdata.tls_stdin))
|
||||
KEEP(*(.tdata.tls_stdout))
|
||||
KEEP(*(.tdata.tls_stderr))
|
||||
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
_picolibc_reent_stub_end = ABSOLUTE(.);
|
||||
#endif // CONFIG_LIBC_PICOLIBC
|
||||
*(.tdata)
|
||||
*(.tdata.*)
|
||||
*(.tbss)
|
||||
*(.tbss.*)
|
||||
_thread_local_end = ABSOLUTE(.);
|
||||
} > default_rodata_seg
|
||||
ASSERT_PICOLIBC_REENT_STUB()
|
||||
|
||||
_flash_rodata_align = ALIGNOF(.flash.rodata);
|
||||
|
||||
|
||||
@@ -409,12 +409,14 @@ SECTIONS
|
||||
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
|
||||
*/
|
||||
ALIGNED_SYMBOL(4, __preinit_array_start)
|
||||
ALIGNED_SYMBOL(4, __bothinit_array_start)
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = ABSOLUTE(.);
|
||||
ALIGNED_SYMBOL(4, __init_array_start)
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors.*)))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
__bothinit_array_end = ABSOLUTE(.);
|
||||
|
||||
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
|
||||
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
|
||||
@@ -442,12 +444,24 @@ SECTIONS
|
||||
|
||||
/* TLS data. */
|
||||
ALIGNED_SYMBOL(4, _thread_local_start)
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
_picolibc_reent_stub_start = ABSOLUTE(.);
|
||||
KEEP(*(.tdata.errno))
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
/* Reproduce the public fields from struct _reent. */
|
||||
KEEP(*(.tdata.tls_stdin))
|
||||
KEEP(*(.tdata.tls_stdout))
|
||||
KEEP(*(.tdata.tls_stderr))
|
||||
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
_picolibc_reent_stub_end = ABSOLUTE(.);
|
||||
#endif // CONFIG_LIBC_PICOLIBC
|
||||
*(.tdata)
|
||||
*(.tdata.*)
|
||||
*(.tbss)
|
||||
*(.tbss.*)
|
||||
_thread_local_end = ABSOLUTE(.);
|
||||
} > default_rodata_seg
|
||||
ASSERT_PICOLIBC_REENT_STUB()
|
||||
|
||||
_flash_rodata_align = ALIGNOF(.flash.rodata);
|
||||
|
||||
|
||||
@@ -219,6 +219,9 @@ SECTIONS
|
||||
|
||||
mapping[flash_rodata]
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
*(.got .got.plt) /* TODO: GCC-439 */
|
||||
#endif
|
||||
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
@@ -236,12 +239,14 @@ SECTIONS
|
||||
* Excluding crtbegin.o/crtend.o since IDF doesn't use the toolchain crt.
|
||||
*/
|
||||
ALIGNED_SYMBOL(4, __preinit_array_start)
|
||||
ALIGNED_SYMBOL(4, __bothinit_array_start)
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = ABSOLUTE(.);
|
||||
ALIGNED_SYMBOL(4, __init_array_start)
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
__bothinit_array_end = ABSOLUTE(.);
|
||||
|
||||
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
|
||||
ALIGNED_SYMBOL(4, soc_reserved_memory_region_start)
|
||||
@@ -296,32 +301,48 @@ SECTIONS
|
||||
|
||||
.flash.tdata :
|
||||
{
|
||||
/* Keep tdata and tbss sections contiguous (no gaps between them).
|
||||
* The TLS runtime code calculates offsets assuming these sections are
|
||||
* adjacent. Gaps would cause incorrect address calculations, leading
|
||||
* to accessing wrong memory.
|
||||
*
|
||||
* Storing all TLS structures in flash increases binary size, but avoids
|
||||
* runtime issues and reduces TLS allocations on the stack.
|
||||
*/
|
||||
/* tdata sections */
|
||||
_thread_local_data_start = ABSOLUTE(.);
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
_picolibc_reent_stub_start = ABSOLUTE(.);
|
||||
KEEP(*(.tdata.errno))
|
||||
#if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
/* Reproduce the public fields from struct _reent. */
|
||||
KEEP(*(.tdata.tls_stdin))
|
||||
KEEP(*(.tdata.tls_stdout))
|
||||
KEEP(*(.tdata.tls_stderr))
|
||||
#endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
_picolibc_reent_stub_end = ABSOLUTE(.);
|
||||
#endif // CONFIG_LIBC_PICOLIBC
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
_thread_local_data_end = ABSOLUTE(.);
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.tbss));
|
||||
/* tbss sections */
|
||||
_thread_local_bss_start = ABSOLUTE(.);
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
_thread_local_bss_end = ABSOLUTE(.);
|
||||
|
||||
. = ALIGN(ALIGNOF(.flash.rodata_noload));
|
||||
#if CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
|
||||
/* Align the end of flash rodata region as per PMP granularity to allow using the
|
||||
* page alignment gap created while mapping the flash region into the PSRAM memory.
|
||||
*/
|
||||
. = ALIGN(_esp_pmp_align_size);
|
||||
#endif // CONFIG_SPIRAM_RODATA && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
|
||||
|
||||
_thread_local_data_end = ABSOLUTE(.);
|
||||
} > rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.tbss)
|
||||
|
||||
.flash.tbss (NOLOAD) :
|
||||
{
|
||||
_thread_local_bss_start = ABSOLUTE(.);
|
||||
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
|
||||
_thread_local_bss_end = ABSOLUTE(.);
|
||||
} > rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tdata, .flash.rodata_noload)
|
||||
ASSERT(_thread_local_data_end == _thread_local_bss_start,
|
||||
"tdata and tbss must be contiguous.")
|
||||
ASSERT_PICOLIBC_REENT_STUB()
|
||||
|
||||
/**
|
||||
* This section contains all the rodata that is not used
|
||||
@@ -334,7 +355,7 @@ SECTIONS
|
||||
* driver to maintain the virtual address.
|
||||
* NOLOAD rodata may not be included in this section.
|
||||
*/
|
||||
_rodata_reserved_end = ADDR(.flash.tbss);
|
||||
_rodata_reserved_end = .;
|
||||
|
||||
arrays[rodata_noload]
|
||||
|
||||
|
||||
@@ -120,3 +120,14 @@ ASSERT((ADDR(NEXT_SECTION) == ADDR(PREV_SECTION) + SIZEOF(PREV_SECTION)), \
|
||||
#else
|
||||
#define FAST_REFLASHING_PADDING
|
||||
#endif
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
# if CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY
|
||||
# define PICOLIBC_REENT_STUB 16
|
||||
# else
|
||||
# define PICOLIBC_REENT_STUB 4
|
||||
# endif
|
||||
#define ASSERT_PICOLIBC_REENT_STUB() ASSERT((_picolibc_reent_stub_end - _picolibc_reent_stub_start) == PICOLIBC_REENT_STUB, "Newlib _reent stub have wrong size")
|
||||
#else
|
||||
#define ASSERT_PICOLIBC_REENT_STUB()
|
||||
#endif
|
||||
|
||||
@@ -197,6 +197,21 @@ static void core_intr_matrix_clear(void)
|
||||
#endif // SOC_INT_CLIC_SUPPORTED
|
||||
}
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
FORCE_INLINE_ATTR IRAM_ATTR void init_pre_rtos_tls_area(int cpu_num)
|
||||
{
|
||||
/**
|
||||
* Initialize the TLS area before RTOS starts, in case any code tries to access
|
||||
* TLS variables.
|
||||
*
|
||||
* TODO IDF-14914: Currently, we only initialize errno, which is the first TLS
|
||||
* variable as guaranteed by the linker script.
|
||||
*/
|
||||
static int s_errno_array[SOC_CPU_CORES_NUM];
|
||||
esp_cpu_set_threadptr(&s_errno_array[cpu_num]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
|
||||
void startup_resume_other_cores(void)
|
||||
{
|
||||
@@ -217,6 +232,10 @@ void ESP_SYSTEM_IRAM_ATTR call_start_cpu1(void)
|
||||
);
|
||||
#endif //#ifdef __riscv
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
init_pre_rtos_tls_area(1);
|
||||
#endif
|
||||
|
||||
#if SOC_BRANCH_PREDICTOR_SUPPORTED
|
||||
esp_cpu_branch_prediction_enable();
|
||||
#endif //#if SOC_BRANCH_PREDICTOR_SUPPORTED
|
||||
@@ -943,6 +962,10 @@ void IRAM_ATTR call_start_cpu0(void)
|
||||
// Clear BSS. Please do not attempt to do any complex stuff (like early logging) before this.
|
||||
init_bss(rst_reas);
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
init_pre_rtos_tls_area(0);
|
||||
#endif
|
||||
|
||||
// When the APP is loaded into ram for execution, some hardware initialization steps used to be executed in the
|
||||
// bootloader are done here.
|
||||
#if CONFIG_APP_BUILD_TYPE_RAM
|
||||
|
||||
@@ -123,11 +123,12 @@ if(CONFIG_SECURE_ENABLE_TEE AND NOT esp_tee_build)
|
||||
list(APPEND exclude_srv "attestation")
|
||||
endif()
|
||||
|
||||
idf_build_get_property(secure_service_headers_dir SECURE_SERVICE_HEADERS_DIR)
|
||||
execute_process(
|
||||
COMMAND python ${secure_service_yml_parser_py}
|
||||
"--sec_srv" ${secure_service_yml}
|
||||
"--exclude" ${exclude_srv}
|
||||
WORKING_DIRECTORY ${CONFIG_DIR}
|
||||
WORKING_DIRECTORY ${secure_service_headers_dir}
|
||||
)
|
||||
|
||||
execute_process(
|
||||
|
||||
@@ -6,7 +6,6 @@ idf_build_get_property(python PYTHON)
|
||||
idf_build_get_property(extra_cmake_args EXTRA_CMAKE_ARGS)
|
||||
idf_build_get_property(project_dir PROJECT_DIR)
|
||||
idf_build_get_property(non_os_build NON_OS_BUILD)
|
||||
idf_build_get_property(config_dir CONFIG_DIR)
|
||||
idf_build_get_property(custom_secure_service_dir CUSTOM_SECURE_SERVICE_COMPONENT_DIR)
|
||||
idf_build_get_property(custom_secure_service_component CUSTOM_SECURE_SERVICE_COMPONENT)
|
||||
|
||||
@@ -33,13 +32,24 @@ set(tee_binary_files
|
||||
"${TEE_BUILD_DIR}/esp_tee.map"
|
||||
)
|
||||
|
||||
# Use only Newlib libc to reduce binary size, as some Newlib functions are already available in ROM
|
||||
set(esp_tee_sdkconfig "${CMAKE_CURRENT_BINARY_DIR}/sdkconfig.esp_tee")
|
||||
configure_file("${sdkconfig}" "${esp_tee_sdkconfig}" COPYONLY)
|
||||
file(APPEND "${esp_tee_sdkconfig}" "\nCONFIG_LIBC_NEWLIB=y\n")
|
||||
|
||||
set(secure_service_headers_dir "${CMAKE_CURRENT_BINARY_DIR}/secure_service_headers")
|
||||
make_directory(${secure_service_headers_dir})
|
||||
idf_build_set_property(SECURE_SERVICE_HEADERS_DIR "${secure_service_headers_dir}")
|
||||
include_directories("${secure_service_headers_dir}")
|
||||
|
||||
externalproject_add(esp_tee
|
||||
SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/subproject"
|
||||
BINARY_DIR "${TEE_BUILD_DIR}"
|
||||
CMAKE_ARGS -DSDKCONFIG=${sdkconfig} -DIDF_PATH=${idf_path} -DIDF_TARGET=${idf_target}
|
||||
-DCONFIG_DIR=${config_dir} -DCUSTOM_SECURE_SERVICE_COMPONENT=${custom_secure_service_component}
|
||||
-DCUSTOM_SECURE_SERVICE_COMPONENT_DIR=${custom_secure_service_dir}
|
||||
${extra_cmake_args} ${sign_key_arg}
|
||||
CMAKE_ARGS -DSDKCONFIG=${esp_tee_sdkconfig} -DIDF_PATH=${idf_path} -DIDF_TARGET=${idf_target}
|
||||
-DCUSTOM_SECURE_SERVICE_COMPONENT=${custom_secure_service_component}
|
||||
-DCUSTOM_SECURE_SERVICE_COMPONENT_DIR=${custom_secure_service_dir}
|
||||
-DSECURE_SERVICE_HEADERS_DIR=${secure_service_headers_dir}
|
||||
${extra_cmake_args} ${sign_key_arg}
|
||||
INSTALL_COMMAND ""
|
||||
BUILD_ALWAYS 1 # no easy way around this...
|
||||
USES_TERMINAL_CONFIGURE TRUE
|
||||
|
||||
@@ -30,8 +30,7 @@ list(APPEND COMPONENTS bootloader_support efuse esp_hal_mspi esp_hal_wdt esp_sec
|
||||
# TEE-specific components
|
||||
list(APPEND COMPONENTS tee_flash_mgr tee_ota_ops tee_sec_storage tee_attestation)
|
||||
|
||||
# Include sdkconfig.h derived from the parent build.
|
||||
include_directories(${CONFIG_DIR})
|
||||
include_directories("${SECURE_SERVICE_HEADERS_DIR}")
|
||||
|
||||
include("${IDF_PATH}/tools/cmake/project.cmake")
|
||||
set(common_req esp_common esp_hw_support esp_rom freertos hal log esp_libc soc spi_flash)
|
||||
|
||||
@@ -70,7 +70,7 @@ idf_component_register(SRCS ${srcs}
|
||||
|
||||
# NOTE: The ESP32-H2 and C61 ROM does not have sprintf/snprintf implementation,
|
||||
# thus newlib-nano implementation from the toolchain has been used.
|
||||
if(CONFIG_IDF_TARGET_ESP32H2 OR CONFIG_IDF_TARGET_ESP32C61)
|
||||
if(CONFIG_LIBC_NEWLIB AND (CONFIG_IDF_TARGET_ESP32H2 OR CONFIG_IDF_TARGET_ESP32C61))
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "--specs=nano.specs")
|
||||
endif()
|
||||
|
||||
@@ -85,6 +85,8 @@ target_link_libraries(${COMPONENT_LIB} PRIVATE "-u esp_app_desc_tee_include_impl
|
||||
# Newlib syscalls stub implementation: Linking symbol
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE "-u esp_tee_include_syscalls_impl")
|
||||
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE "-u esp_tee_include_heap_impl")
|
||||
|
||||
# cut PROJECT_VER and PROJECT_NAME to required 32 characters.
|
||||
idf_build_get_property(project_ver PROJECT_VER)
|
||||
idf_build_get_property(project_name PROJECT_NAME)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_rom_tlsf.h"
|
||||
@@ -151,6 +152,33 @@ void *calloc(size_t n, size_t size)
|
||||
return esp_tee_heap_calloc(n, size);
|
||||
}
|
||||
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
void *realloc(void* ptr, size_t size)
|
||||
{
|
||||
if (tee_heap == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ptr == NULL) {
|
||||
return esp_tee_heap_malloc(heap, size);
|
||||
}
|
||||
|
||||
size_t previous_block_size = tlsf_block_size(ptr);
|
||||
void *result = tlsf_realloc(tee_heap->heap_data, ptr, size);
|
||||
if (result) {
|
||||
/* No need to subtract the tlsf_alloc_overhead() as it has already
|
||||
* been subtracted when allocating the block at first with malloc */
|
||||
tee_heap->free_bytes += previous_block_size;
|
||||
tee_heap->free_bytes -= tlsf_block_size(result);
|
||||
if (tee_heap->free_bytes < tee_heap->minimum_free_bytes) {
|
||||
tee_heap->minimum_free_bytes = tee_heap->free_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
void free(void *ptr)
|
||||
{
|
||||
esp_tee_heap_free(ptr);
|
||||
@@ -206,3 +234,10 @@ void *heap_caps_aligned_calloc(size_t alignment, size_t n, size_t size, uint32_t
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* No-op function, used to force linking this file,
|
||||
instead of the heap implementation from libc.
|
||||
*/
|
||||
void esp_tee_include_heap_impl(void)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "esp_random.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_LIBC_NEWLIB
|
||||
// NOTE: Remove compile-time warnings for the below newlib-provided functions
|
||||
struct _reent *__getreent(void)
|
||||
{
|
||||
@@ -68,6 +70,54 @@ int _getentropy_r(struct _reent *r, void *buffer, size_t length)
|
||||
esp_fill_random(buffer, length);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int fstat(int fd, struct stat *st)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int close(int fd)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
off_t lseek(int fd, off_t offset, int whence)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t read(int fd, void *ptr, size_t len)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t write(int fd, const void *ptr, size_t len)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getpid(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int kill(int pid, int sig)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getentropy(void *buffer, size_t length)
|
||||
{
|
||||
esp_fill_random(buffer, length);
|
||||
return 0;
|
||||
}
|
||||
#endif // CONFIG_LIBC_NEWLIB
|
||||
|
||||
void *pthread_getspecific(pthread_key_t key)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -11,8 +11,20 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void __assert_func(const char *file, int line, const char *func, const char *expr);
|
||||
extern void abort(void);
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
#if defined(__cplusplus) && __cplusplus >= 201103L
|
||||
#define __noreturn [[noreturn]]
|
||||
#elif __has_attribute(__noreturn__)
|
||||
#define __noreturn __attribute__((__noreturn__))
|
||||
#else
|
||||
#define __noreturn
|
||||
#endif
|
||||
#else
|
||||
#define __noreturn
|
||||
#endif
|
||||
|
||||
__noreturn void __assert_func(const char *file, int line, const char *func, const char *expr);
|
||||
__noreturn void abort(void);
|
||||
|
||||
#ifndef __ASSERT_FUNC
|
||||
#ifdef __ASSERT_FUNCTION
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -128,13 +128,21 @@ TEST_CASE("heap trace wrapped buffer check", "[heap-trace]")
|
||||
heap_trace_stop();
|
||||
}
|
||||
|
||||
static void print_floats_task(void *ignore)
|
||||
static void trace_libc_allocs_task(void *ignore)
|
||||
{
|
||||
heap_trace_start(HEAP_TRACE_ALL);
|
||||
|
||||
#if CONFIG_LIBC_NEWLIB
|
||||
char buf[16] = { };
|
||||
volatile float f = 12.3456;
|
||||
sprintf(buf, "%.4f", f);
|
||||
TEST_ASSERT_EQUAL_STRING("12.3456", buf);
|
||||
#endif
|
||||
#if CONFIG_LIBC_PICOLIBC
|
||||
FILE* f = fdopen(100, "r");
|
||||
fclose(f);
|
||||
#endif
|
||||
|
||||
heap_trace_stop();
|
||||
|
||||
vTaskDelete(NULL);
|
||||
@@ -158,11 +166,10 @@ TEST_CASE("can trace allocations made by newlib", "[heap-trace]")
|
||||
- We also do the tracing in the task so we only capture things directly related to it.
|
||||
*/
|
||||
|
||||
xTaskCreate(print_floats_task, "print_float", 4096, NULL, 5, NULL);
|
||||
xTaskCreate(trace_libc_allocs_task, "trace_libc_allocs_task", 4096, NULL, 5, NULL);
|
||||
vTaskDelay(10);
|
||||
|
||||
/* has to be at least a few as newlib allocates via multiple different function calls */
|
||||
TEST_ASSERT(heap_trace_get_count() > 3);
|
||||
TEST_ASSERT(heap_trace_get_count() > 0);
|
||||
}
|
||||
|
||||
TEST_CASE("can stop recording allocs but continue recording frees", "[heap-trace]")
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* SPDX-FileContributor: 2018-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*/
|
||||
#ifndef __ARCH_CC_H__
|
||||
#define __ARCH_CC_H__
|
||||
@@ -25,10 +25,18 @@ extern "C" {
|
||||
#endif // BYTE_ORDER
|
||||
|
||||
#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS
|
||||
#ifndef htons
|
||||
#define htons(x) __builtin_bswap16(x)
|
||||
#endif
|
||||
#ifndef ntohs
|
||||
#define ntohs(x) __builtin_bswap16(x)
|
||||
#endif
|
||||
#ifndef htonl
|
||||
#define htonl(x) __builtin_bswap32(x)
|
||||
#endif
|
||||
#ifndef ntohl
|
||||
#define ntohl(x) __builtin_bswap32(x)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_LWIP_ESP_LWIP_ASSERT
|
||||
#define LWIP_NOASSERT 1
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <esp_types.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
@@ -132,6 +132,18 @@ FORCE_INLINE_ATTR void __attribute__((always_inline)) rv_utils_set_cycle_count(u
|
||||
#endif
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_set_threadptr(void *ptr)
|
||||
{
|
||||
asm volatile("mv tp, %0" :: "r"(ptr));
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void *rv_utils_get_threadptr(void)
|
||||
{
|
||||
void *thread_ptr;
|
||||
asm volatile("mv %0, tp" : "=r"(thread_ptr));
|
||||
return thread_ptr;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------- CPU Interrupts ----------------------------------------------------
|
||||
*
|
||||
* ------------------------------------------------------------------------------------------------------------------ */
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "pmu_reg.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -80,30 +80,8 @@ if(CONFIG_IDF_TOOLCHAIN_GCC)
|
||||
if(NOT CONFIG_SOC_CPU_MISALIGNED_ACCESS_ON_PMP_MISMATCH_ISSUE)
|
||||
idf_toolchain_add_flags(COMPILE_OPTIONS "-mtune=esp-base")
|
||||
endif()
|
||||
idf_toolchain_rerun_abi_detection()
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown Espressif architecture: ${CONFIG_IDF_TARGET_ARCH}")
|
||||
endif()
|
||||
|
||||
# Workaround: Re-run CMake compiler ABI detection after ABI flags are set.
|
||||
#
|
||||
# Problem: CMake performs compiler checks at an early stage during
|
||||
# toolchain.cmake processing. At this early stage, response files are not yet
|
||||
# ready, which causes CMake paths (e.g., CMAKE_<lang>_IMPLICIT_LINK_DIRECTORIES)
|
||||
# to be incorrectly determined.
|
||||
#
|
||||
# Solution: Re-run the ABI detection after ABI flags are present to correctly
|
||||
# determine these paths.
|
||||
#
|
||||
# Note: If the CMake API changes, this solution may need to be revised.
|
||||
set(lang_ext_pairs "C|c" "CXX|cpp")
|
||||
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
|
||||
foreach(lang_ext ${lang_ext_pairs})
|
||||
string(REPLACE "|" ";" lang_ext_parts ${lang_ext})
|
||||
list(GET lang_ext_parts 0 lang)
|
||||
list(GET lang_ext_parts 1 ext)
|
||||
if(DEFINED CMAKE_${lang}_ABI_COMPILED)
|
||||
unset(CMAKE_${lang}_ABI_COMPILED)
|
||||
cmake_determine_compiler_abi(${lang} ${CMAKE_ROOT}/Modules/CMake${lang}CompilerABI.${ext})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include "esp_tls.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# SPDX-FileCopyrightText: 2016-2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# esp32ulp_mapgen utility converts a symbol list provided by nm into an export script
|
||||
@@ -16,50 +16,61 @@ UTIL = os.path.basename(__file__)
|
||||
def name_mangling(name: str) -> str:
|
||||
# Simple and dumb name mangling for namespaced name following GCC algorithm
|
||||
ns, n = name.split('::')
|
||||
return '_ZN{0}{1}{2}{3}E'.format(len(ns), ns, len(n), n)
|
||||
return f'_ZN{len(ns)}{ns}{len(n)}{n}E'
|
||||
|
||||
|
||||
def gen_ld_h_from_sym(f_sym: typing.TextIO, f_ld: typing.TextIO, f_h: typing.TextIO, base_addr: int, prefix: str) -> None:
|
||||
f_ld.write(textwrap.dedent(
|
||||
f"""
|
||||
def gen_ld_h_from_sym(
|
||||
f_sym: typing.TextIO, f_ld: typing.TextIO, f_h: typing.TextIO, base_addr: int, prefix: str
|
||||
) -> None:
|
||||
f_ld.write(
|
||||
textwrap.dedent(
|
||||
f"""
|
||||
/* ULP variable definitions for the linker.
|
||||
* This file is generated automatically by {UTIL} utility.
|
||||
*/
|
||||
""" # noqa: E222
|
||||
))
|
||||
)
|
||||
)
|
||||
cpp_mode = False
|
||||
var_prefix = prefix
|
||||
namespace = ''
|
||||
if '::' in prefix:
|
||||
# C++ mode, let's avoid the extern "C" type and instead use namespace
|
||||
f_h.write(textwrap.dedent(
|
||||
f"""
|
||||
f_h.write(
|
||||
textwrap.dedent(
|
||||
f"""
|
||||
/* ULP variable definitions for the compiler.
|
||||
* This file is generated automatically by {UTIL} utility.
|
||||
*/
|
||||
#pragma once
|
||||
""" # noqa: E222
|
||||
))
|
||||
)
|
||||
)
|
||||
tmp = prefix.split('::')
|
||||
namespace = tmp[0]
|
||||
var_prefix = '_'.join(tmp[1:]) # Limit to a single namespace here to avoid complex mangling rules
|
||||
f_h.write(f'namespace {namespace} {{\n')
|
||||
cpp_mode = True
|
||||
else:
|
||||
f_h.write(textwrap.dedent(
|
||||
f"""
|
||||
f_h.write(
|
||||
textwrap.dedent(
|
||||
f"""
|
||||
/* ULP variable definitions for the compiler.
|
||||
* This file is generated automatically by {UTIL} utility.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {{
|
||||
#endif\n
|
||||
""" # noqa: E222
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
# Format the regular expression to match the readelf output
|
||||
expr = re.compile(r'^.*(?P<address>[a-f0-9]{8})\s+(?P<size>\d+) (OBJECT|NOTYPE)\s+GLOBAL\s+DEFAULT\s+[^ ]+ (?P<name>.*)$')
|
||||
expr = re.compile(
|
||||
r'^.*(?P<address>[a-f0-9]{8})\s+(?P<size>\d+) (OBJECT|NOTYPE)\s+GLOBAL\s+DEFAULT\s+[^ ]+ (?P<name>.*)$'
|
||||
)
|
||||
for line in f_sym:
|
||||
# readelf format output has the following structure:
|
||||
# Num: Value Size Type Bind Vis Ndx Name
|
||||
@@ -90,23 +101,31 @@ def gen_ld_h_from_sym(f_sym: typing.TextIO, f_ld: typing.TextIO, f_h: typing.Tex
|
||||
if cpp_mode:
|
||||
f_h.write('}\n')
|
||||
else:
|
||||
f_h.write(textwrap.dedent(
|
||||
"""
|
||||
f_h.write(
|
||||
textwrap.dedent(
|
||||
"""
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
"""
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
description = ('This application generates .h and .ld files for symbols defined in input file. '
|
||||
'The input symbols file can be generated using readelf utility like this: '
|
||||
'<PREFIX>readelf -sW <elf_file> > <symbols_file>')
|
||||
description = (
|
||||
'This application generates .h and .ld files for symbols defined in input file. '
|
||||
'The input symbols file can be generated using readelf utility like this: '
|
||||
'<PREFIX>readelf -sW <elf_file> > <symbols_file>'
|
||||
)
|
||||
|
||||
parser = argparse.ArgumentParser(description=description)
|
||||
parser.add_argument('-s', '--symfile', required=True, help='symbols file name', metavar='SYMFILE', type=argparse.FileType('r'))
|
||||
parser.add_argument('-o', '--outputfile', required=True, help='destination .h and .ld files name prefix', metavar='OUTFILE')
|
||||
parser.add_argument(
|
||||
'-s', '--symfile', required=True, help='symbols file name', metavar='SYMFILE', type=argparse.FileType('r')
|
||||
)
|
||||
parser.add_argument(
|
||||
'-o', '--outputfile', required=True, help='destination .h and .ld files name prefix', metavar='OUTFILE'
|
||||
)
|
||||
parser.add_argument('--base-addr', required=True, help='base address of the ULP memory, to be added to each symbol')
|
||||
parser.add_argument('-p', '--prefix', required=False, help='prefix for generated header file', default='ulp_')
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "sdkconfig.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/select.h>
|
||||
#include "unity.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "driver/uart.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -82,6 +82,18 @@ FORCE_INLINE_ATTR void xt_utils_wait_for_intr(void)
|
||||
asm volatile ("waiti 0\n");
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void xt_utils_set_threadptr(void *ptr)
|
||||
{
|
||||
asm volatile ("wur.threadptr %0" :: "r"(ptr));
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void *xt_utils_get_threadptr(void)
|
||||
{
|
||||
void *thread_ptr;
|
||||
asm volatile ("rur.threadptr %0" : "=r"(thread_ptr));
|
||||
return thread_ptr;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------- CPU Interrupts ----------------------------------------------------
|
||||
*
|
||||
* ------------------------------------------------------------------------------------------------------------------ */
|
||||
|
||||
@@ -58,13 +58,26 @@ Enabling one of these option will cause the corresponding VFS driver to be built
|
||||
Standard Streams and FreeRTOS Tasks
|
||||
-----------------------------------
|
||||
|
||||
ESP-IDF provides two different implementations of standard I/O streams based on the selected LibC implementation defined by :ref:`CONFIG_LIBC`. The behavior of ``stdin``, ``stdout``, and ``stderr`` streams differs between these implementations, particularly regarding how they are shared across FreeRTOS tasks.
|
||||
|
||||
Common to both implementations, each stream (``stdin``, ``stdout``, ``stderr``) has a mutex associated with it to protect the stream from concurrent access by multiple tasks. For example, if two tasks are writing to ``stdout`` at the same time, the mutex ensures that the outputs from each task are not mixed together.
|
||||
|
||||
Newlib
|
||||
^^^^^^
|
||||
|
||||
In ESP-IDF, to save RAM, ``FILE`` objects for ``stdin``, ``stdout``, and ``stderr`` are shared between all FreeRTOS tasks, but the pointers to these objects are unique for every task. This means that:
|
||||
|
||||
- It is possible to change ``stdin``, ``stdout``, and ``stderr`` for any given task without affecting other tasks, e.g., by doing ``stdin = fopen("/dev/uart/1", "r")``.
|
||||
- To change the default ``stdin``, ``stdout``, ``stderr`` streams for new tasks, modify ``_GLOBAL_REENT->_stdin`` (``_stdout``, ``_stderr``) before creating the task.
|
||||
- Closing default ``stdin``, ``stdout``, or ``stderr`` using ``fclose`` closes the ``FILE`` stream object, which will affect all other tasks.
|
||||
|
||||
Each stream (``stdin``, ``stdout``, ``stderr``) has a mutex associated with it. This mutex is used to protect the stream from concurrent access by multiple tasks. For example, if two tasks are writing to ``stdout`` at the same time, the mutex will ensure that the outputs from each task are not mixed together.
|
||||
Picolibc
|
||||
^^^^^^^^
|
||||
|
||||
According to the POSIX standard, all default ``stdin``, ``stdout``, and ``stderr`` streams are global and shared between all FreeRTOS tasks. This means that:
|
||||
|
||||
- Modifying ``stdin``, ``stdout``, or ``stderr`` will affect all other tasks. It is not possible to change standard I/O streams for specific tasks.
|
||||
- If a thread-local stream is needed, it should be implemented in the application code by opening a file stream and using it within tasks, e.g., ``fscanf()``, ``fprintf()``, etc.
|
||||
|
||||
Blocking and non-blocking I/O
|
||||
-----------------------------
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user