Part 1
요약·해설
특정 SoC를 흉내 내지 않고 호스트 자원을 활용합니다. 시간 동기화, UART·네트워크·Bluetooth·입력·Flash와 분석 도구를 한 실행 파일에서 시험할 수 있습니다.
Linux 네이티브 실행 파일
ILP32 32-bit · LP64 64-bit
Host libc · Minimal libc · Picolibc
Part 2
접을 수 있는 영어 원문 전체
영어 원문 전체 펼치기
4406E2595092120DF772F0142225584E2BDC437E286A7390A851E410AB2D00AB
.. _native_sim:
Native simulator - native_sim
#############################
.. contents::
:depth: 1
:backlinks: entry
:local:
Overview
********
The ``native_sim`` board is a :ref:`POSIX architecture<Posix arch>` based board.
With it, a Zephyr application can be compiled together with
the Zephyr kernel, and libraries, creating a normal Linux executable.
``native_sim`` is based on the
`native simulator <https://github.com/BabbleSim/native_simulator/>`_
and the :ref:`POSIX architecture<Posix arch>`.
This board does not intend to simulate any particular HW, but it provides
a few peripherals such as an Ethernet driver, display, UART, etc., to enable
developing and testing application code which would require them.
See `Peripherals`_ for more information.
.. note::
| ``native_sim`` is an evolution of the older :ref:`native_posix<native_posix>`.
| Some components, code, options names, and documentation will still use the old native_posix
names. But all components which worked with native_posix will work with native_sim.
Host system dependencies
************************
Please check the
:ref:`Posix Arch Dependencies<posix_arch_deps>`
.. _nativesim_important_limitations:
Important limitations and unsupported features
**********************************************
``native_sim`` is based on the :ref:`POSIX architecture<Posix arch>`, and therefore
:ref:`its limitations <posix_arch_limitations>` and considerations apply to it.
Similarly, it inherits the POSIX architecture
:ref:`unsupported features set <posix_arch_unsupported>`.
Note that some drivers may have limitations, or may not support their whole driver API optional
functionality.
.. _native_sim_how_to_use:
How to use it
*************
Compiling
=========
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:
Running
=======
The result of the compilation is an executable (``zephyr.exe``) placed in the
``zephyr/`` subdirectory of the ``build`` folder.
Run the ``zephyr.exe`` executable as you would any other Linux console application.
.. code-block:: console
$ ./build/zephyr/zephyr.exe
# Press Ctrl+C to exit
This executable accepts several command line options depending on the
compilation configuration.
You can run it with the ``--help`` command line switch to get a list of
available options.
.. code-block:: console
$ ./build/zephyr/zephyr.exe --help
Note that the Zephyr kernel does not actually exit once the application is
finished. It simply goes into the idle loop forever.
Therefore you must stop the application manually (Ctrl+C in Linux).
Application tests using the :ref:`ztest framework<test-framework>` will exit after all
tests have completed.
If you want your application to gracefully finish when it reaches some point,
you may add a conditionally compiled (:kconfig:option:`CONFIG_ARCH_POSIX`) call to
``nsi_exit(int status)`` at that point.
.. _native_sim_debug:
Debugging
=========
Since the Zephyr executable is a native application, it can be debugged and
instrumented as any other native program. The program is compiled with debug
information, so it can be run directly in, for example, ``gdb`` or instrumented
with ``valgrind``.
Because the execution of your Zephyr application is normally deterministic
(there are no asynchronous or random components), you can execute the
code multiple times and get the exact same result. Instrumenting the
code does not affect its execution.
To ease debugging you may want to compile your code without optimizations
(e.g., ``-O0``) by setting :kconfig:option:`CONFIG_NO_OPTIMIZATIONS`.
For ease of debugging consider using an IDE as GUI for your debugger.
.. _native_sim_asan:
Address Sanitizer (ASan)
========================
You can also build Zephyr with the `Address Sanitizer`_. To do this, set
:kconfig:option:`CONFIG_ASAN`, for example, in the application project file, or in the
``west build`` or ``cmake`` command line invocation.
Note that you will need the ASan library installed in your system.
In Debian/Ubuntu this is ``libasan1``.
.. _Address Sanitizer:
https://github.com/google/sanitizers/wiki/AddressSanitizer
Undefined Behavior Sanitizer (UBSan)
====================================
You can also build Zephyr with the `Undefined Behavior Sanitizer`_. To do this, set
:kconfig:option:`CONFIG_UBSAN`, for example, in the application project file, or in the
``west build`` or ``cmake`` command line invocation.
.. _Undefined Behavior Sanitizer:
https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
Coverage reports
================
See
:ref:`coverage reports using the POSIX architecture<coverage_posix>`.
.. _native_sim32_64:
32 and 64bit versions
=====================
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/native/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.
.. _native_sim_Clib_choice:
C library choice
****************
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`.
If you select some feature which are not compatible with the host C library,
:ref:`Picolibc <c_library_picolibc>` will be selected by default instead.
When building with either :ref:`minimal <c_library_minimal>` or :ref:`Picolibc<c_library_picolibc>`
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<posix_support>` 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<native_sim_peripherals_c_compat>`.
Rationale for this port and comparison with other options
*********************************************************
The native_sim board shares the overall
:ref:`intent of the POSIX architecture<posix_arch_rationale>`,
while being a HW agnostic test platform which in some cases utilizes the host
OS peripherals.
It does not intend to model any particular HW, and as such can only be used
to develop and test application code which is far decoupled from the HW.
For developing and testing SW which requires specific HW, while retaining the
benefits of the POSIX architecture other solutions like the
:ref:`bsim boards<bsim boards>`
should be considered.
Check the :ref:`POSIX architecture comparison <posix_arch_compare>`
with other development and test options for more insights.
.. _native_sim_architecture:
Architecture
************
This board is based on the POSIX architecture port of Zephyr and shares
:ref:`its basic architecture<posix_arch_architecture>` regarding threading
and CPU/HW scheduling.
If you are interested on the inner workings of the native simulator itself, you can check
`its documentation <https://github.com/BabbleSim/native_simulator/blob/main/docs/README.md>`_.
This board does not try to emulate any particular embedded CPU or SOC.
The code is compiled natively for the host system (typically x86).
About time in native_sim
========================
Normally simulated time runs fully decoupled from the real host time
and as fast as the host compute power would allow.
This is desirable when running in a debugger or testing in batch, but not if
interacting with external interfaces based on the real host time.
The Zephyr kernel is only aware of the simulated time as provided by the
HW models. Therefore any normal Zephyr thread will also know only about
simulated time.
The only link between the simulated time and the real/host time, if any,
is created by the clock and timer model.
This model can be configured to slow down the execution of native_sim to
real time.
You can do this with the ``--rt`` and ``--no-rt`` options from the command line.
The default behavior is set with
:kconfig:option:`CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME`.
Note that all this model does is wait before raising the
next system tick interrupt until the corresponding real/host time.
If, for some reason, native_sim runs slower than real time, all this
model can do is "catch up" as soon as possible by not delaying the
following ticks.
So if the host load is too high, or you are running in a debugger, you will
see simulated time lagging behind the real host time.
This solution ensures that normal runs are still deterministic while
providing an illusion of real timeness to the observer.
When locked to real time, simulated time can also be set to run faster or
slower than real time.
This can be controlled with the ``--rt-ratio=<ratio>`` and ``-rt-drift=<drift>``
command line options. Note that both of these options control the same
underlying mechanism, and that ``drift`` is by definition equal to
``ratio - 1``.
It is also possible to adjust this clock speed on the fly with
:c:func:`native_rtc_adjust_clock()`.
In this way if, for example, ``--rt-ratio=2`` is given, the simulated time
will advance at twice the real time speed.
Similarly if ``--rt-drift=-100e-6`` is given, the simulated time will progress
100ppm slower than real time.
Note that these 2 options have no meaning when running in non real-time
mode.
How simulated time and real time relate to each other
-----------------------------------------------------
Simulated time (``st``) can be calculated from real time (``rt``) as
.. math::
st = (rt - last\_rt) \times ratio + last\_st
And vice-versa:
.. math::
rt = (st - last\_st) / ratio + last\_rt
Where ``last_rt`` and ``last_st`` are respectively the real time and the
simulated time when the last clock ratio adjustment took place.
All times are kept in microseconds.
.. _native_sim_peripherals:
Peripherals
***********
The following peripherals are currently provided with this board:
**Interrupt controller**
A simple yet generic interrupt controller is provided. It can nest interrupts
and provides interrupt priorities. Interrupts can be individually masked or
unmasked. SW interrupts are also supported.
**Clock, timer and system tick model**
This model provides the system tick timer. By default
:kconfig:option:`CONFIG_SYS_CLOCK_TICKS_PER_SEC` configures it to tick every 10ms.
Please refer to the section `About time in native_sim`_ for more
information.
**UART/Serial**
Two optional native UART drivers are available:
**PTTY driver (UART_NATIVE_POSIX)**
With this driver, one or two Zephyr UART devices can be created. These
can be connected to the Linux process stdin/stdout or a newly created
pseudo-tty. For more information refer to the section `PTTY UART`_.
**TTY driver (UART_NATIVE_TTY)**
An UART driver for interacting with host-attached serial port devices
(eg. USB to UART dongles). For more information refer to the section
`TTY UART`_.
**Real time clock**
The real time clock model provides a model of a constantly powered clock.
By default this is initialized to the host time at boot.
This RTC can also be set to start from time 0 with the ``--rtc-reset`` command
line option.
It is possible to offset the RTC clock value at boot with the
``--rtc-offset=<offset>`` option,
or to adjust it dynamically with the function :c:func:`native_rtc_offset`.
After start, this RTC advances with the simulated time, and is therefore
affected by the simulated time speed ratio.
See `About time in native_sim`_ for more information.
The time can be queried with the functions :c:func:`native_rtc_gettime_us`
and :c:func:`native_rtc_gettime`. Both accept as parameter the clock source:
- ``RTC_CLOCK_BOOT``: It counts the simulated time passed since boot.
It is not subject to offset adjustments
- ``RTC_CLOCK_REALTIME``: RTC persistent time. It is affected by
offset adjustments.
- ``RTC_CLOCK_PSEUDOHOSTREALTIME``: A version of the real host time,
as if the host was also affected by the clock speed ratio and offset
adjustments performed to the simulated clock and this RTC. Normally
this value will be a couple of hundredths of microseconds ahead of the
simulated time, depending on the host execution speed.
This clock source should be used with care, as depending on the actual
execution speed of native_sim and the host load,
it may return a value considerably ahead of the simulated time.
Note this device does not yet have an :ref:`RTC API compatible driver <rtc_api>`.
.. _nsim_per_entr:
**Entropy device**
An entropy device based on the host :c:func:`random` API.
This device will generate the same sequence of random numbers if initialized
with the same random seed.
You can change this random seed value by using the command line option:
:samp:`--seed={<random_seed>}` where the value specified is a 32-bit integer
such as 97229 (decimal), 0x17BCD (hex), or 0275715 (octal).
.. _nsim_per_ethe:
**Ethernet driver**
A simple TAP based ethernet driver is provided. The driver expects that the
**zeth** network interface already exists in the host system. The **zeth**
network interface can be created by the ``net-setup.sh`` script found in
the `net-tools`_ zephyr project repository. User can communicate with the
Zephyr instance via the **zeth** network interface. Multiple TAP based
network interfaces can be created if needed. The IP address configuration
can be specified for each network interface instance.
Note that this device can only be used with Linux hosts.
.. _net-tools:
https://github.com/zephyrproject-rtos/net-tools
.. _nsim_per_offloaded_sockets:
**Offloaded sockets driver**
This driver is an alternative to the :ref:`TAP based ethernet driver
<nsim_per_ethe>`. Instead of using a virtual network in the Linux side, this
driver utilizes Linux's standard BSD socket API. With this, multiple Zephyr
applications can communicate over the Linux loopback interface.
The benefit of this approach is that root privileges are not required and
that the process is connected to the same interface as other Linux processes
instead of a virtual network, facilitating testing without the need for extra
setup in the host. The drawback is that the L2 layer of Zephyr's networking
stack is not exercised.
.. _nsim_bt_host_cont:
**Bluetooth controller**
It's possible to use the host's Bluetooth adapter as a Bluetooth
controller for Zephyr. To do this the HCI device needs to be passed as
a command line option to ``zephyr.exe``. For example, to use ``hci0``,
use ``sudo zephyr.exe --bt-dev=hci0``. Using the device requires root
privileges (or the CAP_NET_ADMIN POSIX capability, to be exact) so
``zephyr.exe`` needs to be run through ``sudo``. The chosen HCI device
must be powered down and support Bluetooth Low Energy (i.e. support the
Bluetooth specification version 4.0 or greater).
Another possibility is to use a HCI TCP server which acts as a
:ref:`virtual Bluetooth controller<bluetooth_virtual_posix>` over TCP.
To connect to a HCI TCP server its IP address and port number must
be specified. For example, to connect to a HCI TCP server with IP
address 127.0.0.0 and port number 1020 use ``zephyr.exe --bt-dev=127.0.0.1:1020``.
This alternative option is mainly aimed for testing Bluetooth connectivity over
a virtual Bluetooth controller that does not depend on the Linux Bluetooth
stack and its HCI interface.
.. _nsim_per_usb:
**USB controller**
It's possible to use the Virtual USB controller working over USB/IP
protocol. More information can be found in
:ref:`Testing USB over USP/IP in native_sim <testing_USB_native_sim>`.
.. _nsim_per_disp_sdl:
**Display driver**
A display driver is provided that creates a window on the host machine to
render display content.
This driver requires a 32-bit version of the `SDL2`_ library on the host
machine and ``pkg-config`` settings to correctly pickup the SDL2 install path
and compiler flags.
On a Ubuntu 22.04 host system, for example, install the ``pkg-config`` and
``libsdl2-dev:i386`` packages, and configure the pkg-config search path with
these commands:
.. code-block:: console
$ sudo dpkg --add-architecture i386
$ sudo apt update
$ sudo apt-get install pkg-config libsdl2-dev:i386
$ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig
.. _SDL2:
https://www.libsdl.org/download-2.0.php
.. _nsim_per_flash_simu:
**EEPROM simulator**
The EEPROM simulator can also be used in the native targets. In these, you have the added feature
of keeping the EEPROM content on a file on the host filesystem.
By default this is kept in the file :file:`eeprom.bin` in the current working directory, but you
can select the location of this file and its name with the command line parameter ``--eeprom``.
Some more information can be found in :ref:`the emulators page <emul_eeprom_simu_brief>`.
**Flash simulator**
The flash simulator can also be used in the native targets. In this you have the option to keep
the flash content in a binary file on the host file system or in RAM. The behavior of the flash
device can be configured through the native_sim board devicetree or Kconfig settings under
:kconfig:option:`CONFIG_FLASH_SIMULATOR`.
By default the binary data is located in the file :file:`flash.bin` in the current
working directory. The location of this file can be changed through the
command line parameter ``--flash``. The flash data will be stored in raw format
and the file will be truncated to match the size specified in the devicetree
configuration. In case the file does not exists the driver will take care of
creating the file, else the existing file is used.
Some more information can be found in :ref:`the emulators page <emul_flash_simu_brief>`.
The flash content can be accessed from the host system, as explained in the
`Host based flash access`_ section.
**Input events**
Two optional native input drivers are available:
**evdev driver**
A driver is provided to read input events from a Linux evdev input device and
inject them back into the Zephyr input subsystem.
The driver is automatically enabled when :kconfig:option:`CONFIG_INPUT` is
enabled and the devicetree contains a node such as:
.. code-block:: dts
evdev {
compatible = "zephyr,native-linux-evdev";
};
The application then has to be run with a command line option to specify
which evdev device node has to be used, for example
``zephyr.exe --evdev=/dev/input/event0``.
**Input SDL touch**
This driver emulates a touch panel input using the SDL library. It can be enabled with
:kconfig:option:`CONFIG_INPUT_SDL_TOUCH` and configured with the device tree binding
:dtcompatible:`zephyr,input-sdl-touch`.
More information on using SDL and the Display driver can be found in
:ref:`its section <nsim_per_disp_sdl>`.
**CAN controller**
It is possible to use a host CAN controller with the native SockerCAN Linux driver. It can be
enabled with :kconfig:option:`CONFIG_CAN_NATIVE_LINUX` and configured with the device tree binding
:dtcompatible:`zephyr,native-linux-can`.
.. _native_ptty_uart:
PTTY UART
=========
This driver can be configured with :kconfig:option:`CONFIG_UART_NATIVE_POSIX`
to instantiate up to two UARTs. By default only one UART is enabled.
With :kconfig:option:`CONFIG_UART_NATIVE_POSIX_PORT_1_ENABLE`
you can enable the second one.
For the first UART, it can link it to a new
pseudoterminal (i.e. :file:`/dev/pts{<nbr>}`), or map the UART input and
output to the executable's ``stdin`` and ``stdout``.
This is chosen by selecting either
:kconfig:option:`CONFIG_NATIVE_UART_0_ON_OWN_PTY` or
:kconfig:option:`CONFIG_NATIVE_UART_0_ON_STDINOUT`
For interactive use with the :ref:`shell_api`, choose the first (OWN_PTY) option.
The second (STDINOUT) option can be used with the shell for automated
testing, such as when piping other processes' output to control it.
This is because the shell subsystem expects access to a raw terminal,
which (by default) a normal Linux terminal is not.
When :kconfig:option:`CONFIG_NATIVE_UART_0_ON_OWN_PTY` is chosen, the name of the
newly created UART pseudo-terminal will be displayed in the console.
If you want to interact with it manually, you should attach a terminal emulator
to it. This can be done, for example with the command:
.. code-block:: console
$ xterm -e screen /dev/<ttyn> &
where :file:`/dev/tty{<n>}` should be replaced with the actual TTY device.
You may also chose to automatically attach a terminal emulator to the first UART
by passing the command line option ``-attach_uart`` to the executable.
The command used for attaching to the new shell can be set with the command line
option ``-attach_uart_cmd=<"cmd">``. Where the default command is given by
:kconfig:option:`CONFIG_NATIVE_UART_AUTOATTACH_DEFAULT_CMD`.
Note that the default command assumes both ``xterm`` and ``screen`` are
installed in the system.
This driver only supports poll mode. Interrupt and async mode are not supported.
Neither runtime configuration or line control are supported.
.. _native_tty_uart:
TTY UART
========
With this driver an application can use the polling UART API (``uart_poll_out``,
``uart_poll_in``) to write and read characters to and from a connected serial
port device.
This driver is automatically enabled when a devicetree contains a node
with ``"zephyr,native-tty-uart"`` compatible property and ``okay`` status, such
as one below.
.. code-block:: dts
uart {
status = "okay";
compatible = "zephyr,native-tty-uart";
serial-port = "/dev/ttyUSB0";
current-speed = <115200>;
};
Interaction with serial ports can be configured in several different ways:
* The default serial port and baud rate can be set via the device tree
properties ``serial-port`` and ``current-speed`` respectively. The
``serial-port`` property is optional.
* Serial port and baud rate can also be set via command line options ``X_port``
and ``X_baud`` respectively, where ``X`` is a name of a node. Command line
options override values from the devicetree.
* The rest of the configuration options such as number of data and stop bits,
parity, as well as baud rate can be set at runtime with ``uart_configure``.
* This driver can emulate an interrupt-driven UART by enabling
:kconfig:option:`CONFIG_UART_INTERRUPT_DRIVEN`.
Multiple instances of such uart drivers are supported.
The :zephyr:code-sample:`uart-native-tty` sample app provides a working example of the
driver.
This driver only supports poll mode and interrupt mode. Async mode is not
supported.
It has runtime configuration support, but no line control support.
.. _native_sim_backends:
Subsystems backends
*******************
Apart from its own peripherals, the native_sim board also has some dedicated
backends for some of Zephyr's subsystems. These backends are designed to ease
development by integrating more seamlessly with the host operating system:
.. _nsim_back_console:
**Console backend**:
A console backend which by default is configured to
redirect any :c:func:`printk` write to the native host application's
``stdout``.
This driver is selected by default if the `PTTY UART`_ is not compiled in.
Otherwise :kconfig:option:`CONFIG_UART_CONSOLE` will be set to select the UART as
console backend.
.. _nsim_back_logger:
**Logger backend**:
A backend which prints all logger output to the process ``stdout``.
It supports timestamping, which can be enabled with
:kconfig:option:`CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP`; and colored output which can
be enabled with :kconfig:option:`CONFIG_LOG_BACKEND_SHOW_COLOR` and controlled
with the command line options ``--color``, ``--no-color`` and
``--force-color``.
In native_sim, by default, the logger is configured with
:kconfig:option:`CONFIG_LOG_MODE_IMMEDIATE`.
This backend can be selected with :kconfig:option:`CONFIG_LOG_BACKEND_NATIVE_POSIX`
and is enabled by default.
.. _nsim_back_trace:
**Tracing**:
A backend/"bottom" for Zephyr's CTF tracing subsystem which writes the tracing
data to a file in the host filesystem.
More information can be found in :ref:`Common Tracing Format <ctf>`
Emulators
*********
All :ref:`available HW emulators <emulators>` can be used with native_sim.
.. _native_fuse_flash:
Host based flash access
***********************
If a flash device is present, the file system partitions on the flash
device can be exposed through the host file system by enabling
:kconfig:option:`CONFIG_FUSE_FS_ACCESS`. This option enables a FUSE
(File system in User space) layer that maps the Zephyr file system calls to
the required UNIX file system calls, and provides access to the flash file
system partitions with normal operating system commands such as ``cd``,
``ls`` and ``mkdir``.
By default the partitions are exposed through the directory :file:`flash/` in the
current working directory. This directory can be changed via the command line
option ``--flash-mount``. As this directory operates as a mount point for FUSE
you have to ensure that it exists before starting the native_sim board.
On exit, the native_sim board application will take care of unmounting the
directory. In the unfortunate case that the native_sim board application
crashes, you can cleanup the stale mount point by using the program
``fusermount``:
.. code-block:: console
$ fusermount -u flash
Note that this feature requires a 32-bit version of the FUSE library, with a
minimal version of 2.6, on the host system and ``pkg-config`` settings to
correctly pickup the FUSE install path and compiler flags.
On a Ubuntu 22.04 host system, for example, install the ``pkg-config`` and
``libfuse-dev:i386`` packages, and configure the pkg-config search path with
these commands:
.. code-block:: console
$ sudo dpkg --add-architecture i386
$ sudo apt update
$ sudo apt-get install pkg-config libfuse-dev:i386
$ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig
.. _native_sim_peripherals_c_compat:
Peripherals and backends C library compatibility
************************************************
Today, some native_sim peripherals and backends 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, :ref:`Userchan <nsim_bt_host_cont>`, :kconfig:option:`CONFIG_BT_USERCHAN`, Host libC
CAN, CAN native Linux, :kconfig:option:`CONFIG_CAN_NATIVE_LINUX`, All
Console backend, :ref:`POSIX arch console <nsim_back_console>`, :kconfig:option:`CONFIG_POSIX_ARCH_CONSOLE`, All
Display, :ref:`Display SDL <nsim_per_disp_sdl>`, :kconfig:option:`CONFIG_SDL_DISPLAY`, All
Entropy, :ref:`Native posix entropy <nsim_per_entr>`, :kconfig:option:`CONFIG_FAKE_ENTROPY_NATIVE_POSIX`, All
EEPROM, EEPROM simulator, :kconfig:option:`CONFIG_EEPROM_SIMULATOR`, Host libC
EEPROM, EEPROM emulator, :kconfig:option:`CONFIG_EEPROM_EMULATOR`, All
Ethernet, :ref:`Eth native_posix <nsim_per_ethe>`, :kconfig:option:`CONFIG_ETH_NATIVE_POSIX`, All
Flash, :ref:`Flash simulator <nsim_per_flash_simu>`, :kconfig:option:`CONFIG_FLASH_SIMULATOR`, All
Flash, :ref:`Host based flash access <native_fuse_flash>`, :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`, All
I2C, I2C emulator, :kconfig:option:`CONFIG_I2C_EMUL`, All
Input, Input SDL touch, :kconfig:option:`CONFIG_INPUT_SDL_TOUCH`, All
Input, Linux evdev, :kconfig:option:`CONFIG_NATIVE_LINUX_EVDEV`, All
Logger backend, :ref:`Native backend <nsim_back_logger>`, :kconfig:option:`CONFIG_LOG_BACKEND_NATIVE_POSIX`, All
Offloaded sockets, :ref:`nsim_per_offloaded_sockets`, :kconfig:option:`CONFIG_NET_NATIVE_OFFLOADED_SOCKETS`, All
RTC, RTC emul, :kconfig:option:`CONFIG_RTC_EMUL`, All
Serial, :ref:`UART native posix/PTTY <native_ptty_uart>`, :kconfig:option:`CONFIG_UART_NATIVE_POSIX`, All
Serial, :ref:`UART native TTY <native_tty_uart>`, :kconfig:option:`CONFIG_UART_NATIVE_TTY`, All
SPI, SPI emul, :kconfig:option:`CONFIG_SPI_EMUL`, All
System tick, Native_posix timer, :kconfig:option:`CONFIG_NATIVE_POSIX_TIMER`, All
Tracing, :ref:`Posix tracing backend <nsim_back_trace>`, :kconfig:option:`CONFIG_TRACING_BACKEND_POSIX`, All
USB, :ref:`USB native posix <nsim_per_usb>`, :kconfig:option:`CONFIG_USB_NATIVE_POSIX`, Host libC
Part 3
한국어 전문 번역
개요
native_sim 보드는 POSIX 아키텍처 기반 보드입니다. Zephyr 애플리케이션을 Zephyr 커널과 라이브러리와 함께 컴파일해 일반 Linux 실행 파일을 만들 수 있습니다.
native_sim은 native simulator와 Zephyr POSIX 아키텍처를 기반으로 합니다.
특정 하드웨어를 시뮬레이션하려는 보드는 아니지만 Ethernet 드라이버, 디스플레이, UART 등 여러 주변장치를 제공해 이 기능이 필요한 애플리케이션 코드를 개발·시험할 수 있습니다.
호스트 의존성과 제한
호스트 요구사항은 POSIX 아키텍처 의존성 문서를 따릅니다. native_sim은 POSIX 아키텍처 기반이므로 해당 아키텍처의 중요 제한과 미지원 기능을 그대로 물려받습니다. 일부 드라이버도 전체 API의 선택 기능을 모두 지원하지 않을 수 있습니다.
사용 방법
컴파일
빌드 대상에 native_sim을 지정합니다.
west build -b native_sim samples/hello_world
실행
빌드 결과는 build/zephyr/zephyr.exe에 생성됩니다. 다른 Linux 콘솔 애플리케이션처럼 실행합니다.
$ ./build/zephyr/zephyr.exe
# 종료하려면 Ctrl+C
실행 파일이 받는 명령행 옵션은 빌드 구성에 따라 달라집니다. --help로 사용 가능한 옵션을 확인할 수 있습니다.
$ ./build/zephyr/zephyr.exe --help
애플리케이션 작업이 끝나도 Zephyr 커널은 실제로 종료하지 않고 idle loop에 영원히 머뭅니다. 따라서 Linux에서는 Ctrl+C로 수동 종료해야 합니다. ztest 기반 애플리케이션 테스트는 모든 테스트가 끝나면 종료합니다.
특정 지점에서 정상 종료하려면 CONFIG_ARCH_POSIX 조건부 컴파일 아래에 nsi_exit(int status) 호출을 추가할 수 있습니다.
디버깅
Zephyr 실행 파일은 네이티브 애플리케이션이므로 다른 네이티브 프로그램처럼 디버깅·계측할 수 있습니다. 디버그 정보가 포함되어 gdb에서 직접 실행하거나 valgrind로 계측할 수 있습니다.
비동기·난수 컴포넌트가 없다면 실행은 보통 결정론적이어서 여러 번 실행해 정확히 같은 결과를 얻습니다. 계측도 실행 결과에 영향을 주지 않습니다.
디버깅하기 쉽게 CONFIG_NO_OPTIMIZATIONS를 설정해 -O0처럼 최적화 없이 컴파일할 수 있습니다. 디버거의 GUI로 IDE를 사용하는 것도 좋습니다.
Address Sanitizer (ASan)
Address Sanitizer를 사용하려면 애플리케이션 설정 또는 west build/cmake 명령에 CONFIG_ASAN을 설정합니다. 호스트에 ASan 라이브러리가 필요하며 Debian/Ubuntu 패키지는 libasan1입니다.
Undefined Behavior Sanitizer (UBSan)
Undefined Behavior Sanitizer를 사용하려면 애플리케이션 설정 또는 빌드 명령에 CONFIG_UBSAN을 설정합니다.
Coverage 보고서
코드 coverage는 POSIX 아키텍처용 coverage 보고서 절차를 사용합니다.
32비트와 64비트 대상
native_sim: 기본 32비트 대상입니다. i386 ILP32 ABI로 포인터와long을 32비트로 컴파일해 대부분의 Zephyr 임베디드 대상 ABI를 흉내 냅니다. 크기 의존 버그를 찾는 데 보통 더 좋으며 multilib가 설치된 64비트 시스템 또는 32비트 userspace가 필요합니다.native_sim/native/64: x86-64 LP64 ABI로 포인터와long을 64비트로 컴파일합니다. 32비트 실행 파일을 컴파일하거나 실행할 수 없을 때 사용합니다.
C 라이브러리 선택
native_sim은 여러 C 라이브러리로 컴파일할 수 있습니다. 기본은 CONFIG_EXTERNAL_LIBC 호스트 C 라이브러리이며, CONFIG_MINIMAL_LIBC 또는 CONFIG_PICOLIBC도 선택할 수 있습니다. 호스트 C 라이브러리와 호환되지 않는 기능을 선택하면 기본으로 Picolibc가 대신 선택됩니다.
minimal libc나 Picolibc를 사용하면 임베디드 대상과 더 비슷하게 코드를 빌드하고 해당 라이브러리와의 상호작용을 시험할 수 있습니다. Zephyr POSIX OS 추상화 shim과의 충돌도 없습니다. 반면 임베디드 코드가 테스트 목적으로 호스트에 접근하기 어려워지고 선택할 수 있는 드라이버·backend가 줄어듭니다.
포팅 목적과 다른 선택지
native_sim은 POSIX 아키텍처의 전체 목적을 공유하면서 일부 경우 호스트 OS 주변장치를 이용하는 하드웨어 비종속 테스트 플랫폼입니다. 특정 하드웨어를 모델링하지 않으므로 HW와 충분히 분리된 애플리케이션 코드만 개발·시험할 수 있습니다.
특정 하드웨어가 필요한 소프트웨어를 POSIX 아키텍처의 이점과 함께 시험하려면 bsim 보드 같은 대안을 고려해야 합니다.
아키텍처
이 보드는 Zephyr POSIX 아키텍처 포팅을 기반으로 하며 스레딩과 CPU/HW 스케줄링 구조를 공유합니다. native simulator 내부 동작은 native simulator 문서에서 확인할 수 있습니다.
특정 임베디드 CPU나 SoC를 에뮬레이션하지 않으며, 코드는 보통 x86인 호스트 시스템용 네이티브 코드로 컴파일됩니다.
native_sim의 시간
시뮬레이션 시간은 보통 실제 호스트 시간과 완전히 분리되고 호스트 계산 능력이 허용하는 만큼 빠르게 진행합니다. 디버거나 일괄 테스트에는 좋지만 실제 호스트 시간에 기반한 외부 인터페이스와 상호작용할 때는 적합하지 않습니다.
Zephyr 커널과 일반 Zephyr 스레드는 HW 모델이 제공하는 시뮬레이션 시간만 압니다. 시뮬레이션 시간과 실시간 사이 연결은 clock/timer 모델만 만듭니다.
--rt와 --no-rt로 실행을 실시간 속도에 맞출 수 있고 기본 동작은 CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME으로 정합니다. 모델은 다음 system tick 인터럽트를 올리기 전에 대응 실시간이 될 때까지 기다릴 뿐입니다.
호스트 부하나 디버깅 때문에 시뮬레이션이 실시간보다 느리면 이후 tick을 지연하지 않아 가능한 한 따라잡습니다. 따라서 시뮬레이션 시간이 실시간보다 뒤처질 수 있습니다. 정상 실행의 결정성을 유지하면서 관찰자에게 실시간처럼 보이게 하는 방식입니다.
실시간 고정 모드에서도 --rt-ratio=<ratio>와 원문 표기의 -rt-drift=<drift>로 시뮬레이션 시간을 더 빠르거나 느리게 설정할 수 있습니다. 두 옵션은 같은 메커니즘을 제어하며 drift = ratio - 1입니다. 실행 중에는 native_rtc_adjust_clock()으로 조정할 수 있습니다.
--rt-ratio=2이면 시뮬레이션 시간이 실시간의 두 배로 진행합니다. --rt-drift=-100e-6이면 실시간보다 100ppm 느립니다. 두 옵션은 비실시간 모드에서는 의미가 없습니다.
시뮬레이션 시간과 실시간 관계
st = (rt - last_rt) × ratio + last_st이며 역변환은 rt = (st - last_st) / ratio + last_rt입니다. last_rt와 last_st는 마지막 clock ratio 조정 시점의 실시간과 시뮬레이션 시간입니다. 모든 시간은 마이크로초 단위로 유지합니다.
주변장치
인터럽트 컨트롤러
간단하고 범용적인 컨트롤러로 중첩 인터럽트와 우선순위를 지원합니다. 인터럽트를 개별 마스크·마스크 해제할 수 있고 소프트웨어 인터럽트도 지원합니다.
Clock, timer와 system tick
system tick 타이머를 제공합니다. 기본 CONFIG_SYS_CLOCK_TICKS_PER_SEC 설정은 10ms마다 tick을 발생시킵니다.
UART/직렬
- PTTY (
UART_NATIVE_POSIX): Zephyr UART 한두 개를 Linux 프로세스의 stdin/stdout 또는 새 pseudo-TTY에 연결합니다. - TTY (
UART_NATIVE_TTY): USB-UART 동글처럼 호스트에 연결된 직렬 장치와 상호작용합니다.
Real-time clock
항상 전원이 공급되는 clock 모델이며 기본으로 부팅 시 호스트 시간으로 초기화합니다. --rtc-reset으로 시간 0에서 시작하고, --rtc-offset=<offset> 또는 native_rtc_offset()으로 값을 이동할 수 있습니다. 시작 뒤에는 시뮬레이션 시간과 함께 진행하므로 시간 속도 비율의 영향을 받습니다.
native_rtc_gettime_us()와 native_rtc_gettime()은 다음 clock source를 받습니다.
RTC_CLOCK_BOOT: 부팅 뒤 흐른 시뮬레이션 시간이며 offset 조정의 영향을 받지 않습니다.RTC_CLOCK_REALTIME: offset 조정의 영향을 받는 RTC 영속 시간입니다.RTC_CLOCK_PSEUDOHOSTREALTIME: 호스트도 시뮬레이션 clock ratio와 offset 영향을 받는다고 가정한 실시간입니다. 보통 시뮬레이션 시간보다 수십분의 1마이크로초 앞서지만 실행 속도·호스트 부하에 따라 상당히 앞설 수 있으므로 주의해야 합니다.
이 장치에는 아직 Zephyr RTC API 호환 드라이버가 없습니다.
Entropy 장치
호스트 random() API 기반입니다. 같은 난수 seed로 초기화하면 같은 난수열을 생성합니다. --seed=<random_seed>에 32비트 값을 지정할 수 있으며 예시는 10진수 97229, 16진수 0x17BCD, 8진수 0275715입니다.
Ethernet 드라이버
간단한 TAP 기반 Ethernet 드라이버입니다. 호스트에 zeth 인터페이스가 미리 있어야 하며 Zephyr net-tools 저장소의 net-setup.sh로 만들 수 있습니다. 사용자는 zeth를 통해 Zephyr 인스턴스와 통신하고 필요하면 TAP 인터페이스 여러 개와 인스턴스별 IP를 구성할 수 있습니다. Linux 호스트에서만 사용할 수 있습니다.
Offloaded sockets
TAP Ethernet의 대안으로 Linux 표준 BSD socket API를 사용합니다. 여러 Zephyr 애플리케이션이 Linux loopback을 통해 통신할 수 있습니다. root 권한과 추가 가상 네트워크 설정이 필요 없고 다른 Linux 프로세스와 같은 인터페이스에 연결되는 장점이 있지만, Zephyr 네트워크 스택의 L2 계층을 시험하지 않는 단점이 있습니다.
Bluetooth 컨트롤러
호스트 Bluetooth 어댑터를 Zephyr 컨트롤러로 사용할 수 있습니다. 예를 들어 hci0은 sudo zephyr.exe --bt-dev=hci0으로 전달합니다. 장치 사용에는 root 또는 정확히는 CAP_NET_ADMIN 권한이 필요합니다. 선택한 HCI 장치는 전원이 꺼져 있어야 하며 Bluetooth 4.0 이상인 BLE를 지원해야 합니다.
TCP 기반 HCI 서버를 가상 Bluetooth 컨트롤러로 사용할 수도 있습니다. IP와 포트를 지정하며 원문의 명령 예는 zephyr.exe --bt-dev=127.0.0.1:1020입니다. Linux Bluetooth stack/HCI에 의존하지 않는 가상 연결 시험에 주로 사용합니다.
USB 컨트롤러
USB/IP 프로토콜로 동작하는 Virtual USB 컨트롤러를 사용할 수 있습니다.
Display 드라이버
호스트에 디스플레이 내용을 그리는 창을 만듭니다. 32비트 SDL2와 해당 경로·컴파일러 플래그를 찾는 pkg-config 설정이 필요합니다. Ubuntu 22.04 예는 다음과 같습니다.
$ sudo dpkg --add-architecture i386
$ sudo apt update
$ sudo apt-get install pkg-config libsdl2-dev:i386
$ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig
EEPROM simulator
네이티브 대상에서는 EEPROM 내용을 호스트 파일에 유지할 수 있습니다. 기본 파일은 현재 디렉터리의 eeprom.bin이며 --eeprom으로 경로와 이름을 바꿉니다.
Flash simulator
Flash 내용을 호스트의 바이너리 파일 또는 RAM에 둘 수 있습니다. devicetree 또는 CONFIG_FLASH_SIMULATOR에서 동작을 구성합니다. 기본 파일은 현재 디렉터리의 flash.bin이며 --flash로 바꿉니다.
데이터는 raw 형식이고 파일은 devicetree의 크기에 맞게 잘립니다. 파일이 없으면 드라이버가 만들고, 있으면 기존 파일을 사용합니다. 호스트에서의 내용 접근은 아래 FUSE 절차를 이용합니다.
입력 이벤트
evdev: Linux evdev 장치의 이벤트를 읽어 Zephyr input subsystem에 주입합니다. CONFIG_INPUT과 다음 devicetree node로 자동 활성화합니다.
evdev {
compatible = "zephyr,native-linux-evdev";
};
실행할 때 zephyr.exe --evdev=/dev/input/event0처럼 장치 node를 지정합니다.
SDL touch: SDL로 touch panel 입력을 흉내 냅니다. CONFIG_INPUT_SDL_TOUCH와 zephyr,input-sdl-touch devicetree binding으로 설정합니다.
CAN 컨트롤러
호스트 CAN 컨트롤러를 native SocketCAN Linux 드라이버로 사용할 수 있습니다. CONFIG_CAN_NATIVE_LINUX와 zephyr,native-linux-can binding으로 설정합니다.
PTTY UART
CONFIG_UART_NATIVE_POSIX로 UART를 최대 두 개 만들며 기본은 하나입니다. CONFIG_UART_NATIVE_POSIX_PORT_1_ENABLE로 두 번째 UART를 켭니다.
첫 UART는 새 /dev/pts/<nbr> pseudo-terminal 또는 실행 파일 stdin/stdout에 연결합니다. CONFIG_NATIVE_UART_0_ON_OWN_PTY와 CONFIG_NATIVE_UART_0_ON_STDINOUT 중 하나를 선택합니다.
대화형 Zephyr shell에는 raw terminal을 제공하는 OWN_PTY가 적합합니다. STDINOUT은 다른 프로세스 출력을 pipe로 넣어 shell을 제어하는 자동화 시험에 적합합니다. 일반 Linux terminal은 기본 상태에서 shell subsystem이 요구하는 raw terminal이 아니기 때문입니다.
OWN_PTY를 선택하면 새 pseudo-terminal 이름이 콘솔에 표시됩니다. 수동으로 연결하는 예는 다음과 같습니다.
$ xterm -e screen /dev/<ttyn> &
/dev/<ttyn>을 실제 TTY로 바꿉니다. 실행 파일에 -attach_uart를 주면 자동 연결하고, -attach_uart_cmd=<"cmd">로 명령을 지정합니다. 기본값은 CONFIG_NATIVE_UART_AUTOATTACH_DEFAULT_CMD이며 호스트에 xterm과 screen이 있다고 가정합니다.
PTTY 드라이버는 polling만 지원합니다. interrupt·async, runtime 설정과 line control은 지원하지 않습니다.
TTY UART
애플리케이션은 polling UART API uart_poll_out()과 uart_poll_in()으로 연결된 직렬 장치에 문자를 쓰고 읽습니다.
zephyr,native-tty-uart compatible과 okay 상태의 devicetree node가 있으면 자동 활성화됩니다.
uart {
status = "okay";
compatible = "zephyr,native-tty-uart";
serial-port = "/dev/ttyUSB0";
current-speed = <115200>;
};
serial-port와current-speed로 기본 포트·baud rate를 지정하며 포트는 선택 사항입니다.X_port와X_baud명령행 옵션으로도 지정할 수 있고 devicetree보다 우선합니다.X는 node 이름입니다.- data/stop bit, parity와 baud rate는 실행 중
uart_configure()로 바꿀 수 있습니다. CONFIG_UART_INTERRUPT_DRIVEN으로 interrupt-driven UART를 흉내 낼 수 있습니다.
인스턴스 여러 개를 지원하며 uart-native-tty sample이 동작 예를 제공합니다. polling과 interrupt mode를 지원하지만 async는 지원하지 않습니다. runtime 설정은 지원하고 line control은 지원하지 않습니다.
Subsystem backend
- Console: 기본으로
printk()출력을 호스트 애플리케이션stdout으로 보냅니다. PTTY UART가 없으면 기본 선택되고, 있으면CONFIG_UART_CONSOLE로 UART를 콘솔로 선택합니다. - Logger: 모든 logger 출력을 프로세스 stdout으로 보냅니다.
CONFIG_LOG_BACKEND_FORMAT_TIMESTAMPtimestamp와CONFIG_LOG_BACKEND_SHOW_COLOR색상을 지원합니다. 색상은--color,--no-color,--force-color로 제어합니다. 기본 logger 모드는CONFIG_LOG_MODE_IMMEDIATE이고 backend는CONFIG_LOG_BACKEND_NATIVE_POSIX로 선택되며 기본 활성화됩니다. - Tracing: Zephyr CTF tracing 데이터를 호스트 파일 시스템에 기록하는 backend/bottom을 제공합니다.
Emulator
사용 가능한 모든 Zephyr HW emulator를 native_sim에서 사용할 수 있습니다.
호스트 기반 Flash 접근
Flash 장치가 있으면 CONFIG_FUSE_FS_ACCESS로 Flash 파일 시스템 파티션을 호스트 파일 시스템에 노출할 수 있습니다. FUSE 계층이 Zephyr 파일 시스템 호출을 필요한 UNIX 호출로 변환하므로 cd, ls, mkdir 같은 일반 명령으로 접근합니다.
기본 mount point는 현재 작업 디렉터리의 flash/이며 --flash-mount로 바꿉니다. 실행 전 디렉터리가 존재해야 합니다. 정상 종료 때 자동 unmount하지만 충돌로 남은 mount point는 다음처럼 정리합니다.
$ fusermount -u flash
호스트에는 FUSE 2.6 이상 32비트 라이브러리와 설치 경로·컴파일러 플래그를 찾는 pkg-config 설정이 필요합니다. Ubuntu 22.04 예는 다음과 같습니다.
$ sudo dpkg --add-architecture i386
$ sudo apt update
$ sudo apt-get install pkg-config libfuse-dev:i386
$ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig
주변장치·backend와 C 라이브러리 호환성
다음 표에서 “호스트 libc”로 표시한 기능은 현재 CONFIG_EXTERNAL_LIBC 빌드에서만 사용할 수 있습니다. “모두”는 호스트 libc, minimal libc와 Picolibc 선택에서 사용할 수 있다는 뜻입니다.
| 드라이버 종류 | 드라이버/backend | Kconfig | C 라이브러리 |
|---|---|---|---|
| ADC | ADC emulator | CONFIG_ADC_EMUL | 모두 |
| Bluetooth | User channel | CONFIG_BT_USERCHAN | 호스트 libc |
| CAN | CAN native Linux | CONFIG_CAN_NATIVE_LINUX | 모두 |
| Console backend | POSIX arch console | CONFIG_POSIX_ARCH_CONSOLE | 모두 |
| Display | Display SDL | CONFIG_SDL_DISPLAY | 모두 |
| Entropy | Native POSIX entropy | CONFIG_FAKE_ENTROPY_NATIVE_POSIX | 모두 |
| EEPROM | EEPROM simulator | CONFIG_EEPROM_SIMULATOR | 호스트 libc |
| EEPROM | EEPROM emulator | CONFIG_EEPROM_EMULATOR | 모두 |
| Ethernet | Ethernet native_posix | CONFIG_ETH_NATIVE_POSIX | 모두 |
| Flash | Flash simulator | CONFIG_FLASH_SIMULATOR | 모두 |
| Flash | 호스트 기반 flash 접근 | CONFIG_FUSE_FS_ACCESS | 호스트 libc |
| GPIO | GPIO emulator | CONFIG_GPIO_EMUL | 모두 |
| GPIO | SDL GPIO emulator | CONFIG_GPIO_EMUL_SDL | 모두 |
| I2C | I2C emulator | CONFIG_I2C_EMUL | 모두 |
| Input | Input SDL touch | CONFIG_INPUT_SDL_TOUCH | 모두 |
| Input | Linux evdev | CONFIG_NATIVE_LINUX_EVDEV | 모두 |
| Logger backend | Native backend | CONFIG_LOG_BACKEND_NATIVE_POSIX | 모두 |
| Offloaded sockets | Native offloaded sockets | CONFIG_NET_NATIVE_OFFLOADED_SOCKETS | 모두 |
| RTC | RTC emulator | CONFIG_RTC_EMUL | 모두 |
| Serial | UART native POSIX/PTTY | CONFIG_UART_NATIVE_POSIX | 모두 |
| Serial | UART native TTY | CONFIG_UART_NATIVE_TTY | 모두 |
| SPI | SPI emulator | CONFIG_SPI_EMUL | 모두 |
| System tick | Native_posix timer | CONFIG_NATIVE_POSIX_TIMER | 모두 |
| Tracing | POSIX tracing backend | CONFIG_TRACING_BACKEND_POSIX | 모두 |
| USB | USB native POSIX | CONFIG_USB_NATIVE_POSIX | 호스트 libc |
Source
출처
영어 원문에는 문단, 문서 지시문, 표, 코드, 코드 심벌, 경로를 그대로 보존했습니다.