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