1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_thread_threadx: 2*61c4878aSAndroid Build Coastguard Worker 3*61c4878aSAndroid Build Coastguard Worker================= 4*61c4878aSAndroid Build Coastguard Workerpw_thread_threadx 5*61c4878aSAndroid Build Coastguard Worker================= 6*61c4878aSAndroid Build Coastguard WorkerThis is a set of backends for pw_thread based on ThreadX. 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 for ``pw::Thread`` is offered using ``tx_thread_create``. Optional 15*61c4878aSAndroid Build Coastguard Workerjoining support is enabled via an ``TX_EVENT_FLAGS_GROUP`` in each thread's 16*61c4878aSAndroid Build Coastguard Workercontext. 17*61c4878aSAndroid Build Coastguard Worker 18*61c4878aSAndroid Build Coastguard WorkerThis backend permits users to start threads where contexts must be explicitly 19*61c4878aSAndroid Build Coastguard Workerallocated and passed in as an option. As a quick example, a detached thread can 20*61c4878aSAndroid Build Coastguard Workerbe created as follows: 21*61c4878aSAndroid Build Coastguard Worker 22*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp 23*61c4878aSAndroid Build Coastguard Worker 24*61c4878aSAndroid Build Coastguard Worker #include "pw_thread/detached_thread.h" 25*61c4878aSAndroid Build Coastguard Worker #include "pw_thread_threadx/config.h" 26*61c4878aSAndroid Build Coastguard Worker #include "pw_thread_threadx/context.h" 27*61c4878aSAndroid Build Coastguard Worker #include "pw_thread_threadx/options.h" 28*61c4878aSAndroid Build Coastguard Worker #include "tx_api.h" 29*61c4878aSAndroid Build Coastguard Worker 30*61c4878aSAndroid Build Coastguard Worker constexpr UINT kFooPriority = 31*61c4878aSAndroid Build Coastguard Worker pw::thread::threadx::config::kDefaultPriority; 32*61c4878aSAndroid Build Coastguard Worker constexpr ULONG kFooTimeSliceInterval = 33*61c4878aSAndroid Build Coastguard Worker pw::thread::threadx::config::kDefaultTimeSliceInterval; 34*61c4878aSAndroid Build Coastguard Worker constexpr size_t kFooStackSizeWords = 35*61c4878aSAndroid Build Coastguard Worker pw::thread::threadx::config::kDefaultStackSizeWords; 36*61c4878aSAndroid Build Coastguard Worker 37*61c4878aSAndroid Build Coastguard Worker pw::thread::threadx::ContextWithStack<kFooStackSizeWords> 38*61c4878aSAndroid Build Coastguard Worker example_thread_context; 39*61c4878aSAndroid Build Coastguard Worker void StartExampleThread() { 40*61c4878aSAndroid Build Coastguard Worker pw::thread::DetachedThread( 41*61c4878aSAndroid Build Coastguard Worker pw::thread::threadx::Options() 42*61c4878aSAndroid Build Coastguard Worker .set_name("example_thread") 43*61c4878aSAndroid Build Coastguard Worker .set_priority(kFooPriority) 44*61c4878aSAndroid Build Coastguard Worker .set_time_slice_interval(kFooTimeSliceInterval) 45*61c4878aSAndroid Build Coastguard Worker .set_context(example_thread_context), 46*61c4878aSAndroid Build Coastguard Worker example_thread_function); 47*61c4878aSAndroid Build Coastguard Worker } 48*61c4878aSAndroid Build Coastguard Worker 49*61c4878aSAndroid Build Coastguard Worker.. list-table:: 50*61c4878aSAndroid Build Coastguard Worker 51*61c4878aSAndroid Build Coastguard Worker * - :ref:`module-pw_thread` Facade 52*61c4878aSAndroid Build Coastguard Worker - Backend Target 53*61c4878aSAndroid Build Coastguard Worker - Description 54*61c4878aSAndroid Build Coastguard Worker * - ``pw_thread:id`` 55*61c4878aSAndroid Build Coastguard Worker - ``pw_thread_threadx:id`` 56*61c4878aSAndroid Build Coastguard Worker - Thread identification. 57*61c4878aSAndroid Build Coastguard Worker * - ``pw_thread:yield`` 58*61c4878aSAndroid Build Coastguard Worker - ``pw_thread_threadx:yield`` 59*61c4878aSAndroid Build Coastguard Worker - Thread scheduler yielding. 60*61c4878aSAndroid Build Coastguard Worker * - ``pw_thread:sleep`` 61*61c4878aSAndroid Build Coastguard Worker - ``pw_thread_threadx:sleep`` 62*61c4878aSAndroid Build Coastguard Worker - Thread scheduler sleeping. 63*61c4878aSAndroid Build Coastguard Worker * - ``pw_thread:thread`` 64*61c4878aSAndroid Build Coastguard Worker - ``pw_thread_threadx:thread`` 65*61c4878aSAndroid Build Coastguard Worker - Thread creation. 66*61c4878aSAndroid Build Coastguard Worker 67*61c4878aSAndroid Build Coastguard WorkerModule Configuration Options 68*61c4878aSAndroid Build Coastguard Worker============================ 69*61c4878aSAndroid Build Coastguard WorkerThe following configurations can be adjusted via compile-time configuration of 70*61c4878aSAndroid Build Coastguard Workerthis module, see the 71*61c4878aSAndroid Build Coastguard Worker:ref:`module documentation <module-structure-compile-time-configuration>` for 72*61c4878aSAndroid Build Coastguard Workermore details. 73*61c4878aSAndroid Build Coastguard Worker 74*61c4878aSAndroid Build Coastguard Worker.. c:macro:: PW_THREAD_THREADX_CONFIG_JOINING_ENABLED 75*61c4878aSAndroid Build Coastguard Worker 76*61c4878aSAndroid Build Coastguard Worker Whether thread joining is enabled. By default this is disabled. 77*61c4878aSAndroid Build Coastguard Worker 78*61c4878aSAndroid Build Coastguard Worker We suggest only enabling this when thread joining is required to minimize 79*61c4878aSAndroid Build Coastguard Worker the RAM and ROM cost of threads. 80*61c4878aSAndroid Build Coastguard Worker 81*61c4878aSAndroid Build Coastguard Worker Enabling this grows the RAM footprint of every pw::Thread as it adds a 82*61c4878aSAndroid Build Coastguard Worker TX_EVENT_FLAGS_GROUP to every thread's pw::thread::threadx::Context. In 83*61c4878aSAndroid Build Coastguard Worker addition, there is a minute ROM cost to construct and destroy this added 84*61c4878aSAndroid Build Coastguard Worker object. 85*61c4878aSAndroid Build Coastguard Worker 86*61c4878aSAndroid Build Coastguard Worker PW_THREAD_JOINING_ENABLED gets set to this value. 87*61c4878aSAndroid Build Coastguard Worker 88*61c4878aSAndroid Build Coastguard Worker.. c:macro:: PW_THREAD_THREADX_CONFIG_DEFAULT_STACK_SIZE_WORDS 89*61c4878aSAndroid Build Coastguard Worker 90*61c4878aSAndroid Build Coastguard Worker The default stack size in words. By default this uses the minimal ThreadX 91*61c4878aSAndroid Build Coastguard Worker stack size. 92*61c4878aSAndroid Build Coastguard Worker 93*61c4878aSAndroid Build Coastguard Worker.. c:macro:: PW_THREAD_THREADX_CONFIG_MAX_THREAD_NAME_LEN 94*61c4878aSAndroid Build Coastguard Worker 95*61c4878aSAndroid Build Coastguard Worker The maximum length of a thread's name, not including null termination. By 96*61c4878aSAndroid Build Coastguard Worker default this is arbitrarily set to 15. This results in an array of characters 97*61c4878aSAndroid Build Coastguard Worker which is this length + 1 bytes in every pw::Thread's context. 98*61c4878aSAndroid Build Coastguard Worker 99*61c4878aSAndroid Build Coastguard Worker.. c:macro:: PW_THREAD_THREADX_CONFIG_DEFAULT_TIME_SLICE_INTERVAL 100*61c4878aSAndroid Build Coastguard Worker 101*61c4878aSAndroid Build Coastguard Worker The round robin time slice tick interval for threads at the same priority. 102*61c4878aSAndroid Build Coastguard Worker By default this is disabled as not all ports support this, using a value of 0 103*61c4878aSAndroid Build Coastguard Worker ticks. 104*61c4878aSAndroid Build Coastguard Worker 105*61c4878aSAndroid Build Coastguard Worker.. c:macro:: PW_THREAD_THREADX_CONFIG_MIN_PRIORITY 106*61c4878aSAndroid Build Coastguard Worker 107*61c4878aSAndroid Build Coastguard Worker The minimum priority level, this is normally based on the number of priority 108*61c4878aSAndroid Build Coastguard Worker levels. 109*61c4878aSAndroid Build Coastguard Worker 110*61c4878aSAndroid Build Coastguard Worker.. c:macro:: PW_THREAD_THREADX_CONFIG_DEFAULT_PRIORITY 111*61c4878aSAndroid Build Coastguard Worker 112*61c4878aSAndroid Build Coastguard Worker The default priority level. By default this uses the minimal ThreadX 113*61c4878aSAndroid Build Coastguard Worker priority level, given that 0 is the highest priority. 114*61c4878aSAndroid Build Coastguard Worker 115*61c4878aSAndroid Build Coastguard Worker.. c:macro:: PW_THREAD_THREADX_CONFIG_LOG_LEVEL 116*61c4878aSAndroid Build Coastguard Worker 117*61c4878aSAndroid Build Coastguard Worker The log level to use for this module. Logs below this level are omitted. 118*61c4878aSAndroid Build Coastguard Worker 119*61c4878aSAndroid Build Coastguard WorkerThreadX Thread Options 120*61c4878aSAndroid Build Coastguard Worker====================== 121*61c4878aSAndroid Build Coastguard Worker.. cpp:class:: pw::thread::threadx::Options 122*61c4878aSAndroid Build Coastguard Worker 123*61c4878aSAndroid Build Coastguard Worker .. cpp:function:: set_name(const char* name) 124*61c4878aSAndroid Build Coastguard Worker 125*61c4878aSAndroid Build Coastguard Worker Sets the name for the ThreadX thread, note that this will be deep copied 126*61c4878aSAndroid Build Coastguard Worker into the context and may be truncated based on 127*61c4878aSAndroid Build Coastguard Worker ``PW_THREAD_THREADX_CONFIG_MAX_THREAD_NAME_LEN``. 128*61c4878aSAndroid Build Coastguard Worker 129*61c4878aSAndroid Build Coastguard Worker .. cpp:function:: set_priority(UINT priority) 130*61c4878aSAndroid Build Coastguard Worker 131*61c4878aSAndroid Build Coastguard Worker Sets the priority for the ThreadX thread from 0 through 31, where a value 132*61c4878aSAndroid Build Coastguard Worker of 0 represents the highest priority, see ThreadX tx_thread_create for 133*61c4878aSAndroid Build Coastguard Worker more detail. 134*61c4878aSAndroid Build Coastguard Worker 135*61c4878aSAndroid Build Coastguard Worker **Precondition**: priority <= ``PW_THREAD_THREADX_CONFIG_MIN_PRIORITY``. 136*61c4878aSAndroid Build Coastguard Worker 137*61c4878aSAndroid Build Coastguard Worker .. cpp:function:: set_preemption_threshold(UINT preemption_threshold) 138*61c4878aSAndroid Build Coastguard Worker 139*61c4878aSAndroid Build Coastguard Worker Optionally sets the preemption threshold for the ThreadX thread from 0 140*61c4878aSAndroid Build Coastguard Worker through 31. 141*61c4878aSAndroid Build Coastguard Worker 142*61c4878aSAndroid Build Coastguard Worker Only priorities higher than this level (i.e. lower number) are allowed to 143*61c4878aSAndroid Build Coastguard Worker preempt this thread. In other words this allows the thread to specify the 144*61c4878aSAndroid Build Coastguard Worker priority ceiling for disabling preemption. Threads that have a higher 145*61c4878aSAndroid Build Coastguard Worker priority than the ceiling are still allowed to preempt while those with 146*61c4878aSAndroid Build Coastguard Worker less than the ceiling are not allowed to preempt. 147*61c4878aSAndroid Build Coastguard Worker 148*61c4878aSAndroid Build Coastguard Worker Not setting the preemption threshold or explicitly specifying a value 149*61c4878aSAndroid Build Coastguard Worker equal to the priority disables preemption threshold. 150*61c4878aSAndroid Build Coastguard Worker 151*61c4878aSAndroid Build Coastguard Worker Time slicing is disabled while the preemption threshold is enabled, i.e. 152*61c4878aSAndroid Build Coastguard Worker not equal to the priority, even if a time slice interval was specified. 153*61c4878aSAndroid Build Coastguard Worker 154*61c4878aSAndroid Build Coastguard Worker The preemption threshold can be adjusted at run time, this only sets the 155*61c4878aSAndroid Build Coastguard Worker initial threshold. 156*61c4878aSAndroid Build Coastguard Worker 157*61c4878aSAndroid Build Coastguard Worker **Precondition**: preemption_threshold <= priority 158*61c4878aSAndroid Build Coastguard Worker 159*61c4878aSAndroid Build Coastguard Worker .. cpp:function:: set_time_slice_interval(UINT time_slice_interval) 160*61c4878aSAndroid Build Coastguard Worker 161*61c4878aSAndroid Build Coastguard Worker Sets the number of ticks this thread is allowed to run before other ready 162*61c4878aSAndroid Build Coastguard Worker threads of the same priority are given a chance to run. 163*61c4878aSAndroid Build Coastguard Worker 164*61c4878aSAndroid Build Coastguard Worker Time slicing is disabled while the preemption threshold is enabled, i.e. 165*61c4878aSAndroid Build Coastguard Worker not equal to the priority, even if a time slice interval was specified. 166*61c4878aSAndroid Build Coastguard Worker 167*61c4878aSAndroid Build Coastguard Worker A value of ``TX_NO_TIME_SLICE`` (a value of 0) disables time-slicing of 168*61c4878aSAndroid Build Coastguard Worker this thread. 169*61c4878aSAndroid Build Coastguard Worker 170*61c4878aSAndroid Build Coastguard Worker Using time slicing results in a slight amount of system overhead, threads 171*61c4878aSAndroid Build Coastguard Worker with a unique priority should consider ``TX_NO_TIME_SLICE``. 172*61c4878aSAndroid Build Coastguard Worker 173*61c4878aSAndroid Build Coastguard Worker 174*61c4878aSAndroid Build Coastguard Worker .. cpp:function:: set_context(pw::thread::embos::Context& context) 175*61c4878aSAndroid Build Coastguard Worker 176*61c4878aSAndroid Build Coastguard Worker Set the pre-allocated context (all memory needed to run a thread). Note 177*61c4878aSAndroid Build Coastguard Worker that this is required for this thread creation backend! The Context can 178*61c4878aSAndroid Build Coastguard Worker either be constructed with an externally provided ``pw::span<ULONG>`` 179*61c4878aSAndroid Build Coastguard Worker stack or the templated form of ``ContextWihtStack<kStackSizeWords`` can be 180*61c4878aSAndroid Build Coastguard Worker used. 181*61c4878aSAndroid Build Coastguard Worker 182*61c4878aSAndroid Build Coastguard Worker----------------------------- 183*61c4878aSAndroid Build Coastguard WorkerThread Identification Backend 184*61c4878aSAndroid Build Coastguard Worker----------------------------- 185*61c4878aSAndroid Build Coastguard WorkerA backend for ``pw::Thread::id`` and ``pw::thread::get_id()`` is offerred using 186*61c4878aSAndroid Build Coastguard Worker``tx_thread_identify()``. It uses ``DASSERT`` to ensure that a thread is 187*61c4878aSAndroid Build Coastguard Workerexecuting via ``TX_THREAD_GET_SYSTEM_STATE()``. 188*61c4878aSAndroid Build Coastguard Worker 189*61c4878aSAndroid Build Coastguard Worker-------------------- 190*61c4878aSAndroid Build Coastguard WorkerThread Sleep Backend 191*61c4878aSAndroid Build Coastguard Worker-------------------- 192*61c4878aSAndroid Build Coastguard WorkerA backend for ``pw::thread::sleep_for()`` and ``pw::thread::sleep_until()`` is 193*61c4878aSAndroid Build Coastguard Workerofferred using ``tx_thread_sleep()`` if the duration is at least one tick, else 194*61c4878aSAndroid Build Coastguard Worker``tx_thread_relinquish()`` is used. It uses 195*61c4878aSAndroid Build Coastguard Worker``pw::this_thread::get_id() != Thread::id()`` to ensure it invoked only from a 196*61c4878aSAndroid Build Coastguard Workerthread. 197*61c4878aSAndroid Build Coastguard Worker 198*61c4878aSAndroid Build Coastguard Worker-------------------- 199*61c4878aSAndroid Build Coastguard WorkerThread Yield Backend 200*61c4878aSAndroid Build Coastguard Worker-------------------- 201*61c4878aSAndroid Build Coastguard WorkerA backend for ``pw::thread::yield()`` is offered using via 202*61c4878aSAndroid Build Coastguard Worker``tx_thread_relinquish()``. It uses 203*61c4878aSAndroid Build Coastguard Worker``pw::this_thread::get_id() != Thread::id()`` to ensure it invoked only from a 204*61c4878aSAndroid Build Coastguard Workerthread. 205*61c4878aSAndroid Build Coastguard Worker 206*61c4878aSAndroid Build Coastguard Worker--------- 207*61c4878aSAndroid Build Coastguard WorkerUtilities 208*61c4878aSAndroid Build Coastguard Worker--------- 209*61c4878aSAndroid Build Coastguard Worker``ForEachThread()`` 210*61c4878aSAndroid Build Coastguard Worker=================== 211*61c4878aSAndroid Build Coastguard WorkerIn cases where an operation must be performed for every thread, 212*61c4878aSAndroid Build Coastguard Worker``ForEachThread()`` can be used to iterate over all the created thread TCBs. 213*61c4878aSAndroid Build Coastguard WorkerNote that it's only safe to use this while the scheduler is disabled. 214*61c4878aSAndroid Build Coastguard Worker 215*61c4878aSAndroid Build Coastguard WorkerAn ``Aborted`` error status is returned if the provided callback returns 216*61c4878aSAndroid Build Coastguard Worker``false`` to request an early termination of thread iteration. 217*61c4878aSAndroid Build Coastguard Worker 218*61c4878aSAndroid Build Coastguard Worker*Return values* 219*61c4878aSAndroid Build Coastguard Worker 220*61c4878aSAndroid Build Coastguard Worker* ``Aborted``: The callback requested an early-termination of thread iteration. 221*61c4878aSAndroid Build Coastguard Worker* ``OkStatus``: The callback has been successfully run with every thread. 222*61c4878aSAndroid Build Coastguard Worker 223*61c4878aSAndroid Build Coastguard Worker-------------------- 224*61c4878aSAndroid Build Coastguard WorkerSnapshot integration 225*61c4878aSAndroid Build Coastguard Worker-------------------- 226*61c4878aSAndroid Build Coastguard WorkerThis ``pw_thread`` backend provides helper functions that capture ThreadX thread 227*61c4878aSAndroid Build Coastguard Workerstate to a ``pw::Thread`` proto. 228*61c4878aSAndroid Build Coastguard Worker 229*61c4878aSAndroid Build Coastguard Worker``SnapshotThreads()`` 230*61c4878aSAndroid Build Coastguard Worker===================== 231*61c4878aSAndroid Build Coastguard Worker``SnapshotThreads()`` captures the thread name, state, and stack information for 232*61c4878aSAndroid Build Coastguard Workerthe provided ThreadX TCB to a ``pw::Thread`` protobuf encoder. To ensure the 233*61c4878aSAndroid Build Coastguard Workermost up-to-date information is captured, the stack pointer for the currently 234*61c4878aSAndroid Build Coastguard Workerrunning thread must be provided for cases where the running thread is being 235*61c4878aSAndroid Build Coastguard Workercaptured. For ARM Cortex-M CPUs, you can do something like this: 236*61c4878aSAndroid Build Coastguard Worker 237*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp 238*61c4878aSAndroid Build Coastguard Worker 239*61c4878aSAndroid Build Coastguard Worker // Capture PSP. 240*61c4878aSAndroid Build Coastguard Worker void* stack_ptr = 0; 241*61c4878aSAndroid Build Coastguard Worker asm volatile("mrs %0, psp\n" : "=r"(stack_ptr)); 242*61c4878aSAndroid Build Coastguard Worker pw::thread::ProcessThreadStackCallback cb = 243*61c4878aSAndroid Build Coastguard Worker [](pw::thread::proto::Thread::StreamEncoder& encoder, 244*61c4878aSAndroid Build Coastguard Worker pw::ConstByteSpan stack) -> pw::Status { 245*61c4878aSAndroid Build Coastguard Worker return encoder.WriteRawStack(stack); 246*61c4878aSAndroid Build Coastguard Worker }; 247*61c4878aSAndroid Build Coastguard Worker pw::thread::threadx::SnapshotThread(my_thread, stack_ptr, 248*61c4878aSAndroid Build Coastguard Worker snapshot_encoder, cb); 249*61c4878aSAndroid Build Coastguard Worker 250*61c4878aSAndroid Build Coastguard Worker``SnapshotThreads()`` wraps the singular thread capture to instead captures 251*61c4878aSAndroid Build Coastguard Workerall created threads to a ``pw::thread::proto::SnapshotThreadInfo`` message. 252*61c4878aSAndroid Build Coastguard WorkerThis proto message overlays a snapshot, so it is safe to static cast a 253*61c4878aSAndroid Build Coastguard Worker``pw::snapshot::Snapshot::StreamEncoder`` to a 254*61c4878aSAndroid Build Coastguard Worker``pw::thread::proto::SnapshotThreadInfo::StreamEncoder`` when calling this 255*61c4878aSAndroid Build Coastguard Workerfunction. 256