xref: /aosp_15_r20/external/pigweed/docs/os/index.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _docs-os:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker==========
4*61c4878aSAndroid Build Coastguard WorkerOS support
5*61c4878aSAndroid Build Coastguard Worker==========
6*61c4878aSAndroid Build Coastguard Worker
7*61c4878aSAndroid Build Coastguard Worker.. toctree::
8*61c4878aSAndroid Build Coastguard Worker   :hidden:
9*61c4878aSAndroid Build Coastguard Worker
10*61c4878aSAndroid Build Coastguard Worker   zephyr/index
11*61c4878aSAndroid Build Coastguard Worker
12*61c4878aSAndroid Build Coastguard WorkerPigweed’s operating system abstraction layers are portable and configurable
13*61c4878aSAndroid Build Coastguard Workerbuilding blocks, giving users full control while maintaining high performance
14*61c4878aSAndroid Build Coastguard Workerand low overhead.
15*61c4878aSAndroid Build Coastguard Worker
16*61c4878aSAndroid Build Coastguard WorkerAlthough we primarily target smaller-footprint MMU-less 32-bit microcontrollers,
17*61c4878aSAndroid Build Coastguard Workerthe OS abstraction layers are written to work on everything from single-core
18*61c4878aSAndroid Build Coastguard Workerbare metal low end microcontrollers to asymmetric multiprocessing (AMP) and
19*61c4878aSAndroid Build Coastguard Workersymmetric multiprocessing (SMP) embedded systems using Real Time Operating
20*61c4878aSAndroid Build Coastguard WorkerSystems (RTOS). They even fully work on your developer workstation on Linux,
21*61c4878aSAndroid Build Coastguard WorkerWindows, or MacOS!
22*61c4878aSAndroid Build Coastguard Worker
23*61c4878aSAndroid Build Coastguard WorkerPigweed has ports for the following systems:
24*61c4878aSAndroid Build Coastguard Worker
25*61c4878aSAndroid Build Coastguard Worker.. list-table::
26*61c4878aSAndroid Build Coastguard Worker
27*61c4878aSAndroid Build Coastguard Worker  * - **Environment**
28*61c4878aSAndroid Build Coastguard Worker    - **Status**
29*61c4878aSAndroid Build Coastguard Worker  * - STL (Mac, Window, & Linux)
30*61c4878aSAndroid Build Coastguard Worker    - **✔ Supported**
31*61c4878aSAndroid Build Coastguard Worker  * - `FreeRTOS <https://www.freertos.org/>`_
32*61c4878aSAndroid Build Coastguard Worker    - **✔ Supported**
33*61c4878aSAndroid Build Coastguard Worker  * - :ref:`Zephyr <docs-os-zephyr>`
34*61c4878aSAndroid Build Coastguard Worker    - **✔ Supported**
35*61c4878aSAndroid Build Coastguard Worker  * - `Azure RTOS (formerly ThreadX) <https://azure.microsoft.com/en-us/services/rtos/>`_
36*61c4878aSAndroid Build Coastguard Worker    - **✔ Supported**
37*61c4878aSAndroid Build Coastguard Worker  * - `SEGGER embOS <https://www.segger.com/products/rtos/embos/>`_
38*61c4878aSAndroid Build Coastguard Worker    - **✔ Supported**
39*61c4878aSAndroid Build Coastguard Worker  * - Baremetal
40*61c4878aSAndroid Build Coastguard Worker    - *In Progress*
41*61c4878aSAndroid Build Coastguard Worker
42*61c4878aSAndroid Build Coastguard WorkerPigweed's OS abstraction layers are divided by the **functional grouping of the
43*61c4878aSAndroid Build Coastguard Workerprimitives**. Many of our APIs are similar or **nearly identical to C++'s
44*61c4878aSAndroid Build Coastguard WorkerStandard Template Library (STL)** with the notable exception that we do not
45*61c4878aSAndroid Build Coastguard Workersupport exceptions. We opted to follow the STL's APIs partially because they
46*61c4878aSAndroid Build Coastguard Workerare relatively well thought out and many developers are already familiar with
47*61c4878aSAndroid Build Coastguard Workerthem, but also because this means they are compatible with existing helpers in
48*61c4878aSAndroid Build Coastguard Workerthe STL; for example, ``std::lock_guard``.
49*61c4878aSAndroid Build Coastguard Worker
50*61c4878aSAndroid Build Coastguard Worker---------------
51*61c4878aSAndroid Build Coastguard WorkerTime Primitives
52*61c4878aSAndroid Build Coastguard Worker---------------
53*61c4878aSAndroid Build Coastguard WorkerThe :ref:`module-pw_chrono` module provides the building blocks for expressing
54*61c4878aSAndroid Build Coastguard Workerdurations, timestamps, and acquiring the current time. This in turn is used by
55*61c4878aSAndroid Build Coastguard Workerother modules, including  :ref:`module-pw_sync` and :ref:`module-pw_thread` as
56*61c4878aSAndroid Build Coastguard Workerthe basis for any time bound APIs (i.e. with timeouts and/or deadlines). Note
57*61c4878aSAndroid Build Coastguard Workerthat this module is optional and bare metal targets may opt not to use this.
58*61c4878aSAndroid Build Coastguard Worker
59*61c4878aSAndroid Build Coastguard Worker.. list-table::
60*61c4878aSAndroid Build Coastguard Worker
61*61c4878aSAndroid Build Coastguard Worker  * - **Supported On**
62*61c4878aSAndroid Build Coastguard Worker    - **SystemClock**
63*61c4878aSAndroid Build Coastguard Worker  * - FreeRTOS
64*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_chrono_freertos`
65*61c4878aSAndroid Build Coastguard Worker  * - Zephyr
66*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_chrono_zephyr`
67*61c4878aSAndroid Build Coastguard Worker  * - ThreadX
68*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_chrono_threadx`
69*61c4878aSAndroid Build Coastguard Worker  * - embOS
70*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_chrono_embos`
71*61c4878aSAndroid Build Coastguard Worker  * - STL
72*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_chrono_stl`
73*61c4878aSAndroid Build Coastguard Worker  * - Baremetal
74*61c4878aSAndroid Build Coastguard Worker    - Planned
75*61c4878aSAndroid Build Coastguard Worker
76*61c4878aSAndroid Build Coastguard Worker
77*61c4878aSAndroid Build Coastguard WorkerSystem Clock
78*61c4878aSAndroid Build Coastguard Worker============
79*61c4878aSAndroid Build Coastguard WorkerFor RTOS and HAL interactions, we provide a ``pw::chrono::SystemClock`` facade
80*61c4878aSAndroid Build Coastguard Workerwhich provides 64 bit timestamps and duration support along with a C API. For
81*61c4878aSAndroid Build Coastguard WorkerC++ there is an optional virtual wrapper, ``pw::chrono::VirtualSystemClock``,
82*61c4878aSAndroid Build Coastguard Workeraround the singleton clock facade to enable dependency injection.
83*61c4878aSAndroid Build Coastguard Worker
84*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
85*61c4878aSAndroid Build Coastguard Worker
86*61c4878aSAndroid Build Coastguard Worker   #include <chrono>
87*61c4878aSAndroid Build Coastguard Worker
88*61c4878aSAndroid Build Coastguard Worker   #include "pw_thread/sleep.h"
89*61c4878aSAndroid Build Coastguard Worker
90*61c4878aSAndroid Build Coastguard Worker   using namespace std::literals::chrono_literals;
91*61c4878aSAndroid Build Coastguard Worker
92*61c4878aSAndroid Build Coastguard Worker   void ThisSleeps() {
93*61c4878aSAndroid Build Coastguard Worker     pw::thread::sleep_for(42ms);
94*61c4878aSAndroid Build Coastguard Worker   }
95*61c4878aSAndroid Build Coastguard Worker
96*61c4878aSAndroid Build Coastguard WorkerUnlike the STL's time bound templated APIs which are not specific to a
97*61c4878aSAndroid Build Coastguard Workerparticular clock, Pigweed's time bound APIs are strongly typed to use the
98*61c4878aSAndroid Build Coastguard Worker``pw::chrono::SystemClock``'s ``duration`` and ``time_points`` directly.
99*61c4878aSAndroid Build Coastguard Worker
100*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
101*61c4878aSAndroid Build Coastguard Worker
102*61c4878aSAndroid Build Coastguard Worker   #include "pw_chrono/system_clock.h"
103*61c4878aSAndroid Build Coastguard Worker
104*61c4878aSAndroid Build Coastguard Worker   bool HasThisPointInTimePassed(const SystemClock::time_point timestamp) {
105*61c4878aSAndroid Build Coastguard Worker     return SystemClock::now() > timestamp;
106*61c4878aSAndroid Build Coastguard Worker   }
107*61c4878aSAndroid Build Coastguard Worker
108*61c4878aSAndroid Build Coastguard Worker--------------------------
109*61c4878aSAndroid Build Coastguard WorkerSynchronization Primitives
110*61c4878aSAndroid Build Coastguard Worker--------------------------
111*61c4878aSAndroid Build Coastguard WorkerThe :ref:`module-pw_sync` provides the building blocks for synchronizing between
112*61c4878aSAndroid Build Coastguard Workerthreads and/or interrupts through signaling primitives and critical section lock
113*61c4878aSAndroid Build Coastguard Workerprimitives.
114*61c4878aSAndroid Build Coastguard Worker
115*61c4878aSAndroid Build Coastguard WorkerCritical Section Lock Primitives
116*61c4878aSAndroid Build Coastguard Worker================================
117*61c4878aSAndroid Build Coastguard WorkerPigweed's locks support Clang's thread safety lock annotations and the STL's
118*61c4878aSAndroid Build Coastguard WorkerRAII helpers.
119*61c4878aSAndroid Build Coastguard Worker
120*61c4878aSAndroid Build Coastguard Worker.. list-table::
121*61c4878aSAndroid Build Coastguard Worker
122*61c4878aSAndroid Build Coastguard Worker  * - **Supported On**
123*61c4878aSAndroid Build Coastguard Worker    - **Mutex**
124*61c4878aSAndroid Build Coastguard Worker    - **TimedMutex**
125*61c4878aSAndroid Build Coastguard Worker    - **InterruptSpinLock**
126*61c4878aSAndroid Build Coastguard Worker  * - FreeRTOS
127*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_freertos`
128*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_freertos`
129*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_freertos`
130*61c4878aSAndroid Build Coastguard Worker  * - Zephyr
131*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_zephyr`
132*61c4878aSAndroid Build Coastguard Worker    - Planned
133*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_zephyr`
134*61c4878aSAndroid Build Coastguard Worker  * - ThreadX
135*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_threadx`
136*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_threadx`
137*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_threadx`
138*61c4878aSAndroid Build Coastguard Worker  * - embOS
139*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_embos`
140*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_embos`
141*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_embos`
142*61c4878aSAndroid Build Coastguard Worker  * - STL
143*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_stl`
144*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_stl`
145*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_stl`
146*61c4878aSAndroid Build Coastguard Worker  * - Baremetal
147*61c4878aSAndroid Build Coastguard Worker    - Planned, not ready for use
148*61c4878aSAndroid Build Coastguard Worker    - ✗
149*61c4878aSAndroid Build Coastguard Worker    - Planned, not ready for use
150*61c4878aSAndroid Build Coastguard Worker
151*61c4878aSAndroid Build Coastguard Worker
152*61c4878aSAndroid Build Coastguard WorkerThread Safe Mutex
153*61c4878aSAndroid Build Coastguard Worker-----------------
154*61c4878aSAndroid Build Coastguard WorkerThe ``pw::sync::Mutex`` protects shared data from being simultaneously accessed
155*61c4878aSAndroid Build Coastguard Workerby multiple threads. Optionally, the ``pw::sync::TimedMutex`` can be used as an
156*61c4878aSAndroid Build Coastguard Workerextension with timeout and deadline based semantics.
157*61c4878aSAndroid Build Coastguard Worker
158*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
159*61c4878aSAndroid Build Coastguard Worker
160*61c4878aSAndroid Build Coastguard Worker   #include <mutex>
161*61c4878aSAndroid Build Coastguard Worker
162*61c4878aSAndroid Build Coastguard Worker   #include "pw_sync/mutex.h"
163*61c4878aSAndroid Build Coastguard Worker
164*61c4878aSAndroid Build Coastguard Worker   pw::sync::Mutex mutex;
165*61c4878aSAndroid Build Coastguard Worker
166*61c4878aSAndroid Build Coastguard Worker   void ThreadSafeCriticalSection() {
167*61c4878aSAndroid Build Coastguard Worker     std::lock_guard lock(mutex);
168*61c4878aSAndroid Build Coastguard Worker     NotThreadSafeCriticalSection();
169*61c4878aSAndroid Build Coastguard Worker   }
170*61c4878aSAndroid Build Coastguard Worker
171*61c4878aSAndroid Build Coastguard WorkerInterrupt Safe InterruptSpinLock
172*61c4878aSAndroid Build Coastguard Worker--------------------------------
173*61c4878aSAndroid Build Coastguard WorkerThe ``pw::sync::InterruptSpinLock`` protects shared data from being
174*61c4878aSAndroid Build Coastguard Workersimultaneously accessed by multiple threads and/or interrupts as a targeted
175*61c4878aSAndroid Build Coastguard Workerglobal lock, with the exception of Non-Maskable Interrupts (NMIs). Unlike global
176*61c4878aSAndroid Build Coastguard Workerinterrupt locks, this also works safely and efficiently on SMP systems.
177*61c4878aSAndroid Build Coastguard Worker
178*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
179*61c4878aSAndroid Build Coastguard Worker
180*61c4878aSAndroid Build Coastguard Worker   #include <mutex>
181*61c4878aSAndroid Build Coastguard Worker
182*61c4878aSAndroid Build Coastguard Worker   #include "pw_sync/interrupt_spin_lock.h"
183*61c4878aSAndroid Build Coastguard Worker
184*61c4878aSAndroid Build Coastguard Worker   pw::sync::InterruptSpinLock interrupt_spin_lock;
185*61c4878aSAndroid Build Coastguard Worker
186*61c4878aSAndroid Build Coastguard Worker   void InterruptSafeCriticalSection() {
187*61c4878aSAndroid Build Coastguard Worker     std::lock_guard lock(interrupt_spin_lock);
188*61c4878aSAndroid Build Coastguard Worker     NotThreadSafeCriticalSection();
189*61c4878aSAndroid Build Coastguard Worker   }
190*61c4878aSAndroid Build Coastguard Worker
191*61c4878aSAndroid Build Coastguard WorkerSignaling Primitives
192*61c4878aSAndroid Build Coastguard Worker====================
193*61c4878aSAndroid Build Coastguard WorkerNative signaling primitives tend to vary more compared to critical section locks
194*61c4878aSAndroid Build Coastguard Workeracross different platforms. For example, although common signaling primitives
195*61c4878aSAndroid Build Coastguard Workerlike semaphores are in most if not all RTOSes and even POSIX, it was not in the
196*61c4878aSAndroid Build Coastguard WorkerSTL before C++20. Likewise many C++ developers are surprised that conditional
197*61c4878aSAndroid Build Coastguard Workervariables tend to not be natively supported on RTOSes. Although you can usually
198*61c4878aSAndroid Build Coastguard Workerbuild any signaling primitive based on other native signaling primitives,
199*61c4878aSAndroid Build Coastguard Workerthis may come with non-trivial added overhead in ROM, RAM, and execution
200*61c4878aSAndroid Build Coastguard Workerefficiency.
201*61c4878aSAndroid Build Coastguard Worker
202*61c4878aSAndroid Build Coastguard WorkerFor this reason, Pigweed intends to provide some simpler signaling primitives
203*61c4878aSAndroid Build Coastguard Workerwhich exist to solve a narrow programming need but can be implemented as
204*61c4878aSAndroid Build Coastguard Workerefficiently as possible for the platform that it is used on. This simpler but
205*61c4878aSAndroid Build Coastguard Workerhighly portable class of signaling primitives is intended to ensure that a
206*61c4878aSAndroid Build Coastguard Workerportability efficiency tradeoff does not have to be made up front.
207*61c4878aSAndroid Build Coastguard Worker
208*61c4878aSAndroid Build Coastguard Worker.. list-table::
209*61c4878aSAndroid Build Coastguard Worker
210*61c4878aSAndroid Build Coastguard Worker  * - **Supported On**
211*61c4878aSAndroid Build Coastguard Worker    - **ThreadNotification**
212*61c4878aSAndroid Build Coastguard Worker    - **TimedThreadNotification**
213*61c4878aSAndroid Build Coastguard Worker    - **CountingSemaphore**
214*61c4878aSAndroid Build Coastguard Worker    - **BinarySemaphore**
215*61c4878aSAndroid Build Coastguard Worker  * - FreeRTOS
216*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_freertos`
217*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_freertos`
218*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_freertos`
219*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_freertos`
220*61c4878aSAndroid Build Coastguard Worker  * - Zephyr
221*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_stl`
222*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_stl`
223*61c4878aSAndroid Build Coastguard Worker    - Planned
224*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_stl`
225*61c4878aSAndroid Build Coastguard Worker  * - ThreadX
226*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_threadx`
227*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_threadx`
228*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_threadx`
229*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_threadx`
230*61c4878aSAndroid Build Coastguard Worker  * - embOS
231*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_embos`
232*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_embos`
233*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_embos`
234*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_embos`
235*61c4878aSAndroid Build Coastguard Worker  * - STL
236*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_stl`
237*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_stl`
238*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_stl`
239*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_sync_stl`
240*61c4878aSAndroid Build Coastguard Worker  * - Baremetal
241*61c4878aSAndroid Build Coastguard Worker    - Planned
242*61c4878aSAndroid Build Coastguard Worker    - ✗
243*61c4878aSAndroid Build Coastguard Worker    - TBD
244*61c4878aSAndroid Build Coastguard Worker    - TBD
245*61c4878aSAndroid Build Coastguard Worker
246*61c4878aSAndroid Build Coastguard WorkerThread Notification
247*61c4878aSAndroid Build Coastguard Worker-------------------
248*61c4878aSAndroid Build Coastguard WorkerPigweed intends to provide the ``pw::sync::ThreadNotification`` and
249*61c4878aSAndroid Build Coastguard Worker``pw::sync::TimedThreadNotification`` facades which permit a single consumer to
250*61c4878aSAndroid Build Coastguard Workerblock until an event occurs. This should be backed by the most efficient native
251*61c4878aSAndroid Build Coastguard Workerprimitive for a target, regardless of whether that is a semaphore, event flag
252*61c4878aSAndroid Build Coastguard Workergroup, condition variable, direct task notification with a critical section, or
253*61c4878aSAndroid Build Coastguard Workersomething else.
254*61c4878aSAndroid Build Coastguard Worker
255*61c4878aSAndroid Build Coastguard WorkerCounting Semaphore
256*61c4878aSAndroid Build Coastguard Worker------------------
257*61c4878aSAndroid Build Coastguard WorkerThe ``pw::sync::CountingSemaphore`` is a synchronization primitive that can be
258*61c4878aSAndroid Build Coastguard Workerused for counting events and/or resource management where receiver(s) can block
259*61c4878aSAndroid Build Coastguard Workeron acquire until notifier(s) signal by invoking release.
260*61c4878aSAndroid Build Coastguard Worker
261*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
262*61c4878aSAndroid Build Coastguard Worker
263*61c4878aSAndroid Build Coastguard Worker   #include "pw_sync/counting_semaphore.h"
264*61c4878aSAndroid Build Coastguard Worker
265*61c4878aSAndroid Build Coastguard Worker   pw::sync::CountingSemaphore event_semaphore;
266*61c4878aSAndroid Build Coastguard Worker
267*61c4878aSAndroid Build Coastguard Worker   void NotifyEventOccurred() {
268*61c4878aSAndroid Build Coastguard Worker     event_semaphore.release();
269*61c4878aSAndroid Build Coastguard Worker   }
270*61c4878aSAndroid Build Coastguard Worker
271*61c4878aSAndroid Build Coastguard Worker   void HandleEventsForever() {
272*61c4878aSAndroid Build Coastguard Worker     while (true) {
273*61c4878aSAndroid Build Coastguard Worker       event_semaphore.acquire();
274*61c4878aSAndroid Build Coastguard Worker       HandleEvent();
275*61c4878aSAndroid Build Coastguard Worker     }
276*61c4878aSAndroid Build Coastguard Worker   }
277*61c4878aSAndroid Build Coastguard Worker
278*61c4878aSAndroid Build Coastguard WorkerBinary Semaphore
279*61c4878aSAndroid Build Coastguard Worker----------------
280*61c4878aSAndroid Build Coastguard WorkerThe ``pw::sync::BinarySemaphore`` is a specialization of the counting semaphore
281*61c4878aSAndroid Build Coastguard Workerwith an arbitrary token limit of 1, meaning it's either full or empty.
282*61c4878aSAndroid Build Coastguard Worker
283*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
284*61c4878aSAndroid Build Coastguard Worker
285*61c4878aSAndroid Build Coastguard Worker   #include "pw_sync/binary_semaphore.h"
286*61c4878aSAndroid Build Coastguard Worker
287*61c4878aSAndroid Build Coastguard Worker   pw::sync::BinarySemaphore do_foo_semaphore;
288*61c4878aSAndroid Build Coastguard Worker
289*61c4878aSAndroid Build Coastguard Worker   void NotifyResultReady() {
290*61c4878aSAndroid Build Coastguard Worker     result_ready_semaphore.release();
291*61c4878aSAndroid Build Coastguard Worker   }
292*61c4878aSAndroid Build Coastguard Worker
293*61c4878aSAndroid Build Coastguard Worker   void BlockUntilResultReady() {
294*61c4878aSAndroid Build Coastguard Worker     result_ready_semaphore.acquire();
295*61c4878aSAndroid Build Coastguard Worker   }
296*61c4878aSAndroid Build Coastguard Worker
297*61c4878aSAndroid Build Coastguard Worker--------------------
298*61c4878aSAndroid Build Coastguard WorkerThreading Primitives
299*61c4878aSAndroid Build Coastguard Worker--------------------
300*61c4878aSAndroid Build Coastguard WorkerThe :ref:`module-pw_thread` module provides the building blocks for creating and
301*61c4878aSAndroid Build Coastguard Workerusing threads including yielding and sleeping.
302*61c4878aSAndroid Build Coastguard Worker
303*61c4878aSAndroid Build Coastguard Worker.. list-table::
304*61c4878aSAndroid Build Coastguard Worker
305*61c4878aSAndroid Build Coastguard Worker  * - **Supported On**
306*61c4878aSAndroid Build Coastguard Worker    - **Thread Creation**
307*61c4878aSAndroid Build Coastguard Worker    - **Thread Id/Sleep/Yield**
308*61c4878aSAndroid Build Coastguard Worker  * - FreeRTOS
309*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_thread_freertos`
310*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_thread_freertos`
311*61c4878aSAndroid Build Coastguard Worker  * - Zephyr
312*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_thread_zephyr`
313*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_thread_zephyr`
314*61c4878aSAndroid Build Coastguard Worker  * - ThreadX
315*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_thread_threadx`
316*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_thread_threadx`
317*61c4878aSAndroid Build Coastguard Worker  * - embOS
318*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_thread_embos`
319*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_thread_embos`
320*61c4878aSAndroid Build Coastguard Worker  * - STL
321*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_thread_stl`
322*61c4878aSAndroid Build Coastguard Worker    - :ref:`module-pw_thread_stl`
323*61c4878aSAndroid Build Coastguard Worker  * - Baremetal
324*61c4878aSAndroid Build Coastguard Worker    - ✗
325*61c4878aSAndroid Build Coastguard Worker    - ✗
326*61c4878aSAndroid Build Coastguard Worker
327*61c4878aSAndroid Build Coastguard WorkerThread Creation
328*61c4878aSAndroid Build Coastguard Worker===============
329*61c4878aSAndroid Build Coastguard WorkerThe :cpp:type:`pw::Thread`’s API is C++11 STL ``std::thread`` like. Unlike
330*61c4878aSAndroid Build Coastguard Worker``std::thread``, the Pigweed's API requires ``pw::thread::Options`` as an
331*61c4878aSAndroid Build Coastguard Workerargument for creating a thread. This is used to give the user full control over
332*61c4878aSAndroid Build Coastguard Workerthe native OS's threading options without getting in your way.
333*61c4878aSAndroid Build Coastguard Worker
334*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
335*61c4878aSAndroid Build Coastguard Worker
336*61c4878aSAndroid Build Coastguard Worker   #include "pw_thread/detached_thread.h"
337*61c4878aSAndroid Build Coastguard Worker   #include "pw_thread_freertos/context.h"
338*61c4878aSAndroid Build Coastguard Worker   #include "pw_thread_freertos/options.h"
339*61c4878aSAndroid Build Coastguard Worker
340*61c4878aSAndroid Build Coastguard Worker   pw::thread::freertos::ContextWithStack<42> example_thread_context;
341*61c4878aSAndroid Build Coastguard Worker
342*61c4878aSAndroid Build Coastguard Worker   void StartDetachedExampleThread() {
343*61c4878aSAndroid Build Coastguard Worker      pw::thread::DetachedThread(
344*61c4878aSAndroid Build Coastguard Worker        pw::thread::freertos::Options()
345*61c4878aSAndroid Build Coastguard Worker            .set_name("static_example_thread")
346*61c4878aSAndroid Build Coastguard Worker            .set_priority(kFooPriority)
347*61c4878aSAndroid Build Coastguard Worker            .set_static_context(example_thread_context),
348*61c4878aSAndroid Build Coastguard Worker        example_thread_function);
349*61c4878aSAndroid Build Coastguard Worker   }
350*61c4878aSAndroid Build Coastguard Worker
351*61c4878aSAndroid Build Coastguard WorkerControlling the current thread
352*61c4878aSAndroid Build Coastguard Worker==============================
353*61c4878aSAndroid Build Coastguard WorkerBeyond thread creation, Pigweed offers support for sleeping, identifying, and
354*61c4878aSAndroid Build Coastguard Workeryielding the current thread.
355*61c4878aSAndroid Build Coastguard Worker
356*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
357*61c4878aSAndroid Build Coastguard Worker
358*61c4878aSAndroid Build Coastguard Worker   #include "pw_thread/yield.h"
359*61c4878aSAndroid Build Coastguard Worker
360*61c4878aSAndroid Build Coastguard Worker   void CooperativeBusyLooper() {
361*61c4878aSAndroid Build Coastguard Worker     while (true) {
362*61c4878aSAndroid Build Coastguard Worker       DoChunkOfWork();
363*61c4878aSAndroid Build Coastguard Worker       pw::this_thread::yield();
364*61c4878aSAndroid Build Coastguard Worker     }
365*61c4878aSAndroid Build Coastguard Worker   }
366*61c4878aSAndroid Build Coastguard Worker
367*61c4878aSAndroid Build Coastguard Worker------------------
368*61c4878aSAndroid Build Coastguard WorkerExecution Contexts
369*61c4878aSAndroid Build Coastguard Worker------------------
370*61c4878aSAndroid Build Coastguard WorkerCode runs in *execution contexts*. Common examples of execution contexts on
371*61c4878aSAndroid Build Coastguard Workermicrocontrollers are **thread context** and **interrupt context**, though there
372*61c4878aSAndroid Build Coastguard Workerare others. Since OS abstractions deal with concurrency, it's important to
373*61c4878aSAndroid Build Coastguard Workerunderstand what API primitives are safe to call in what contexts.  Since the
374*61c4878aSAndroid Build Coastguard Workernumber of execution contexts is too large for Pigweed to cover exhaustively,
375*61c4878aSAndroid Build Coastguard WorkerPigweed has the following classes of APIs:
376*61c4878aSAndroid Build Coastguard Worker
377*61c4878aSAndroid Build Coastguard Worker**Thread Safe APIs** - These APIs are safe to use in any execution context where
378*61c4878aSAndroid Build Coastguard Workerone can use blocking or yielding APIs such as sleeping, blocking on a mutex
379*61c4878aSAndroid Build Coastguard Workerwaiting on a semaphore.
380*61c4878aSAndroid Build Coastguard Worker
381*61c4878aSAndroid Build Coastguard Worker**Interrupt (IRQ) Safe APIs** - These APIs can be used in any execution context
382*61c4878aSAndroid Build Coastguard Workerwhich cannot use blocking and yielding APIs. These APIs must protect themselves
383*61c4878aSAndroid Build Coastguard Workerfrom preemption from maskable interrupts, etc. This includes critical section
384*61c4878aSAndroid Build Coastguard Workerthread contexts in addition to "real" interrupt contexts. Our definition
385*61c4878aSAndroid Build Coastguard Workerexplicitly excludes any interrupts which are not masked when holding a SpinLock,
386*61c4878aSAndroid Build Coastguard Workerthose are all considered non-maskable interrupts. An interrupt safe API may
387*61c4878aSAndroid Build Coastguard Workeralways be safely used in a context which permits thread safe APIs.
388*61c4878aSAndroid Build Coastguard Worker
389*61c4878aSAndroid Build Coastguard Worker**Non-Maskable Interrupt (NMI) Safe APIs** - Like the Interrupt Safe APIs, these
390*61c4878aSAndroid Build Coastguard Workercan be used in any execution context which cannot use blocking or yielding APIs.
391*61c4878aSAndroid Build Coastguard WorkerIn addition, these may be used by interrupts which are not masked when for
392*61c4878aSAndroid Build Coastguard Workerexample holding a SpinLock like CPU exceptions or C++/POSIX signals. These tend
393*61c4878aSAndroid Build Coastguard Workerto come with significant overhead and restrictions compared to regular interrupt
394*61c4878aSAndroid Build Coastguard Workersafe APIs as they **cannot rely on critical sections**, instead
395*61c4878aSAndroid Build Coastguard Workeronly atomic signaling can be used. An interrupt safe API may always be
396*61c4878aSAndroid Build Coastguard Workerused in a context which permits interrupt safe and thread safe APIs.
397*61c4878aSAndroid Build Coastguard Worker
398*61c4878aSAndroid Build Coastguard WorkerOn naming
399*61c4878aSAndroid Build Coastguard Worker=========
400*61c4878aSAndroid Build Coastguard WorkerInstead of having context specific APIs like FreeRTOS's ``...FromISR()``,
401*61c4878aSAndroid Build Coastguard WorkerPigweed has a single API which validates the context requirements through
402*61c4878aSAndroid Build Coastguard Worker``DASSERT`` and ``DCHECK`` in the backends (user configurable). We did this for
403*61c4878aSAndroid Build Coastguard Workera few reasons:
404*61c4878aSAndroid Build Coastguard Worker
405*61c4878aSAndroid Build Coastguard Worker#. **Too many contexts** - Since there are contexts beyond just thread,
406*61c4878aSAndroid Build Coastguard Worker   interrupt, and NMI, having context-specific APIs would be a hard to
407*61c4878aSAndroid Build Coastguard Worker   maintain. The proliferation of postfixed APIs (``...FromISR``,
408*61c4878aSAndroid Build Coastguard Worker   ``...FromNMI``, ``...FromThreadCriticalSection``, and so on) would also be
409*61c4878aSAndroid Build Coastguard Worker   confusing for users.
410*61c4878aSAndroid Build Coastguard Worker
411*61c4878aSAndroid Build Coastguard Worker#. **Must verify context anyway** - Backends are required to enforce context
412*61c4878aSAndroid Build Coastguard Worker   requirements with ``DCHECK`` or related calls, so we chose a simple API
413*61c4878aSAndroid Build Coastguard Worker   which happens to match both the C++'s STL and Google's Abseil.
414*61c4878aSAndroid Build Coastguard Worker
415*61c4878aSAndroid Build Coastguard Worker#. **Multi-context code** - Code running in multiple contexts would need to be
416*61c4878aSAndroid Build Coastguard Worker   duplicated for each context if the APIs were postfixed, or duplicated with
417*61c4878aSAndroid Build Coastguard Worker   macros. The authors chose the duplication/macro route in previous projects
418*61c4878aSAndroid Build Coastguard Worker   and found it clunky and hard to maintain.
419*61c4878aSAndroid Build Coastguard Worker
420*61c4878aSAndroid Build Coastguard Worker-----------------------------
421*61c4878aSAndroid Build Coastguard WorkerConstruction & Initialization
422*61c4878aSAndroid Build Coastguard Worker-----------------------------
423*61c4878aSAndroid Build Coastguard Worker**TL;DR: Pigweed OS primitives are initialized through C++ construction.**
424*61c4878aSAndroid Build Coastguard Worker
425*61c4878aSAndroid Build Coastguard WorkerWe have chosen to go with a model which initializes the synchronization
426*61c4878aSAndroid Build Coastguard Workerprimitive during C++ object construction. This means that there is a requirement
427*61c4878aSAndroid Build Coastguard Workerin order for static instantiation to be safe that the user ensures that any
428*61c4878aSAndroid Build Coastguard Workernecessary kernel and/or platform initialization is done before the global static
429*61c4878aSAndroid Build Coastguard Workerconstructors are run which would include construction of the C++ synchronization
430*61c4878aSAndroid Build Coastguard Workerprimitives.
431*61c4878aSAndroid Build Coastguard Worker
432*61c4878aSAndroid Build Coastguard WorkerIn addition this model for now assumes that Pigweed code will always be used to
433*61c4878aSAndroid Build Coastguard Workerconstruct synchronization primitives used with Pigweed modules. Note that with
434*61c4878aSAndroid Build Coastguard Workerthis model the backend provider can decide if they want to statically
435*61c4878aSAndroid Build Coastguard Workerpreallocate space for the primitives or rely on dynamic allocation strategies.
436*61c4878aSAndroid Build Coastguard WorkerIf we discover at a later point that this is not sufficiently portable than we
437*61c4878aSAndroid Build Coastguard Workercan either produce an optional constructor that takes in a reference to an
438*61c4878aSAndroid Build Coastguard Workerexisting native synchronization type and wastes a little bit RAM or we can
439*61c4878aSAndroid Build Coastguard Workerrefactor the existing class into two layers where one is a StaticMutex for
440*61c4878aSAndroid Build Coastguard Workerexample and the other is a Mutex which only holds a handle to the native mutex
441*61c4878aSAndroid Build Coastguard Workertype. This would then permit users who cannot construct their synchronization
442*61c4878aSAndroid Build Coastguard Workerprimitives to skip the optional static layer.
443*61c4878aSAndroid Build Coastguard Worker
444*61c4878aSAndroid Build Coastguard WorkerKernel / Platform Initialization Before C++ Global Static Constructors
445*61c4878aSAndroid Build Coastguard Worker======================================================================
446*61c4878aSAndroid Build Coastguard WorkerWhat is this kernel and/or platform initialization that must be done first?
447*61c4878aSAndroid Build Coastguard Worker
448*61c4878aSAndroid Build Coastguard WorkerIt's not uncommon for an RTOS to require some initialization functions to be
449*61c4878aSAndroid Build Coastguard Workerinvoked before more of its API can be safely used. For example for CMSIS RTOSv2
450*61c4878aSAndroid Build Coastguard Worker``osKernelInitialize()`` must be invoked before anything but two basic getters
451*61c4878aSAndroid Build Coastguard Workerare called. Similarly, Segger's embOS requires ``OS_Init()`` to be invoked first
452*61c4878aSAndroid Build Coastguard Workerbefore any other embOS API.
453*61c4878aSAndroid Build Coastguard Worker
454*61c4878aSAndroid Build Coastguard Worker.. Note::
455*61c4878aSAndroid Build Coastguard Worker  To get around this one should invoke these initialization functions earlier
456*61c4878aSAndroid Build Coastguard Worker  and/or delay the static C++ constructors to meet this ordering requirement. As
457*61c4878aSAndroid Build Coastguard Worker  an example if you were using :ref:`module-pw_boot_cortex_m`, then
458*61c4878aSAndroid Build Coastguard Worker  ``pw_boot_PreStaticConstructorInit()`` would be a great place to invoke kernel
459*61c4878aSAndroid Build Coastguard Worker  initialization.
460*61c4878aSAndroid Build Coastguard Worker
461*61c4878aSAndroid Build Coastguard Worker-------
462*61c4878aSAndroid Build Coastguard WorkerRoadmap
463*61c4878aSAndroid Build Coastguard Worker-------
464*61c4878aSAndroid Build Coastguard WorkerPigweed is still actively expanding and improving its OS Abstraction Layers.
465*61c4878aSAndroid Build Coastguard WorkerThat being said, the following concrete areas are being worked on and can be
466*61c4878aSAndroid Build Coastguard Workerexpected to land at some point in the future:
467*61c4878aSAndroid Build Coastguard Worker
468*61c4878aSAndroid Build Coastguard Worker1. We'd like to offer a system clock based timer abstraction facade which can be
469*61c4878aSAndroid Build Coastguard Worker   used on either an RTOS or a hardware timer.
470*61c4878aSAndroid Build Coastguard Worker2. We are evaluating a less-portable but very useful portability facade for
471*61c4878aSAndroid Build Coastguard Worker   event flags / groups. This would make it even easier to ensure all firmware
472*61c4878aSAndroid Build Coastguard Worker   can be fully executed on the host.
473*61c4878aSAndroid Build Coastguard Worker3. Cooperative cancellation thread joining along with a ``std::jthread`` like
474*61c4878aSAndroid Build Coastguard Worker   wrapper is in progress.
475*61c4878aSAndroid Build Coastguard Worker4. We'd like to add support for queues, message queues, and similar channel
476*61c4878aSAndroid Build Coastguard Worker   abstractions which also support interprocessor communication in a transparent
477*61c4878aSAndroid Build Coastguard Worker   manner.
478*61c4878aSAndroid Build Coastguard Worker5. We're interested in supporting asynchronous worker queues and worker queue
479*61c4878aSAndroid Build Coastguard Worker   pools.
480*61c4878aSAndroid Build Coastguard Worker6. Migrate HAL and similar APIs to use deadlines for the backend virtual
481*61c4878aSAndroid Build Coastguard Worker   interfaces to permit a smaller vtable which supports both public timeout and
482*61c4878aSAndroid Build Coastguard Worker   deadline semantics.
483*61c4878aSAndroid Build Coastguard Worker7. Baremetal support is partially in place today, but it's not ready for use.
484*61c4878aSAndroid Build Coastguard Worker8. Most of our APIs today are focused around synchronous blocking APIs, however
485*61c4878aSAndroid Build Coastguard Worker   we would love to extend this to include asynchronous APIs.
486