pw_thread_embos: add thread creation for embOS
Adds thread creation support to embOS.
Also updates existing documentation to reflect that this is now
supported.
Change-Id: Id95dbb5f7b283733b7cd071831ddcf95c0c549d0
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/44144
Reviewed-by: Keir Mierle <keir@google.com>
Commit-Queue: Ewout van Bekkum <ewout@google.com>
Pigweed-Auto-Submit: Ewout van Bekkum <ewout@google.com>
diff --git a/pw_thread_embos/docs.rst b/pw_thread_embos/docs.rst
index cad1908..16de090 100644
--- a/pw_thread_embos/docs.rst
+++ b/pw_thread_embos/docs.rst
@@ -1,8 +1,150 @@
.. _module-pw_thread_embos:
----------------
+===============
pw_thread_embos
----------------
-This is a set of backends for pw_thread based on embOS v4. It is not ready for
-use, and is under construction.
+===============
+This is a set of backends for pw_thread based on embOS v4.
+.. contents::
+ :local:
+ :depth: 1
+
+.. Warning::
+ This module is still under construction, the API is not yet stable.
+
+-----------------------
+Thread Creation Backend
+-----------------------
+A backend or ``pw::thread::Thread`` is offered using ``OS_CreateTaskEx()``.
+Optional joining support is enabled via an ``OS_EVENT`` in each thread's
+context.
+
+This backend permits users to start threads where contexts must be explicitly
+allocated and passed in as an option. As a quick example, a detached thread
+can be created as follows:
+
+.. code-block:: cpp
+
+ #include "pw_thread/detached_thread.h"
+ #include "pw_thread_embos/context.h"
+ #include "pw_thread_embos/options.h"
+ #include "RTOS.h" // For the embOS types.
+
+ pw::thread::embos::ContextWithStack<42> example_thread_context;
+ void StartExampleThread() {
+ pw::thread::DetachedThread(
+ pw::thread::embos::Options()
+ .set_name("static_example_thread")
+ .set_priority(kFooPriority)
+ .set_time_slice_interval(kFooTimeSliceInterval)
+ .set_context(example_thread_context),
+ example_thread_function)
+ }
+
+
+Module Configuration Options
+============================
+The following configurations can be adjusted via compile-time configuration of
+this module, see the
+:ref:`module documentation <module-structure-compile-time-configuration>` for
+more details.
+
+.. c:macro:: PW_THREAD_EMBOS_CONFIG_JOINING_ENABLED
+
+ Whether thread joining is enabled. By default this is disabled.
+
+ We suggest only enabling this when thread joining is required to minimize
+ the RAM and ROM cost of threads.
+
+ Enabling this grows the RAM footprint of every pw::thread::Thread as it adds
+ an OS_EVENT to every thread's pw::thread::embos::Context. In addition, there
+ is a minute ROM cost to construct and destroy this added object.
+
+ PW_THREAD_JOINING_ENABLED gets set to this value.
+
+.. c:macro:: PW_THREAD_EMBOS_CONFIG_MINIMUM_STACK_SIZE_WORDS
+
+ The minimum stack size in words. By default this uses Segger's recommendation
+ of 68 bytes.
+
+.. c:macro:: PW_THREAD_EMBOS_CONFIG_DEFAULT_STACK_SIZE_WORDS
+
+ The default stack size in words. By default this uses Segger's recommendation
+ of 256 bytes to start.
+
+.. c:macro:: PW_THREAD_EMBOS_CONFIG_MAX_THREAD_NAME_LEN
+
+ The maximum length of a thread's name, not including null termination. By
+ default this is arbitrarily set to 15. This results in an array of characters
+ which is this length + 1 bytes in every ``pw::thread::Thread``'s context.
+
+.. c:macro:: PW_THREAD_EMBOS_CONFIG_MIN_PRIORITY
+
+ The minimum priority level, this is normally 1, since 0 is not a valid
+ priority level.
+
+.. c:macro:: PW_THREAD_EMBOS_CONFIG_DEFAULT_PRIORITY
+
+ The default priority level. By default this uses the minimal embOS priority.
+
+.. c:macro:: PW_THREAD_EMBOS_CONFIG_DEFAULT_TIME_SLICE_INTERVAL
+
+ The round robin time slice tick interval for threads at the same priority.
+ By default this is set to 2 ticks based on the embOS default.
+
+
+embOS Thread Options
+====================
+.. cpp:class:: pw::thread::embos::Options
+
+ .. cpp:function:: set_name(const char* name)
+
+ Sets the name for the embOS task, this is optional.
+ Note that this will be deep copied into the context and may be truncated
+ based on ``PW_THREAD_EMBOS_CONFIG_MAX_THREAD_NAME_LEN``.
+
+ .. cpp:function:: set_priority(OS_PRIO priority)
+
+ Sets the priority for the embOS task. Higher values are higher priority,
+ see embOS OS_CreateTaskEx for more detail.
+ Precondition: This must be >= ``PW_THREAD_EMBOS_CONFIG_MIN_PRIORITY``.
+
+ .. cpp:function:: set_time_slice_interval(OS_UINT time_slice_interval)
+
+ Sets the number of ticks this thread is allowed to run before other ready
+ threads of the same priority are given a chance to run.
+
+ A value of 0 disables time-slicing of this thread.
+
+ Precondition: This must be <= 255 ticks.
+
+ .. cpp:function:: set_context(pw::thread::embos::Context& context)
+
+ Set the pre-allocated context (all memory needed to run a thread). Note that
+ this is required for this thread creation backend! The ``Context`` can
+ either be constructed with an externally provided ``std::span<OS_UINT>``
+ stack or the templated form of ``ContextWithStack<kStackSizeWords>`` can
+ be used.
+
+
+-----------------------------
+Thread Identification Backend
+-----------------------------
+A backend for ``pw::thread::Id`` and ``pw::thread::get_id()`` is offerred using
+``OS_GetTaskID()``. It uses ``DASSERT`` to ensure that the scheduler has started
+via ``OS_IsRunning()``.
+
+--------------------
+Thread Sleep Backend
+--------------------
+A backend for ``pw::thread::sleep_for()`` and ``pw::thread::sleep_until()`` is
+offerred using ``OS_Delay()`` if the duration is at least one tick, else
+``OS_Yield()`` is used. It uses ``pw::this_thread::get_id() != thread::Id()`` to
+ensure it invoked only from a thread.
+
+--------------------
+Thread Yield Backend
+--------------------
+A backend for ``pw::thread::yield()`` is offered using via ``OS_Yield()``.
+It uses ``pw::this_thread::get_id() != thread::Id()`` to ensure it invoked only
+from a thread.