1.. _posix_details: 2 3Implementation Details 4###################### 5 6In many ways, Zephyr provides support like any POSIX OS; API bindings are provided in the C 7programming language, POSIX headers are available in the standard include path, when configured. 8 9Unlike other multi-purpose POSIX operating systems 10 11- Zephyr is not "a POSIX OS". The Zephyr kernel was not designed around the POSIX standard, and 12 POSIX support is an opt-in feature 13- Zephyr apps are not linked separately, nor do they execute as subprocesses 14- Zephyr, libraries, and application code are compiled and linked together, running similarly to 15 a single-process application, in a single (possibly virtual) address space 16- Zephyr does not provide a POSIX shell, compiler, utilities, and is not self-hosting. 17 18.. note:: 19 Unlike the Linux kernel or FreeBSD, Zephyr does not maintain a static table of system call 20 numbers for each supported architecture, but instead generates system calls dynamically at 21 build time. See `System Calls <syscalls>` for more information. 22 23Design 24====== 25 26As a library, Zephyr's POSIX API implementation makes an effort to be a thin abstraction layer 27between the application, middleware, and the Zephyr kernel. 28 29Some general design considerations: 30 31- The POSIX interface and implementations should be part of Zephyr's POSIX library, and not 32 elsewhere, unless required both by the POSIX API implementation and some other feature. An 33 example where the implementation should remain part of the POSIX implementation is 34 ``getopt()``. Examples where the implementation should be part of separate libraries are 35 multithreading and networking. 36 37- When the POSIX API and another Zephyr subsystem both rely on a feature, the implementation of 38 that feature should be as a separate Zephyr library that can be used by both the POSIX API and 39 the other library or subsystem. This reduces the likelihood of dependency cycles in code. When 40 practical, that rule should expand to include macros. In the example below, ``libposix`` 41 depends on ``libzfoo`` for the implementation of some functionality "foo" in Zephyr. If 42 ``libzfoo`` also depends on ``libposix``, then there is a dependency cycle. The cycle can be 43 removed via mutual dependency, ``libcommon``. 44 45.. graphviz:: 46 :caption: Dependency cycle between POSIX and another Zephyr library 47 48 digraph { 49 node [shape=rect, style=rounded]; 50 rankdir=LR; 51 52 libposix [fillcolor="#d5e8d4"]; 53 libzfoo [fillcolor="#dae8fc"]; 54 55 libposix -> libzfoo; 56 libzfoo -> libposix; 57 } 58 59.. graphviz:: 60 :caption: Mutual dependencies between POSIX and other Zephyr libraries 61 62 digraph { 63 node [shape=rect, style=rounded]; 64 rankdir=LR; 65 66 libposix [fillcolor="#d5e8d4"]; 67 libzfoo [fillcolor="#dae8fc"]; 68 libcommon [fillcolor="#f8cecc"]; 69 70 libposix -> libzfoo; 71 libposix -> libcommon; 72 libzfoo -> libcommon; 73 } 74 75- POSIX API calls should be provided as regular callable C functions; if a Zephyr 76 `System Call <syscalls>` is needed as part of the implementation, the declaration and the 77 implementation of that system call should be hidden behind the POSIX API. 78