mirror of
https://git.rtems.org/rtems-docs/
synced 2025-05-15 05:26:39 +08:00
c-user: Split up task manager
This makes it easier to automatically generate parts of the manager documentation in the future. Update #3993.
This commit is contained in:
parent
e3523ed062
commit
ccb384b623
@ -30,7 +30,7 @@ RTEMS Classic API Guide (|version|).
|
||||
rtems_data_types
|
||||
scheduling_concepts
|
||||
initialization
|
||||
task_manager
|
||||
task/index
|
||||
interrupt/index
|
||||
clock/index
|
||||
timer_manager
|
||||
|
390
c-user/task/background.rst
Normal file
390
c-user/task/background.rst
Normal file
@ -0,0 +1,390 @@
|
||||
.. SPDX-License-Identifier: CC-BY-SA-4.0
|
||||
|
||||
.. Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
|
||||
.. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR)
|
||||
|
||||
Background
|
||||
==========
|
||||
|
||||
.. index:: task, definition
|
||||
|
||||
Task Definition
|
||||
---------------
|
||||
|
||||
Many definitions of a task have been proposed in computer literature.
|
||||
Unfortunately, none of these definitions encompasses all facets of the concept
|
||||
in a manner which is operating system independent. Several of the more common
|
||||
definitions are provided to enable each user to select a definition which best
|
||||
matches their own experience and understanding of the task concept:
|
||||
|
||||
- a "dispatchable" unit.
|
||||
|
||||
- an entity to which the processor is allocated.
|
||||
|
||||
- an atomic unit of a real-time, multiprocessor system.
|
||||
|
||||
- single threads of execution which concurrently compete for resources.
|
||||
|
||||
- a sequence of closely related computations which can execute concurrently
|
||||
with other computational sequences.
|
||||
|
||||
From RTEMS' perspective, a task is the smallest thread of execution which can
|
||||
compete on its own for system resources. A task is manifested by the existence
|
||||
of a task control block (TCB).
|
||||
|
||||
.. _TaskControlBlock:
|
||||
|
||||
Task Control Block
|
||||
------------------
|
||||
|
||||
The Task Control Block (TCB) is an RTEMS defined data structure which contains
|
||||
all the information that is pertinent to the execution of a task. During
|
||||
system initialization, RTEMS reserves a TCB for each task configured. A TCB is
|
||||
allocated upon creation of the task and is returned to the TCB free list upon
|
||||
deletion of the task.
|
||||
|
||||
The TCB's elements are modified as a result of system calls made by the
|
||||
application in response to external and internal stimuli. TCBs are the only
|
||||
RTEMS internal data structure that can be accessed by an application via user
|
||||
extension routines. The TCB contains a task's name, ID, current priority,
|
||||
current and starting states, execution mode, TCB user extension pointer,
|
||||
scheduling control structures, as well as data required by a blocked task.
|
||||
|
||||
A task's context is stored in the TCB when a task switch occurs. When the task
|
||||
regains control of the processor, its context is restored from the TCB. When a
|
||||
task is restarted, the initial state of the task is restored from the starting
|
||||
context area in the task's TCB.
|
||||
|
||||
.. index:: task memory
|
||||
|
||||
Task Memory
|
||||
-----------
|
||||
|
||||
The system uses two separate memory areas to manage a task. One memory area is
|
||||
the :ref:`TaskControlBlock`. The other memory area is allocated from the stack
|
||||
space or provided by the user and contains
|
||||
|
||||
* the task stack,
|
||||
|
||||
* the thread-local storage (:term:`TLS`), and
|
||||
|
||||
* an optional architecture-specific floating-point context.
|
||||
|
||||
The size of the thread-local storage is determined at link time. A
|
||||
user-provided task stack must take the size of the thread-local storage into
|
||||
account.
|
||||
|
||||
On architectures with a dedicated floating-point context, the application
|
||||
configuration assumes that every task is a floating-point task, but whether or
|
||||
not a task is actually floating-point is determined at runtime during task
|
||||
creation (see :ref:`TaskFloatingPointConsiderations`). In highly memory
|
||||
constrained systems this potential overestimate of the task stack space can be
|
||||
mitigated through the :ref:`CONFIGURE_MINIMUM_TASK_STACK_SIZE` configuration
|
||||
option and aligned task stack sizes for the tasks. A user-provided task stack
|
||||
must take the potential floating-point context into account.
|
||||
|
||||
.. index:: task name
|
||||
|
||||
Task Name
|
||||
---------
|
||||
|
||||
By default, the task name is defined by the task object name given to
|
||||
:ref:`rtems_task_create() <rtems_task_create>`. The task name can be obtained
|
||||
with the `pthread_getname_np()
|
||||
<http://man7.org/linux/man-pages/man3/pthread_setname_np.3.html>`_ function.
|
||||
Optionally, a new task name may be set with the `pthread_setname_np()
|
||||
<http://man7.org/linux/man-pages/man3/pthread_setname_np.3.html>`_ function.
|
||||
The maximum size of a task name is defined by the application configuration
|
||||
option :ref:`CONFIGURE_MAXIMUM_THREAD_NAME_SIZE
|
||||
<CONFIGURE_MAXIMUM_THREAD_NAME_SIZE>`.
|
||||
|
||||
.. index:: task states
|
||||
|
||||
Task States
|
||||
-----------
|
||||
|
||||
A task may exist in one of the following five states:
|
||||
|
||||
- *executing* - Currently scheduled to the CPU
|
||||
|
||||
- *ready* - May be scheduled to the CPU
|
||||
|
||||
- *blocked* - Unable to be scheduled to the CPU
|
||||
|
||||
- *dormant* - Created task that is not started
|
||||
|
||||
- *non-existent* - Uncreated or deleted task
|
||||
|
||||
An active task may occupy the executing, ready, blocked or dormant state,
|
||||
otherwise the task is considered non-existent. One or more tasks may be active
|
||||
in the system simultaneously. Multiple tasks communicate, synchronize, and
|
||||
compete for system resources with each other via system calls. The multiple
|
||||
tasks appear to execute in parallel, but actually each is dispatched to the CPU
|
||||
for periods of time determined by the RTEMS scheduling algorithm. The
|
||||
scheduling of a task is based on its current state and priority.
|
||||
|
||||
.. index:: task priority
|
||||
.. index:: priority, task
|
||||
.. index:: rtems_task_priority
|
||||
|
||||
Task Priority
|
||||
-------------
|
||||
|
||||
A task's priority determines its importance in relation to the other tasks
|
||||
executing on the same processor. RTEMS supports 255 levels of priority ranging
|
||||
from 1 to 255. The data type ``rtems_task_priority`` is used to store task
|
||||
priorities.
|
||||
|
||||
Tasks of numerically smaller priority values are more important tasks than
|
||||
tasks of numerically larger priority values. For example, a task at priority
|
||||
level 5 is of higher privilege than a task at priority level 10. There is no
|
||||
limit to the number of tasks assigned to the same priority.
|
||||
|
||||
Each task has a priority associated with it at all times. The initial value of
|
||||
this priority is assigned at task creation time. The priority of a task may be
|
||||
changed at any subsequent time.
|
||||
|
||||
Priorities are used by the scheduler to determine which ready task will be
|
||||
allowed to execute. In general, the higher the logical priority of a task, the
|
||||
more likely it is to receive processor execution time.
|
||||
|
||||
.. index:: task mode
|
||||
.. index:: rtems_task_mode
|
||||
|
||||
Task Mode
|
||||
---------
|
||||
|
||||
A task's execution mode is a combination of the following four components:
|
||||
|
||||
- preemption
|
||||
|
||||
- ASR processing
|
||||
|
||||
- timeslicing
|
||||
|
||||
- interrupt level
|
||||
|
||||
It is used to modify RTEMS' scheduling process and to alter the execution
|
||||
environment of the task. The data type ``rtems_task_mode`` is used to manage
|
||||
the task execution mode.
|
||||
|
||||
.. index:: preemption
|
||||
|
||||
The preemption component allows a task to determine when control of the
|
||||
processor is relinquished. If preemption is disabled (``RTEMS_NO_PREEMPT``),
|
||||
the task will retain control of the processor as long as it is in the executing
|
||||
state - even if a higher priority task is made ready. If preemption is enabled
|
||||
(``RTEMS_PREEMPT``) and a higher priority task is made ready, then the
|
||||
processor will be taken away from the current task immediately and given to the
|
||||
higher priority task.
|
||||
|
||||
.. index:: timeslicing
|
||||
|
||||
The timeslicing component is used by the RTEMS scheduler to determine how the
|
||||
processor is allocated to tasks of equal priority. If timeslicing is enabled
|
||||
(``RTEMS_TIMESLICE``), then RTEMS will limit the amount of time the task can
|
||||
execute before the processor is allocated to another ready task of equal
|
||||
priority. The length of the timeslice is application dependent and specified in
|
||||
the Configuration Table. If timeslicing is disabled (``RTEMS_NO_TIMESLICE``),
|
||||
then the task will be allowed to execute until a task of higher priority is
|
||||
made ready. If ``RTEMS_NO_PREEMPT`` is selected, then the timeslicing component
|
||||
is ignored by the scheduler.
|
||||
|
||||
The asynchronous signal processing component is used to determine when received
|
||||
signals are to be processed by the task. If signal processing is enabled
|
||||
(``RTEMS_ASR``), then signals sent to the task will be processed the next time
|
||||
the task executes. If signal processing is disabled (``RTEMS_NO_ASR``), then
|
||||
all signals received by the task will remain posted until signal processing is
|
||||
enabled. This component affects only tasks which have established a routine to
|
||||
process asynchronous signals.
|
||||
|
||||
.. index:: interrupt level, task
|
||||
|
||||
The interrupt level component is used to determine which interrupts will be
|
||||
enabled when the task is executing. ``RTEMS_INTERRUPT_LEVEL(n)`` specifies that
|
||||
the task will execute at interrupt level n.
|
||||
|
||||
.. list-table::
|
||||
:class: rtems-table
|
||||
|
||||
* - ``RTEMS_PREEMPT``
|
||||
- enable preemption (default)
|
||||
* - ``RTEMS_NO_PREEMPT``
|
||||
- disable preemption
|
||||
* - ``RTEMS_NO_TIMESLICE``
|
||||
- disable timeslicing (default)
|
||||
* - ``RTEMS_TIMESLICE``
|
||||
- enable timeslicing
|
||||
* - ``RTEMS_ASR``
|
||||
- enable ASR processing (default)
|
||||
* - ``RTEMS_NO_ASR``
|
||||
- disable ASR processing
|
||||
* - ``RTEMS_INTERRUPT_LEVEL(0)``
|
||||
- enable all interrupts (default)
|
||||
* - ``RTEMS_INTERRUPT_LEVEL(n)``
|
||||
- execute at interrupt level n
|
||||
|
||||
The set of default modes may be selected by specifying the
|
||||
``RTEMS_DEFAULT_MODES`` constant.
|
||||
|
||||
.. index:: task arguments
|
||||
.. index:: task prototype
|
||||
|
||||
Accessing Task Arguments
|
||||
------------------------
|
||||
|
||||
All RTEMS tasks are invoked with a single argument which is specified when they
|
||||
are started or restarted. The argument is commonly used to communicate startup
|
||||
information to the task. The simplest manner in which to define a task which
|
||||
accesses it argument is:
|
||||
|
||||
.. index:: rtems_task
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
rtems_task user_task(
|
||||
rtems_task_argument argument
|
||||
);
|
||||
|
||||
Application tasks requiring more information may view this single argument as
|
||||
an index into an array of parameter blocks.
|
||||
|
||||
.. index:: floating point
|
||||
|
||||
.. _TaskFloatingPointConsiderations:
|
||||
|
||||
Floating Point Considerations
|
||||
-----------------------------
|
||||
|
||||
Please consult the *RTEMS CPU Architecture Supplement* if this section is
|
||||
relevant on your architecture. On some architectures the floating-point context
|
||||
is contained in the normal task context and this section does not apply.
|
||||
|
||||
Creating a task with the ``RTEMS_FLOATING_POINT`` attribute flag results in
|
||||
additional memory being allocated for the task to store the state of the numeric
|
||||
coprocessor during task switches. This additional memory is **not** allocated
|
||||
for ``RTEMS_NO_FLOATING_POINT`` tasks. Saving and restoring the context of a
|
||||
``RTEMS_FLOATING_POINT`` task takes longer than that of a
|
||||
``RTEMS_NO_FLOATING_POINT`` task because of the relatively large amount of time
|
||||
required for the numeric coprocessor to save or restore its computational state.
|
||||
|
||||
Since RTEMS was designed specifically for embedded military applications which
|
||||
are floating point intensive, the executive is optimized to avoid unnecessarily
|
||||
saving and restoring the state of the numeric coprocessor. In uniprocessor
|
||||
configurations, the state of the numeric coprocessor is only saved when a
|
||||
``RTEMS_FLOATING_POINT`` task is dispatched and that task was not the last task
|
||||
to utilize the coprocessor. In a uniprocessor system with only one
|
||||
``RTEMS_FLOATING_POINT`` task, the state of the numeric coprocessor will never
|
||||
be saved or restored.
|
||||
|
||||
Although the overhead imposed by ``RTEMS_FLOATING_POINT`` tasks is minimal,
|
||||
some applications may wish to completely avoid the overhead associated with
|
||||
``RTEMS_FLOATING_POINT`` tasks and still utilize a numeric coprocessor. By
|
||||
preventing a task from being preempted while performing a sequence of floating
|
||||
point operations, a ``RTEMS_NO_FLOATING_POINT`` task can utilize the numeric
|
||||
coprocessor without incurring the overhead of a ``RTEMS_FLOATING_POINT``
|
||||
context switch. This approach also avoids the allocation of a floating point
|
||||
context area. However, if this approach is taken by the application designer,
|
||||
**no** tasks should be created as ``RTEMS_FLOATING_POINT`` tasks. Otherwise, the
|
||||
floating point context will not be correctly maintained because RTEMS assumes
|
||||
that the state of the numeric coprocessor will not be altered by
|
||||
``RTEMS_NO_FLOATING_POINT`` tasks. Some architectures with a dedicated
|
||||
floating-point context raise a processor exception if a task with
|
||||
``RTEMS_NO_FLOATING_POINT`` issues a floating-point instruction, so this
|
||||
approach may not work at all.
|
||||
|
||||
If the supported processor type does not have hardware floating capabilities or
|
||||
a standard numeric coprocessor, RTEMS will not provide built-in support for
|
||||
hardware floating point on that processor. In this case, all tasks are
|
||||
considered ``RTEMS_NO_FLOATING_POINT`` whether created as
|
||||
``RTEMS_FLOATING_POINT`` or ``RTEMS_NO_FLOATING_POINT`` tasks. A floating
|
||||
point emulation software library must be utilized for floating point
|
||||
operations.
|
||||
|
||||
On some processors, it is possible to disable the floating point unit
|
||||
dynamically. If this capability is supported by the target processor, then
|
||||
RTEMS will utilize this capability to enable the floating point unit only for
|
||||
tasks which are created with the ``RTEMS_FLOATING_POINT`` attribute. The
|
||||
consequence of a ``RTEMS_NO_FLOATING_POINT`` task attempting to access the
|
||||
floating point unit is CPU dependent but will generally result in an exception
|
||||
condition.
|
||||
|
||||
.. index:: task attributes, building
|
||||
|
||||
Building a Task Attribute Set
|
||||
-----------------------------
|
||||
|
||||
In general, an attribute set is built by a bitwise OR of the desired
|
||||
components. The set of valid task attribute components is listed below:
|
||||
|
||||
.. list-table::
|
||||
:class: rtems-table
|
||||
|
||||
* - ``RTEMS_NO_FLOATING_POINT``
|
||||
- does not use coprocessor (default)
|
||||
* - ``RTEMS_FLOATING_POINT``
|
||||
- uses numeric coprocessor
|
||||
* - ``RTEMS_LOCAL``
|
||||
- local task (default)
|
||||
* - ``RTEMS_GLOBAL``
|
||||
- global task
|
||||
|
||||
Attribute values are specifically designed to be mutually exclusive, therefore
|
||||
bitwise OR and addition operations are equivalent as long as each attribute
|
||||
appears exactly once in the component list. A component listed as a default is
|
||||
not required to appear in the component list, although it is a good programming
|
||||
practice to specify default components. If all defaults are desired, then
|
||||
``RTEMS_DEFAULT_ATTRIBUTES`` should be used.
|
||||
|
||||
This example demonstrates the attribute_set parameter needed to create a local
|
||||
task which utilizes the numeric coprocessor. The attribute_set parameter could
|
||||
be ``RTEMS_FLOATING_POINT`` or ``RTEMS_LOCAL | RTEMS_FLOATING_POINT``. The
|
||||
attribute_set parameter can be set to ``RTEMS_FLOATING_POINT`` because
|
||||
``RTEMS_LOCAL`` is the default for all created tasks. If the task were global
|
||||
and used the numeric coprocessor, then the attribute_set parameter would be
|
||||
``RTEMS_GLOBAL | RTEMS_FLOATING_POINT``.
|
||||
|
||||
.. index:: task mode, building
|
||||
|
||||
Building a Mode and Mask
|
||||
------------------------
|
||||
|
||||
In general, a mode and its corresponding mask is built by a bitwise OR of the
|
||||
desired components. The set of valid mode constants and each mode's
|
||||
corresponding mask constant is listed below:
|
||||
|
||||
.. list-table::
|
||||
:class: rtems-table
|
||||
|
||||
* - ``RTEMS_PREEMPT``
|
||||
- is masked by ``RTEMS_PREEMPT_MASK`` and enables preemption
|
||||
* - ``RTEMS_NO_PREEMPT``
|
||||
- is masked by ``RTEMS_PREEMPT_MASK`` and disables preemption
|
||||
* - ``RTEMS_NO_TIMESLICE``
|
||||
- is masked by ``RTEMS_TIMESLICE_MASK`` and disables timeslicing
|
||||
* - ``RTEMS_TIMESLICE``
|
||||
- is masked by ``RTEMS_TIMESLICE_MASK`` and enables timeslicing
|
||||
* - ``RTEMS_ASR``
|
||||
- is masked by ``RTEMS_ASR_MASK`` and enables ASR processing
|
||||
* - ``RTEMS_NO_ASR``
|
||||
- is masked by ``RTEMS_ASR_MASK`` and disables ASR processing
|
||||
* - ``RTEMS_INTERRUPT_LEVEL(0)``
|
||||
- is masked by ``RTEMS_INTERRUPT_MASK`` and enables all interrupts
|
||||
* - ``RTEMS_INTERRUPT_LEVEL(n)``
|
||||
- is masked by ``RTEMS_INTERRUPT_MASK`` and sets interrupts level n
|
||||
|
||||
Mode values are specifically designed to be mutually exclusive, therefore
|
||||
bitwise OR and addition operations are equivalent as long as each mode appears
|
||||
exactly once in the component list. A mode component listed as a default is
|
||||
not required to appear in the mode component list, although it is a good
|
||||
programming practice to specify default components. If all defaults are
|
||||
desired, the mode ``RTEMS_DEFAULT_MODES`` and the mask ``RTEMS_ALL_MODE_MASKS``
|
||||
should be used.
|
||||
|
||||
The following example demonstrates the mode and mask parameters used with the
|
||||
``rtems_task_mode`` directive to place a task at interrupt level 3 and make it
|
||||
non-preemptible. The mode should be set to ``RTEMS_INTERRUPT_LEVEL(3) |
|
||||
RTEMS_NO_PREEMPT`` to indicate the desired preemption mode and interrupt level,
|
||||
while the mask parameter should be set to ``RTEMS_INTERRUPT_MASK |
|
||||
RTEMS_NO_PREEMPT_MASK`` to indicate that the calling task's interrupt level and
|
||||
preemption mode are being altered.
|
@ -3,631 +3,6 @@
|
||||
.. Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
|
||||
.. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR)
|
||||
|
||||
.. index:: tasks
|
||||
|
||||
Task Manager
|
||||
************
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
The task manager provides a comprehensive set of directives to create, delete,
|
||||
and administer tasks. The directives provided by the task manager are:
|
||||
|
||||
- rtems_task_create_ - Create a task
|
||||
|
||||
- rtems_task_ident_ - Get ID of a task
|
||||
|
||||
- rtems_task_self_ - Obtain ID of caller
|
||||
|
||||
- rtems_task_start_ - Start a task
|
||||
|
||||
- rtems_task_restart_ - Restart a task
|
||||
|
||||
- rtems_task_delete_ - Delete a task
|
||||
|
||||
- rtems_task_exit_ - Delete the calling task
|
||||
|
||||
- rtems_task_suspend_ - Suspend a task
|
||||
|
||||
- rtems_task_resume_ - Resume a task
|
||||
|
||||
- rtems_task_is_suspended_ - Determine if a task is suspended
|
||||
|
||||
- rtems_task_set_priority_ - Set task priority
|
||||
|
||||
- rtems_task_get_priority_ - Get task priority
|
||||
|
||||
- rtems_task_mode_ - Change current task's mode
|
||||
|
||||
- rtems_task_wake_after_ - Wake up after interval
|
||||
|
||||
- rtems_task_wake_when_ - Wake up when specified
|
||||
|
||||
- rtems_task_get_scheduler_ - Get scheduler of a task
|
||||
|
||||
- rtems_task_set_scheduler_ - Set scheduler of a task
|
||||
|
||||
- rtems_task_get_affinity_ - Get task processor affinity
|
||||
|
||||
- rtems_task_set_affinity_ - Set task processor affinity
|
||||
|
||||
- rtems_task_iterate_ - Iterate Over Tasks
|
||||
|
||||
Background
|
||||
==========
|
||||
|
||||
.. index:: task, definition
|
||||
|
||||
Task Definition
|
||||
---------------
|
||||
|
||||
Many definitions of a task have been proposed in computer literature.
|
||||
Unfortunately, none of these definitions encompasses all facets of the concept
|
||||
in a manner which is operating system independent. Several of the more common
|
||||
definitions are provided to enable each user to select a definition which best
|
||||
matches their own experience and understanding of the task concept:
|
||||
|
||||
- a "dispatchable" unit.
|
||||
|
||||
- an entity to which the processor is allocated.
|
||||
|
||||
- an atomic unit of a real-time, multiprocessor system.
|
||||
|
||||
- single threads of execution which concurrently compete for resources.
|
||||
|
||||
- a sequence of closely related computations which can execute concurrently
|
||||
with other computational sequences.
|
||||
|
||||
From RTEMS' perspective, a task is the smallest thread of execution which can
|
||||
compete on its own for system resources. A task is manifested by the existence
|
||||
of a task control block (TCB).
|
||||
|
||||
.. _TaskControlBlock:
|
||||
|
||||
Task Control Block
|
||||
------------------
|
||||
|
||||
The Task Control Block (TCB) is an RTEMS defined data structure which contains
|
||||
all the information that is pertinent to the execution of a task. During
|
||||
system initialization, RTEMS reserves a TCB for each task configured. A TCB is
|
||||
allocated upon creation of the task and is returned to the TCB free list upon
|
||||
deletion of the task.
|
||||
|
||||
The TCB's elements are modified as a result of system calls made by the
|
||||
application in response to external and internal stimuli. TCBs are the only
|
||||
RTEMS internal data structure that can be accessed by an application via user
|
||||
extension routines. The TCB contains a task's name, ID, current priority,
|
||||
current and starting states, execution mode, TCB user extension pointer,
|
||||
scheduling control structures, as well as data required by a blocked task.
|
||||
|
||||
A task's context is stored in the TCB when a task switch occurs. When the task
|
||||
regains control of the processor, its context is restored from the TCB. When a
|
||||
task is restarted, the initial state of the task is restored from the starting
|
||||
context area in the task's TCB.
|
||||
|
||||
.. index:: task memory
|
||||
|
||||
Task Memory
|
||||
-----------
|
||||
|
||||
The system uses two separate memory areas to manage a task. One memory area is
|
||||
the :ref:`TaskControlBlock`. The other memory area is allocated from the stack
|
||||
space or provided by the user and contains
|
||||
|
||||
* the task stack,
|
||||
|
||||
* the thread-local storage (:term:`TLS`), and
|
||||
|
||||
* an optional architecture-specific floating-point context.
|
||||
|
||||
The size of the thread-local storage is determined at link time. A
|
||||
user-provided task stack must take the size of the thread-local storage into
|
||||
account.
|
||||
|
||||
On architectures with a dedicated floating-point context, the application
|
||||
configuration assumes that every task is a floating-point task, but whether or
|
||||
not a task is actually floating-point is determined at runtime during task
|
||||
creation (see :ref:`TaskFloatingPointConsiderations`). In highly memory
|
||||
constrained systems this potential overestimate of the task stack space can be
|
||||
mitigated through the :ref:`CONFIGURE_MINIMUM_TASK_STACK_SIZE` configuration
|
||||
option and aligned task stack sizes for the tasks. A user-provided task stack
|
||||
must take the potential floating-point context into account.
|
||||
|
||||
.. index:: task name
|
||||
|
||||
Task Name
|
||||
---------
|
||||
|
||||
By default, the task name is defined by the task object name given to
|
||||
:ref:`rtems_task_create() <rtems_task_create>`. The task name can be obtained
|
||||
with the `pthread_getname_np()
|
||||
<http://man7.org/linux/man-pages/man3/pthread_setname_np.3.html>`_ function.
|
||||
Optionally, a new task name may be set with the `pthread_setname_np()
|
||||
<http://man7.org/linux/man-pages/man3/pthread_setname_np.3.html>`_ function.
|
||||
The maximum size of a task name is defined by the application configuration
|
||||
option :ref:`CONFIGURE_MAXIMUM_THREAD_NAME_SIZE
|
||||
<CONFIGURE_MAXIMUM_THREAD_NAME_SIZE>`.
|
||||
|
||||
.. index:: task states
|
||||
|
||||
Task States
|
||||
-----------
|
||||
|
||||
A task may exist in one of the following five states:
|
||||
|
||||
- *executing* - Currently scheduled to the CPU
|
||||
|
||||
- *ready* - May be scheduled to the CPU
|
||||
|
||||
- *blocked* - Unable to be scheduled to the CPU
|
||||
|
||||
- *dormant* - Created task that is not started
|
||||
|
||||
- *non-existent* - Uncreated or deleted task
|
||||
|
||||
An active task may occupy the executing, ready, blocked or dormant state,
|
||||
otherwise the task is considered non-existent. One or more tasks may be active
|
||||
in the system simultaneously. Multiple tasks communicate, synchronize, and
|
||||
compete for system resources with each other via system calls. The multiple
|
||||
tasks appear to execute in parallel, but actually each is dispatched to the CPU
|
||||
for periods of time determined by the RTEMS scheduling algorithm. The
|
||||
scheduling of a task is based on its current state and priority.
|
||||
|
||||
.. index:: task priority
|
||||
.. index:: priority, task
|
||||
.. index:: rtems_task_priority
|
||||
|
||||
Task Priority
|
||||
-------------
|
||||
|
||||
A task's priority determines its importance in relation to the other tasks
|
||||
executing on the same processor. RTEMS supports 255 levels of priority ranging
|
||||
from 1 to 255. The data type ``rtems_task_priority`` is used to store task
|
||||
priorities.
|
||||
|
||||
Tasks of numerically smaller priority values are more important tasks than
|
||||
tasks of numerically larger priority values. For example, a task at priority
|
||||
level 5 is of higher privilege than a task at priority level 10. There is no
|
||||
limit to the number of tasks assigned to the same priority.
|
||||
|
||||
Each task has a priority associated with it at all times. The initial value of
|
||||
this priority is assigned at task creation time. The priority of a task may be
|
||||
changed at any subsequent time.
|
||||
|
||||
Priorities are used by the scheduler to determine which ready task will be
|
||||
allowed to execute. In general, the higher the logical priority of a task, the
|
||||
more likely it is to receive processor execution time.
|
||||
|
||||
.. index:: task mode
|
||||
.. index:: rtems_task_mode
|
||||
|
||||
Task Mode
|
||||
---------
|
||||
|
||||
A task's execution mode is a combination of the following four components:
|
||||
|
||||
- preemption
|
||||
|
||||
- ASR processing
|
||||
|
||||
- timeslicing
|
||||
|
||||
- interrupt level
|
||||
|
||||
It is used to modify RTEMS' scheduling process and to alter the execution
|
||||
environment of the task. The data type ``rtems_task_mode`` is used to manage
|
||||
the task execution mode.
|
||||
|
||||
.. index:: preemption
|
||||
|
||||
The preemption component allows a task to determine when control of the
|
||||
processor is relinquished. If preemption is disabled (``RTEMS_NO_PREEMPT``),
|
||||
the task will retain control of the processor as long as it is in the executing
|
||||
state - even if a higher priority task is made ready. If preemption is enabled
|
||||
(``RTEMS_PREEMPT``) and a higher priority task is made ready, then the
|
||||
processor will be taken away from the current task immediately and given to the
|
||||
higher priority task.
|
||||
|
||||
.. index:: timeslicing
|
||||
|
||||
The timeslicing component is used by the RTEMS scheduler to determine how the
|
||||
processor is allocated to tasks of equal priority. If timeslicing is enabled
|
||||
(``RTEMS_TIMESLICE``), then RTEMS will limit the amount of time the task can
|
||||
execute before the processor is allocated to another ready task of equal
|
||||
priority. The length of the timeslice is application dependent and specified in
|
||||
the Configuration Table. If timeslicing is disabled (``RTEMS_NO_TIMESLICE``),
|
||||
then the task will be allowed to execute until a task of higher priority is
|
||||
made ready. If ``RTEMS_NO_PREEMPT`` is selected, then the timeslicing component
|
||||
is ignored by the scheduler.
|
||||
|
||||
The asynchronous signal processing component is used to determine when received
|
||||
signals are to be processed by the task. If signal processing is enabled
|
||||
(``RTEMS_ASR``), then signals sent to the task will be processed the next time
|
||||
the task executes. If signal processing is disabled (``RTEMS_NO_ASR``), then
|
||||
all signals received by the task will remain posted until signal processing is
|
||||
enabled. This component affects only tasks which have established a routine to
|
||||
process asynchronous signals.
|
||||
|
||||
.. index:: interrupt level, task
|
||||
|
||||
The interrupt level component is used to determine which interrupts will be
|
||||
enabled when the task is executing. ``RTEMS_INTERRUPT_LEVEL(n)`` specifies that
|
||||
the task will execute at interrupt level n.
|
||||
|
||||
.. list-table::
|
||||
:class: rtems-table
|
||||
|
||||
* - ``RTEMS_PREEMPT``
|
||||
- enable preemption (default)
|
||||
* - ``RTEMS_NO_PREEMPT``
|
||||
- disable preemption
|
||||
* - ``RTEMS_NO_TIMESLICE``
|
||||
- disable timeslicing (default)
|
||||
* - ``RTEMS_TIMESLICE``
|
||||
- enable timeslicing
|
||||
* - ``RTEMS_ASR``
|
||||
- enable ASR processing (default)
|
||||
* - ``RTEMS_NO_ASR``
|
||||
- disable ASR processing
|
||||
* - ``RTEMS_INTERRUPT_LEVEL(0)``
|
||||
- enable all interrupts (default)
|
||||
* - ``RTEMS_INTERRUPT_LEVEL(n)``
|
||||
- execute at interrupt level n
|
||||
|
||||
The set of default modes may be selected by specifying the
|
||||
``RTEMS_DEFAULT_MODES`` constant.
|
||||
|
||||
.. index:: task arguments
|
||||
.. index:: task prototype
|
||||
|
||||
Accessing Task Arguments
|
||||
------------------------
|
||||
|
||||
All RTEMS tasks are invoked with a single argument which is specified when they
|
||||
are started or restarted. The argument is commonly used to communicate startup
|
||||
information to the task. The simplest manner in which to define a task which
|
||||
accesses it argument is:
|
||||
|
||||
.. index:: rtems_task
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
rtems_task user_task(
|
||||
rtems_task_argument argument
|
||||
);
|
||||
|
||||
Application tasks requiring more information may view this single argument as
|
||||
an index into an array of parameter blocks.
|
||||
|
||||
.. index:: floating point
|
||||
|
||||
.. _TaskFloatingPointConsiderations:
|
||||
|
||||
Floating Point Considerations
|
||||
-----------------------------
|
||||
|
||||
Please consult the *RTEMS CPU Architecture Supplement* if this section is
|
||||
relevant on your architecture. On some architectures the floating-point context
|
||||
is contained in the normal task context and this section does not apply.
|
||||
|
||||
Creating a task with the ``RTEMS_FLOATING_POINT`` attribute flag results in
|
||||
additional memory being allocated for the task to store the state of the numeric
|
||||
coprocessor during task switches. This additional memory is **not** allocated
|
||||
for ``RTEMS_NO_FLOATING_POINT`` tasks. Saving and restoring the context of a
|
||||
``RTEMS_FLOATING_POINT`` task takes longer than that of a
|
||||
``RTEMS_NO_FLOATING_POINT`` task because of the relatively large amount of time
|
||||
required for the numeric coprocessor to save or restore its computational state.
|
||||
|
||||
Since RTEMS was designed specifically for embedded military applications which
|
||||
are floating point intensive, the executive is optimized to avoid unnecessarily
|
||||
saving and restoring the state of the numeric coprocessor. In uniprocessor
|
||||
configurations, the state of the numeric coprocessor is only saved when a
|
||||
``RTEMS_FLOATING_POINT`` task is dispatched and that task was not the last task
|
||||
to utilize the coprocessor. In a uniprocessor system with only one
|
||||
``RTEMS_FLOATING_POINT`` task, the state of the numeric coprocessor will never
|
||||
be saved or restored.
|
||||
|
||||
Although the overhead imposed by ``RTEMS_FLOATING_POINT`` tasks is minimal,
|
||||
some applications may wish to completely avoid the overhead associated with
|
||||
``RTEMS_FLOATING_POINT`` tasks and still utilize a numeric coprocessor. By
|
||||
preventing a task from being preempted while performing a sequence of floating
|
||||
point operations, a ``RTEMS_NO_FLOATING_POINT`` task can utilize the numeric
|
||||
coprocessor without incurring the overhead of a ``RTEMS_FLOATING_POINT``
|
||||
context switch. This approach also avoids the allocation of a floating point
|
||||
context area. However, if this approach is taken by the application designer,
|
||||
**no** tasks should be created as ``RTEMS_FLOATING_POINT`` tasks. Otherwise, the
|
||||
floating point context will not be correctly maintained because RTEMS assumes
|
||||
that the state of the numeric coprocessor will not be altered by
|
||||
``RTEMS_NO_FLOATING_POINT`` tasks. Some architectures with a dedicated
|
||||
floating-point context raise a processor exception if a task with
|
||||
``RTEMS_NO_FLOATING_POINT`` issues a floating-point instruction, so this
|
||||
approach may not work at all.
|
||||
|
||||
If the supported processor type does not have hardware floating capabilities or
|
||||
a standard numeric coprocessor, RTEMS will not provide built-in support for
|
||||
hardware floating point on that processor. In this case, all tasks are
|
||||
considered ``RTEMS_NO_FLOATING_POINT`` whether created as
|
||||
``RTEMS_FLOATING_POINT`` or ``RTEMS_NO_FLOATING_POINT`` tasks. A floating
|
||||
point emulation software library must be utilized for floating point
|
||||
operations.
|
||||
|
||||
On some processors, it is possible to disable the floating point unit
|
||||
dynamically. If this capability is supported by the target processor, then
|
||||
RTEMS will utilize this capability to enable the floating point unit only for
|
||||
tasks which are created with the ``RTEMS_FLOATING_POINT`` attribute. The
|
||||
consequence of a ``RTEMS_NO_FLOATING_POINT`` task attempting to access the
|
||||
floating point unit is CPU dependent but will generally result in an exception
|
||||
condition.
|
||||
|
||||
.. index:: task attributes, building
|
||||
|
||||
Building a Task Attribute Set
|
||||
-----------------------------
|
||||
|
||||
In general, an attribute set is built by a bitwise OR of the desired
|
||||
components. The set of valid task attribute components is listed below:
|
||||
|
||||
.. list-table::
|
||||
:class: rtems-table
|
||||
|
||||
* - ``RTEMS_NO_FLOATING_POINT``
|
||||
- does not use coprocessor (default)
|
||||
* - ``RTEMS_FLOATING_POINT``
|
||||
- uses numeric coprocessor
|
||||
* - ``RTEMS_LOCAL``
|
||||
- local task (default)
|
||||
* - ``RTEMS_GLOBAL``
|
||||
- global task
|
||||
|
||||
Attribute values are specifically designed to be mutually exclusive, therefore
|
||||
bitwise OR and addition operations are equivalent as long as each attribute
|
||||
appears exactly once in the component list. A component listed as a default is
|
||||
not required to appear in the component list, although it is a good programming
|
||||
practice to specify default components. If all defaults are desired, then
|
||||
``RTEMS_DEFAULT_ATTRIBUTES`` should be used.
|
||||
|
||||
This example demonstrates the attribute_set parameter needed to create a local
|
||||
task which utilizes the numeric coprocessor. The attribute_set parameter could
|
||||
be ``RTEMS_FLOATING_POINT`` or ``RTEMS_LOCAL | RTEMS_FLOATING_POINT``. The
|
||||
attribute_set parameter can be set to ``RTEMS_FLOATING_POINT`` because
|
||||
``RTEMS_LOCAL`` is the default for all created tasks. If the task were global
|
||||
and used the numeric coprocessor, then the attribute_set parameter would be
|
||||
``RTEMS_GLOBAL | RTEMS_FLOATING_POINT``.
|
||||
|
||||
.. index:: task mode, building
|
||||
|
||||
Building a Mode and Mask
|
||||
------------------------
|
||||
|
||||
In general, a mode and its corresponding mask is built by a bitwise OR of the
|
||||
desired components. The set of valid mode constants and each mode's
|
||||
corresponding mask constant is listed below:
|
||||
|
||||
.. list-table::
|
||||
:class: rtems-table
|
||||
|
||||
* - ``RTEMS_PREEMPT``
|
||||
- is masked by ``RTEMS_PREEMPT_MASK`` and enables preemption
|
||||
* - ``RTEMS_NO_PREEMPT``
|
||||
- is masked by ``RTEMS_PREEMPT_MASK`` and disables preemption
|
||||
* - ``RTEMS_NO_TIMESLICE``
|
||||
- is masked by ``RTEMS_TIMESLICE_MASK`` and disables timeslicing
|
||||
* - ``RTEMS_TIMESLICE``
|
||||
- is masked by ``RTEMS_TIMESLICE_MASK`` and enables timeslicing
|
||||
* - ``RTEMS_ASR``
|
||||
- is masked by ``RTEMS_ASR_MASK`` and enables ASR processing
|
||||
* - ``RTEMS_NO_ASR``
|
||||
- is masked by ``RTEMS_ASR_MASK`` and disables ASR processing
|
||||
* - ``RTEMS_INTERRUPT_LEVEL(0)``
|
||||
- is masked by ``RTEMS_INTERRUPT_MASK`` and enables all interrupts
|
||||
* - ``RTEMS_INTERRUPT_LEVEL(n)``
|
||||
- is masked by ``RTEMS_INTERRUPT_MASK`` and sets interrupts level n
|
||||
|
||||
Mode values are specifically designed to be mutually exclusive, therefore
|
||||
bitwise OR and addition operations are equivalent as long as each mode appears
|
||||
exactly once in the component list. A mode component listed as a default is
|
||||
not required to appear in the mode component list, although it is a good
|
||||
programming practice to specify default components. If all defaults are
|
||||
desired, the mode ``RTEMS_DEFAULT_MODES`` and the mask ``RTEMS_ALL_MODE_MASKS``
|
||||
should be used.
|
||||
|
||||
The following example demonstrates the mode and mask parameters used with the
|
||||
``rtems_task_mode`` directive to place a task at interrupt level 3 and make it
|
||||
non-preemptible. The mode should be set to ``RTEMS_INTERRUPT_LEVEL(3) |
|
||||
RTEMS_NO_PREEMPT`` to indicate the desired preemption mode and interrupt level,
|
||||
while the mask parameter should be set to ``RTEMS_INTERRUPT_MASK |
|
||||
RTEMS_NO_PREEMPT_MASK`` to indicate that the calling task's interrupt level and
|
||||
preemption mode are being altered.
|
||||
|
||||
Operations
|
||||
==========
|
||||
|
||||
Creating Tasks
|
||||
--------------
|
||||
|
||||
The ``rtems_task_create`` directive creates a task by allocating a task control
|
||||
block, assigning the task a user-specified name, allocating it a stack and
|
||||
floating point context area, setting a user-specified initial priority, setting
|
||||
a user-specified initial mode, and assigning it a task ID. Newly created tasks
|
||||
are initially placed in the dormant state. All RTEMS tasks execute in the most
|
||||
privileged mode of the processor.
|
||||
|
||||
Obtaining Task IDs
|
||||
------------------
|
||||
|
||||
When a task is created, RTEMS generates a unique task ID and assigns it to the
|
||||
created task until it is deleted. The task ID may be obtained by either of two
|
||||
methods. First, as the result of an invocation of the ``rtems_task_create``
|
||||
directive, the task ID is stored in a user provided location. Second, the task
|
||||
ID may be obtained later using the ``rtems_task_ident`` directive. The task ID
|
||||
is used by other directives to manipulate this task.
|
||||
|
||||
Starting and Restarting Tasks
|
||||
-----------------------------
|
||||
|
||||
The ``rtems_task_start`` directive is used to place a dormant task in the ready
|
||||
state. This enables the task to compete, based on its current priority, for
|
||||
the processor and other system resources. Any actions, such as suspension or
|
||||
change of priority, performed on a task prior to starting it are nullified when
|
||||
the task is started.
|
||||
|
||||
With the ``rtems_task_start`` directive the user specifies the task's starting
|
||||
address and argument. The argument is used to communicate some startup
|
||||
information to the task. As part of this directive, RTEMS initializes the
|
||||
task's stack based upon the task's initial execution mode and start address.
|
||||
The starting argument is passed to the task in accordance with the target
|
||||
processor's calling convention.
|
||||
|
||||
The ``rtems_task_restart`` directive restarts a task at its initial starting
|
||||
address with its original priority and execution mode, but with a possibly
|
||||
different argument. The new argument may be used to distinguish between the
|
||||
original invocation of the task and subsequent invocations. The task's stack
|
||||
and control block are modified to reflect their original creation values.
|
||||
Although references to resources that have been requested are cleared,
|
||||
resources allocated by the task are NOT automatically returned to RTEMS. A
|
||||
task cannot be restarted unless it has previously been started (i.e. dormant
|
||||
tasks cannot be restarted). All restarted tasks are placed in the ready state.
|
||||
|
||||
Suspending and Resuming Tasks
|
||||
-----------------------------
|
||||
|
||||
The ``rtems_task_suspend`` directive is used to place either the caller or
|
||||
another task into a suspended state. The task remains suspended until a
|
||||
``rtems_task_resume`` directive is issued. This implies that a task may be
|
||||
suspended as well as blocked waiting either to acquire a resource or for the
|
||||
expiration of a timer.
|
||||
|
||||
The ``rtems_task_resume`` directive is used to remove another task from the
|
||||
suspended state. If the task is not also blocked, resuming it will place it in
|
||||
the ready state, allowing it to once again compete for the processor and
|
||||
resources. If the task was blocked as well as suspended, this directive clears
|
||||
the suspension and leaves the task in the blocked state.
|
||||
|
||||
Suspending a task which is already suspended or resuming a task which is not
|
||||
suspended is considered an error. The ``rtems_task_is_suspended`` can be used
|
||||
to determine if a task is currently suspended.
|
||||
|
||||
Delaying the Currently Executing Task
|
||||
-------------------------------------
|
||||
|
||||
The ``rtems_task_wake_after`` directive creates a sleep timer which allows a
|
||||
task to go to sleep for a specified interval. The task is blocked until the
|
||||
delay interval has elapsed, at which time the task is unblocked. A task
|
||||
calling the ``rtems_task_wake_after`` directive with a delay interval of
|
||||
``RTEMS_YIELD_PROCESSOR`` ticks will yield the processor to any other ready
|
||||
task of equal or greater priority and remain ready to execute.
|
||||
|
||||
The ``rtems_task_wake_when`` directive creates a sleep timer which allows a
|
||||
task to go to sleep until a specified date and time. The calling task is
|
||||
blocked until the specified date and time has occurred, at which time the task
|
||||
is unblocked.
|
||||
|
||||
Changing Task Priority
|
||||
----------------------
|
||||
|
||||
The ``rtems_task_set_priority`` directive is used to obtain or change the
|
||||
current priority of either the calling task or another task. If the new
|
||||
priority requested is ``RTEMS_CURRENT_PRIORITY`` or the task's actual priority,
|
||||
then the current priority will be returned and the task's priority will remain
|
||||
unchanged. If the task's priority is altered, then the task will be scheduled
|
||||
according to its new priority.
|
||||
|
||||
The ``rtems_task_restart`` directive resets the priority of a task to its
|
||||
original value.
|
||||
|
||||
Changing Task Mode
|
||||
------------------
|
||||
|
||||
The ``rtems_task_mode`` directive is used to obtain or change the current
|
||||
execution mode of the calling task. A task's execution mode is used to enable
|
||||
preemption, timeslicing, ASR processing, and to set the task's interrupt level.
|
||||
|
||||
The ``rtems_task_restart`` directive resets the mode of a task to its original
|
||||
value.
|
||||
|
||||
Task Deletion
|
||||
-------------
|
||||
|
||||
RTEMS provides the ``rtems_task_delete`` directive to allow a task to delete
|
||||
itself or any other task. This directive removes all RTEMS references to the
|
||||
task, frees the task's control block, removes it from resource wait queues, and
|
||||
deallocates its stack as well as the optional floating point context. The
|
||||
task's name and ID become inactive at this time, and any subsequent references
|
||||
to either of them is invalid. In fact, RTEMS may reuse the task ID for another
|
||||
task which is created later in the application. A specialization of
|
||||
``rtems_task_delete`` is ``rtems_task_exit`` which deletes the calling task.
|
||||
|
||||
Unexpired delay timers (i.e. those used by ``rtems_task_wake_after`` and
|
||||
``rtems_task_wake_when``) and timeout timers associated with the task are
|
||||
automatically deleted, however, other resources dynamically allocated by the
|
||||
task are NOT automatically returned to RTEMS. Therefore, before a task is
|
||||
deleted, all of its dynamically allocated resources should be deallocated by
|
||||
the user. This may be accomplished by instructing the task to delete itself
|
||||
rather than directly deleting the task. Other tasks may instruct a task to
|
||||
delete itself by sending a "delete self" message, event, or signal, or by
|
||||
restarting the task with special arguments which instruct the task to delete
|
||||
itself.
|
||||
|
||||
Setting Affinity to a Single Processor
|
||||
--------------------------------------
|
||||
|
||||
On some embedded applications targeting SMP systems, it may be beneficial to
|
||||
lock individual tasks to specific processors. In this way, one can designate a
|
||||
processor for I/O tasks, another for computation, etc.. The following
|
||||
illustrates the code sequence necessary to assign a task an affinity for
|
||||
processor with index ``processor_index``.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include <rtems.h>
|
||||
#include <assert.h>
|
||||
|
||||
void pin_to_processor(rtems_id task_id, int processor_index)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(processor_index, &cpuset);
|
||||
sc = rtems_task_set_affinity(task_id, sizeof(cpuset), &cpuset);
|
||||
assert(sc == RTEMS_SUCCESSFUL);
|
||||
}
|
||||
|
||||
It is important to note that the ``cpuset`` is not validated until the
|
||||
``rtems_task_set_affinity`` call is made. At that point, it is validated
|
||||
against the current system configuration.
|
||||
|
||||
.. index:: rtems_task_get_note
|
||||
.. index:: rtems_task_set_note
|
||||
|
||||
Transition Advice for Removed Notepads
|
||||
---------------------------------------
|
||||
|
||||
Task notepads and the associated directives :ref:`rtems_task_get_note` and
|
||||
:ref:`rtems_task_set_note` were removed in RTEMS 5.1. These were never
|
||||
thread-safe to access and subject to conflicting use of the notepad index by
|
||||
libraries which were designed independently.
|
||||
|
||||
It is recommended that applications be modified to use services which are
|
||||
thread safe and not subject to issues with multiple applications conflicting
|
||||
over the key (e.g. notepad index) selection. For most applications, POSIX Keys
|
||||
should be used. These are available in all RTEMS build configurations. It is
|
||||
also possible that thread-local storage (TLS) is an option for some use cases.
|
||||
|
||||
.. index:: rtems_task_variable_add
|
||||
.. index:: rtems_task_variable_get
|
||||
.. index:: rtems_task_variable_delete
|
||||
|
||||
Transition Advice for Removed Task Variables
|
||||
---------------------------------------------
|
||||
|
||||
Task notepads and the associated directives :ref:`rtems_task_variable_add`,
|
||||
:ref:`rtems_task_variable_get` and :ref:`rtems_task_variable_delete` were
|
||||
removed in RTEMS 5.1. Task variables must be replaced by POSIX Keys or
|
||||
thread-local storage (TLS). POSIX Keys are available in all configurations and
|
||||
support value destructors. For the TLS support consult the :title:`RTEMS CPU
|
||||
Architecture Supplement`.
|
||||
|
||||
Directives
|
||||
==========
|
||||
|
15
c-user/task/index.rst
Normal file
15
c-user/task/index.rst
Normal file
@ -0,0 +1,15 @@
|
||||
.. SPDX-License-Identifier: CC-BY-SA-4.0
|
||||
|
||||
.. Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
|
||||
|
||||
.. index:: tasks
|
||||
|
||||
Task Manager
|
||||
************
|
||||
|
||||
.. toctree::
|
||||
|
||||
introduction
|
||||
background
|
||||
operations
|
||||
directives
|
50
c-user/task/introduction.rst
Normal file
50
c-user/task/introduction.rst
Normal file
@ -0,0 +1,50 @@
|
||||
.. SPDX-License-Identifier: CC-BY-SA-4.0
|
||||
|
||||
.. Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
|
||||
.. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR)
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
The task manager provides a comprehensive set of directives to create, delete,
|
||||
and administer tasks. The directives provided by the task manager are:
|
||||
|
||||
- :ref:`rtems_task_create`
|
||||
|
||||
- :ref:`rtems_task_ident`
|
||||
|
||||
- :ref:`rtems_task_self`
|
||||
|
||||
- :ref:`rtems_task_start`
|
||||
|
||||
- :ref:`rtems_task_restart`
|
||||
|
||||
- :ref:`rtems_task_delete`
|
||||
|
||||
- :ref:`rtems_task_exit`
|
||||
|
||||
- :ref:`rtems_task_suspend`
|
||||
|
||||
- :ref:`rtems_task_resume`
|
||||
|
||||
- :ref:`rtems_task_is_suspended`
|
||||
|
||||
- :ref:`rtems_task_set_priority`
|
||||
|
||||
- :ref:`rtems_task_get_priority`
|
||||
|
||||
- :ref:`rtems_task_mode`
|
||||
|
||||
- :ref:`rtems_task_wake_after`
|
||||
|
||||
- :ref:`rtems_task_wake_when`
|
||||
|
||||
- :ref:`rtems_task_get_scheduler`
|
||||
|
||||
- :ref:`rtems_task_set_scheduler`
|
||||
|
||||
- :ref:`rtems_task_get_affinity`
|
||||
|
||||
- :ref:`rtems_task_set_affinity`
|
||||
|
||||
- :ref:`rtems_task_iterate`
|
192
c-user/task/operations.rst
Normal file
192
c-user/task/operations.rst
Normal file
@ -0,0 +1,192 @@
|
||||
.. SPDX-License-Identifier: CC-BY-SA-4.0
|
||||
|
||||
.. Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
|
||||
.. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR)
|
||||
|
||||
Operations
|
||||
==========
|
||||
|
||||
Creating Tasks
|
||||
--------------
|
||||
|
||||
The ``rtems_task_create`` directive creates a task by allocating a task control
|
||||
block, assigning the task a user-specified name, allocating it a stack and
|
||||
floating point context area, setting a user-specified initial priority, setting
|
||||
a user-specified initial mode, and assigning it a task ID. Newly created tasks
|
||||
are initially placed in the dormant state. All RTEMS tasks execute in the most
|
||||
privileged mode of the processor.
|
||||
|
||||
Obtaining Task IDs
|
||||
------------------
|
||||
|
||||
When a task is created, RTEMS generates a unique task ID and assigns it to the
|
||||
created task until it is deleted. The task ID may be obtained by either of two
|
||||
methods. First, as the result of an invocation of the ``rtems_task_create``
|
||||
directive, the task ID is stored in a user provided location. Second, the task
|
||||
ID may be obtained later using the ``rtems_task_ident`` directive. The task ID
|
||||
is used by other directives to manipulate this task.
|
||||
|
||||
Starting and Restarting Tasks
|
||||
-----------------------------
|
||||
|
||||
The ``rtems_task_start`` directive is used to place a dormant task in the ready
|
||||
state. This enables the task to compete, based on its current priority, for
|
||||
the processor and other system resources. Any actions, such as suspension or
|
||||
change of priority, performed on a task prior to starting it are nullified when
|
||||
the task is started.
|
||||
|
||||
With the ``rtems_task_start`` directive the user specifies the task's starting
|
||||
address and argument. The argument is used to communicate some startup
|
||||
information to the task. As part of this directive, RTEMS initializes the
|
||||
task's stack based upon the task's initial execution mode and start address.
|
||||
The starting argument is passed to the task in accordance with the target
|
||||
processor's calling convention.
|
||||
|
||||
The ``rtems_task_restart`` directive restarts a task at its initial starting
|
||||
address with its original priority and execution mode, but with a possibly
|
||||
different argument. The new argument may be used to distinguish between the
|
||||
original invocation of the task and subsequent invocations. The task's stack
|
||||
and control block are modified to reflect their original creation values.
|
||||
Although references to resources that have been requested are cleared,
|
||||
resources allocated by the task are NOT automatically returned to RTEMS. A
|
||||
task cannot be restarted unless it has previously been started (i.e. dormant
|
||||
tasks cannot be restarted). All restarted tasks are placed in the ready state.
|
||||
|
||||
Suspending and Resuming Tasks
|
||||
-----------------------------
|
||||
|
||||
The ``rtems_task_suspend`` directive is used to place either the caller or
|
||||
another task into a suspended state. The task remains suspended until a
|
||||
``rtems_task_resume`` directive is issued. This implies that a task may be
|
||||
suspended as well as blocked waiting either to acquire a resource or for the
|
||||
expiration of a timer.
|
||||
|
||||
The ``rtems_task_resume`` directive is used to remove another task from the
|
||||
suspended state. If the task is not also blocked, resuming it will place it in
|
||||
the ready state, allowing it to once again compete for the processor and
|
||||
resources. If the task was blocked as well as suspended, this directive clears
|
||||
the suspension and leaves the task in the blocked state.
|
||||
|
||||
Suspending a task which is already suspended or resuming a task which is not
|
||||
suspended is considered an error. The ``rtems_task_is_suspended`` can be used
|
||||
to determine if a task is currently suspended.
|
||||
|
||||
Delaying the Currently Executing Task
|
||||
-------------------------------------
|
||||
|
||||
The ``rtems_task_wake_after`` directive creates a sleep timer which allows a
|
||||
task to go to sleep for a specified interval. The task is blocked until the
|
||||
delay interval has elapsed, at which time the task is unblocked. A task
|
||||
calling the ``rtems_task_wake_after`` directive with a delay interval of
|
||||
``RTEMS_YIELD_PROCESSOR`` ticks will yield the processor to any other ready
|
||||
task of equal or greater priority and remain ready to execute.
|
||||
|
||||
The ``rtems_task_wake_when`` directive creates a sleep timer which allows a
|
||||
task to go to sleep until a specified date and time. The calling task is
|
||||
blocked until the specified date and time has occurred, at which time the task
|
||||
is unblocked.
|
||||
|
||||
Changing Task Priority
|
||||
----------------------
|
||||
|
||||
The ``rtems_task_set_priority`` directive is used to obtain or change the
|
||||
current priority of either the calling task or another task. If the new
|
||||
priority requested is ``RTEMS_CURRENT_PRIORITY`` or the task's actual priority,
|
||||
then the current priority will be returned and the task's priority will remain
|
||||
unchanged. If the task's priority is altered, then the task will be scheduled
|
||||
according to its new priority.
|
||||
|
||||
The ``rtems_task_restart`` directive resets the priority of a task to its
|
||||
original value.
|
||||
|
||||
Changing Task Mode
|
||||
------------------
|
||||
|
||||
The ``rtems_task_mode`` directive is used to obtain or change the current
|
||||
execution mode of the calling task. A task's execution mode is used to enable
|
||||
preemption, timeslicing, ASR processing, and to set the task's interrupt level.
|
||||
|
||||
The ``rtems_task_restart`` directive resets the mode of a task to its original
|
||||
value.
|
||||
|
||||
Task Deletion
|
||||
-------------
|
||||
|
||||
RTEMS provides the ``rtems_task_delete`` directive to allow a task to delete
|
||||
itself or any other task. This directive removes all RTEMS references to the
|
||||
task, frees the task's control block, removes it from resource wait queues, and
|
||||
deallocates its stack as well as the optional floating point context. The
|
||||
task's name and ID become inactive at this time, and any subsequent references
|
||||
to either of them is invalid. In fact, RTEMS may reuse the task ID for another
|
||||
task which is created later in the application. A specialization of
|
||||
``rtems_task_delete`` is ``rtems_task_exit`` which deletes the calling task.
|
||||
|
||||
Unexpired delay timers (i.e. those used by ``rtems_task_wake_after`` and
|
||||
``rtems_task_wake_when``) and timeout timers associated with the task are
|
||||
automatically deleted, however, other resources dynamically allocated by the
|
||||
task are NOT automatically returned to RTEMS. Therefore, before a task is
|
||||
deleted, all of its dynamically allocated resources should be deallocated by
|
||||
the user. This may be accomplished by instructing the task to delete itself
|
||||
rather than directly deleting the task. Other tasks may instruct a task to
|
||||
delete itself by sending a "delete self" message, event, or signal, or by
|
||||
restarting the task with special arguments which instruct the task to delete
|
||||
itself.
|
||||
|
||||
Setting Affinity to a Single Processor
|
||||
--------------------------------------
|
||||
|
||||
On some embedded applications targeting SMP systems, it may be beneficial to
|
||||
lock individual tasks to specific processors. In this way, one can designate a
|
||||
processor for I/O tasks, another for computation, etc.. The following
|
||||
illustrates the code sequence necessary to assign a task an affinity for
|
||||
processor with index ``processor_index``.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include <rtems.h>
|
||||
#include <assert.h>
|
||||
|
||||
void pin_to_processor(rtems_id task_id, int processor_index)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(processor_index, &cpuset);
|
||||
sc = rtems_task_set_affinity(task_id, sizeof(cpuset), &cpuset);
|
||||
assert(sc == RTEMS_SUCCESSFUL);
|
||||
}
|
||||
|
||||
It is important to note that the ``cpuset`` is not validated until the
|
||||
``rtems_task_set_affinity`` call is made. At that point, it is validated
|
||||
against the current system configuration.
|
||||
|
||||
.. index:: rtems_task_get_note
|
||||
.. index:: rtems_task_set_note
|
||||
|
||||
Transition Advice for Removed Notepads
|
||||
---------------------------------------
|
||||
|
||||
Task notepads and the associated directives :ref:`rtems_task_get_note` and
|
||||
:ref:`rtems_task_set_note` were removed in RTEMS 5.1. These were never
|
||||
thread-safe to access and subject to conflicting use of the notepad index by
|
||||
libraries which were designed independently.
|
||||
|
||||
It is recommended that applications be modified to use services which are
|
||||
thread safe and not subject to issues with multiple applications conflicting
|
||||
over the key (e.g. notepad index) selection. For most applications, POSIX Keys
|
||||
should be used. These are available in all RTEMS build configurations. It is
|
||||
also possible that thread-local storage (TLS) is an option for some use cases.
|
||||
|
||||
.. index:: rtems_task_variable_add
|
||||
.. index:: rtems_task_variable_get
|
||||
.. index:: rtems_task_variable_delete
|
||||
|
||||
Transition Advice for Removed Task Variables
|
||||
---------------------------------------------
|
||||
|
||||
Task notepads and the associated directives :ref:`rtems_task_variable_add`,
|
||||
:ref:`rtems_task_variable_get` and :ref:`rtems_task_variable_delete` were
|
||||
removed in RTEMS 5.1. Task variables must be replaced by POSIX Keys or
|
||||
thread-local storage (TLS). POSIX Keys are available in all configurations and
|
||||
support value destructors. For the TLS support consult the :title:`RTEMS CPU
|
||||
Architecture Supplement`.
|
Loading…
x
Reference in New Issue
Block a user