7.3.1. Creating Tasks¶
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.
7.3.2. 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
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.
7.3.3. Starting and Restarting Tasks¶
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.
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.
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.
7.3.4. Suspending and Resuming Tasks¶
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.
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.
7.3.5. Delaying the Currently Executing Task¶
rtems_task_wake_after directive creates a sleep timer which allows a
task to go to sleep for a specified count of clock ticks. The task is blocked
until the count of clock ticks has elapsed, at which time the task is unblocked.
A task calling the
rtems_task_wake_after directive with a delay of
RTEMS_YIELD_PROCESSOR ticks will yield the processor to any other ready
task of equal or greater priority and remain ready to execute.
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
7.3.6. Changing Task Priority¶
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.
rtems_task_restart directive resets the priority of a task to its
7.3.7. Changing Task Mode¶
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.
rtems_task_restart directive resets the mode of a task to its original
7.3.8. 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_exit which deletes the calling task.
Unexpired delay timers (i.e. those used by
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
7.3.9. 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
void pin_to_processor(rtems_id task_id, int processor_index)
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.
7.3.10. Transition Advice for Removed Notepads¶
Task notepads and the associated directives TASK_GET_NOTE - Get task notepad entry and TASK_SET_NOTE - Set task notepad entry 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.
7.3.11. Transition Advice for Removed Task Variables¶
Task notepads and the associated directives TASK_VARIABLE_ADD - Associate per task variable, TASK_VARIABLE_GET - Obtain value of a per task variable and TASK_VARIABLE_DELETE - Remove per task variable 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 RTEMS CPU Architecture Supplement.