691 lines
27 KiB
ReStructuredText
691 lines
27 KiB
ReStructuredText
.. _native_posix:
|
|
|
|
Native POSIX execution (native_posix)
|
|
#######################################
|
|
|
|
.. contents::
|
|
:depth: 1
|
|
:backlinks: entry
|
|
:local:
|
|
|
|
Overview
|
|
********
|
|
|
|
Using this board, a Zephyr application can be compiled together with
|
|
the Zephyr kernel, creating a normal console executable that runs as
|
|
a native application on the host OS, without emulation. Instead,
|
|
you use native host tools for compiling, debugging, and analyzing your
|
|
Zephyr application, eliminating the need for architecture-specific
|
|
target hardware in the early phases of development.
|
|
|
|
This board provides a few peripherals such as an Ethernet driver and UART.
|
|
See `Peripherals`_ for more information.
|
|
|
|
.. _native_posix_deps:
|
|
|
|
Host system dependencies
|
|
========================
|
|
|
|
This port is designed to run in POSIX compatible operating systems,
|
|
but it has only been tested on Linux.
|
|
|
|
.. note::
|
|
|
|
You must have the 32-bit C library installed in your system
|
|
(in Ubuntu 16.04 install the gcc-multilib package)
|
|
|
|
.. note::
|
|
|
|
The 32 bit version of this port does not directly work in Windows Subsystem
|
|
for Linux (WSL) because WSL does not support native 32-bit binaries.
|
|
You may want to consider WSL2, or you can also just use the native_posix_64
|
|
target: Check `32 and 64bit versions`_.
|
|
Otherwise `with some tinkering
|
|
<https://github.com/microsoft/WSL/issues/2468#issuecomment-374904520>`_ it
|
|
should be possible to make it work.
|
|
|
|
.. _native_important_limitations:
|
|
|
|
Important limitations
|
|
*********************
|
|
|
|
The underlying assumptions behind this port set some limitations on what
|
|
can and cannot be done.
|
|
These limitations are due to the code executing natively in
|
|
the host CPU without any instrumentation or means to interrupt it unless the
|
|
simulated CPU is sleeping.
|
|
|
|
You can imagine the code executes in a simulated CPU
|
|
which runs at an infinitely fast clock: No time passes while the CPU is
|
|
running.
|
|
Therefore interrupts, including timer interrupts, will not arrive
|
|
while code executes, except immediately after the SW enables or unmasks
|
|
them if they were pending.
|
|
|
|
This behavior is intentional, as it provides a deterministic environment to
|
|
develop and debug.
|
|
For more information please see the
|
|
`Rationale for this port`_ and `Architecture`_ sections
|
|
|
|
Therefore these limitations apply:
|
|
|
|
- There can **not** be busy wait loops in the application code that wait for
|
|
something to happen without letting the CPU sleep.
|
|
If busy wait loops do exist, they will behave as infinite loops and
|
|
will stall the execution. For example, the following busy wait loop code,
|
|
which could be interrupted on actual hardware, will stall the execution of
|
|
all threads, kernel, and HW models:
|
|
|
|
.. code-block:: c
|
|
|
|
while (1){}
|
|
|
|
Similarly the following code where we expect ``condition`` to be
|
|
updated by an interrupt handler or another thread, will also stall
|
|
the application when compiled for this port.
|
|
|
|
.. code-block:: c
|
|
|
|
volatile condition = true;
|
|
while (condition){}
|
|
|
|
|
|
- Code that depends on its own execution speed will normally not
|
|
work as expected. For example, code such as shown below, will likely not
|
|
work as expected:
|
|
|
|
.. code-block:: c
|
|
|
|
peripheral_x->run = true;
|
|
|
|
/* Wait for a number of CPU cycles */
|
|
for (int i = 0; i < 100; i++) NOP;
|
|
|
|
/* We expect the peripheral done and ready to do something else */
|
|
|
|
|
|
- This port is not meant to, and could not possibly help debug races between
|
|
HW and SW, or similar timing related issues.
|
|
|
|
- You may not use hard coded memory addresses because there is no I/O or
|
|
MMU emulation.
|
|
|
|
|
|
Working around these limitations
|
|
================================
|
|
|
|
If a busy wait loop exists, it will become evident as the application will be
|
|
stalled in it. To find the loop, you can run the binary in a debugger and
|
|
pause it after the execution is stuck; it will be paused in
|
|
some part of that loop.
|
|
|
|
The best solution is to remove that busy wait loop, and instead use
|
|
an appropriate kernel primitive to synchronize your threads.
|
|
Note that busy wait loops are in general a bad coding practice as they
|
|
keep the CPU executing and consuming power.
|
|
|
|
If removing the busy loop is really not an option, you may add a conditionally
|
|
compiled call to :c:func:`k_cpu_idle` if you are waiting for an
|
|
interrupt, or a call to :c:func:`k_busy_wait` with some small delay in
|
|
microseconds.
|
|
In the previous example, modifying the code as follows would work:
|
|
|
|
.. code-block:: c
|
|
|
|
volatile condition = true;
|
|
while (condition) {
|
|
#if defined(CONFIG_ARCH_POSIX)
|
|
k_cpu_idle();
|
|
#endif
|
|
}
|
|
|
|
|
|
How to use it
|
|
*************
|
|
|
|
Compiling
|
|
=========
|
|
|
|
Specify the native_posix board target to build a native POSIX application:
|
|
|
|
.. zephyr-app-commands::
|
|
:zephyr-app: samples/hello_world
|
|
:host-os: unix
|
|
:board: native_posix
|
|
: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::
|
|
|
|
$ ./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 ``ztest`` 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 (:option:`CONFIG_ARCH_POSIX`) call to
|
|
``posix_exit(int status)`` at that point.
|
|
|
|
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 :option:`CONFIG_NO_OPTIMIZATIONS`.
|
|
|
|
Address Sanitizer (ASan)
|
|
========================
|
|
|
|
You can also build Zephyr with `Address Sanitizer`_. To do this, set
|
|
: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
|
|
|
|
Coverage reports
|
|
================
|
|
|
|
See
|
|
:ref:`coverage reports using the POSIX architecture <coverage_posix>`.
|
|
|
|
|
|
32 and 64bit versions
|
|
*********************
|
|
|
|
native_posix comes with two targets: A 32 bit and 64 bit version.
|
|
The 32 bit version, ``native_posix``, 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_posix_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.
|
|
|
|
If you are using another 32 bit POSIX arch target you may also override its ABI
|
|
target and pointer bit width by setting :option:`CONFIG_64BIT`.
|
|
|
|
|
|
Rationale for this port
|
|
***********************
|
|
|
|
The main intents of this port are:
|
|
|
|
- Allow functional debugging, instrumentation and analysis of the code with
|
|
native tooling.
|
|
- Allow functional regression testing, and simulations in which we have the
|
|
full functionality of the code.
|
|
- Run tests fast: several minutes of simulated time per wall time second.
|
|
- Possibility to connect to external tools which may be able to run much
|
|
faster or much slower than real time.
|
|
- Deterministic, repeatable runs:
|
|
There must not be any randomness or indeterminism (unless host peripherals
|
|
are used).
|
|
The result must **not** be affected by:
|
|
|
|
- Debugging or instrumenting the code.
|
|
- Pausing in a breakpoint and continuing later.
|
|
- The host computer performance or its load.
|
|
|
|
The aim of this port is not to debug HW/SW races, missed HW programming
|
|
deadlines, or issues in which an interrupt comes when it was not expected.
|
|
Normally those would be debugged with a cycle accurate Instruction Set Simulator
|
|
(ISS) or with a development board.
|
|
|
|
Comparison with other options
|
|
*****************************
|
|
|
|
This port does not try to replace cycle accurate instruction set simulators
|
|
(ISS), development boards, or QEMU, but to complement them. This port's main aim
|
|
is to meet the targets described in the previous `Rationale for this port`_
|
|
section.
|
|
|
|
.. figure:: Port_vs_QEMU_vs.svg
|
|
:align: center
|
|
:alt: Comparison of different debugging targets
|
|
:figclass: align-center
|
|
|
|
Comparison of different debugging options. Note that realism has many
|
|
dimensions: Having the real memory map or emulating the exact time an
|
|
instruction executes is just some of it; Emulating peripherals accurately
|
|
is another side.
|
|
|
|
This native port compiles your code directly to x86, with no instrumentation or
|
|
monitoring code. Your code executes directly in the host CPU. That is, your code
|
|
executes just as fast as it possibly can.
|
|
|
|
Simulated time is normally decoupled from real host time.
|
|
The problem of how to emulate the instruction execution speed is solved
|
|
by assuming that code executes in zero simulated time.
|
|
|
|
There is no I/O or MMU emulation. If you try to access memory through hardcoded
|
|
addresses your binary will simply segfault.
|
|
The drivers and HW models for this architecture will hide this from the
|
|
application developers when it relates to those peripherals.
|
|
In general this port is not meant to help developing low level drivers for
|
|
target HW. But for developing application code.
|
|
|
|
Your code can be debugged, instrumented, or analyzed with all normal native
|
|
development tools just like any other Linux application.
|
|
|
|
Execution is fully reproducible, you can pause it without side-effects.
|
|
|
|
How does this port compare to QEMU:
|
|
===================================
|
|
|
|
With QEMU you compile your image targeting the board which is closer to
|
|
your desired board. For example an ARM based one. QEMU emulates the real memory
|
|
layout of the board, loads the compiled binary and through instructions
|
|
translation executes that ARM targeted binary on the host CPU.
|
|
Depending on configuration, QEMU also provides models of some peripherals
|
|
and, in some cases, can expose host HW as emulated target peripherals.
|
|
|
|
QEMU cannot provide any emulation of execution speed. It simply
|
|
executes code as fast as it can, and lets the host CPU speed determine the
|
|
emulated CPU speed. This produces highly indeterministic behavior,
|
|
as the execution speed depends on the host system performance and its load.
|
|
|
|
As instructions are translated to the host architecture, and the target CPU and
|
|
MMU are emulated, there is a performance penalty.
|
|
|
|
You can connect gdb to QEMU, but have few other instrumentation abilities.
|
|
|
|
Execution is not reproducible. Some bugs may be triggered only in some runs
|
|
depending on the computer and its load.
|
|
|
|
How does this port compare to an ISS:
|
|
======================================
|
|
|
|
With a cycle accurate instruction set simulator you compile targeting either
|
|
your real CPU/platform or a close enough relative. The memory layout is modeled
|
|
and some or all peripherals too.
|
|
|
|
The simulator loads your binary, slowly interprets each instruction, and
|
|
accounts for the time each instruction takes.
|
|
Time is simulated and is fully decoupled from real time.
|
|
Simulations are on the order of 10 to 100 times slower than real time.
|
|
|
|
Some instruction set simulators work with gdb, and may
|
|
provide some extra tools for analyzing your code.
|
|
|
|
Execution is fully reproducible. You can normally pause your execution without
|
|
side-effects.
|
|
|
|
|
|
Architecture
|
|
************
|
|
|
|
.. figure:: native_layers.svg
|
|
:align: center
|
|
:alt: Zephyr layering in native build
|
|
:figclass: align-center
|
|
|
|
Zephyr layering when built against an embedded target (left), and
|
|
targeting the native_posix board (right)
|
|
|
|
This board is based on the POSIX architecture port of Zephyr.
|
|
In this architecture each Zephyr thread is mapped to one POSIX pthread,
|
|
but only one of these pthreads executes at a time.
|
|
This architecture provides the same interface to the Kernel as other
|
|
architectures and is therefore transparent for the application.
|
|
|
|
This board does not try to emulate any particular embedded CPU or SOC.
|
|
The code is compiled natively for the host x86 system, as a 32-bit
|
|
binary assuming pointer and integer types are 32-bits wide.
|
|
|
|
To ensure determinism when the Zephyr code is running,
|
|
and to ease application debugging,
|
|
the board uses a different time than real time: simulated time.
|
|
This simulated time is, in principle, not linked to the host time.
|
|
|
|
The Zephyr application sees the code executing as if the CPU were running at
|
|
an infinitely fast clock, and fully decoupled from the underlying host CPU
|
|
speed.
|
|
No simulated time passes while the application or kernel code execute.
|
|
|
|
The CPU boot is emulated by creating the Zephyr initialization thread and
|
|
letting it run. This in turn may spawn more Zephyr threads.
|
|
Eventually the SW will run to completion, that is, it will set the CPU
|
|
back to sleep.
|
|
|
|
At this point, control is transferred back to the HW models and the simulation
|
|
time can be advanced.
|
|
|
|
When the HW models raise an interrupt, the CPU wakes back up, the interrupt
|
|
is handled, the SW runs until completion again, and control is
|
|
transferred back to the HW models, all in zero simulated time.
|
|
|
|
If the SW unmasks a pending interrupt while running, or triggers a SW
|
|
interrupt, the interrupt controller may raise the interrupt immediately
|
|
depending on interrupt priorities, masking, and locking state.
|
|
|
|
About time in native_posix
|
|
==========================
|
|
|
|
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_posix to
|
|
real time.
|
|
You can do this with the ``--rt`` and ``--no-rt`` options from the command line.
|
|
The default behavior is set with
|
|
:option:`CONFIG_NATIVE_POSIX_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_posix 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
|
|
|
|
``st = (rt - last_rt) * ratio + last_st``
|
|
|
|
And vice-versa:
|
|
|
|
``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.
|
|
|
|
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
|
|
:option:`CONFIG_SYS_CLOCK_TICKS_PER_SEC` configures it to tick every 10ms.
|
|
|
|
This peripheral driver also provides the needed functionality for this
|
|
architecture-specific :c:func:`k_busy_wait`.
|
|
|
|
Please refer to the section `About time in native_posix`_ for more
|
|
information.
|
|
|
|
**UART**
|
|
An optional UART driver can be compiled with native_posix.
|
|
For more information refer to the section `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_posix`_ 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_posix and the host load,
|
|
it may return a value considerably ahead of the simulated time.
|
|
|
|
**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:
|
|
``--seed=<random_seed>`` where the value specified is a 32-bit integer
|
|
such as 97229 (decimal), 0x17BCD (hex), or 0275715 (octal).
|
|
|
|
**Ethernet driver**:
|
|
A simple TAP based ethernet driver is provided. The driver will create
|
|
a **zeth** network interface to the host system. One can communicate with
|
|
Zephyr via this network interface. Multiple TAP based network interfaces can
|
|
be created if needed. The IP address configuration can be specified for each
|
|
network interface instance.
|
|
See :option:`CONFIG_ETH_NATIVE_POSIX_SETUP_SCRIPT` option for more details.
|
|
The :ref:`eth-native-posix-sample` sample app provides
|
|
some use examples and more information about this driver configuration.
|
|
|
|
Note that this device can only be used with Linux hosts, and that the user
|
|
needs elevated permissions.
|
|
|
|
**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).
|
|
|
|
**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_posix <testing_USB_native_posix>`.
|
|
|
|
**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 18.04 host system, for example, install the ``pkg-config`` and
|
|
``libsdl2-dev:i386`` packages, and configure the pkg-config search path with
|
|
these commands::
|
|
|
|
$ 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
|
|
|
|
**Flash driver**:
|
|
A flash driver is provided that accesses all flash data through a binary file
|
|
on the host file system. The behavior of the flash device can be configured
|
|
through the native POSIX board devicetree or Kconfig settings under
|
|
:option:`CONFIG_FLASH_SIMULATOR`.
|
|
|
|
By default the binary data is located in the 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.
|
|
|
|
The flash content can be accessed from the host system, as explained in the
|
|
`Host based flash access`_ section.
|
|
|
|
UART
|
|
****
|
|
|
|
This driver can be configured with :option:`CONFIG_UART_NATIVE_POSIX`
|
|
to instantiate up to two UARTs. By default only one UART is enabled.
|
|
With :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. ``/dev/pts<nbr>``), or map the UART input and
|
|
output to the executable's ``stdin`` and ``stdout``.
|
|
This is chosen by selecting either
|
|
:option:`CONFIG_NATIVE_UART_0_ON_OWN_PTY` or
|
|
: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 :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::
|
|
|
|
$ xterm -e screen /dev/<ttyn> &
|
|
|
|
where ``/dev/<ttyn>`` 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
|
|
:option:`CONFIG_NATIVE_UART_AUTOATTACH_DEFAULT_CMD`.
|
|
Note that the default command assumes both ``xterm`` and ``screen`` are
|
|
installed in the system.
|
|
|
|
Subsystems backends
|
|
*******************
|
|
|
|
Apart from its own peripherals, the native_posix 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:
|
|
|
|
**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 `UART`_ is not compiled in.
|
|
Otherwise :option:`CONFIG_UART_CONSOLE` will be set to select the UART as
|
|
console backend.
|
|
|
|
**Logger backend**:
|
|
A backend which prints all logger output to the process ``stdout``.
|
|
It supports timestamping, which can be enabled with
|
|
:option:`CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP`; and colored output which can
|
|
be enabled with :option:`CONFIG_LOG_BACKEND_SHOW_COLOR` and controlled
|
|
with the command line options ``--color``, ``--no-color`` and
|
|
``--force-color``.
|
|
|
|
In native_posix, by default, the logger is configured with
|
|
:option:`CONFIG_LOG_IMMEDIATE`.
|
|
|
|
This backend can be selected with :option:`CONFIG_LOG_BACKEND_NATIVE_POSIX`
|
|
and is enabled by default unless the native_posix UART is compiled in.
|
|
In this later case, by default, the logger is set to output to the `UART`_.
|
|
|
|
**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>`
|
|
|
|
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
|
|
: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 *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 POSIX board.
|
|
|
|
On exit, the native POSIX board application will take care of unmounting the
|
|
directory. In the unfortunate case that the native POSIX board application
|
|
crashes, you can cleanup the stale mount point by using the program
|
|
``fusermount``::
|
|
|
|
$ 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 18.04 host system, for example, install the ``pkg-config`` and
|
|
``libfuse-dev:i386`` packages, and configure the pkg-config search path with
|
|
these commands::
|
|
|
|
$ sudo apt-get install pkg-config libfuse-dev:i386
|
|
$ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig
|