docs: Tweaks to OS abstraction layer doc

This makes some minor tweaks to the OS abstraction layer doc; including
adding links to OS references, re-ordering some tables for clarity,
shortening section tames to tame the sidebar width, and rewording the
execution contexts section.

Change-Id: Ide8ad540ff3adf56deb494e4b427f2363cd62adc
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/45182
Pigweed-Auto-Submit: Keir Mierle <keir@google.com>
Reviewed-by: Ewout van Bekkum <ewout@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
This commit is contained in:
Keir Mierle 2021-05-13 10:36:48 -07:00 committed by CQ Bot Account
parent 0dbff30e16
commit 3a3d463561

View File

@ -3,9 +3,9 @@
===================== =====================
OS Abstraction Layers OS Abstraction Layers
===================== =====================
Pigweeds operating system abstraction layers are configurable building blocks. Pigweeds operating system abstraction layers are portable and configurable
They are designed to be lightweight, portable, and easy to use while giving building blocks, giving users full control while maintaining high performance
users full control and configurability. and low overhead.
Although we primarily target smaller-footprint MMU-less 32-bit microcontrollers, Although we primarily target smaller-footprint MMU-less 32-bit microcontrollers,
the OS abstraction layers are written to work on everything from single-core the OS abstraction layers are written to work on everything from single-core
@ -14,43 +14,38 @@ symmetric multiprocessing (SMP) embedded systems using Real Time Operating
Systems (RTOS). They even fully work on your developer workstation on Linux, Systems (RTOS). They even fully work on your developer workstation on Linux,
Windows, or MacOS! Windows, or MacOS!
Pigweed has ports for the following systems:
.. list-table:: .. list-table::
* - **Environment** * - **Environment**
- **Status** - **Status**
* - FreeRTOS * - STL (Mac, Window, & Linux)
- Supported - **✔ Supported**
* - ThreadX * - `FreeRTOS <https://www.freertos.org/>`_
- Supported - **✔ Supported**
* - embOS * - `Azure RTOS (formerly ThreadX) <https://azure.microsoft.com/en-us/services/rtos/>`_
- **✔ Supported**
* - `SEGGER embOS <https://www.segger.com/products/rtos/embos/>`_
- *In Progress* - *In Progress*
* - STL
- Supported
* - Zephyr
- Planned
* - CMSIS-RTOS API v2 & RTX5
- Planned
* - Baremetal * - Baremetal
- *In Progress* - *In Progress*
* - `Zephyr <https://www.zephyrproject.org/>`_
- Planned
* - `CMSIS-RTOS API v2 & RTX5 <https://www.keil.com/pack/doc/CMSIS/RTOS2/html/index.html>`_
- Planned
.. contents:: Pigweed's OS abstraction layers are divided by the **functional grouping of the
:local: primitives**. Many of our APIs are similar or **nearly identical to C++'s
:depth: 1 Standard Template Library (STL)** with the notable exception that we do not
support exceptions. We opted to follow the STL's APIs partially because they
are relatively well thought out and many developers are already familiar with
them, but also because this means they are compatible with existing helpers in
the STL; for example, ``std::lock_guard``.
------------- ---------------
OS Primitives Time Primitives
------------- ---------------
Pigweed's OS abstraction layers are divided by the functional grouping of the
primitives. Many of our APIs are similar or nearly identical to C++'s Standard
Template Library (STL) with the notable exception that we do not support
exceptions. We opted to follow the STL's APIs partially because they are
relatively well thought out and many developers are already familiar with them,
but also because this means they are compatible with existing helpers in the STL
which can then be further leveraged.
---------------------------
pw_chrono - Time Primitives
---------------------------
The :ref:`module-pw_chrono` module provides the building blocks for expressing The :ref:`module-pw_chrono` module provides the building blocks for expressing
durations, timestamps, and acquiring the current time. This in turn is used by durations, timestamps, and acquiring the current time. This in turn is used by
other modules, including :ref:`module-pw_sync` and :ref:`module-pw_thread` as other modules, including :ref:`module-pw_sync` and :ref:`module-pw_thread` as
@ -77,8 +72,8 @@ that this module is optional and bare metal targets may opt not to use this.
- Planned - Planned
SystemClock System Clock
=========== ============
For RTOS and HAL interactions, we provide a ``pw::chrono::SystemClock`` facade For RTOS and HAL interactions, we provide a ``pw::chrono::SystemClock`` facade
which provides 64 bit timestamps and duration support along with a C API. For which provides 64 bit timestamps and duration support along with a C API. For
C++ there is an optional virtual wrapper, ``pw::chrono::VirtualSystemClock``, C++ there is an optional virtual wrapper, ``pw::chrono::VirtualSystemClock``,
@ -108,9 +103,9 @@ particular clock, Pigweed's time bound APIs are strongly typed to use the
return SystemClock::now() > timestamp; return SystemClock::now() > timestamp;
} }
------------------------------------ --------------------------
pw_sync - Synchronization Primitives Synchronization Primitives
------------------------------------ --------------------------
The :ref:`module-pw_sync` provides the building blocks for synchronizing between The :ref:`module-pw_sync` provides the building blocks for synchronizing between
threads and/or interrupts through signaling primitives and critical section lock threads and/or interrupts through signaling primitives and critical section lock
primitives. primitives.
@ -306,9 +301,9 @@ with an arbitrary token limit of 1, meaning it's either full or empty.
result_ready_semaphore.acquire(); result_ready_semaphore.acquire();
} }
-------------------------------- --------------------
pw_thread - Threading Primitives Threading Primitives
-------------------------------- --------------------
The :ref:`module-pw_thread` module provides the building blocks for creating and The :ref:`module-pw_thread` module provides the building blocks for creating and
using threads including yielding and sleeping. using threads including yielding and sleeping.
@ -379,17 +374,15 @@ yielding the current thread.
} }
} }
-------------------------------------------- ------------------
Execution Contexts & Thread-Safety API Model Execution Contexts
-------------------------------------------- ------------------
The explosion of real contexts is too large for Pigweed to fully cover in a way Code runs in *execution contexts*. Common examples of execution contexts on
that provides value. First there are many more contexts than just threads and microcontrollers are **thread context** and **interrupt context**, though there
IRQ handlers on microcontrollers, there are many more meta contexts like are others. Since OS abstactions deal with concurrency, it's important to
non-blocking thread callbacks which may have scheduling and/or interrupts masked understand what API primitives are safe to call in what contexts. Since the
to some degree. On top of this some environments like in userspace may not even number of execution contexts is too large for Pigweed to cover exhaustively,
have interrupts and instead deal with signals. Instead we use the following Pigweed has the following classes of APIs:
simplified execution thread-safety model which our APIs should be ported to
support regardless of the real contexts they are executed in:
**Thread Safe APIs** - These APIs are safe to use in any execution context where **Thread Safe APIs** - These APIs are safe to use in any execution context where
one can use blocking or yielding APIs such as sleeping, blocking on a mutex one can use blocking or yielding APIs such as sleeping, blocking on a mutex
@ -408,25 +401,35 @@ can be used in any execution context which cannot use blocking or yielding APIs.
In addition, these may be used by interrupts which are not masked when for In addition, these may be used by interrupts which are not masked when for
example holding a SpinLock like CPU exceptions or C++/POSIX signals. These tend example holding a SpinLock like CPU exceptions or C++/POSIX signals. These tend
to come with significant overhead and restrictions compared to regular interrupt to come with significant overhead and restrictions compared to regular interrupt
safe APIs as they cannot rely on critical sections for implementations, instead safe APIs as they **cannot rely on critical sections**, instead
only atomic signaling can be used. An interrupt safe API may always be safely only atomic signaling can be used. An interrupt safe API may always be
used in a context which permits interrupt safe and thread safe APIs. used in a context which permits interrupt safe and thread safe APIs.
Instead of going with context specific APIs, e.g. FreeRTOS's ``*FromISR()`` On naming
APIs, Pigweed opted to go with the merged (context agnostic) API which validates =========
the context requirements through ``DASSERT`` and ``DCHECK`` in the backends Instead of having context specific APIs like FreeRTOS's ``...FromISR()``,
(user configurable). We did this primarily for two reasons. The explosion of Pigweed has a single API which validates the context requirements through
real contexts is too large for Pigweed to fully cover as mentioned above, ``DASSERT`` and ``DCHECK`` in the backends (user configurable). We did this for
meaning there would likely have to be some context aware multiplexing with our a few reasons:
simplified thread safety model split APIs. Second, we would recommend a
``DHCECK`` to enforce context requirements regardless, so we've opted with a
simplest API which also happens to match both the C++'s STL and Google's Abseil
relatively closely.
--------------------------------------------------- #. **Too many contexts** - Since there are contexts beyond just thread,
Construction Requirements & Initialization Paradigm interrupt, and NMI, having context-specefic APIs would be a hard to
--------------------------------------------------- maintain. The proliferation of postfixed APIs (``...FromISR``,
``...FromNMI``, ``...FromThreadCriticalSection``, and so on) would also be
confusing for users.
#. **Must verify context anyway** - Backends are requried to enforce context
requirements with ``DHCECK`` or related calls, so we chose a simple API
which happens to match both the C++'s STL and Google's Abseil.
#. **Multi-context code** - Code running in multiple contexts would need to be
duplicated for each context if the APIs were postfixed, or duplicated with
macros. The authors chose the duplication/macro route in previous projects
and found it clunky and hard to maintain.
-----------------------------
Construction & Initialization
-----------------------------
**TL;DR: Pigweed OS primitives are initialized through C++ construction.** **TL;DR: Pigweed OS primitives are initialized through C++ construction.**
We have chosen to go with a model which initializes the synchronization We have chosen to go with a model which initializes the synchronization