102 lines
3.1 KiB
ReStructuredText
102 lines
3.1 KiB
ReStructuredText
.. _common_contexts:
|
|
|
|
Execution Context Services
|
|
##########################
|
|
|
|
Concepts
|
|
********
|
|
|
|
Every kernel execution context has an associated *type* that indicates whether
|
|
the context is a task, a fiber, or the kernel's interrupt handling context.
|
|
|
|
All task and fiber contexts have a unique *thread identifier* value used to
|
|
uniquely identify them. Each task and fiber can also support a 32-bit *thread
|
|
custom data* value. This value is accessible only by the task or fiber itself,
|
|
and may 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 because these operate
|
|
only within the shared kernel interrupt handling context.
|
|
|
|
The kernel permits a task or a fiber to perform a ``busy wait``, thus delaying
|
|
its processing for a specified time period. Such a delay occurs without
|
|
requiring the kernel to perform context switching, as it typically does with
|
|
timer and timeout services.
|
|
|
|
|
|
Purpose
|
|
*******
|
|
|
|
Use kernel execution context services when writing code that should
|
|
operate differently when it is 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. The ``busy wait``
|
|
service may also be used when performing a delay as part of the
|
|
nanokernel's background task in a nanokernel-only system; this task is
|
|
not allowed to voluntarily relinquish the CPU.
|
|
|
|
|
|
Usage
|
|
*****
|
|
|
|
Configuring Custom Data Support
|
|
===============================
|
|
|
|
Use the :option:`CONFIG_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. Note that
|
|
counting is not performed when the routine is called by an ISR; ISRs
|
|
do 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 common to both
|
|
:file:`microkernel.h` and :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.
|