zephyr/doc/kernel/common/common_contexts.rst

100 lines
3.0 KiB
ReStructuredText

.. _context_services:
Execution Context Services
##########################
Concepts
********
Each kernel execution context has an associated *type*, which indicates whether
the context is a task, a fiber, or the kernel's interrupt handling context.
Task and fiber contexts also have an associated *thread identifier* value,
which is used to uniquely identify these threads.
Each task and fiber may also support a 32-bit *thread custom data* value.
This value is accessible only by the task or fiber itself, and can be used
by the application for any purpose. The default custom data value for a
task or fiber is zero.
.. note::
The custom data value is not available to ISRs, which operate in the shared
kernel interrupt handling context.
The kernel allows a task or fiber to delay its processing for a specified time
period by performing a busy wait. This allows the delay to occur without
requiring the kernel to perform the context switching that occurs with its
more typical timer and timeout services.
Purpose
*******
Use the kernel execution context services when writing code that needs to
operate differently when executed by different contexts.
Use the busy wait service when the required delay is too short to warrant
context switching to another task or fiber, or when performing a delay
as part of the nanokernel's background task (which is not allowed to
volutarily relinquish the CPU).
Usage
*****
Configuring Custom Data Support
===============================
Use the :option:`THREAD_CUSTOM_DATA` configuration option
to enable support for thread custom data. By default, custom data
support is disabled.
Example: Performing Execution Context-Specific Processing
=========================================================
This code shows how a routine can use a thread's custom data value
to limit the number of times a thread may call the routine.
Counting is not performed when the routine is called by an ISR, which does not
have a custom data value.
.. note::
Obviously, only a single routine can use this technique
since it monopolizes the use of the custom data value.
.. code-block:: c
#define CALL_LIMIT 7
int call_tracking_routine(void)
{
uint32_t call_count;
if (sys_execution_context_type_get() != NANO_CTX_ISR) {
call_count = (uint32_t)sys_thread_custom_data_get();
if (call_count == CALL_LIMIT)
return -1;
call_count++;
sys_thread_custom_data_set((void *)call_count);
}
/* do rest of routine's processing */
...
}
APIs
****
The following kernel execution context APIs are provided by
:file:`microkernel.h` and by :file:`nanokernel.h`:
:c:func:`sys_thread_self_get()`
Gets thread identifier of currently executing task or fiber.
:c:func:`sys_execution_context_type_get()`
Gets type of currently executing context (i.e. task, fiber, or ISR).
:c:func:`sys_thread_custom_data_set()`
Writes custom data for currently executing task or fiber.
:c:func:`sys_thread_custom_data_get()`
Reads custom data for currently executing task or fiber.