xref: /aosp_15_r20/external/pigweed/pw_thread_threadx/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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