feat(newlib): add picolibc support

This commit is contained in:
Alexey Lapshin
2024-09-26 13:13:20 +07:00
parent 22a38779fb
commit 888b5f7e8d
171 changed files with 8438 additions and 1016 deletions

View File

@@ -2,7 +2,6 @@
cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components")
set(COMPONENTS main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(newlib_test)

View File

@@ -1,13 +1,21 @@
idf_component_register(SRCS
"test_app_main.c"
"test_atomic.c"
"test_file.c"
"test_locks.c"
"test_misc.c"
"test_newlib.c"
"test_printf.c"
"test_setjmp.c"
"test_stdatomic.c"
"test_time.c"
PRIV_REQUIRES unity vfs cmock esp_timer spi_flash test_utils pthread esp_psram
set(srcs
"test_app_main.c"
"test_atomic.c"
"test_locks.c"
"test_misc.c"
"test_memstream.c"
"test_newlib.c"
"test_setjmp.c"
"test_stdatomic.c"
"test_time.c")
if(CONFIG_LIBC_NEWLIB)
list(APPEND srcs
# test_file.c tests if "_blksize" field was set correct to "FILE" struct.
# But picolibc does not have such field in the "FILE". So test is applicable only for newlib.
"test_file.c")
endif()
idf_component_register(SRCS "${srcs}"
PRIV_REQUIRES unity vfs cmock driver esp_timer spi_flash test_utils pthread esp_psram
WHOLE_ARCHIVE)

View File

@@ -0,0 +1,72 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "test_utils.h"
TEST_CASE("memstream_fseek", "[newlib]")
{
FILE *stream;
char *buf;
size_t len;
off_t eob;
stream = open_memstream(&buf, &len);
fprintf(stream, "Hello Espressif!");
fflush(stream);
TEST_ASSERT_EQUAL_STRING("Hello Espressif!", buf);
TEST_ASSERT_EQUAL_UINT32(strlen("Hello Espressif!"), len);
eob = ftell(stream);
fseek(stream, 0, SEEK_SET);
fprintf(stream, "HELLO");
fseek(stream, eob, SEEK_SET);
fclose(stream);
TEST_ASSERT_EQUAL_STRING("HELLO Espressif!", buf);
TEST_ASSERT_EQUAL_UINT32(strlen("HELLO Espressif!"), len);
free(buf);
}
TEST_CASE("memstream_overwrite", "[newlib]")
{
FILE *stream;
char *buf;
size_t len;
stream = open_memstream(&buf, &len);
fprintf(stream, "Hello Espressif!");
fflush(stream);
TEST_ASSERT_EQUAL_STRING("Hello Espressif!", buf);
TEST_ASSERT_EQUAL_UINT32(strlen("Hello Espressif!"), len);
fseek(stream, 0, SEEK_SET);
fprintf(stream, "HELLO");
fclose(stream);
TEST_ASSERT_EQUAL_STRING("HELLO", buf);
TEST_ASSERT_EQUAL_UINT32(strlen("HELLO"), len);
free(buf);
}
TEST_CASE("memstream_realloc", "[newlib]")
{
FILE *stream;
char *buf;
size_t len;
stream = open_memstream(&buf, &len);
// Initial buf size is BUFSIZ. Try to go out of bounds.
for (int i = 0; i < BUFSIZ * 2; i++) {
fputc('A' + (i % ('Z' - 'A')), stream);
}
fclose(stream);
for (int i = 0; i < BUFSIZ * 2; i++) {
TEST_ASSERT_EQUAL_UINT32('A' + (i % ('Z' - 'A')), buf[i]);
}
free(buf);
}

View File

@@ -136,18 +136,19 @@ static bool fn_in_rom(void *fn)
TEST_CASE("check if ROM or Flash is used for functions", "[newlib]")
{
#if PRINTF_NANO_IN_ROM || (ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT && !CONFIG_NEWLIB_NANO_FORMAT)
#if CONFIG_LIBC_NEWLIB && (PRINTF_NANO_IN_ROM || (ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT && !CONFIG_NEWLIB_NANO_FORMAT))
TEST_ASSERT(fn_in_rom(vfprintf));
#else
TEST_ASSERT_FALSE(fn_in_rom(vfprintf));
#endif // PRINTF_NANO_IN_ROM || (ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT && !CONFIG_NEWLIB_NANO_FORMAT)
#endif // CONFIG_LIBC_NEWLIB && (PRINTF_NANO_IN_ROM || (ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT && !CONFIG_NEWLIB_NANO_FORMAT))
#if SSCANF_NANO_IN_ROM || (ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT && !CONFIG_NEWLIB_NANO_FORMAT)
#if CONFIG_LIBC_NEWLIB && (SSCANF_NANO_IN_ROM || (ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT && !CONFIG_NEWLIB_NANO_FORMAT))
TEST_ASSERT(fn_in_rom(sscanf));
#else
TEST_ASSERT_FALSE(fn_in_rom(sscanf));
#endif // SSCANF_NANO_IN_ROM || (ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT && !CONFIG_NEWLIB_NANO_FORMAT)
#endif // CONFIG_LIBC_NEWLIB && (SSCANF_NANO_IN_ROM || (ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT && !CONFIG_NEWLIB_NANO_FORMAT))
#if CONFIG_LIBC_NEWLIB
#if defined(CONFIG_IDF_TARGET_ESP32)
#if defined(CONFIG_SPIRAM_CACHE_WORKAROUND)
@@ -162,10 +163,15 @@ TEST_CASE("check if ROM or Flash is used for functions", "[newlib]")
/* S2 do not have these in ROM */
TEST_ASSERT_FALSE(fn_in_rom(atoi));
TEST_ASSERT_FALSE(fn_in_rom(strtol));
#else
#else // defined(CONFIG_IDF_TARGET_ESP32)
TEST_ASSERT(fn_in_rom(atoi));
TEST_ASSERT(fn_in_rom(strtol));
#endif // defined(CONFIG_IDF_TARGET_ESP32)
#else // CONFIG_LIBC_NEWLIB
/* picolobc uses it's own implementation without using struct reent */
TEST_ASSERT_FALSE(fn_in_rom(atoi));
TEST_ASSERT_FALSE(fn_in_rom(strtol));
#endif // CONFIG_LIBC_NEWLIB
}
#ifndef CONFIG_NEWLIB_NANO_FORMAT

View File

@@ -9,6 +9,7 @@ from pytest_embedded import Dut
'config',
[
pytest.param('default', marks=[pytest.mark.supported_targets]),
pytest.param('picolibc', marks=[pytest.mark.supported_targets]),
pytest.param('options', marks=[pytest.mark.supported_targets]),
pytest.param('single_core_esp32', marks=[pytest.mark.esp32]),
pytest.param('psram_esp32', marks=[pytest.mark.esp32]),

View File

@@ -0,0 +1,2 @@
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
CONFIG_LIBC_PICOLIBC=y

View File

@@ -4,7 +4,7 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
# C2 specific moved from old C2 default config
CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE=n
CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT=y
CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC=n
CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=n
CONFIG_LIBC_TIME_SYSCALL_USE_NONE=n
CONFIG_LIBC_TIME_SYSCALL_USE_HRT=y
CONFIG_LIBC_TIME_SYSCALL_USE_RTC=n
CONFIG_LIBC_TIME_SYSCALL_USE_RTC_HRT=n