diff --git a/CMakeLists.txt b/CMakeLists.txt index 390d12fbd90..b5ffba54fbc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1764,15 +1764,32 @@ if(CONFIG_BUILD_OUTPUT_STRIPPED) endif() if(CONFIG_BUILD_OUTPUT_EXE) - list(APPEND - post_build_commands - COMMAND - ${CMAKE_COMMAND} -E copy ${KERNEL_ELF_NAME} ${KERNEL_EXE_NAME} - ) - list(APPEND - post_build_byproducts - ${KERNEL_EXE_NAME} + if (NOT CONFIG_NATIVE_LIBRARY) + list(APPEND + post_build_commands + COMMAND + ${CMAKE_COMMAND} -E copy ${KERNEL_ELF_NAME} ${KERNEL_EXE_NAME} + ) + list(APPEND + post_build_byproducts + ${KERNEL_EXE_NAME} + ) + else() + if(CMAKE_GENERATOR STREQUAL "Unix Makefiles") + set(MAKE "${CMAKE_MAKE_PROGRAM}" CACHE FILEPATH "cmake defined make") + endif() + find_program(MAKE make REQUIRED) + add_custom_target(native_runner_executable + ALL + COMMENT "Building native simulator runner, and linking final executable" + COMMAND + ${MAKE} -f ${ZEPHYR_BASE}/scripts/native_simulator/Makefile all --warn-undefined-variables + -r NSI_CONFIG_FILE=${CMAKE_BINARY_DIR}/zephyr/NSI/nsi_config + # nsi_config is created by the board cmake file + DEPENDS ${logical_target_for_zephyr_elf} + BYPRODUCTS ${KERNEL_EXE_NAME} ) + endif() endif() if(CONFIG_BUILD_OUTPUT_INFO_HEADER) diff --git a/arch/common/CMakeLists.txt b/arch/common/CMakeLists.txt index 5c7dd0ea53e..401cc82148c 100644 --- a/arch/common/CMakeLists.txt +++ b/arch/common/CMakeLists.txt @@ -71,7 +71,7 @@ endif() if(CONFIG_COVERAGE) zephyr_compile_options($) - zephyr_link_libraries($) + zephyr_link_libraries_ifndef(CONFIG_NATIVE_LIBRARY $) endif() zephyr_sources_ifdef(CONFIG_SEMIHOST semihost.c) diff --git a/arch/posix/CMakeLists.txt b/arch/posix/CMakeLists.txt index 2f7a8cec673..2333c2044ab 100644 --- a/arch/posix/CMakeLists.txt +++ b/arch/posix/CMakeLists.txt @@ -1,5 +1,21 @@ # SPDX-License-Identifier: Apache-2.0 +# This native_simulator library is used to pass options to the +# native_simulator runner build. Currently the following are used: +# INTERFACE_COMPILE_OPTIONS: +# Extra compile options to be used during the build of the runner files +# For ex. target_compile_options(native_simulator INTERFACE "-m64") +# INTERFACE_LINK_OPTIONS: +# Extra link options to be passed during the *final* link of the runner +# with the embedded SW. +# For ex. target_link_options(native_simulator INTERFACE "-lstdc++") +# INTERFACE_SOURCES: +# Extra sources to be built in the native simulator runner context +# For ex. target_sources(native_simulator INTERFACE silly.c) +# Note that these are built with the host libC and the include directories +# the runner is built with. +add_library(native_simulator INTERFACE) + if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/${CMAKE_HOST_SYSTEM_NAME}.${CMAKE_HOST_SYSTEM_PROCESSOR}.cmake) # @Intent: Set necessary compiler & linker options for this specific host architecture & OS include(${CMAKE_HOST_SYSTEM_NAME}.${CMAKE_HOST_SYSTEM_PROCESSOR}.cmake) @@ -8,9 +24,15 @@ else() # some gcc versions fail to build without -fPIC zephyr_compile_options(-m64 -fPIC) zephyr_link_libraries(-m64) + + target_link_options(native_simulator INTERFACE "-m64") + target_compile_options(native_simulator INTERFACE "-m64") else () zephyr_compile_options(-m32) zephyr_link_libraries(-m32) + + target_link_options(native_simulator INTERFACE "-m32") + target_compile_options(native_simulator INTERFACE "-m32") endif () endif() @@ -22,24 +44,72 @@ if (CONFIG_NATIVE_APPLICATION) zephyr_compile_options( -include ${ZEPHYR_BASE}/arch/posix/include/posix_cheats.h ) +elseif (CONFIG_NATIVE_LIBRARY) + zephyr_compile_options( + -fvisibility=hidden + ) + + # While doing the partial linking of the native library, some symbols will be missing + # which are provided by the native simulator runner + zephyr_ld_options( + -Wl,--unresolved-symbols=ignore-all + ) + + if (NOT CONFIG_EXTERNAL_LIBC) + # Get the *compiler* include path, that is where the *compiler* provided headers are (not the + # default libC ones). This includes basic headers like stdint.h, stddef.h or float.h + # We expect something like + # /usr/lib/gcc/x86_64-linux-gnu/12/include or /usr/lib/llvm-14/lib/clang/14.0.0/include + execute_process( + COMMAND ${CMAKE_C_COMPILER} --print-file-name=include/stddef.h + OUTPUT_VARIABLE _OUTPUT + COMMAND_ERROR_IS_FATAL ANY + ) + get_filename_component(COMPILER_OWN_INCLUDE_PATH "${_OUTPUT}" DIRECTORY) + + # Do not use the C library from this compiler/host, + # but still use the basic compiler headers + # -fno-builtin to avoid the compiler using builtin replacements for std library functions + zephyr_compile_options( + -nostdinc + -isystem ${COMPILER_OWN_INCLUDE_PATH} + $ + -fno-builtin + ) + endif() endif() -# @Intent: Obtain compiler specific flags for no freestanding compilation -zephyr_compile_options($) +if(CONFIG_EXTERNAL_LIBC) + # @Intent: Obtain compiler specific flags for no freestanding compilation + zephyr_compile_options($) +endif() + +if(CONFIG_EXTERNAL_LIBCPP) + target_link_options(native_simulator INTERFACE "-lstdc++") +endif() zephyr_include_directories(${BOARD_DIR}) +if(CONFIG_COVERAGE) + target_compile_options(native_simulator INTERFACE $) + target_link_options(native_simulator INTERFACE $) +endif() + if (CONFIG_GPROF) zephyr_compile_options($) zephyr_link_libraries($) + + target_link_options(native_simulator INTERFACE "-pg") endif() zephyr_compile_definitions(_POSIX_C_SOURCE=200809 _XOPEN_SOURCE=600 _XOPEN_SOURCE_EXTENDED) -zephyr_ld_options( - -ldl - -pthread -) +if (CONFIG_NATIVE_APPLICATION) + zephyr_ld_options( + -ldl + -pthread + ) +endif() # About the -include directive: The reason to do it this way, is because in this # manner it is transparent to the application. Otherwise posix_cheats.h needs to @@ -85,6 +155,9 @@ if(NOT ${LLVM_SANITIZERS_ARG} STREQUAL "") set(LLVM_SANITIZERS_ARG "-fsanitize=${LLVM_SANITIZERS_ARG}") zephyr_compile_options("${LLVM_SANITIZERS_ARG}") zephyr_link_libraries("${LLVM_SANITIZERS_ARG}") + + target_link_options(native_simulator INTERFACE ${LLVM_SANITIZERS_ARG}) + target_compile_options(native_simulator INTERFACE ${LLVM_SANITIZERS_ARG}) endif() # Override the C standard used for compilation to C 2011 diff --git a/boards/posix/common/sdl/CMakeLists.txt b/boards/posix/common/sdl/CMakeLists.txt index 8def28b1c38..b2d4d815443 100644 --- a/boards/posix/common/sdl/CMakeLists.txt +++ b/boards/posix/common/sdl/CMakeLists.txt @@ -7,6 +7,10 @@ zephyr_library_compile_definitions(NO_POSIX_CHEATS) find_package(PkgConfig REQUIRED) pkg_search_module(SDL2 REQUIRED sdl2) zephyr_include_directories(${SDL2_INCLUDE_DIRS}) -zephyr_link_libraries(${SDL2_LIBRARIES}) +if (CONFIG_NATIVE_APPLICATION) + zephyr_link_libraries(${SDL2_LIBRARIES}) +else() + target_link_options(native_simulator INTERFACE "-l${SDL2_LIBRARIES}") +endif() zephyr_compile_options(${SDL2_CFLAGS_OTHER}) zephyr_library_sources(sdl_events.c) diff --git a/boards/posix/native_posix/doc/index.rst b/boards/posix/native_posix/doc/index.rst index 0bfdc564756..37e651b344d 100644 --- a/boards/posix/native_posix/doc/index.rst +++ b/boards/posix/native_posix/doc/index.rst @@ -36,6 +36,7 @@ Important limitations This board inherits :ref:`the limitations of its architecture` +.. _native_posix_how_to_use: How to use it ************* @@ -173,6 +174,7 @@ should be considered. Check the :ref:`POSIX architecture comparison ` with other development and test options for more insights. +.. _native_posix_architecture: Architecture ************ @@ -246,6 +248,8 @@ simulated time when the last clock ratio adjustment took place. All times are kept in microseconds. +.. _native_posix_peripherals: + Peripherals *********** diff --git a/boards/posix/native_sim/CMakeLists.txt b/boards/posix/native_sim/CMakeLists.txt new file mode 100644 index 00000000000..ee807583f7c --- /dev/null +++ b/boards/posix/native_sim/CMakeLists.txt @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: Apache-2.0 + +set(NSI_DIR ${ZEPHYR_BASE}/scripts/native_simulator) + +zephyr_library() + +zephyr_library_compile_definitions(NO_POSIX_CHEATS) + +zephyr_library_sources( + cmdline.c + cpu_wait.c + nsi_if.c + irq_handler.c + misc.c + posix_arch_if.c + ) + +zephyr_include_directories( + ${NSI_DIR}/common/src/include + ${NSI_DIR}/native/src/include +) + +zephyr_library_include_directories( + ${ZEPHYR_BASE}/kernel/include + ${ZEPHYR_BASE}/arch/posix/include +) + +if(CONFIG_HAS_SDL) + add_subdirectory(${ZEPHYR_BASE}/boards/${ARCH}/common/sdl/ ${CMAKE_CURRENT_BINARY_DIR}/sdl) +endif() + +set(zephyr_build_path ${CMAKE_BINARY_DIR}/zephyr) + +set(nsi_config_content + "NSI_BUILD_OPTIONS:=$,\ >" + "NSI_BUILD_PATH:=${zephyr_build_path}/NSI" + "NSI_CC:=${CMAKE_C_COMPILER}" + "NSI_EMBEDDED_CPU_SW:=${zephyr_build_path}/${KERNEL_ELF_NAME}" + "NSI_EXE:=${zephyr_build_path}/${KERNEL_EXE_NAME}" + "NSI_EXTRA_SRCS:=$,\ >" + "NSI_LINK_OPTIONS:=$,\ >" + "NSI_PATH:=${NSI_DIR}/" +) + +string(REPLACE ";" "\n" nsi_config_content "${nsi_config_content}") + +file(GENERATE OUTPUT "${zephyr_build_path}/NSI/nsi_config" + CONTENT "${nsi_config_content}" +) diff --git a/boards/posix/native_sim/Kconfig b/boards/posix/native_sim/Kconfig new file mode 100644 index 00000000000..aabbd4d794f --- /dev/null +++ b/boards/posix/native_sim/Kconfig @@ -0,0 +1,50 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NATIVE_SIM + bool "Native simulator (Single Core)" + select POSIX_ARCH_CONSOLE + select NATIVE_LIBRARY + select NATIVE_POSIX_TIMER + depends on SOC_POSIX + imply BOARD_NATIVE_POSIX if NATIVE_SIM_NATIVE_POSIX_COMPAT + +if BOARD_NATIVE_SIM + +comment "Native Simular (Single Core) options" + +config NATIVE_SIM_NATIVE_POSIX_COMPAT + bool "Pretend to be a native_posix board" + default y + help + When this option is set the native_sim board will pretend to be + a native_posix board from kconfig point of view, to allow using it directly with + code which was meant for the native_posix board and checks for the macro + CONFIG_BOARD_NATIVE_POSIX, or requires other kconfig options which depend on it. + +config NATIVE_SIM_SLOWDOWN_TO_REAL_TIME + bool "Slow down execution to real time" + default n if ARCH_POSIX_LIBFUZZER + default y if BT_USERCHAN || !TEST + help + When selected the execution of the process will be slowed down to real time. + (if there is a lot of load it may be slower than real time) + If deselected, the process will run as fast as possible. + Note that this only decouples simulated time from real/wall time. In either + case the zephyr kernel and application cannot tell the difference unless they + interact with some other driver/device which runs at real time. + +# This option definition exists only to enable NATIVE_SIM_NATIVE_POSIX_COMPAT +config BOARD_NATIVE_POSIX + bool + +config NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME + bool "Slow down execution to real time (native_posix compat)" + select NATIVE_SIM_SLOWDOWN_TO_REAL_TIME + help + Transitional option which allows applications which targeted native_posix + to set the correct native_sim option (CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME) + +source "boards/$(ARCH)/common/sdl/Kconfig" + +endif # BOARD_NATIVE_SIM diff --git a/boards/posix/native_sim/Kconfig.board b/boards/posix/native_sim/Kconfig.board new file mode 100644 index 00000000000..7cc9ead031f --- /dev/null +++ b/boards/posix/native_sim/Kconfig.board @@ -0,0 +1,17 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NATIVE_SIM_32BIT + bool "Native simulation, 32-bit mode" + select BOARD_NATIVE_SIM + help + Will produce a console Linux process which can be executed natively + as a 32-bit executable. + +config BOARD_NATIVE_SIM_64BIT + bool "Native simulation, 64-bit mode" + select BOARD_NATIVE_SIM + select 64BIT + help + Will produce a console Linux process which can be executed natively + as a 64-bit executable. diff --git a/boards/posix/native_sim/Kconfig.defconfig b/boards/posix/native_sim/Kconfig.defconfig new file mode 100644 index 00000000000..c4bcb6184a3 --- /dev/null +++ b/boards/posix/native_sim/Kconfig.defconfig @@ -0,0 +1,73 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NATIVE_SIM + +config BUILD_OUTPUT_BIN + default n + +config BUILD_OUTPUT_EXE + default y + +config OUTPUT_PRINT_MEMORY_USAGE + default n + +config BOARD + default "native_sim_64" if BOARD_NATIVE_SIM_64BIT + default "native_sim" + +if NETWORKING + +config NET_L2_ETHERNET + default y if !NET_LOOPBACK && !NET_TEST + +config ETH_NATIVE_POSIX + default y if NET_L2_ETHERNET && ETH_DRIVER + +endif # NETWORKING + +choice BT_HCI_BUS_TYPE + default BT_USERCHAN + depends on BT_HCI +endchoice + +if LOG + +# For native_sim we can log synchronously without any problem +# Doing so will be nicer for debugging +choice LOG_MODE + default LOG_MODE_IMMEDIATE +endchoice + +endif # LOG + +if CONSOLE + +config POSIX_ARCH_CONSOLE + default y if !SERIAL + +config UART_CONSOLE + default y if SERIAL + +endif # CONSOLE + +config FLASH_SIMULATOR + default y + depends on FLASH + +config USB_NATIVE_POSIX + default y + depends on USB_DEVICE_DRIVER + +config EEPROM_SIMULATOR + default y + depends on EEPROM + +if I2C + +config EMUL + default y + +endif # I2C + +endif # BOARD_NATIVE_SIM diff --git a/boards/posix/native_sim/board.cmake b/boards/posix/native_sim/board.cmake new file mode 100644 index 00000000000..0ec9fc6a83a --- /dev/null +++ b/boards/posix/native_sim/board.cmake @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +set(SUPPORTED_EMU_PLATFORMS native) diff --git a/boards/posix/native_sim/board_irq.h b/boards/posix/native_sim/board_irq.h new file mode 100644 index 00000000000..8d5d227b930 --- /dev/null +++ b/boards/posix/native_sim/board_irq.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BOARDS_POSIX_NATIVE_SIM_BOARD_IRQ_H +#define BOARDS_POSIX_NATIVE_SIM_BOARD_IRQ_H + +#include "../common/irq/board_irq.h" + +#endif /* BOARDS_POSIX_NATIVE_SIM_BOARD_IRQ_H */ diff --git a/boards/posix/native_sim/board_soc.h b/boards/posix/native_sim/board_soc.h new file mode 100644 index 00000000000..2d2419038f4 --- /dev/null +++ b/boards/posix/native_sim/board_soc.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2017 Oticon A/S + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @file Extra definitions provided by the board to soc.h + * + * Background: + * The POSIX ARCH/SOC/board layering is different than in normal archs + * The "SOC" does not provide almost any of the typical SOC functionality + * but that is left for the "board" to define it + * Device code may rely on the soc.h defining some things (like the interrupts + * numbers) + * Therefore this file is included from the inf_clock soc.h to allow a board + * to define that kind of SOC related snippets + */ + +#ifndef BOARDS_POSIX_NATIVE_SIM_BOARD_SOC_H +#define BOARDS_POSIX_NATIVE_SIM_BOARD_SOC_H + +#include "nsi_cpu0_interrupts.h" + +#endif /* BOARDS_POSIX_NATIVE_SIM_BOARD_SOC_H */ diff --git a/boards/posix/native_sim/cmdline.c b/boards/posix/native_sim/cmdline.c new file mode 100644 index 00000000000..0cab99d2832 --- /dev/null +++ b/boards/posix/native_sim/cmdline.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * To support native_posix drivers or tests which register their own arguments + * we provide the same API as in native_posix + */ + +#include "nsi_cmdline.h" + +void native_add_command_line_opts(struct args_struct_t *args) +{ + nsi_add_command_line_opts(args); +} + +void native_get_cmd_line_args(int *argc, char ***argv) +{ + nsi_get_cmd_line_args(argc, argv); +} + +void native_get_test_cmd_line_args(int *argc, char ***argv) +{ + nsi_get_test_cmd_line_args(argc, argv); +} diff --git a/boards/posix/native_sim/cmdline.h b/boards/posix/native_sim/cmdline.h new file mode 100644 index 00000000000..acf46d1ce26 --- /dev/null +++ b/boards/posix/native_sim/cmdline.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018 Oticon A/S + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BOARDS_POSIX_NATIVE_SIM_CMDLINE_H +#define BOARDS_POSIX_NATIVE_SIM_CMDLINE_H + +#include "nsi_cmdline.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * To support native_posix drivers or tests which register their own arguments + * we provide a header with the same name as in native_posix + */ +void native_get_cmd_line_args(int *argc, char ***argv); +void native_get_test_cmd_line_args(int *argc, char ***argv); +void native_add_command_line_opts(struct args_struct_t *args); + +#ifdef __cplusplus +} +#endif + +#endif /* BOARDS_POSIX_NATIVE_SIM_CMDLINE_H */ diff --git a/boards/posix/native_sim/cmdline_common.h b/boards/posix/native_sim/cmdline_common.h new file mode 100644 index 00000000000..c645caadc00 --- /dev/null +++ b/boards/posix/native_sim/cmdline_common.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2018 Oticon A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef BOARDS_POSIX_NATIVE_SIM_CMDLINE_COMMON_H +#define BOARDS_POSIX_NATIVE_SIM_CMDLINE_COMMON_H + +/* + * To support native_posix drivers which register their own arguments + * we provide a header with the same name as in native_posix + */ +#include "nsi_cmdline.h" + +#endif /* BOARDS_POSIX_NATIVE_SIM_CMDLINE_COMMON_H */ diff --git a/boards/posix/native_sim/cpu_wait.c b/boards/posix/native_sim/cpu_wait.c new file mode 100644 index 00000000000..eba13a54ff8 --- /dev/null +++ b/boards/posix/native_sim/cpu_wait.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2020 Oticon A/S + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include "nsi_hw_scheduler.h" +#include "nsi_timer_model.h" + +/** + * Replacement to the kernel k_busy_wait() + * Will block this thread (and therefore the whole Zephyr) during usec_to_wait + * + * Note that interrupts may be received in the meanwhile and that therefore this + * thread may lose context. + * Therefore the wait time may be considerably longer. + * + * All this function ensures is that it will return after usec_to_wait or later. + * + * This special arch_busy_wait() is necessary due to how the POSIX arch/SOC INF + * models a CPU. Conceptually it could be thought as if the MCU was running + * at an infinitely high clock, and therefore no simulated time passes while + * executing instructions(*1). + * Therefore to be able to busy wait this function does the equivalent of + * programming a dedicated timer which will raise a non-maskable interrupt, + * and halting the CPU. + * + * (*1) In reality simulated time is simply not advanced just due to the "MCU" + * running. Meaning, the SW running on the MCU is assumed to take 0 time. + */ +void arch_busy_wait(uint32_t usec_to_wait) +{ + uint64_t time_end = nsi_hws_get_time() + usec_to_wait; + + while (nsi_hws_get_time() < time_end) { + /* + * There may be wakes due to other interrupts including + * other threads calling arch_busy_wait + */ + hwtimer_wake_in_time(time_end); + posix_halt_cpu(); + } +} + +/** + * Will block this thread (and therefore the whole Zephyr) during usec_to_waste + * + * Very similar to arch_busy_wait(), but if an interrupt or context switch + * occurs this function will continue waiting after, ensuring that + * usec_to_waste are spent in this context, irrespectively of how much more + * time would be spent on interrupt handling or possible switched-in tasks. + * + * Can be used to emulate code execution time. + */ +void posix_cpu_hold(uint32_t usec_to_waste) +{ + uint64_t time_start; + int64_t to_wait = usec_to_waste; + + while (to_wait > 0) { + /* + * There may be wakes due to other interrupts or nested calls to + * cpu_hold in interrupt handlers + */ + time_start = nsi_hws_get_time(); + hwtimer_wake_in_time(time_start + to_wait); + posix_change_cpu_state_and_wait(true); + to_wait -= nsi_hws_get_time() - time_start; + + posix_irq_handler(); + } +} diff --git a/boards/posix/native_sim/doc/index.rst b/boards/posix/native_sim/doc/index.rst new file mode 100644 index 00000000000..42cef26e40c --- /dev/null +++ b/boards/posix/native_sim/doc/index.rst @@ -0,0 +1,128 @@ +.. _native_sim: + +Native simulator - native_sim +############################# + +Overview +******** + +The native_sim board is an evolution of :ref:`native_posix`. +Just like with :ref:`native_posix` you can build your Zephyr application +with the Zephyr kernel, creating a normal Linux executable with your host tooling, +and can debug and instrument it like any other Linux program. + +native_sim is based on the +`native simulator `_ +and the :ref:`POSIX architecture`. + +Host system dependencies +************************ + +Please check the +:ref:`Posix Arch Dependencies` + +.. _nativesim_important_limitations: + +Important limitations +********************* + +Native_sim is based on the :ref:`POSIX architecture`, and therefore +:ref:`its limitations ` and considerations apply to it. + +How to use it +************* + +To build, simply specify the native_sim board as target: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :host-os: unix + :board: native_sim + :goals: build + :compact: + +Now you have a Linux executable, ``./build/zephyr/zephyr.exe``, you can use just like any +other Linux program. + +You can run, debug, build it with sanitizers or with coverage just like with +:ref:`native_posix `. +Please check :ref:`native_posix's how to` for more info. + +32 and 64bit versions +********************* + +Just like native_posix, native_sim comes with two targets: A 32 bit and 64 bit version. +The 32 bit version, ``native_sim``, is the default target, which will compile +your code for the ILP32 ABI (i386 in a x86 or x86_64 system) where pointers +and longs are 32 bits. +This mimics the ABI of most embedded systems Zephyr targets, +and is therefore normally best to test and debug your code, as some bugs are +dependent on the size of pointers and longs. +This target requires either a 64 bit system with multilib support installed or +one with a 32bit userspace. + +The 64 bit version, ``native_sim_64``, compiles your code targeting the +LP64 ABI (x86-64 in x86 systems), where pointers and longs are 64 bits. +You can use this target if you cannot compile or run 32 bit binaries. + +C library choice +**************** + +Unlike native_posix, native_sim may be compiled with a choice of C libraries. +By default it will be compiled with the host C library (:kconfig:option:`CONFIG_EXTERNAL_LIBC`), +but you can also select to build it with :kconfig:option:`CONFIG_MINIMAL_LIBC` or with +:kconfig:option:`CONFIG_PICOLIBC`. + +When building with either :ref:`MINIMAL` or :ref:`PICO` libC +you will build your code in a more similar way as when building for the embedded target, +you will be able to test your code interacting with that C library, +and there will be no conflicts with the :ref:`POSIX OS abstraction` shim, +but, accessing the host for test purposes from your embedded code will be more +difficult, and you will have a limited choice of +:ref:`drivers and backends to chose from`. + +Architecture +************ + +:ref:`native_posix's architecture description` as well as the +:ref:`POSIX architecture description` are directly +applicable to native_sim. + +If you are interested on the inner workigns of the native simulator itself, you can check +`its documentation `_. + +.. _native_sim_peripherals: + +Peripherals, subsystems backends and host based flash access +************************************************************ + +Today, native_sim supports the exact same +:ref:`peripherals and backends as native_posix`, +with the only caveat that some of these are, so far, only available when compiling with the +host libC (:kconfig:option:`CONFIG_EXTERNAL_LIBC`). + +.. csv-table:: Drivers/backends vs libC choice + :header: Driver class, driver name, driver kconfig, libC choices + + adc, ADC emul, :kconfig:option:`CONFIG_ADC_EMUL`, all + bluetooth, userchan, :kconfig:option:`CONFIG_BT_USERCHAN`, host libC + can, can native posix, :kconfig:option:`CONFIG_CAN_NATIVE_POSIX_LINUX`, host libC + console backend, POSIX arch console, :kconfig:option:`CONFIG_POSIX_ARCH_CONSOLE`, all + display, display SDL, :kconfig:option:`CONFIG_SDL_DISPLAY`, host libC + entropy, native posix entropy, :kconfig:option:`CONFIG_FAKE_ENTROPY_NATIVE_POSIX`, host libC + eprom, eprom emulator, :kconfig:option:`CONFIG_EEPROM_EMULATOR`, host libC + ethernet, eth native_posix, :kconfig:option:`CONFIG_ETH_NATIVE_POSIX`, host libC + flash, flash simulator, :kconfig:option:`CONFIG_FLASH_SIMULATOR`, host libC + flash, host based flash access, :kconfig:option:`CONFIG_FUSE_FS_ACCESS`, host libC + gpio, GPIO emulator, :kconfig:option:`CONFIG_GPIO_EMUL`, all + gpio, SDL GPIO emulator, :kconfig:option:`CONFIG_GPIO_EMUL_SDL`, host libC + i2c, I2C emulator, :kconfig:option:`CONFIG_I2C_EMUL`, all + input, input SDL touch, :kconfig:option:`CONFIG_INPUT_SDL_TOUCH`, host libC + log backend, native backend, :kconfig:option:`CONFIG_LOG_BACKEND_NATIVE_POSIX`, all + rtc, RTC emul, :kconfig:option:`CONFIG_RTC_EMUL`, all + serial, uart native posix/PTTY, :kconfig:option:`CONFIG_UART_NATIVE_POSIX`, host libC + serial, uart native TTY, :kconfig:option:`CONFIG_UART_NATIVE_TTY`, host libC + spi, SPI emul, :kconfig:option:`CONFIG_SPI_EMUL`, all + system tick, native_posix timer, :kconfig:option:`CONFIG_NATIVE_POSIX_TIMER`, all + tracing, Posix tracing backend, :kconfig:option:`CONFIG_TRACING_BACKEND_POSIX`, host libC + usb, USB native posix, :kconfig:option:`CONFIG_USB_NATIVE_POSIX`, host libC diff --git a/boards/posix/native_sim/irq_handler.c b/boards/posix/native_sim/irq_handler.c new file mode 100644 index 00000000000..dc43ad3974d --- /dev/null +++ b/boards/posix/native_sim/irq_handler.c @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2014 Wind River Systems, Inc. + * Copyright (c) 2017 Oticon A/S + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + * + * SW side of the IRQ handling + */ + +#include +#include +#include +#include "kernel_internal.h" +#include "kswap.h" +#include "irq_ctrl.h" +#include "posix_core.h" +#include +#include "soc.h" +#include +#include "irq_handler.h" +#include "board_soc.h" +#include "nsi_cpu_if.h" + +typedef void (*normal_irq_f_ptr)(const void *); +typedef int (*direct_irq_f_ptr)(void); + +static struct _isr_list irq_vector_table[N_IRQS] = { { 0 } }; + +static int currently_running_irq = -1; + +static inline void vector_to_irq(int irq_nbr, int *may_swap) +{ + sys_trace_isr_enter(); + + if (irq_vector_table[irq_nbr].func == NULL) { /* LCOV_EXCL_BR_LINE */ + /* LCOV_EXCL_START */ + posix_print_error_and_exit("Received irq %i without a " + "registered handler\n", + irq_nbr); + /* LCOV_EXCL_STOP */ + } else { + if (irq_vector_table[irq_nbr].flags & ISR_FLAG_DIRECT) { + *may_swap |= ((direct_irq_f_ptr) + irq_vector_table[irq_nbr].func)(); + } else { +#ifdef CONFIG_PM + posix_irq_check_idle_exit(); +#endif + ((normal_irq_f_ptr)irq_vector_table[irq_nbr].func) + (irq_vector_table[irq_nbr].param); + *may_swap = 1; + } + } + + sys_trace_isr_exit(); +} + +/** + * When an interrupt is raised, this function is called to handle it and, if + * needed, swap to a re-enabled thread + * + * Note that even that this function is executing in a Zephyr thread, it is + * effectively the model of the interrupt controller passing context to the IRQ + * handler and therefore its priority handling + */ +void posix_irq_handler(void) +{ + uint64_t irq_lock; + int irq_nbr; + static int may_swap; + + irq_lock = hw_irq_ctrl_get_current_lock(); + + if (irq_lock) { + /* "spurious" wakes can happen with interrupts locked */ + return; + } + + if (_kernel.cpus[0].nested == 0) { + may_swap = 0; + } + + _kernel.cpus[0].nested++; + + while ((irq_nbr = hw_irq_ctrl_get_highest_prio_irq()) != -1) { + int last_current_running_prio = hw_irq_ctrl_get_cur_prio(); + int last_running_irq = currently_running_irq; + + hw_irq_ctrl_set_cur_prio(hw_irq_ctrl_get_prio(irq_nbr)); + hw_irq_ctrl_clear_irq(irq_nbr); + + currently_running_irq = irq_nbr; + vector_to_irq(irq_nbr, &may_swap); + currently_running_irq = last_running_irq; + + hw_irq_ctrl_set_cur_prio(last_current_running_prio); + } + + _kernel.cpus[0].nested--; + + /* Call swap if all the following is true: + * 1) may_swap was enabled + * 2) We are not nesting irq_handler calls (interrupts) + * 3) Next thread to run in the ready queue is not this thread + */ + if (may_swap + && (hw_irq_ctrl_get_cur_prio() == 256) + && (_kernel.ready_q.cache != _current)) { + + (void)z_swap_irqlock(irq_lock); + } +} + +/** + * Thru this function the IRQ controller can raise an immediate interrupt which + * will interrupt the SW itself + * (this function should only be called from the HW model code, from SW threads) + */ +void nsif_cpu0_irq_raised_from_sw(void) +{ + /* + * if a higher priority interrupt than the possibly currently running is + * pending we go immediately into irq_handler() to vector into its + * handler + */ + if (hw_irq_ctrl_get_highest_prio_irq() != -1) { + if (!posix_is_cpu_running()) { /* LCOV_EXCL_BR_LINE */ + /* LCOV_EXCL_START */ + posix_print_error_and_exit("programming error: %s " + "called from a HW model thread\n", + __func__); + /* LCOV_EXCL_STOP */ + } + posix_irq_handler(); + } +} + +/** + * @brief Disable all interrupts on the CPU + * + * This routine disables interrupts. It can be called from either interrupt, + * task or fiber level. This routine returns an architecture-dependent + * lock-out key representing the "interrupt disable state" prior to the call; + * this key can be passed to irq_unlock() to re-enable interrupts. + * + * The lock-out key should only be used as the argument to the irq_unlock() + * API. It should never be used to manually re-enable interrupts or to inspect + * or manipulate the contents of the source register. + * + * This function can be called recursively: it will return a key to return the + * state of interrupt locking to the previous level. + * + * WARNINGS + * Invoking a kernel routine with interrupts locked may result in + * interrupts being re-enabled for an unspecified period of time. If the + * called routine blocks, interrupts will be re-enabled while another + * thread executes, or while the system is idle. + * + * The "interrupt disable state" is an attribute of a thread. Thus, if a + * fiber or task disables interrupts and subsequently invokes a kernel + * routine that causes the calling thread to block, the interrupt + * disable state will be restored when the thread is later rescheduled + * for execution. + * + * @return An architecture-dependent lock-out key representing the + * "interrupt disable state" prior to the call. + * + */ +unsigned int posix_irq_lock(void) +{ + return hw_irq_ctrl_change_lock(true); +} + +/** + * @brief Enable all interrupts on the CPU + * + * This routine re-enables interrupts on the CPU. The @a key parameter is a + * board-dependent lock-out key that is returned by a previous invocation of + * board_irq_lock(). + * + * This routine can be called from either interrupt, task or fiber level. + */ +void posix_irq_unlock(unsigned int key) +{ + hw_irq_ctrl_change_lock(key); +} + +void posix_irq_full_unlock(void) +{ + hw_irq_ctrl_change_lock(false); +} + +void posix_irq_enable(unsigned int irq) +{ + hw_irq_ctrl_enable_irq(irq); +} + +void posix_irq_disable(unsigned int irq) +{ + hw_irq_ctrl_disable_irq(irq); +} + +int posix_irq_is_enabled(unsigned int irq) +{ + return hw_irq_ctrl_is_irq_enabled(irq); +} + +int posix_get_current_irq(void) +{ + return currently_running_irq; +} + +/** + * Configure a static interrupt. + * + * posix_isr_declare will populate the interrupt table table with the + * interrupt's parameters, the vector table and the software ISR table. + * + * We additionally set the priority in the interrupt controller at + * runtime. + * + * @param irq_p IRQ line number + * @param flags [plug it directly (1), or as a SW managed interrupt (0)] + * @param isr_p Interrupt service routine + * @param isr_param_p ISR parameter + * @param flags_p IRQ options + */ +void posix_isr_declare(unsigned int irq_p, int flags, void isr_p(const void *), + const void *isr_param_p) +{ + irq_vector_table[irq_p].irq = irq_p; + irq_vector_table[irq_p].func = isr_p; + irq_vector_table[irq_p].param = isr_param_p; + irq_vector_table[irq_p].flags = flags; +} + +/** + * @internal + * + * @brief Set an interrupt's priority + * + * Lower values take priority over higher values. + */ +void posix_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) +{ + hw_irq_ctrl_prio_set(irq, prio); +} + +/** + * Similar to ARM's NVIC_SetPendingIRQ + * set a pending IRQ from SW + * + * Note that this will interrupt immediately if the interrupt is not masked and + * IRQs are not locked, and this interrupt has higher priority than a possibly + * currently running interrupt + */ +void posix_sw_set_pending_IRQ(unsigned int IRQn) +{ + hw_irq_ctrl_raise_im_from_sw(IRQn); +} + +/** + * Similar to ARM's NVIC_ClearPendingIRQ + * clear a pending irq from SW + */ +void posix_sw_clear_pending_IRQ(unsigned int IRQn) +{ + hw_irq_ctrl_clear_irq(IRQn); +} + +#ifdef CONFIG_IRQ_OFFLOAD +/** + * Storage for functions offloaded to IRQ + */ +static void (*off_routine)(const void *); +static const void *off_parameter; + +/** + * IRQ handler for the SW interrupt assigned to irq_offload() + */ +static void offload_sw_irq_handler(const void *a) +{ + ARG_UNUSED(a); + off_routine(off_parameter); +} + +/** + * @brief Run a function in interrupt context + * + * Raise the SW IRQ assigned to handled this + */ +void posix_irq_offload(void (*routine)(const void *), const void *parameter) +{ + off_routine = routine; + off_parameter = parameter; + posix_isr_declare(OFFLOAD_SW_IRQ, 0, offload_sw_irq_handler, NULL); + posix_irq_enable(OFFLOAD_SW_IRQ); + posix_sw_set_pending_IRQ(OFFLOAD_SW_IRQ); + posix_irq_disable(OFFLOAD_SW_IRQ); +} +#endif /* CONFIG_IRQ_OFFLOAD */ diff --git a/boards/posix/native_sim/irq_handler.h b/boards/posix/native_sim/irq_handler.h new file mode 100644 index 00000000000..44f9619a91c --- /dev/null +++ b/boards/posix/native_sim/irq_handler.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2017 Oticon A/S + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BOARDS_POSIX_NATIVE_SIM_IRQ_HANDLER_H +#define BOARDS_POSIX_NATIVE_SIM_IRQ_HANDLER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void posix_sw_set_pending_IRQ(unsigned int IRQn); +void posix_sw_clear_pending_IRQ(unsigned int IRQn); + +#ifdef __cplusplus +} +#endif + +#endif /* BOARDS_POSIX_NATIVE_SIM_IRQ_HANDLER_H */ diff --git a/boards/posix/native_sim/misc.c b/boards/posix/native_sim/misc.c new file mode 100644 index 00000000000..9a847246b18 --- /dev/null +++ b/boards/posix/native_sim/misc.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "posix_native_task.h" +#include "nsi_timer_model.h" + +#if defined(CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME) + +static void set_realtime_default(void) +{ + hwtimer_set_real_time_mode(true); +} + +NATIVE_TASK(set_realtime_default, PRE_BOOT_1, 0); + +#endif /* CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME */ diff --git a/boards/posix/native_sim/native_posix_compat.h b/boards/posix/native_sim/native_posix_compat.h new file mode 100644 index 00000000000..a2b5dc0299b --- /dev/null +++ b/boards/posix/native_sim/native_posix_compat.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * This file provides in native_sim a set of APIs the native_posix board provided + * to allow building the native_posix drivers or applications which depended + * on those. + * Note that all these APIs should be considered deprecated in native_sim, as this + * exists solely as a transitional component. + */ + +#ifndef BOARDS_POSIX_NATIVE_SIM_NATIVE_POSIX_COMPAT_H +#define BOARDS_POSIX_NATIVE_SIM_NATIVE_POSIX_COMPAT_H + +#include +#include +#include "nsi_hw_scheduler.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static ALWAYS_INLINE void hwm_find_next_timer(void) +{ + nsi_hws_find_next_event(); +} + +static ALWAYS_INLINE uint64_t hwm_get_time(void) +{ + return nsi_hws_get_time(); +} + +#ifdef __cplusplus +} +#endif + +#endif /* BOARDS_POSIX_NATIVE_SIM_NATIVE_POSIX_COMPAT_H */ diff --git a/boards/posix/native_sim/native_sim.dts b/boards/posix/native_sim/native_sim.dts new file mode 100644 index 00000000000..b27a9bd540d --- /dev/null +++ b/boards/posix/native_sim/native_sim.dts @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../native_posix/native_posix.dts" diff --git a/boards/posix/native_sim/native_sim.yaml b/boards/posix/native_sim/native_sim.yaml new file mode 100644 index 00000000000..327cf2f6049 --- /dev/null +++ b/boards/posix/native_sim/native_sim.yaml @@ -0,0 +1,20 @@ +identifier: native_sim +name: Native Simulation port - 32-bit +type: native +simulation: native +arch: posix +ram: 65536 +flash: 65536 +toolchain: + - host + - llvm +supported: + - can + - eeprom + - netif:eth + - usb_device + - adc + - i2c + - spi + - gpio + - rtc diff --git a/boards/posix/native_sim/native_sim_64.dts b/boards/posix/native_sim/native_sim_64.dts new file mode 100644 index 00000000000..4ac77d414f9 --- /dev/null +++ b/boards/posix/native_sim/native_sim_64.dts @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "native_sim.dts" diff --git a/boards/posix/native_sim/native_sim_64.yaml b/boards/posix/native_sim/native_sim_64.yaml new file mode 100644 index 00000000000..c2c8b3ac530 --- /dev/null +++ b/boards/posix/native_sim/native_sim_64.yaml @@ -0,0 +1,18 @@ +identifier: native_sim_64 +name: Native Simulation port - 64-bit +type: native +simulation: native +arch: posix +ram: 65536 +flash: 65536 +toolchain: + - host + - llvm +supported: + - can + - eeprom + - netif:eth + - usb_device + - adc + - gpio + - rtc diff --git a/boards/posix/native_sim/native_sim_64_defconfig b/boards/posix/native_sim/native_sim_64_defconfig new file mode 100644 index 00000000000..abd666317cd --- /dev/null +++ b/boards/posix/native_sim/native_sim_64_defconfig @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_POSIX=y +CONFIG_BOARD_NATIVE_SIM_64BIT=y +CONFIG_CONSOLE=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=1000000 diff --git a/boards/posix/native_sim/native_sim_defconfig b/boards/posix/native_sim/native_sim_defconfig new file mode 100644 index 00000000000..f3f1e1299c1 --- /dev/null +++ b/boards/posix/native_sim/native_sim_defconfig @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_POSIX=y +CONFIG_BOARD_NATIVE_SIM_32BIT=y +CONFIG_CONSOLE=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=1000000 diff --git a/boards/posix/native_sim/nsi_if.c b/boards/posix/native_sim/nsi_if.c new file mode 100644 index 00000000000..f0d82ef41a8 --- /dev/null +++ b/boards/posix/native_sim/nsi_if.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +void nsif_cpu0_pre_cmdline_hooks(void) +{ + run_native_tasks(_NATIVE_PRE_BOOT_1_LEVEL); +} + +void nsif_cpu0_pre_hw_init_hooks(void) +{ + run_native_tasks(_NATIVE_PRE_BOOT_2_LEVEL); +} + +void nsif_cpu0_boot(void) +{ + run_native_tasks(_NATIVE_PRE_BOOT_3_LEVEL); + posix_boot_cpu(); + run_native_tasks(_NATIVE_FIRST_SLEEP_LEVEL); +} + +void nsif_cpu0_cleanup(void) +{ + posix_soc_clean_up(); +} + +void nsif_cpu0_irq_raised(void) +{ + posix_interrupt_raised(); +} diff --git a/boards/posix/native_sim/posix_arch_if.c b/boards/posix/native_sim/posix_arch_if.c new file mode 100644 index 00000000000..3ae4c578466 --- /dev/null +++ b/boards/posix/native_sim/posix_arch_if.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "nsi_cpu_es_if.h" + +/* + * This file provides the interfaces the POSIX architecture and soc_inf + * expect from all boards that use them + */ + +void posix_exit(int exit_code) +{ + nsi_exit(exit_code); +} + +void posix_vprint_error_and_exit(const char *format, va_list vargs) +{ + nsi_vprint_error_and_exit(format, vargs); +} + +void posix_vprint_warning(const char *format, va_list vargs) +{ + nsi_vprint_warning(format, vargs); +} + +void posix_vprint_trace(const char *format, va_list vargs) +{ + nsi_vprint_trace(format, vargs); +} + +void posix_print_error_and_exit(const char *format, ...) +{ + va_list variable_args; + + va_start(variable_args, format); + nsi_vprint_error_and_exit(format, variable_args); + va_end(variable_args); +} + +void posix_print_warning(const char *format, ...) +{ + va_list variable_args; + + va_start(variable_args, format); + nsi_vprint_warning(format, variable_args); + va_end(variable_args); +} + +void posix_print_trace(const char *format, ...) +{ + va_list variable_args; + + va_start(variable_args, format); + nsi_vprint_trace(format, variable_args); + va_end(variable_args); +} + +int posix_trace_over_tty(int file_number) +{ + return nsi_trace_over_tty(file_number); +} + +uint64_t posix_get_hw_cycle(void) +{ + return nsi_hws_get_time(); +} diff --git a/boards/posix/native_sim/timer_model.h b/boards/posix/native_sim/timer_model.h new file mode 100644 index 00000000000..a159ef444f1 --- /dev/null +++ b/boards/posix/native_sim/timer_model.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BOARDS_POSIX_NATIVE_SIM_TIMER_MODEL_H +#define BOARDS_POSIX_NATIVE_SIM_TIMER_MODEL_H + +/* + * To support the native_posix timer driver + * we provide a header with the same name as in native_posix + */ +#include "nsi_hw_scheduler.h" +#include "nsi_timer_model.h" +#include "native_posix_compat.h" + +#endif /* BOARDS_POSIX_NATIVE_SIM_TIMER_MODEL_H */ diff --git a/include/zephyr/arch/posix/linker.ld b/include/zephyr/arch/posix/linker.ld index 3eaa15aec42..06dfb3254f1 100644 --- a/include/zephyr/arch/posix/linker.ld +++ b/include/zephyr/arch/posix/linker.ld @@ -55,6 +55,7 @@ SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,) #include #include +#include /* Located in generated directory. This file is populated by the * zephyr_linker_sources() Cmake function. diff --git a/include/zephyr/arch/posix/native_sim_interface.ld b/include/zephyr/arch/posix/native_sim_interface.ld new file mode 100644 index 00000000000..43b7c7a7878 --- /dev/null +++ b/include/zephyr/arch/posix/native_sim_interface.ld @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_PROLOGUE (.native_sim_if,,) +{ + KEEP(*(.native_sim_if)); + KEEP(*(.native_sim_if.*)); +}