1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_thread_embos: 2*61c4878aSAndroid Build Coastguard Worker 3*61c4878aSAndroid Build Coastguard Worker=============== 4*61c4878aSAndroid Build Coastguard Workerpw_thread_embos 5*61c4878aSAndroid Build Coastguard Worker=============== 6*61c4878aSAndroid Build Coastguard WorkerThis is a set of backends for pw_thread based on embOS v4. 7*61c4878aSAndroid Build Coastguard Worker 8*61c4878aSAndroid Build Coastguard Worker.. Warning:: 9*61c4878aSAndroid Build Coastguard Worker This module is still under construction, the API is not yet stable. 10*61c4878aSAndroid Build Coastguard Worker 11*61c4878aSAndroid Build Coastguard Worker----------------------- 12*61c4878aSAndroid Build Coastguard WorkerThread Creation Backend 13*61c4878aSAndroid Build Coastguard Worker----------------------- 14*61c4878aSAndroid Build Coastguard WorkerA backend or ``pw::Thread`` is offered using ``OS_CreateTaskEx()``. Optional 15*61c4878aSAndroid Build Coastguard Workerjoining support is enabled via an ``OS_EVENT`` in each thread's context. 16*61c4878aSAndroid Build Coastguard Worker 17*61c4878aSAndroid Build Coastguard WorkerThis backend permits users to start threads where contexts must be explicitly 18*61c4878aSAndroid Build Coastguard Workerallocated and passed in as an option. As a quick example, a detached thread 19*61c4878aSAndroid Build Coastguard Workercan be created as follows: 20*61c4878aSAndroid Build Coastguard Worker 21*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp 22*61c4878aSAndroid Build Coastguard Worker 23*61c4878aSAndroid Build Coastguard Worker #include "pw_thread/detached_thread.h" 24*61c4878aSAndroid Build Coastguard Worker #include "pw_thread_embos/config.h" 25*61c4878aSAndroid Build Coastguard Worker #include "pw_thread_embos/context.h" 26*61c4878aSAndroid Build Coastguard Worker #include "pw_thread_embos/options.h" 27*61c4878aSAndroid Build Coastguard Worker #include "RTOS.h" // For the embOS types. 28*61c4878aSAndroid Build Coastguard Worker 29*61c4878aSAndroid Build Coastguard Worker constexpr OS_PRIO kFooPriority = 30*61c4878aSAndroid Build Coastguard Worker pw::thread::embos::config::kDefaultPriority; 31*61c4878aSAndroid Build Coastguard Worker constexpr OS_UINT kFooTimeSliceInterval = 32*61c4878aSAndroid Build Coastguard Worker pw::thread::embos::config::kDefaultTimeSliceInterval; 33*61c4878aSAndroid Build Coastguard Worker constexpr size_t kFooStackSizeWords = 34*61c4878aSAndroid Build Coastguard Worker pw::thread::embos::config::kDefaultStackSizeWords; 35*61c4878aSAndroid Build Coastguard Worker 36*61c4878aSAndroid Build Coastguard Worker pw::thread::embos::ContextWithStack<kFooStackSizeWords> 37*61c4878aSAndroid Build Coastguard Worker example_thread_context; 38*61c4878aSAndroid Build Coastguard Worker void StartExampleThread() { 39*61c4878aSAndroid Build Coastguard Worker pw::thread::DetachedThread( 40*61c4878aSAndroid Build Coastguard Worker pw::thread::embos::Options() 41*61c4878aSAndroid Build Coastguard Worker .set_name("example_thread") 42*61c4878aSAndroid Build Coastguard Worker .set_priority(kFooPriority) 43*61c4878aSAndroid Build Coastguard Worker .set_time_slice_interval(kFooTimeSliceInterval) 44*61c4878aSAndroid Build Coastguard Worker .set_context(example_thread_context), 45*61c4878aSAndroid Build Coastguard Worker example_thread_function); 46*61c4878aSAndroid Build Coastguard Worker } 47*61c4878aSAndroid Build Coastguard Worker 48*61c4878aSAndroid Build Coastguard Worker 49*61c4878aSAndroid Build Coastguard WorkerModule Configuration Options 50*61c4878aSAndroid Build Coastguard Worker============================ 51*61c4878aSAndroid Build Coastguard WorkerThe following configurations can be adjusted via compile-time configuration of 52*61c4878aSAndroid Build Coastguard Workerthis module, see the 53*61c4878aSAndroid Build Coastguard Worker:ref:`module documentation <module-structure-compile-time-configuration>` for 54*61c4878aSAndroid Build Coastguard Workermore details. 55*61c4878aSAndroid Build Coastguard Worker 56*61c4878aSAndroid Build Coastguard Worker.. c:macro:: PW_THREAD_EMBOS_CONFIG_JOINING_ENABLED 57*61c4878aSAndroid Build Coastguard Worker 58*61c4878aSAndroid Build Coastguard Worker Whether thread joining is enabled. By default this is disabled. 59*61c4878aSAndroid Build Coastguard Worker 60*61c4878aSAndroid Build Coastguard Worker We suggest only enabling this when thread joining is required to minimize 61*61c4878aSAndroid Build Coastguard Worker the RAM and ROM cost of threads. 62*61c4878aSAndroid Build Coastguard Worker 63*61c4878aSAndroid Build Coastguard Worker Enabling this grows the RAM footprint of every pw::Thread as it adds an 64*61c4878aSAndroid Build Coastguard Worker OS_EVENT to every thread's pw::thread::embos::Context. In addition, there is a 65*61c4878aSAndroid Build Coastguard Worker minute ROM cost to construct and destroy this added object. 66*61c4878aSAndroid Build Coastguard Worker 67*61c4878aSAndroid Build Coastguard Worker PW_THREAD_JOINING_ENABLED gets set to this value. 68*61c4878aSAndroid Build Coastguard Worker 69*61c4878aSAndroid Build Coastguard Worker.. c:macro:: PW_THREAD_EMBOS_CONFIG_MINIMUM_STACK_SIZE_WORDS 70*61c4878aSAndroid Build Coastguard Worker 71*61c4878aSAndroid Build Coastguard Worker The minimum stack size in words. By default this uses Segger's recommendation 72*61c4878aSAndroid Build Coastguard Worker of 68 bytes. 73*61c4878aSAndroid Build Coastguard Worker 74*61c4878aSAndroid Build Coastguard Worker.. c:macro:: PW_THREAD_EMBOS_CONFIG_DEFAULT_STACK_SIZE_WORDS 75*61c4878aSAndroid Build Coastguard Worker 76*61c4878aSAndroid Build Coastguard Worker The default stack size in words. By default this uses Segger's recommendation 77*61c4878aSAndroid Build Coastguard Worker of 256 bytes to start. 78*61c4878aSAndroid Build Coastguard Worker 79*61c4878aSAndroid Build Coastguard Worker.. c:macro:: PW_THREAD_EMBOS_CONFIG_MAX_THREAD_NAME_LEN 80*61c4878aSAndroid Build Coastguard Worker 81*61c4878aSAndroid Build Coastguard Worker The maximum length of a thread's name, not including null termination. By 82*61c4878aSAndroid Build Coastguard Worker default this is arbitrarily set to 15. This results in an array of characters 83*61c4878aSAndroid Build Coastguard Worker which is this length + 1 bytes in every ``pw::Thread``'s context. 84*61c4878aSAndroid Build Coastguard Worker 85*61c4878aSAndroid Build Coastguard Worker.. c:macro:: PW_THREAD_EMBOS_CONFIG_MIN_PRIORITY 86*61c4878aSAndroid Build Coastguard Worker 87*61c4878aSAndroid Build Coastguard Worker The minimum priority level, this is normally 1, since 0 is not a valid 88*61c4878aSAndroid Build Coastguard Worker priority level. 89*61c4878aSAndroid Build Coastguard Worker 90*61c4878aSAndroid Build Coastguard Worker.. c:macro:: PW_THREAD_EMBOS_CONFIG_DEFAULT_PRIORITY 91*61c4878aSAndroid Build Coastguard Worker 92*61c4878aSAndroid Build Coastguard Worker The default priority level. By default this uses the minimal embOS priority. 93*61c4878aSAndroid Build Coastguard Worker 94*61c4878aSAndroid Build Coastguard Worker.. c:macro:: PW_THREAD_EMBOS_CONFIG_DEFAULT_TIME_SLICE_INTERVAL 95*61c4878aSAndroid Build Coastguard Worker 96*61c4878aSAndroid Build Coastguard Worker The round robin time slice tick interval for threads at the same priority. 97*61c4878aSAndroid Build Coastguard Worker By default this is set to 2 ticks based on the embOS default. 98*61c4878aSAndroid Build Coastguard Worker 99*61c4878aSAndroid Build Coastguard Worker.. c:macro:: PW_THREAD_EMBOS_CONFIG_LOG_LEVEL 100*61c4878aSAndroid Build Coastguard Worker 101*61c4878aSAndroid Build Coastguard Worker The log level to use for this module. Logs below this level are omitted. 102*61c4878aSAndroid Build Coastguard Worker 103*61c4878aSAndroid Build Coastguard WorkerembOS Thread Options 104*61c4878aSAndroid Build Coastguard Worker==================== 105*61c4878aSAndroid Build Coastguard Worker.. cpp:class:: pw::thread::embos::Options 106*61c4878aSAndroid Build Coastguard Worker 107*61c4878aSAndroid Build Coastguard Worker .. cpp:function:: set_name(const char* name) 108*61c4878aSAndroid Build Coastguard Worker 109*61c4878aSAndroid Build Coastguard Worker Sets the name for the embOS task, this is optional. 110*61c4878aSAndroid Build Coastguard Worker Note that this will be deep copied into the context and may be truncated 111*61c4878aSAndroid Build Coastguard Worker based on ``PW_THREAD_EMBOS_CONFIG_MAX_THREAD_NAME_LEN``. 112*61c4878aSAndroid Build Coastguard Worker 113*61c4878aSAndroid Build Coastguard Worker .. cpp:function:: set_priority(OS_PRIO priority) 114*61c4878aSAndroid Build Coastguard Worker 115*61c4878aSAndroid Build Coastguard Worker Sets the priority for the embOS task. Higher values are higher priority, 116*61c4878aSAndroid Build Coastguard Worker see embOS OS_CreateTaskEx for more detail. 117*61c4878aSAndroid Build Coastguard Worker Precondition: This must be >= ``PW_THREAD_EMBOS_CONFIG_MIN_PRIORITY``. 118*61c4878aSAndroid Build Coastguard Worker 119*61c4878aSAndroid Build Coastguard Worker .. cpp:function:: set_time_slice_interval(OS_UINT time_slice_interval) 120*61c4878aSAndroid Build Coastguard Worker 121*61c4878aSAndroid Build Coastguard Worker Sets the number of ticks this thread is allowed to run before other ready 122*61c4878aSAndroid Build Coastguard Worker threads of the same priority are given a chance to run. 123*61c4878aSAndroid Build Coastguard Worker 124*61c4878aSAndroid Build Coastguard Worker A value of 0 disables time-slicing of this thread. 125*61c4878aSAndroid Build Coastguard Worker 126*61c4878aSAndroid Build Coastguard Worker Precondition: This must be <= 255 ticks. 127*61c4878aSAndroid Build Coastguard Worker 128*61c4878aSAndroid Build Coastguard Worker .. cpp:function:: set_context(pw::thread::embos::Context& context) 129*61c4878aSAndroid Build Coastguard Worker 130*61c4878aSAndroid Build Coastguard Worker Set the pre-allocated context (all memory needed to run a thread). Note that 131*61c4878aSAndroid Build Coastguard Worker this is required for this thread creation backend! The ``Context`` can 132*61c4878aSAndroid Build Coastguard Worker either be constructed with an externally provided ``pw::span<OS_UINT>`` 133*61c4878aSAndroid Build Coastguard Worker stack or the templated form of ``ContextWithStack<kStackSizeWords>`` can 134*61c4878aSAndroid Build Coastguard Worker be used. 135*61c4878aSAndroid Build Coastguard Worker 136*61c4878aSAndroid Build Coastguard Worker 137*61c4878aSAndroid Build Coastguard Worker----------------------------- 138*61c4878aSAndroid Build Coastguard WorkerThread Identification Backend 139*61c4878aSAndroid Build Coastguard Worker----------------------------- 140*61c4878aSAndroid Build Coastguard WorkerA backend for ``pw::Thread::id`` and ``pw::thread::get_id()`` is offerred using 141*61c4878aSAndroid Build Coastguard Worker``OS_GetTaskID()``. It uses ``DASSERT`` to ensure that the scheduler has started 142*61c4878aSAndroid Build Coastguard Workervia ``OS_IsRunning()``. 143*61c4878aSAndroid Build Coastguard Worker 144*61c4878aSAndroid Build Coastguard Worker-------------------- 145*61c4878aSAndroid Build Coastguard WorkerThread Sleep Backend 146*61c4878aSAndroid Build Coastguard Worker-------------------- 147*61c4878aSAndroid Build Coastguard WorkerA backend for ``pw::thread::sleep_for()`` and ``pw::thread::sleep_until()`` is 148*61c4878aSAndroid Build Coastguard Workerofferred using ``OS_Delay()`` if the duration is at least one tick, else 149*61c4878aSAndroid Build Coastguard Worker``OS_Yield()`` is used. It uses ``pw::this_thread::get_id() != Thread::id()`` to 150*61c4878aSAndroid Build Coastguard Workerensure it invoked only from a thread. 151*61c4878aSAndroid Build Coastguard Worker 152*61c4878aSAndroid Build Coastguard Worker-------------------- 153*61c4878aSAndroid Build Coastguard WorkerThread Yield Backend 154*61c4878aSAndroid Build Coastguard Worker-------------------- 155*61c4878aSAndroid Build Coastguard WorkerA backend for ``pw::thread::yield()`` is offered using via ``OS_Yield()``. 156*61c4878aSAndroid Build Coastguard WorkerIt uses ``pw::this_thread::get_id() != Thread::id()`` to ensure it invoked only 157*61c4878aSAndroid Build Coastguard Workerfrom a thread. 158*61c4878aSAndroid Build Coastguard Worker 159*61c4878aSAndroid Build Coastguard Worker--------- 160*61c4878aSAndroid Build Coastguard WorkerUtilities 161*61c4878aSAndroid Build Coastguard Worker--------- 162*61c4878aSAndroid Build Coastguard Worker``ForEachThread()`` 163*61c4878aSAndroid Build Coastguard Worker=================== 164*61c4878aSAndroid Build Coastguard WorkerIn cases where an operation must be performed for every thread, 165*61c4878aSAndroid Build Coastguard Worker``ForEachThread()`` can be used to iterate over all the created thread TCBs. 166*61c4878aSAndroid Build Coastguard WorkerNote that it's only safe to use this while the scheduler is suspended, and this 167*61c4878aSAndroid Build Coastguard Workershould only be used after ``OS_Start()`` has been called. Calling this before 168*61c4878aSAndroid Build Coastguard Workerthe scheduler has started is non-fatal, but will result in no action and a 169*61c4878aSAndroid Build Coastguard Worker``FailedPrecondition`` error code. 170*61c4878aSAndroid Build Coastguard Worker 171*61c4878aSAndroid Build Coastguard WorkerAn ``Aborted`` error status is returned if the provided callback returns 172*61c4878aSAndroid Build Coastguard Worker``false`` to request an early termination of thread iteration. 173*61c4878aSAndroid Build Coastguard Worker 174*61c4878aSAndroid Build Coastguard Worker*Return values* 175*61c4878aSAndroid Build Coastguard Worker 176*61c4878aSAndroid Build Coastguard Worker* ``FailedPrecondition``: Returned when ``ForEachThread()`` is run before the OS 177*61c4878aSAndroid Build Coastguard Worker has been initialized. 178*61c4878aSAndroid Build Coastguard Worker* ``Aborted``: The callback requested an early-termination of thread iteration. 179*61c4878aSAndroid Build Coastguard Worker* ``OkStatus``: The callback has been successfully run with every thread. 180*61c4878aSAndroid Build Coastguard Worker 181*61c4878aSAndroid Build Coastguard Worker-------------------- 182*61c4878aSAndroid Build Coastguard WorkerSnapshot Integration 183*61c4878aSAndroid Build Coastguard Worker-------------------- 184*61c4878aSAndroid Build Coastguard WorkerThis ``pw_thread`` backend provides helper functions that capture embOS thread 185*61c4878aSAndroid Build Coastguard Workerinfo to a ``pw::Thread`` proto. 186*61c4878aSAndroid Build Coastguard Worker 187*61c4878aSAndroid Build Coastguard Worker``SnapshotThreads()`` 188*61c4878aSAndroid Build Coastguard Worker===================== 189*61c4878aSAndroid Build Coastguard Worker``SnapshotThreads()`` captures the thread name, state, and stack information for 190*61c4878aSAndroid Build Coastguard Workerthe provided embOS TCB to a ``pw::Thread`` protobuf encoder. To ensure the most 191*61c4878aSAndroid Build Coastguard Workerup-to-date information is captured, the stack pointer for the currently running 192*61c4878aSAndroid Build Coastguard Workerthread must be provided for cases where the running thread is being captured. 193*61c4878aSAndroid Build Coastguard WorkerFor ARM Cortex-M CPUs, you can do something like this: 194*61c4878aSAndroid Build Coastguard Worker 195*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp 196*61c4878aSAndroid Build Coastguard Worker 197*61c4878aSAndroid Build Coastguard Worker // Capture PSP. 198*61c4878aSAndroid Build Coastguard Worker void* stack_ptr = 0; 199*61c4878aSAndroid Build Coastguard Worker asm volatile("mrs %0, psp\n" : "=r"(stack_ptr)); 200*61c4878aSAndroid Build Coastguard Worker pw::thread::ProcessThreadStackCallback cb = 201*61c4878aSAndroid Build Coastguard Worker [](pw::thread::proto::Thread::StreamEncoder& encoder, 202*61c4878aSAndroid Build Coastguard Worker pw::ConstByteSpan stack) -> pw::Status { 203*61c4878aSAndroid Build Coastguard Worker return encoder.WriteRawStack(stack); 204*61c4878aSAndroid Build Coastguard Worker }; 205*61c4878aSAndroid Build Coastguard Worker pw::thread::embos::SnapshotThread(my_thread, stack_ptr, 206*61c4878aSAndroid Build Coastguard Worker snapshot_encoder, cb); 207*61c4878aSAndroid Build Coastguard Worker 208*61c4878aSAndroid Build Coastguard Worker``SnapshotThreads()`` wraps the singular thread capture to instead captures 209*61c4878aSAndroid Build Coastguard Workerall created threads to a ``pw::thread::proto::SnapshotThreadInfo`` message. 210*61c4878aSAndroid Build Coastguard WorkerThis proto message overlays a snapshot, so it is safe to static cast a 211*61c4878aSAndroid Build Coastguard Worker``pw::snapshot::Snapshot::StreamEncoder`` to a 212*61c4878aSAndroid Build Coastguard Worker``pw::thread::proto::SnapshotThreadInfo::StreamEncoder`` when calling this 213*61c4878aSAndroid Build Coastguard Workerfunction. 214*61c4878aSAndroid Build Coastguard Worker 215*61c4878aSAndroid Build Coastguard WorkerThread Name Capture 216*61c4878aSAndroid Build Coastguard Worker------------------- 217*61c4878aSAndroid Build Coastguard WorkerIn order to capture thread names when snapshotting a thread, embOS must have 218*61c4878aSAndroid Build Coastguard Worker``OS_TRACKNAME`` enabled. If ``OS_TRACKNAME`` is disabled, no thread name 219*61c4878aSAndroid Build Coastguard Workeris captured. Enabling this is strongly recommended for debugability. 220*61c4878aSAndroid Build Coastguard Worker 221*61c4878aSAndroid Build Coastguard WorkerThread State Capture 222*61c4878aSAndroid Build Coastguard Worker-------------------- 223*61c4878aSAndroid Build Coastguard WorkerembOS thread state is not part of embOS's public API. Despite this, the 224*61c4878aSAndroid Build Coastguard Workersnapshot integration captures thread state based on information on how the 225*61c4878aSAndroid Build Coastguard Workerthread state is represented from 226*61c4878aSAndroid Build Coastguard Worker`Segger's public forum <https://forum.segger.com/index.php/Thread/6548-ABANDONED-Task-state-values/?postID=23963#post23963>`_. 227*61c4878aSAndroid Build Coastguard WorkerThis has been tested on embOS 4.22, and was initially 228*61c4878aSAndroid Build Coastguard Workerreported for embOS 5.06. The logic Pigweed uses to interpret thread state may 229*61c4878aSAndroid Build Coastguard Workerbe incorrect for other versions of embOS. 230*61c4878aSAndroid Build Coastguard Worker 231*61c4878aSAndroid Build Coastguard WorkerThread Stack Capture 232*61c4878aSAndroid Build Coastguard Worker-------------------- 233*61c4878aSAndroid Build Coastguard WorkerFull thread stack information capture is dependent on embOS tracking the stack 234*61c4878aSAndroid Build Coastguard Workerbounds for each task. When either ``OS_SUPPORT_MPU`` or ``OS_CHECKSTACK`` are 235*61c4878aSAndroid Build Coastguard Workerenabled, stack bounds are tracked and the callback for thread stack dumping 236*61c4878aSAndroid Build Coastguard Workerwill be called. If both of these options are disabled, ``stack_start_pointer`` 237*61c4878aSAndroid Build Coastguard Workerand ``stack_end_pointer`` will not be captured, and the 238*61c4878aSAndroid Build Coastguard Worker``ProcessThreadStackCallback`` will not be called. 239