Clean up.

This commit is contained in:
Chris Johns 2016-02-18 15:29:28 +11:00 committed by Amar Takhar
parent 1762611192
commit 0d86b7111e
10 changed files with 1630 additions and 1219 deletions

View File

@ -1,3 +1,6 @@
.. COMMENT: Copyright 2014 Gedare Bloom.
.. COMMENT: All rights reserved.
Chains
######
@ -7,89 +10,83 @@ Introduction
============
The Chains API is an interface to the Super Core (score) chain
implementation. The Super Core uses chains for all list type
functions. This includes wait queues and task queues. The Chains API
provided by RTEMS is:
- build_id
implementation. The Super Core uses chains for all list type functions. This
includes wait queues and task queues. The Chains API provided by RTEMS is:
- ``rtems_chain_node`` - Chain node used in user objects
- ``rtems_chain_control`` - Chain control node
- ``rtems_chain_initialize`` - initialize the chain with nodes
- rtems_chain_initialize_ - initialize the chain with nodes
- ``rtems_chain_initialize_empty`` - initialize the chain as empty
- rtems_chain_initialize_empty_ - initialize the chain as empty
- ``rtems_chain_is_null_node`` - Is the node NULL ?
- rtems_chain_is_null_node_ - Is the node NULL ?
- ``rtems_chain_head`` - Return the chain's head
- rtems_chain_head_ - Return the chain's head
- ``rtems_chain_tail`` - Return the chain's tail
- rtems_chain_tail_ - Return the chain's tail
- ``rtems_chain_are_nodes_equal`` - Are the node's equal ?
- rtems_chain_are_nodes_equal_ - Are the node's equal ?
- ``rtems_chain_is_empty`` - Is the chain empty ?
- rtems_chain_is_empty_ - Is the chain empty ?
- ``rtems_chain_is_first`` - Is the Node the first in the chain ?
- rtems_chain_is_first_ - Is the Node the first in the chain ?
- ``rtems_chain_is_last`` - Is the Node the last in the chain ?
- rtems_chain_is_last_ - Is the Node the last in the chain ?
- ``rtems_chain_has_only_one_node`` - Does the node have one node ?
- rtems_chain_has_only_one_node_ - Does the node have one node ?
- ``rtems_chain_node_count_unprotected`` - Returns the node count of the chain (unprotected)
- rtems_chain_node_count_unprotected_ - Returns the node count of the chain (unprotected)
- ``rtems_chain_is_head`` - Is the node the head ?
- rtems_chain_is_head_ - Is the node the head ?
- ``rtems_chain_is_tail`` - Is the node the tail ?
- rtems_chain_is_tail_ - Is the node the tail ?
- ``rtems_chain_extract`` - Extract the node from the chain
- rtems_chain_extract_ - Extract the node from the chain
- ``rtems_chain_extract_unprotected`` - Extract the node from the chain (unprotected)
- rtems_chain_extract_unprotected_ - Extract the node from the chain (unprotected)
- ``rtems_chain_get`` - Return the first node on the chain
- rtems_chain_get_ - Return the first node on the chain
- ``rtems_chain_get_unprotected`` - Return the first node on the chain (unprotected)
- rtems_chain_get_unprotected_ - Return the first node on the chain (unprotected)
- ``rtems_chain_get_first_unprotected`` - Get the first node on the chain (unprotected)
- rtems_chain_insert_ - Insert the node into the chain
- ``rtems_chain_insert`` - Insert the node into the chain
- rtems_chain_insert_unprotected_ - Insert the node into the chain (unprotected)
- ``rtems_chain_insert_unprotected`` - Insert the node into the chain (unprotected)
- rtems_chain_append_ - Append the node to chain
- ``rtems_chain_append`` - Append the node to chain
- rtems_chain_append_unprotected_ - Append the node to chain (unprotected)
- ``rtems_chain_append_unprotected`` - Append the node to chain (unprotected)
- rtems_chain_prepend_ - Prepend the node to the end of the chain
- ``rtems_chain_prepend`` - Prepend the node to the end of the chain
- ``rtems_chain_prepend_unprotected`` - Prepend the node to chain (unprotected)
- rtems_chain_prepend_unprotected_ - Prepend the node to chain (unprotected)
Background
==========
The Chains API maps to the Super Core Chains API. Chains are
implemented as a double linked list of nodes anchored to a control
node. The list starts at the control node and is terminated at the
control node. A node has previous and next pointers. Being a double
linked list nodes can be inserted and removed without the need to
travse the chain.
The Chains API maps to the Super Core Chains API. Chains are implemented as a
double linked list of nodes anchored to a control node. The list starts at the
control node and is terminated at the control node. A node has previous and
next pointers. Being a double linked list nodes can be inserted and removed
without the need to travse the chain.
Chains have a small memory footprint and can be used in interrupt
service routines and are thread safe in a multi-threaded
environment. The directives list which operations disable interrupts.
Chains have a small memory footprint and can be used in interrupt service
routines and are thread safe in a multi-threaded environment. The directives
list which operations disable interrupts.
Chains are very useful in Board Support packages and applications.
Nodes
-----
A chain is made up from nodes that orginate from a chain control
object. A node is of type ``rtems_chain_node``. The node
is designed to be part of a user data structure and a cast is used to
move from the node address to the user data structure address. For
example:
.. code:: c
A chain is made up from nodes that orginate from a chain control object. A node
is of type ``rtems_chain_node``. The node is designed to be part of a user data
structure and a cast is used to move from the node address to the user data
structure address. For example:
.. code-block:: c
typedef struct foo
{
@ -97,39 +94,38 @@ example:
int bar;
} foo;
creates a type ``foo`` that can be placed on a chain. To get the
foo structure from the list you perform the following:
.. code:: c
creates a type ``foo`` that can be placed on a chain. To get the foo structure
from the list you perform the following:
.. code-block:: c
foo* get_foo(rtems_chain_control* control)
{
return (foo*) rtems_chain_get(control);
}
The node is placed at the start of the user's structure to allow the
node address on the chain to be easly cast to the user's structure
address.
The node is placed at the start of the user's structure to allow the node
address on the chain to be easly cast to the user's structure address.
Controls
--------
A chain is anchored with a control object. Chain control provide the
user with access to the nodes on the chain. The control is head of the
node.
A chain is anchored with a control object. Chain control provide the user with
access to the nodes on the chain. The control is head of the node.
.. code:: c
.. code-block:: c
Control
[Control]
first ------------------------>
permanent_null <--------------- NODE
permanent_null <--------------- [NODE]
last ------------------------->
The implementation does not require special checks for manipulating
the first and last nodes on the chain. To accomplish this the``rtems_chain_control`` structure is treated as two
overlapping ``rtems_chain_node`` structures. The
permanent head of the chain overlays a node structure on the first and``permanent_null`` fields. The ``permanent_tail`` of the chain
overlays a node structure on the ``permanent_null`` and ``last``
elements of the structure.
The implementation does not require special checks for manipulating the first
and last nodes on the chain. To accomplish this the ``rtems_chain_control``
structure is treated as two overlapping ``rtems_chain_node`` structures. The
permanent head of the chain overlays a node structure on the first and
``permanent_null`` fields. The ``permanent_tail`` of the chain overlays a node
structure on the ``permanent_null`` and ``last`` elements of the structure.
Operations
==========
@ -137,21 +133,21 @@ Operations
Multi-threading
---------------
Chains are designed to be used in a multi-threading environment. The
directives list which operations mask interrupts. Chains supports
tasks and interrupt service routines appending and extracting nodes
with out the need for extra locks. Chains how-ever cannot insure the
integrity of a chain for all operations. This is the responsibility of
the user. For example an interrupt service routine extracting nodes
while a task is iterating over the chain can have unpredictable
results.
Chains are designed to be used in a multi-threading environment. The directives
list which operations mask interrupts. Chains supports tasks and interrupt
service routines appending and extracting nodes with out the need for extra
locks. Chains how-ever cannot insure the integrity of a chain for all
operations. This is the responsibility of the user. For example an interrupt
service routine extracting nodes while a task is iterating over the chain can
have unpredictable results.
Creating a Chain
----------------
To create a chain you need to declare a chain control then add nodes
to the control. Consider a user structure and chain control:
.. code:: c
.. code-block:: c
typedef struct foo
{
@ -161,9 +157,11 @@ to the control. Consider a user structure and chain control:
rtems_chain_control chain;
Add nodes with the following code:
.. code:: c
.. code-block:: c
rtems_chain_initialize_empty (&chain);
for (i = 0; i < count; i++)
{
foo* bar = malloc (sizeof (foo));
@ -180,11 +178,12 @@ Iterating a Chain
-----------------
.. index:: chain iterate
Iterating a chain is a common function. The example shows how to
iterate the buffer pool chain created in the last section to find
buffers starting with a specific string. If the buffer is located it is
extracted from the chain and placed on another chain:
.. code:: c
Iterating a chain is a common function. The example shows how to iterate the
buffer pool chain created in the last section to find buffers starting with a
specific string. If the buffer is located it is extracted from the chain and
placed on another chain:
.. code-block:: c
void foobar (const char* match,
rtems_chain_control* chain,
@ -192,7 +191,9 @@ extracted from the chain and placed on another chain:
{
rtems_chain_node* node;
foo* bar;
rtems_chain_initialize_empty (out);
node = chain->first;
while (!rtems_chain_is_tail (chain, node))
{
@ -214,6 +215,8 @@ The section details the Chains directives.
.. COMMENT: Initialize this Chain With Nodes
.. _rtems_chain_initialize:
Initialize Chain With Nodes
---------------------------
.. index:: chain initialize
@ -222,11 +225,11 @@ Initialize Chain With Nodes
.. index:: rtems_chain_initialize
.. code:: c
.. code-block:: c
void rtems_chain_initialize(
rtems_chain_control \*the_chain,
void \*starting_address,
rtems_chain_control *the_chain,
void *starting_address,
size_t number_nodes,
size_t node_size
)
@ -237,10 +240,10 @@ Returns nothing.
**DESCRIPTION:**
This function take in a pointer to a chain control and initializes it
to contain a set of chain nodes. The chain will contain ``number_nodes``
chain nodes from the memory pointed to by ``start_address``. Each node
is assumed to be ``node_size`` bytes.
This function take in a pointer to a chain control and initializes it to
contain a set of chain nodes. The chain will contain ``number_nodes`` chain
nodes from the memory pointed to by ``start_address``. Each node is assumed to
be ``node_size`` bytes.
**NOTES:**
@ -250,6 +253,8 @@ This call does NOT inititialize any user data on each node.
.. COMMENT: Initialize this Chain as Empty
.. _rtems_chain_initialize_empty:
Initialize Empty
----------------
.. index:: chain initialize empty
@ -258,10 +263,10 @@ Initialize Empty
.. index:: rtems_chain_initialize_empty
.. code:: c
.. code-block:: c
void rtems_chain_initialize_empty(
rtems_chain_control \*the_chain
rtems_chain_control *the_chain
);
**RETURNS**
@ -270,13 +275,14 @@ Returns nothing.
**DESCRIPTION:**
This function take in a pointer to a chain control and initializes it
to empty.
This function take in a pointer to a chain control and initializes it to empty.
**NOTES:**
This call will discard any nodes on the chain.
.. _rtems_chain_is_null_node:
Is Null Node ?
--------------
.. index:: chain is node null
@ -285,10 +291,10 @@ Is Null Node ?
.. index:: rtems_chain_is_null_node
.. code:: c
.. code-block:: c
bool rtems_chain_is_null_node(
const rtems_chain_node \*the_node
const rtems_chain_node *the_node
);
**RETURNS**
@ -300,6 +306,8 @@ NULL.
Tests the node to see if it is a NULL returning ``true`` if a null.
.. _rtems_chain_head:
Head
----
.. index:: chain get head
@ -308,10 +316,10 @@ Head
.. index:: rtems_chain_head
.. code:: c
.. code-block:: c
rtems_chain_node \*rtems_chain_head(
rtems_chain_control \*the_chain
rtems_chain_node *rtems_chain_head(
rtems_chain_control *the_chain
)
**RETURNS**
@ -322,6 +330,8 @@ Returns the permanent head node of the chain.
This function returns a pointer to the first node on the chain.
.. _rtems_chain_tail:
Tail
----
.. index:: chain get tail
@ -330,10 +340,10 @@ Tail
.. index:: rtems_chain_tail
.. code:: c
.. code-block:: c
rtems_chain_node \*rtems_chain_tail(
rtems_chain_control \*the_chain
rtems_chain_node *rtems_chain_tail(
rtems_chain_control *the_chain
);
**RETURNS**
@ -344,6 +354,8 @@ Returns the permanent tail node of the chain.
This function returns a pointer to the last node on the chain.
.. _rtems_chain_are_nodes_equal:
Are Two Nodes Equal ?
---------------------
.. index:: chare are nodes equal
@ -352,22 +364,24 @@ Are Two Nodes Equal ?
.. index:: rtems_chain_are_nodes_equal
.. code:: c
.. code-block:: c
bool rtems_chain_are_nodes_equal(
const rtems_chain_node \*left,
const rtems_chain_node \*right
const rtems_chain_node *left,
const rtems_chain_node *right
);
**RETURNS**
This function returns ``true`` if the left node and the right node are
equal, and ``false`` otherwise.
This function returns ``true`` if the left node and the right node are equal,
and ``false`` otherwise.
**DESCRIPTION:**
This function returns ``true`` if the left node and the right node are
equal, and ``false`` otherwise.
This function returns ``true`` if the left node and the right node are equal,
and ``false`` otherwise.
.. _rtems_chain_is_empty:
Is the Chain Empty
------------------
@ -377,10 +391,10 @@ Is the Chain Empty
.. index:: rtems_chain_is_empty
.. code:: c
.. code-block:: c
bool rtems_chain_is_empty(
rtems_chain_control \*the_chain
rtems_chain_control *the_chain
);
**RETURNS**
@ -393,6 +407,8 @@ otherwise.
This function returns ``true`` if there a no nodes on the chain and ``false``
otherwise.
.. _rtems_chain_is_first:
Is this the First Node on the Chain ?
-------------------------------------
.. index:: chain is node the first
@ -401,21 +417,23 @@ Is this the First Node on the Chain ?
.. index:: rtems_chain_is_first
.. code:: c
.. code-block:: c
bool rtems_chain_is_first(
const rtems_chain_node \*the_node
const rtems_chain_node *the_node
);
**RETURNS**
This function returns ``true`` if the node is the first node on a chain
and ``false`` otherwise.
This function returns ``true`` if the node is the first node on a chain and
``false`` otherwise.
**DESCRIPTION:**
This function returns ``true`` if the node is the first node on a chain
and ``false`` otherwise.
This function returns ``true`` if the node is the first node on a chain and
``false`` otherwise.
.. _rtems_chain_is_last:
Is this the Last Node on the Chain ?
------------------------------------
@ -425,19 +443,23 @@ Is this the Last Node on the Chain ?
.. index:: rtems_chain_is_last
.. code:: c
.. code-block:: c
bool rtems_chain_is_last(
const rtems_chain_node \*the_node
const rtems_chain_node *the_node
);
**RETURNS**
This function returns ``true`` if the node is the last node on a chain and``false`` otherwise.
This function returns ``true`` if the node is the last node on a chain and
``false`` otherwise.
**DESCRIPTION:**
This function returns ``true`` if the node is the last node on a chain and``false`` otherwise.
This function returns ``true`` if the node is the last node on a chain and
``false`` otherwise.
.. _rtems_chain_has_only_one_node:
Does this Chain have only One Node ?
------------------------------------
@ -447,19 +469,23 @@ Does this Chain have only One Node ?
.. index:: rtems_chain_has_only_one_node
.. code:: c
.. code-block:: c
bool rtems_chain_has_only_one_node(
const rtems_chain_control \*the_chain
const rtems_chain_control *the_chain
);
**RETURNS**
This function returns ``true`` if there is only one node on the chain and``false`` otherwise.
This function returns ``true`` if there is only one node on the chain and
``false`` otherwise.
**DESCRIPTION:**
This function returns ``true`` if there is only one node on the chain and``false`` otherwise.
This function returns ``true`` if there is only one node on the chain and
``false`` otherwise.
.. _rtems_chain_node_count_unprotected:
Returns the node count of the chain (unprotected)
-------------------------------------------------
@ -469,10 +495,10 @@ Returns the node count of the chain (unprotected)
.. index:: rtems_chain_node_count_unprotected
.. code:: c
.. code-block:: c
size_t rtems_chain_node_count_unprotected(
const rtems_chain_control \*the_chain
const rtems_chain_control *the_chain
);
**RETURNS**
@ -483,6 +509,8 @@ This function returns the node count of the chain.
This function returns the node count of the chain.
.. _rtems_chain_is_head:
Is this Node the Chain Head ?
-----------------------------
.. index:: chain is node the head
@ -491,20 +519,24 @@ Is this Node the Chain Head ?
.. index:: rtems_chain_is_head
.. code:: c
.. code-block:: c
bool rtems_chain_is_head(
rtems_chain_control \*the_chain,
rtems_const chain_node \*the_node
rtems_chain_control *the_chain,
rtems_const chain_node *the_node
);
**RETURNS**
This function returns ``true`` if the node is the head of the chain and``false`` otherwise.
This function returns ``true`` if the node is the head of the chain and
``false`` otherwise.
**DESCRIPTION:**
This function returns ``true`` if the node is the head of the chain and``false`` otherwise.
This function returns ``true`` if the node is the head of the chain and
``false`` otherwise.
.. _rtems_chain_is_tail:
Is this Node the Chain Tail ?
-----------------------------
@ -514,20 +546,24 @@ Is this Node the Chain Tail ?
.. index:: rtems_chain_is_tail
.. code:: c
.. code-block:: c
bool rtems_chain_is_tail(
rtems_chain_control \*the_chain,
const rtems_chain_node \*the_node
rtems_chain_control *the_chain,
const rtems_chain_node *the_node
)
**RETURNS**
This function returns ``true`` if the node is the tail of the chain and``false`` otherwise.
This function returns ``true`` if the node is the tail of the chain and
``false`` otherwise.
**DESCRIPTION:**
This function returns ``true`` if the node is the tail of the chain and``false`` otherwise.
This function returns ``true`` if the node is the tail of the chain and
``false`` otherwise.
.. _rtems_chain_extract:
Extract a Node
--------------
@ -537,10 +573,10 @@ Extract a Node
.. index:: rtems_chain_extract
.. code:: c
.. code-block:: c
void rtems_chain_extract(
rtems_chain_node \*the_node
rtems_chain_node *the_node
);
**RETURNS**
@ -553,11 +589,40 @@ This routine extracts the node from the chain on which it resides.
**NOTES:**
Interrupts are disabled while extracting the node to ensure the
atomicity of the operation.
Interrupts are disabled while extracting the node to ensure the atomicity of
the operation.
Use ``rtems_chain_extract_unprotected()`` to avoid disabling of
interrupts.
Use rtems_chain_extract_unprotected_ to avoid disabling of interrupts.
.. _rtems_chain_extract_unprotected:
Extract a Node (unprotected)
----------------------------
.. index:: chain extract a node unprotected
**CALLING SEQUENCE:**
.. index:: rtems_chain_extract_unprotected
.. code-block:: c
void rtems_chain_extract_unprotected(
rtems_chain_node *the_node
);
**RETURNS**
Returns nothing.
**DESCRIPTION:**
This routine extracts the node from the chain on which it resides.
**NOTES:**
The function does nothing to ensure the atomicity of the operation.
.. _rtems_chain_get:
Get the First Node
------------------
@ -567,30 +632,30 @@ Get the First Node
.. index:: rtems_chain_get
.. code:: c
.. code-block:: c
rtems_chain_node \*rtems_chain_get(
rtems_chain_control \*the_chain
rtems_chain_node *rtems_chain_get(
rtems_chain_control *the_chain
);
**RETURNS**
Returns a pointer a node. If a node was removed, then a pointer to
that node is returned. If the chain was empty, then NULL is
returned.
Returns a pointer a node. If a node was removed, then a pointer to that node is
returned. If the chain was empty, then ``NULL`` is returned.
**DESCRIPTION:**
This function removes the first node from the chain and returns a
pointer to that node. If the chain is empty, then NULL is returned.
This function removes the first node from the chain and returns a pointer to
that node. If the chain is empty, then ``NULL`` is returned.
**NOTES:**
Interrupts are disabled while obtaining the node to ensure the
atomicity of the operation.
Interrupts are disabled while obtaining the node to ensure the atomicity of the
operation.
Use ``rtems_chain_get_unprotected()`` to avoid disabling of
interrupts.
Use ``rtems_chain_get_unprotected()`` to avoid disabling of interrupts.
.. _rtems_chain_get_unprotected:
Get the First Node (unprotected)
--------------------------------
@ -598,12 +663,12 @@ Get the First Node (unprotected)
**CALLING SEQUENCE:**
.. index:: rtems_chain_get_first_unprotected
.. index:: rtems_chain_get_unprotected
.. code:: c
.. code-block:: c
rtems_chain_node \*rtems_chain_get_first_unprotected(
rtems_chain_control \*the_chain
rtems_chain_node *rtems_chain_get_unprotected(
rtems_chain_control *the_chain
);
**RETURNS:**
@ -619,6 +684,8 @@ chain was empty, then the results are unpredictable.
The function does nothing to ensure the atomicity of the operation.
.. _rtems_chain_insert:
Insert a Node
-------------
.. index:: chain insert a node
@ -627,11 +694,11 @@ Insert a Node
.. index:: rtems_chain_insert
.. code:: c
.. code-block:: c
void rtems_chain_insert(
rtems_chain_node \*after_node,
rtems_chain_node \*the_node
rtems_chain_node *after_node,
rtems_chain_node *the_node
);
**RETURNS**
@ -640,16 +707,47 @@ Returns nothing.
**DESCRIPTION:**
This routine inserts a node on a chain immediately following the
specified node.
This routine inserts a node on a chain immediately following the specified
node.
**NOTES:**
Interrupts are disabled during the insert to ensure the atomicity of
the operation.
Interrupts are disabled during the insert to ensure the atomicity of the
operation.
Use ``rtems_chain_insert_unprotected()`` to avoid disabling of
interrupts.
Use rtems_chain_insert_unprotected_ to avoid disabling of interrupts.
.. _rtems_chain_insert_unprotected:
Insert a Node (unprotected)
---------------------------
.. index:: chain insert a node unprotected
**CALLING SEQUENCE:**
.. index:: rtems_chain_insert_unprotected
.. code-block:: c
void rtems_chain_insert_unprotected(
rtems_chain_node *after_node,
rtems_chain_node *the_node
);
**RETURNS**
Returns nothing.
**DESCRIPTION:**
This routine inserts a node on a chain immediately following the specified
node.
**NOTES:**
The function does nothing to ensure the atomicity of the operation.
.. _rtems_chain_append:
Append a Node
-------------
@ -659,11 +757,11 @@ Append a Node
.. index:: rtems_chain_append
.. code:: c
.. code-block:: c
void rtems_chain_append(
rtems_chain_control \*the_chain,
rtems_chain_node \*the_node
rtems_chain_control *the_chain,
rtems_chain_node *the_node
);
**RETURNS**
@ -676,11 +774,41 @@ This routine appends a node to the end of a chain.
**NOTES:**
Interrupts are disabled during the append to ensure the atomicity of
the operation.
Interrupts are disabled during the append to ensure the atomicity of the
operation.
Use ``rtems_chain_append_unprotected()`` to avoid disabling of
interrupts.
Use rtems_chain_append_unprotected_ to avoid disabling of interrupts.
.. _rtems_chain_append_unprotected:
Append a Node (unprotected)
---------------------------
.. index:: chain append a node unprotected
**CALLING SEQUENCE:**
.. index:: rtems_chain_append_unprotected
.. code-block:: c
void rtems_chain_append_unprotected(
rtems_chain_control *the_chain,
rtems_chain_node *the_node
);
**RETURNS**
Returns nothing.
**DESCRIPTION:**
This routine appends a node to the end of a chain.
**NOTES:**
The function does nothing to ensure the atomicity of the operation.
.. _rtems_chain_prepend:
Prepend a Node
--------------
@ -690,11 +818,11 @@ Prepend a Node
.. index:: rtems_chain_prepend
.. code:: c
.. code-block:: c
void rtems_chain_prepend(
rtems_chain_control \*the_chain,
rtems_chain_node \*the_node
rtems_chain_control *the_chain,
rtems_chain_node *the_node
);
**RETURNS**
@ -707,13 +835,37 @@ This routine prepends a node to the front of the chain.
**NOTES:**
Interrupts are disabled during the prepend to ensure the atomicity of
the operation.
Interrupts are disabled during the prepend to ensure the atomicity of the
operation.
Use ``rtems_chain_prepend_unprotected()`` to avoid disabling of
Use rtems_chain_prepend_unprotected_ to avoid disabling of
interrupts.
.. COMMENT: Copyright 2014 Gedare Bloom.
.. _rtems_chain_prepend_unprotected:
.. COMMENT: All rights reserved.
Prepend a Node (unprotected)
----------------------------
.. index:: prepend node unprotected
**CALLING SEQUENCE:**
.. index:: rtems_chain_prepend_unprotected
.. code-block:: c
void rtems_chain_prepend_unprotected(
rtems_chain_control *the_chain,
rtems_chain_node *the_node
);
**RETURNS**
Returns nothing.
**DESCRIPTION:**
This routine prepends a node to the front of the chain.
**NOTES:**
The function does nothing to ensure the atomicity of the operation.

View File

@ -1,3 +1,7 @@
.. COMMENT: COPYRIGHT (c) 1989-2011.
.. COMMENT: On-Line Applications Research Corporation (OAR).
.. COMMENT: All rights reserved.
Constant Bandwidth Server Scheduler API
#######################################
@ -6,33 +10,33 @@ Constant Bandwidth Server Scheduler API
Introduction
============
Unlike simple schedulers, the Constant Bandwidth Server (CBS) requires
a special API for tasks to indicate their scheduling parameters.
The directives provided by the CBS API are:
Unlike simple schedulers, the Constant Bandwidth Server (CBS) requires a
special API for tasks to indicate their scheduling parameters. The directives
provided by the CBS API are:
- ``rtems_cbs_initialize`` - Initialize the CBS library
- rtems_cbs_initialize_ - Initialize the CBS library
- ``rtems_cbs_cleanup`` - Cleanup the CBS library
- rtems_cbs_cleanup_ - Cleanup the CBS library
- ``rtems_cbs_create_server`` - Create a new bandwidth server
- rtems_cbs_create_server_ - Create a new bandwidth server
- ``rtems_cbs_attach_thread`` - Attach a thread to server
- rtems_cbs_attach_thread_ - Attach a thread to server
- ``rtems_cbs_detach_thread`` - Detach a thread from server
- rtems_cbs_detach_thread_ - Detach a thread from server
- ``rtems_cbs_destroy_server`` - Destroy a bandwidth server
- rtems_cbs_destroy_server_ - Destroy a bandwidth server
- ``rtems_cbs_get_server_id`` - Get an ID of a server
- rtems_cbs_get_server_id_ - Get an ID of a server
- ``rtems_cbs_get_parameters`` - Get scheduling parameters of a server
- rtems_cbs_get_parameters_ - Get scheduling parameters of a server
- ``rtems_cbs_set_parameters`` - Set scheduling parameters of a server
- rtems_cbs_set_parameters_ - Set scheduling parameters of a server
- ``rtems_cbs_get_execution_time`` - Get elapsed execution time
- rtems_cbs_get_execution_time_ - Get elapsed execution time
- ``rtems_cbs_get_remaining_budget`` - Get remainig execution time
- rtems_cbs_get_remaining_budget_ - Get remainig execution time
- ``rtems_cbs_get_approved_budget`` - Get scheduler approved execution time
- rtems_cbs_get_approved_budget_ - Get scheduler approved execution time
Background
==========
@ -43,68 +47,66 @@ Constant Bandwidth Server Definitions
.. index:: rtems_cbs_parameters
The Constant Bandwidth Server API enables tasks to communicate with
the scheduler and indicate its scheduling parameters. The scheduler
has to be set up first (by defining ``CONFIGURE_SCHEDULER_CBS`` macro).
The Constant Bandwidth Server API enables tasks to communicate with the
scheduler and indicate its scheduling parameters. The scheduler has to be set
up first (by defining ``CONFIGURE_SCHEDULER_CBS`` macro).
The difference to a plain EDF is the presence of servers.
It is a budget aware extention of the EDF scheduler, therefore, tasks
attached to servers behave in a similar way as with EDF unless they
exceed their budget.
The difference to a plain EDF is the presence of servers. It is a budget aware
extention of the EDF scheduler, therefore, tasks attached to servers behave in
a similar way as with EDF unless they exceed their budget.
The intention of servers is reservation of a certain computation
time (budget) of the processor for all subsequent periods. The structure``rtems_cbs_parameters`` determines the behavior of
a server. It contains ``deadline`` which is equal to period,
and ``budget`` which is the time the server is allowed to
spend on CPU per each period. The ratio between those two parameters
yields the maximum percentage of the CPU the server can use
(bandwidth). Moreover, thanks to this limitation the overall
utilization of CPU is under control, and the sum of bandwidths
of all servers in the system yields the overall reserved portion
of processor. The rest is still available for ordinary tasks that
are not attached to any server.
The intention of servers is reservation of a certain computation time (budget)
of the processor for all subsequent periods. The structure
``rtems_cbs_parameters`` determines the behavior of a server. It contains
``deadline`` which is equal to period, and ``budget`` which is the time the
server is allowed to spend on CPU per each period. The ratio between those two
parameters yields the maximum percentage of the CPU the server can use
(bandwidth). Moreover, thanks to this limitation the overall utilization of CPU
is under control, and the sum of bandwidths of all servers in the system yields
the overall reserved portion of processor. The rest is still available for
ordinary tasks that are not attached to any server.
In order to make the server effective to the executing tasks,
tasks have to be attached to the servers. The``rtems_cbs_server_id`` is a type denoting an id of a server
and ``rtems_id`` a type for id of tasks.
In order to make the server effective to the executing tasks, tasks have to be
attached to the servers. The ``rtems_cbs_server_id`` is a type denoting an id
of a server and ``rtems_id`` a type for id of tasks.
Handling Periodic Tasks
-----------------------
.. index:: CBS periodic tasks
Each task's execution begins with a default background priority
(see the chapter Scheduling Concepts to understand the concept of
priorities in EDF). Once you decide the tasks should start periodic
execution, you have two possibilities. Either you use only the Rate
Monotonic manager which takes care of periodic behavior, or you declare
deadline and budget using the CBS API in which case these properties
are constant for all subsequent periods, unless you change them using
the CBS API again. Task now only has to indicate and end of
Each task's execution begins with a default background priority (see the
chapter Scheduling Concepts to understand the concept of priorities in
EDF). Once you decide the tasks should start periodic execution, you have two
possibilities. Either you use only the Rate Monotonic manager which takes care
of periodic behavior, or you declare deadline and budget using the CBS API in
which case these properties are constant for all subsequent periods, unless you
change them using the CBS API again. Task now only has to indicate and end of
each period using ``rtems_rate_monotonic_period``.
Registering a Callback Function
-------------------------------
.. index:: CBS overrun handler
In case tasks attached to servers are not aware of their execution time
and happen to exceed it, the scheduler does not guarantee execution any
more and pulls the priority of the task to background, which would
possibly lead to immediate preemption (if there is at least one ready
task with a higher pirority). However, the task is not blocked but a
callback function is invoked. The callback function
(``rtems_cbs_budget_overrun``) might be optionally registered upon
a server creation (``rtems_cbs_create_server``).
In case tasks attached to servers are not aware of their execution time and
happen to exceed it, the scheduler does not guarantee execution any more and
pulls the priority of the task to background, which would possibly lead to
immediate preemption (if there is at least one ready task with a higher
pirority). However, the task is not blocked but a callback function is
invoked. The callback function (``rtems_cbs_budget_overrun``) might be
optionally registered upon a server creation (``rtems_cbs_create_server``).
This enables the user to define what should happen in case of budget
overrun. There is obviously no space for huge operations because the
priority is down and not real time any more, however, you still can at
least in release resources for other tasks, restart the task or log an
error information. Since the routine is called directly from kernel,
use ``printk()`` instead of ``printf()``.
overrun. There is obviously no space for huge operations because the priority
is down and not real time any more, however, you still can at least in release
resources for other tasks, restart the task or log an error information. Since
the routine is called directly from kernel, use ``printk()`` instead of
``printf()``.
The calling convention of the callback function is:.. index:: rtems_asr
The calling convention of the callback function is:
.. code:: c
.. index:: rtems_asr
.. code-block:: c
void overrun_handler(
rtems_cbs_server_id server_id
@ -118,17 +120,16 @@ When using this scheduler you have to keep in mind several things:
- it_limitations
- In the current implementation it is possible to attach only
a single task to each server.
- In the current implementation it is possible to attach only a single task to
each server.
- If you have a task attached to a server and you voluntatily
block it in the beginning of its execution, its priority will be
probably pulled to background upon unblock, thus not guaranteed
deadline any more. This is because you are effectively raising
computation time of the task. When unbocking, you should be always
sure that the ratio between remaining computation time and remaining
deadline is not higher that the utilization you have agreed with the
scheduler.
- If you have a task attached to a server and you voluntatily block it in the
beginning of its execution, its priority will be probably pulled to
background upon unblock, thus not guaranteed deadline any more. This is
because you are effectively raising computation time of the task. When
unbocking, you should be always sure that the ratio between remaining
computation time and remaining deadline is not higher that the utilization
you have agreed with the scheduler.
Operations
==========
@ -136,36 +137,33 @@ Operations
Setting up a server
-------------------
The directive ``rtems_cbs_create_server`` is used to create a new
server that is characterized by ``rtems_cbs_parameters``. You also
might want to register the ``rtems_cbs_budget_overrun`` callback
routine. After this step tasks can be attached to the server. The directive``rtems_cbs_set_parameters`` can change the scheduling parameters
to avoid destroying and creating a new server again.
The directive ``rtems_cbs_create_server`` is used to create a new server that
is characterized by ``rtems_cbs_parameters``. You also might want to register
the ``rtems_cbs_budget_overrun`` callback routine. After this step tasks can be
attached to the server. The directive ``rtems_cbs_set_parameters`` can change
the scheduling parameters to avoid destroying and creating a new server again.
Attaching Task to a Server
--------------------------
If a task is attached to a server using ``rtems_cbs_attach_thread``,
the task's computation time per period is limited by the server and
the deadline (period) of task is equal to deadline of the server which
means if you conclude a period using ``rate_monotonic_period``,
the length of next period is always determined by the server's property.
If a task is attached to a server using ``rtems_cbs_attach_thread``, the task's
computation time per period is limited by the server and the deadline (period)
of task is equal to deadline of the server which means if you conclude a period
using ``rate_monotonic_period``, the length of next period is always determined
by the server's property.
The task has a guaranteed bandwidth given by the server but should not
exceed it, otherwise the priority is pulled to background until the
start of next period and the ``rtems_cbs_budget_overrun`` callback
function is invoked.
The task has a guaranteed bandwidth given by the server but should not exceed
it, otherwise the priority is pulled to background until the start of next
period and the ``rtems_cbs_budget_overrun`` callback function is invoked.
When attaching a task to server, the preemptability flag of the task
is raised, otherwise it would not be possible to control the execution
of the task.
When attaching a task to server, the preemptability flag of the task is raised,
otherwise it would not be possible to control the execution of the task.
Detaching Task from a Server
----------------------------
The directive ``rtems_cbs_detach_thread`` is just an inverse
operation to the previous one, the task continues its execution with
the initial priority.
The directive ``rtems_cbs_detach_thread`` is just an inverse operation to the
previous one, the task continues its execution with the initial priority.
Preemptability of the task is restored to the initial value.
@ -174,18 +172,18 @@ Examples
The following example presents a simple common use of the API.
You can see the initialization and cleanup call here, if there are
multiple tasks in the system, it is obvious that the initialization
should be called before creating the task.
You can see the initialization and cleanup call here, if there are multiple
tasks in the system, it is obvious that the initialization should be called
before creating the task.
Notice also that in this case we decided to register an overrun handler,
instead of which there could be ``NULL``. This handler just prints
a message to terminal, what else may be done here depends on a specific
application.
instead of which there could be ``NULL``. This handler just prints a message to
terminal, what else may be done here depends on a specific application.
During the periodic execution, remaining budget should be watched
to avoid overrun.
.. code:: c
During the periodic execution, remaining budget should be watched to avoid
overrun.
.. code-block:: c
void overrun_handler (
rtems_cbs_server_id server_id
@ -194,6 +192,7 @@ to avoid overrun.
printk( "Budget overrun, fixing the task\\n" );
return;
}
rtems_task Tasks_Periodic(
rtems_task_argument argument
)
@ -201,17 +200,21 @@ to avoid overrun.
rtems_id rmid;
rtems_cbs_server_id server_id;
rtems_cbs_parameters params;
params.deadline = 10;
params.budget = 4;
rtems_cbs_initialize();
rtems_cbs_create_server( &params, &overrun_handler, &server_id )
rtems_cbs_attach_thread( server_id, SELF );
rtems_rate_monotonic_create( argument, &rmid );
while ( 1 ) {
if (rtems_rate_monotonic_period(rmid, params.deadline)==RTEMS_TIMEOUT)
if (rtems_rate_monotonic_period(rmid, params.deadline) == RTEMS_TIMEOUT)
break;
/* Perform some periodic action \*/
}
rtems_rate_monotonic_delete( rmid );
rtems_cbs_cleanup();
exit( 1 );
@ -220,10 +223,11 @@ to avoid overrun.
Directives
==========
This section details the Constant Bandwidth Server's directives.
A subsection is dedicated to each of this manager's directives
and describes the calling sequence, related constants, usage,
and status codes.
This section details the Constant Bandwidth Server's directives. A subsection
is dedicated to each of this manager's directives and describes the calling
sequence, related constants, usage, and status codes.
.. _rtems_cbs_initialize:
CBS_INITIALIZE - Initialize the CBS library
-------------------------------------------
@ -233,26 +237,35 @@ CBS_INITIALIZE - Initialize the CBS library
.. index:: rtems_cbs_initialize
.. code:: c
.. code-block:: c
int rtems_cbs_initialize( void );
**DIRECTIVE STATUS CODES:**
``RTEMS_CBS_OK`` - successful initialization
``RTEMS_CBS_ERROR_NO_MEMORY`` - not enough memory for data
.. list-table::
:class: rtems-table
* - ``RTEMS_CBS_OK``
- successful initialization
* - ``RTEMS_CBS_ERROR_NO_MEMORY``
- not enough memory for data
**DESCRIPTION:**
This routine initializes the library in terms of allocating necessary memory
for the servers. In case not enough memory is available in the system,``RTEMS_CBS_ERROR_NO_MEMORY`` is returned, otherwise``RTEMS_CBS_OK``.
for the servers. In case not enough memory is available in the system,
``RTEMS_CBS_ERROR_NO_MEMORY`` is returned, otherwise ``RTEMS_CBS_OK``.
**NOTES:**
Additional memory per each server is allocated upon invocation of``rtems_cbs_create_server``.
Additional memory per each server is allocated upon invocation of
``rtems_cbs_create_server``.
Tasks in the system are not influenced, they still keep executing
with their initial parameters.
Tasks in the system are not influenced, they still keep executing with their
initial parameters.
.. _rtems_cbs_cleanup:
CBS_CLEANUP - Cleanup the CBS library
-------------------------------------
@ -262,23 +275,29 @@ CBS_CLEANUP - Cleanup the CBS library
.. index:: rtems_cbs_cleanup
.. code:: c
.. code-block:: c
int rtems_cbs_cleanup( void );
**DIRECTIVE STATUS CODES:**
``RTEMS_CBS_OK`` - always successful
.. list-table::
:class: rtems-table
* - ``RTEMS_CBS_OK``
- always successful
**DESCRIPTION:**
This routine detaches all tasks from their servers, destroys all servers
and returns memory back to the system.
This routine detaches all tasks from their servers, destroys all servers and
returns memory back to the system.
**NOTES:**
All tasks continue executing with their initial priorities.
.. _rtems_cbs_create_server:
CBS_CREATE_SERVER - Create a new bandwidth server
-------------------------------------------------
.. index:: create a new bandwidth server
@ -287,36 +306,46 @@ CBS_CREATE_SERVER - Create a new bandwidth server
.. index:: rtems_cbs_create_server
.. code:: c
.. code-block:: c
int rtems_cbs_create_server (
rtems_cbs_parameters \*params,
rtems_cbs_parameters *params,
rtems_cbs_budget_overrun budget_overrun_callback,
rtems_cbs_server_id \*server_id
rtems_cbs_server_id *server_id
);
**DIRECTIVE STATUS CODES:**
``RTEMS_CBS_OK`` - successfully created
``RTEMS_CBS_ERROR_NO_MEMORY`` - not enough memory for data
``RTEMS_CBS_ERROR_FULL`` - maximum servers exceeded
``RTEMS_CBS_ERROR_INVALID_PARAMETER`` - invalid input argument
.. list-table::
:class: rtems-table
* - ``RTEMS_CBS_OK``
- successfully created
* - ``RTEMS_CBS_ERROR_NO_MEMORY``
- not enough memory for data
* - ``RTEMS_CBS_ERROR_FULL``
- maximum servers exceeded
* - ``RTEMS_CBS_ERROR_INVALID_PARAMETER``
- invalid input argument
**DESCRIPTION:**
This routine prepares an instance of a constant bandwidth server.
The input parameter ``rtems_cbs_parameters`` specifies scheduling
parameters of the server (period and budget). If these are not valid,``RTEMS_CBS_ERROR_INVALID_PARAMETER`` is returned.
The ``budget_overrun_callback`` is an optional callback function, which is
invoked in case the server's budget within one period is exceeded.
Output parameter ``server_id`` becomes an id of the newly created server.
If there is not enough memory, the ``RTEMS_CBS_ERROR_NO_MEMORY``
is returned. If the maximum server count in the system is exceeded,``RTEMS_CBS_ERROR_FULL`` is returned.
This routine prepares an instance of a constant bandwidth server. The input
parameter ``rtems_cbs_parameters`` specifies scheduling parameters of the
server (period and budget). If these are not valid,
``RTEMS_CBS_ERROR_INVALID_PARAMETER`` is returned. The
``budget_overrun_callback`` is an optional callback function, which is invoked
in case the server's budget within one period is exceeded. Output parameter
``server_id`` becomes an id of the newly created server. If there is not
enough memory, the ``RTEMS_CBS_ERROR_NO_MEMORY`` is returned. If the maximum
server count in the system is exceeded, ``RTEMS_CBS_ERROR_FULL`` is returned.
**NOTES:**
No task execution is being influenced so far.
.. _rtems_cbs_attach_thread:
CBS_ATTACH_THREAD - Attach a thread to server
---------------------------------------------
.. index:: attach a thread to server
@ -325,7 +354,7 @@ CBS_ATTACH_THREAD - Attach a thread to server
.. index:: rtems_cbs_attach_thread
.. code:: c
.. code-block:: c
int rtems_cbs_attach_thread (
rtems_cbs_server_id server_id,
@ -334,24 +363,32 @@ CBS_ATTACH_THREAD - Attach a thread to server
**DIRECTIVE STATUS CODES:**
``RTEMS_CBS_OK`` - successfully attached
``RTEMS_CBS_ERROR_FULL`` - server maximum tasks exceeded
``RTEMS_CBS_ERROR_INVALID_PARAMETER`` - invalid input argument
``RTEMS_CBS_ERROR_NOSERVER`` - server is not valid
.. list-table::
:class: rtems-table
* - ``RTEMS_CBS_OK``
- successfully attached
* - ``RTEMS_CBS_ERROR_FULL``
- server maximum tasks exceeded
* - ``RTEMS_CBS_ERROR_INVALID_PARAMETER``
- invalid input argument
* - ``RTEMS_CBS_ERROR_NOSERVER``
- server is not valid
**DESCRIPTION:**
Attaches a task (``task_id``) to a server (``server_id``).
The server has to be previously created. Now, the task starts
to be scheduled according to the server parameters and not
using initial priority. This implementation allows only one task
per server, if the user tries to bind another task to the same
Attaches a task (``task_id``) to a server (``server_id``). The server has to
be previously created. Now, the task starts to be scheduled according to the
server parameters and not using initial priority. This implementation allows
only one task per server, if the user tries to bind another task to the same
server, ``RTEMS_CBS_ERROR_FULL`` is returned.
**NOTES:**
Tasks attached to servers become preemptible.
.. _rtems_cbs_detach_thread:
CBS_DETACH_THREAD - Detach a thread from server
-----------------------------------------------
.. index:: detach a thread from server
@ -360,7 +397,7 @@ CBS_DETACH_THREAD - Detach a thread from server
.. index:: rtems_cbs_detach_thread
.. code:: c
.. code-block:: c
int rtems_cbs_detach_thread (
rtems_cbs_server_id server_id,
@ -369,19 +406,27 @@ CBS_DETACH_THREAD - Detach a thread from server
**DIRECTIVE STATUS CODES:**
``RTEMS_CBS_OK`` - successfully detached
``RTEMS_CBS_ERROR_INVALID_PARAMETER`` - invalid input argument
``RTEMS_CBS_ERROR_NOSERVER`` - server is not valid
.. list-table::
:class: rtems-table
* - ``RTEMS_CBS_OK``
- successfully detached
* - ``RTEMS_CBS_ERROR_INVALID_PARAMETER``
- invalid input argument
* - ``RTEMS_CBS_ERROR_NOSERVER``
- server is not valid
**DESCRIPTION:**
This directive detaches a thread from server. The task continues its
execution with initial priority.
This directive detaches a thread from server. The task continues its execution
with initial priority.
**NOTES:**
The server can be reused for any other task.
.. _rtems_cbs_destroy_server:
CBS_DESTROY_SERVER - Destroy a bandwidth server
-----------------------------------------------
.. index:: destroy a bandwidth server
@ -390,7 +435,7 @@ CBS_DESTROY_SERVER - Destroy a bandwidth server
.. index:: rtems_cbs_destroy_server
.. code:: c
.. code-block:: c
int rtems_cbs_destroy_server (
rtems_cbs_server_id server_id
@ -398,20 +443,28 @@ CBS_DESTROY_SERVER - Destroy a bandwidth server
**DIRECTIVE STATUS CODES:**
``RTEMS_CBS_OK`` - successfully destroyed
``RTEMS_CBS_ERROR_INVALID_PARAMETER`` - invalid input argument
``RTEMS_CBS_ERROR_NOSERVER`` - server is not valid
.. list-table::
:class: rtems-table
* - ``RTEMS_CBS_OK``
- successfully destroyed
* - ``RTEMS_CBS_ERROR_INVALID_PARAMETER``
- invalid input argument
* - ``RTEMS_CBS_ERROR_NOSERVER``
- server is not valid
**DESCRIPTION:**
This directive destroys a server. If any task was attached to the server,
the task is detached and continues its execution according to EDF rules
with initial properties.
This directive destroys a server. If any task was attached to the server, the
task is detached and continues its execution according to EDF rules with
initial properties.
**NOTES:**
This again enables one more task to be created.
.. _rtems_cbs_get_server_id:
CBS_GET_SERVER_ID - Get an ID of a server
-----------------------------------------
.. index:: get an ID of a server
@ -420,22 +473,29 @@ CBS_GET_SERVER_ID - Get an ID of a server
.. index:: rtems_cbs_get_server_id
.. code:: c
.. code-block:: c
int rtems_cbs_get_server_id (
rtems_id task_id,
rtems_cbs_server_id \*server_id
rtems_cbs_server_id *server_id
);
**DIRECTIVE STATUS CODES:**
``RTEMS_CBS_OK`` - successful
``RTEMS_CBS_ERROR_NOSERVER`` - server is not valid
.. list-table::
:class: rtems-table
* - ``RTEMS_CBS_OK``
- successful
* - ``RTEMS_CBS_ERROR_NOSERVER``
- server is not valid
**DESCRIPTION:**
This directive returns an id of server belonging to a given task.
.. _rtems_cbs_get_parameters:
CBS_GET_PARAMETERS - Get scheduling parameters of a server
----------------------------------------------------------
.. index:: get scheduling parameters of a server
@ -444,18 +504,24 @@ CBS_GET_PARAMETERS - Get scheduling parameters of a server
.. index:: rtems_cbs_get_parameters
.. code:: c
.. code-block:: c
rtems_cbs_get_parameters (
rtems_cbs_server_id server_id,
rtems_cbs_parameters \*params
rtems_cbs_parameters *params
);
**DIRECTIVE STATUS CODES:**
``RTEMS_CBS_OK`` - successful
``RTEMS_CBS_ERROR_INVALID_PARAMETER`` - invalid input argument
``RTEMS_CBS_ERROR_NOSERVER`` - server is not valid
.. list-table::
:class: rtems-table
* - ``RTEMS_CBS_OK``
- successful
* - ``RTEMS_CBS_ERROR_INVALID_PARAMETER``
- invalid input argument
* - ``RTEMS_CBS_ERROR_NOSERVER``
- server is not valid
**DESCRIPTION:**
@ -466,6 +532,8 @@ of a given server (period and execution time).
It makes no difference if any task is assigned or not.
.. _rtems_cbs_set_parameters:
CBS_SET_PARAMETERS - Set scheduling parameters
----------------------------------------------
.. index:: set scheduling parameters
@ -474,30 +542,38 @@ CBS_SET_PARAMETERS - Set scheduling parameters
.. index:: rtems_cbs_set_parameters
.. code:: c
.. code-block:: c
int rtems_cbs_set_parameters (
rtems_cbs_server_id server_id,
rtems_cbs_parameters \*params
rtems_cbs_parameters *params
);
**DIRECTIVE STATUS CODES:**
``RTEMS_CBS_OK`` - successful
``RTEMS_CBS_ERROR_INVALID_PARAMETER`` - invalid input argument
``RTEMS_CBS_ERROR_NOSERVER`` - server is not valid
.. list-table::
:class: rtems-table
* - ``RTEMS_CBS_OK``
- successful
* - ``RTEMS_CBS_ERROR_INVALID_PARAMETER``
- invalid input argument
* - ``RTEMS_CBS_ERROR_NOSERVER``
- server is not valid
**DESCRIPTION:**
This directive sets new scheduling parameters to the server. This operation
can be performed regardless of whether a task is assigned or not.
If a task is assigned, the parameters become effective imediately, therefore it
is recommended to apply the change between two subsequent periods.
This directive sets new scheduling parameters to the server. This operation can
be performed regardless of whether a task is assigned or not. If a task is
assigned, the parameters become effective imediately, therefore it is
recommended to apply the change between two subsequent periods.
**NOTES:**
There is an upper limit on both period and budget equal to (2^31)-1 ticks.
.. _rtems_cbs_get_execution_time:
CBS_GET_EXECUTION_TIME - Get elapsed execution time
---------------------------------------------------
.. index:: get elapsed execution time
@ -506,29 +582,37 @@ CBS_GET_EXECUTION_TIME - Get elapsed execution time
.. index:: rtems_cbs_get_execution_time
.. code:: c
.. code-block:: c
int rtems_cbs_get_execution_time (
rtems_cbs_server_id server_id,
time_t \*exec_time,
time_t \*abs_time
time_t *exec_time,
time_t *abs_time
);
**DIRECTIVE STATUS CODES:**
``RTEMS_CBS_OK`` - successful
``RTEMS_CBS_ERROR_INVALID_PARAMETER`` - invalid input argument
``RTEMS_CBS_ERROR_NOSERVER`` - server is not valid
.. list-table::
:class: rtems-table
* - ``RTEMS_CBS_OK``
- successful
* - ``RTEMS_CBS_ERROR_INVALID_PARAMETER``
- invalid input argument
* - ``RTEMS_CBS_ERROR_NOSERVER``
- server is not valid
**DESCRIPTION:**
This routine returns consumed execution time (``exec_time``) of a server
during the current period.
This routine returns consumed execution time (``exec_time``) of a server during
the current period.
**NOTES:**
Absolute time (``abs_time``) not supported now.
.. _rtems_cbs_get_remaining_budget:
CBS_GET_REMAINING_BUDGET - Get remaining execution time
-------------------------------------------------------
.. index:: get remaining execution time
@ -537,29 +621,37 @@ CBS_GET_REMAINING_BUDGET - Get remaining execution time
.. index:: rtems_cbs_get_remaining_budget
.. code:: c
.. code-block:: c
int rtems_cbs_get_remaining_budget (
rtems_cbs_server_id server_id,
time_t \*remaining_budget
time_t *remaining_budget
);
**DIRECTIVE STATUS CODES:**
``RTEMS_CBS_OK`` - successful
``RTEMS_CBS_ERROR_INVALID_PARAMETER`` - invalid input argument
``RTEMS_CBS_ERROR_NOSERVER`` - server is not valid
.. list-table::
:class: rtems-table
* - ``RTEMS_CBS_OK``
- successful
* - ``RTEMS_CBS_ERROR_INVALID_PARAMETER``
- invalid input argument
* - ``RTEMS_CBS_ERROR_NOSERVER``
- server is not valid
**DESCRIPTION:**
This directive returns remaining execution time of a given server for
current period.
This directive returns remaining execution time of a given server for current
period.
**NOTES:**
If the execution time approaches zero, the assigned task should finish
computations of the current period.
.. _rtems_cbs_get_approved_budget:
CBS_GET_APPROVED_BUDGET - Get scheduler approved execution time
---------------------------------------------------------------
.. index:: get scheduler approved execution time
@ -568,26 +660,25 @@ CBS_GET_APPROVED_BUDGET - Get scheduler approved execution time
.. index:: rtems_cbs_get_approved_budget
.. code:: c
.. code-block:: c
int rtems_cbs_get_approved_budget (
rtems_cbs_server_id server_id,
time_t \*appr_budget
time_t *appr_budget
);
**DIRECTIVE STATUS CODES:**
``RTEMS_CBS_OK`` - successful
``RTEMS_CBS_ERROR_INVALID_PARAMETER`` - invalid input argument
``RTEMS_CBS_ERROR_NOSERVER`` - server is not valid
.. list-table::
:class: rtems-table
* - ``RTEMS_CBS_OK``
- successful
* - ``RTEMS_CBS_ERROR_INVALID_PARAMETER``
- invalid input argument
* - ``RTEMS_CBS_ERROR_NOSERVER``
- server is not valid
**DESCRIPTION:**
This directive returns server's approved budget for subsequent periods.
.. COMMENT: COPYRIGHT (c) 1989-2011.
.. COMMENT: On-Line Applications Research Corporation (OAR).
.. COMMENT: All rights reserved.

View File

@ -1,39 +1,41 @@
.. COMMENT: COPYRIGHT (c) 1988-2008.
.. COMMENT: On-Line Applications Research Corporation (OAR).
.. COMMENT: All rights reserved.
CPU Usage Statistics
####################
Introduction
============
The CPU usage statistics manager is an RTEMS support
component that provides a convenient way to manipulate
the CPU usage information associated with each task
The routines provided by the CPU usage statistics manager are:
The CPU usage statistics manager is an RTEMS support component that provides a
convenient way to manipulate the CPU usage information associated with each
task The routines provided by the CPU usage statistics manager are:
- ``rtems_cpu_usage_report`` - Report CPU Usage Statistics
- rtems_cpu_usage_report_ - Report CPU Usage Statistics
- ``rtems_cpu_usage_reset`` - Reset CPU Usage Statistics
- rtems_cpu_usage_reset_ - Reset CPU Usage Statistics
Background
==========
When analyzing and debugging real-time applications, it is important
to be able to know how much CPU time each task in the system consumes.
This support component provides a mechanism to easily obtain this
information with little burden placed on the target.
When analyzing and debugging real-time applications, it is important to be able
to know how much CPU time each task in the system consumes. This support
component provides a mechanism to easily obtain this information with little
burden placed on the target.
The raw data is gathered as part of performing a context switch. RTEMS
keeps track of how many clock ticks have occurred which the task being
switched out has been executing. If the task has been running less than
1 clock tick, then for the purposes of the statistics, it is assumed to
have executed 1 clock tick. This results in some inaccuracy but the
alternative is for the task to have appeared to execute 0 clock ticks.
The raw data is gathered as part of performing a context switch. RTEMS keeps
track of how many clock ticks have occurred which the task being switched out
has been executing. If the task has been running less than 1 clock tick, then
for the purposes of the statistics, it is assumed to have executed 1 clock
tick. This results in some inaccuracy but the alternative is for the task to
have appeared to execute 0 clock ticks.
RTEMS versions newer than the 4.7 release series, support the ability
to obtain timestamps with nanosecond granularity if the BSP provides
support. It is a desirable enhancement to change the way the usage
data is gathered to take advantage of this recently added capability.
Please consider sponsoring the core RTEMS development team to add
this capability.
RTEMS versions newer than the 4.7 release series, support the ability to obtain
timestamps with nanosecond granularity if the BSP provides support. It is a
desirable enhancement to change the way the usage data is gathered to take
advantage of this recently added capability. Please consider sponsoring the
core RTEMS development team to add this capability.
Operations
==========
@ -41,9 +43,9 @@ Operations
Report CPU Usage Statistics
---------------------------
The application may dynamically report the CPU usage for every
task in the system by calling the``rtems_cpu_usage_report`` routine.
This routine prints a table with the following information per task:
The application may dynamically report the CPU usage for every task in the
system by calling the ``rtems_cpu_usage_report`` routine. This routine prints
a table with the following information per task:
- task id
@ -55,52 +57,52 @@ This routine prints a table with the following information per task:
The following is an example of the report generated:
.. code:: c
+------------------------------------------------------------------------------+
|CPU USAGE BY THREAD |
+-----------+----------------------------------------+-------------------------+
|ID | NAME | SECONDS | PERCENT |
+-----------+----------------------------------------+---------------+---------+
|0x04010001 | IDLE | 0 | 0.000 |
+-----------+----------------------------------------+---------------+---------+
|0x08010002 | TA1 | 1203 | 0.748 |
+-----------+----------------------------------------+---------------+---------+
|0x08010003 | TA2 | 203 | 0.126 |
+-----------+----------------------------------------+---------------+---------+
|0x08010004 | TA3 | 202 | 0.126 |
+-----------+----------------------------------------+---------------+---------+
|TICKS SINCE LAST SYSTEM RESET: 1600 |
|TOTAL UNITS: 1608 |
+------------------------------------------------------------------------------+
+------------------------------------------------------------------------------+
|CPU USAGE BY THREAD |
+-----------+----------------------------------------+-------------------------+
|ID | NAME | SECONDS | PERCENT |
+-----------+----------------------------------------+---------------+---------+
|0x04010001 | IDLE | 0 | 0.000 |
+-----------+----------------------------------------+---------------+---------+
|0x08010002 | TA1 | 1203 | 0.748 |
+-----------+----------------------------------------+---------------+---------+
|0x08010003 | TA2 | 203 | 0.126 |
+-----------+----------------------------------------+---------------+---------+
|0x08010004 | TA3 | 202 | 0.126 |
+-----------+----------------------------------------+---------------+---------+
|TICKS SINCE LAST SYSTEM RESET: 1600 |
|TOTAL UNITS: 1608 |
+------------------------------------------------------------------------------+
Notice that the "TOTAL UNITS" is greater than the ticks per reset.
This is an artifact of the way in which RTEMS keeps track of CPU
usage. When a task is context switched into the CPU, the number
of clock ticks it has executed is incremented. While the task
is executing, this number is incremented on each clock tick.
Otherwise, if a task begins and completes execution between
successive clock ticks, there would be no way to tell that it
executed at all.
Notice that the ``TOTAL UNITS`` is greater than the ticks per reset. This is
an artifact of the way in which RTEMS keeps track of CPU usage. When a task is
context switched into the CPU, the number of clock ticks it has executed is
incremented. While the task is executing, this number is incremented on each
clock tick. Otherwise, if a task begins and completes execution between
successive clock ticks, there would be no way to tell that it executed at all.
Another thing to keep in mind when looking at idle time, is that
many systems - especially during debug - have a task providing
some type of debug interface. It is usually fine to think of the
total idle time as being the sum of the IDLE task and a debug
task that will not be included in a production build of an application.
Another thing to keep in mind when looking at idle time, is that many systems -
especially during debug - have a task providing some type of debug interface.
It is usually fine to think of the total idle time as being the sum of the
``IDLE`` task and a debug task that will not be included in a production build
of an application.
Reset CPU Usage Statistics
--------------------------
Invoking the ``rtems_cpu_usage_reset`` routine resets
the CPU usage statistics for all tasks in the system.
Invoking the ``rtems_cpu_usage_reset`` routine resets the CPU usage statistics
for all tasks in the system.
Directives
==========
This section details the CPU usage statistics manager's directives.
A subsection is dedicated to each of this manager's directives
and describes the calling sequence, related constants, usage,
and status codes.
This section details the CPU usage statistics manager's directives. A
subsection is dedicated to each of this manager's directives and describes the
calling sequence, related constants, usage, and status codes.
.. _rtems_cpu_usage_report:
cpu_usage_report - Report CPU Usage Statistics
----------------------------------------------
@ -111,17 +113,21 @@ cpu_usage_report - Report CPU Usage Statistics
void rtems_cpu_usage_report( void );
**STATUS CODES: NONE**
**STATUS CODES:**
NONE
**DESCRIPTION:**
This routine prints out a table detailing the CPU usage statistics for
all tasks in the system.
This routine prints out a table detailing the CPU usage statistics for all
tasks in the system.
**NOTES:**
The table is printed using the ``printk`` routine.
.. _rtems_cpu_usage_reset:
cpu_usage_reset - Reset CPU Usage Statistics
--------------------------------------------
@ -131,22 +137,17 @@ cpu_usage_reset - Reset CPU Usage Statistics
void rtems_cpu_usage_reset( void );
**STATUS CODES: NONE**
**STATUS CODES:**
NONE
**DESCRIPTION:**
This routine re-initializes the CPU usage statistics for all tasks
in the system to their initial state. The initial state is that
a task has not executed and thus has consumed no CPU time.
default state which is when zero period executions have occurred.
This routine re-initializes the CPU usage statistics for all tasks in the
system to their initial state. The initial state is that a task has not
executed and thus has consumed no CPU time. default state which is when zero
period executions have occurred.
**NOTES:**
NONE
.. COMMENT: COPYRIGHT (c) 1988-2008.
.. COMMENT: On-Line Applications Research Corporation (OAR).
.. COMMENT: All rights reserved.

View File

@ -1,66 +1,81 @@
.. COMMENT: Copyright 2015 embedded brains GmbH
.. COMMENT: All rights reserved.
Directive Status Codes
######################
Introduction
============
*``RTEMS_SUCCESSFUL`` - successful completion*
The directive status code directives are:
*``RTEMS_TASK_EXITTED`` - returned from a task*
*``RTEMS_MP_NOT_CONFIGURED`` - multiprocessing not configured*
*``RTEMS_INVALID_NAME`` - invalid object name*
*``RTEMS_INVALID_ID`` - invalid object id*
*``RTEMS_TOO_MANY`` - too many*
*``RTEMS_TIMEOUT`` - timed out waiting*
*``RTEMS_OBJECT_WAS_DELETED`` - object was deleted while waiting*
*``RTEMS_INVALID_SIZE`` - invalid specified size*
*``RTEMS_INVALID_ADDRESS`` - invalid address specified*
*``RTEMS_INVALID_NUMBER`` - number was invalid*
*``RTEMS_NOT_DEFINED`` - item not initialized*
*``RTEMS_RESOURCE_IN_USE`` - resources outstanding*
*``RTEMS_UNSATISFIED`` - request not satisfied*
*``RTEMS_INCORRECT_STATE`` - task is in wrong state*
*``RTEMS_ALREADY_SUSPENDED`` - task already in state*
*``RTEMS_ILLEGAL_ON_SELF`` - illegal for calling task*
*``RTEMS_ILLEGAL_ON_REMOTE_OBJECT`` - illegal for remote object*
*``RTEMS_CALLED_FROM_ISR`` - invalid environment*
*``RTEMS_INVALID_PRIORITY`` - invalid task priority*
*``RTEMS_INVALID_CLOCK`` - invalid time buffer*
*``RTEMS_INVALID_NODE`` - invalid node id*
*``RTEMS_NOT_CONFIGURED`` - directive not configured*
*``RTEMS_NOT_OWNER_OF_RESOURCE`` - not owner of resource*
*``RTEMS_NOT_IMPLEMENTED`` - directive not implemented*
*``RTEMS_INTERNAL_ERROR`` - RTEMS inconsistency detected*
*``RTEMS_NO_MEMORY`` - could not get enough memory*
- rtems_status_text_ - Return the name for the status code
Directives
==========
The directives are:
.. list-table::
:class: rtems-table
* - ``RTEMS_SUCCESSFUL``
- successful completion
* - ``RTEMS_TASK_EXITTED``
- returned from a task
* - ``RTEMS_MP_NOT_CONFIGURED``
- multiprocessing not configured
* - ``RTEMS_INVALID_NAME``
- invalid object name
* - ``RTEMS_INVALID_ID``
- invalid object id
* - ``RTEMS_TOO_MANY``
- too many
* - ``RTEMS_TIMEOUT``
- timed out waiting
* - ``RTEMS_OBJECT_WAS_DELETED``
- object was deleted while waiting
* - ``RTEMS_INVALID_SIZE``
- invalid specified size
* - ``RTEMS_INVALID_ADDRESS``
- invalid address specified
* - ``RTEMS_INVALID_NUMBER``
- number was invalid
* - ``RTEMS_NOT_DEFINED``
- item not initialized
* - ``RTEMS_RESOURCE_IN_USE``
- resources outstanding
* - ``RTEMS_UNSATISFIED``
- request not satisfied
* - ``RTEMS_INCORRECT_STATE``
- task is in wrong state
* - ``RTEMS_ALREADY_SUSPENDED``
- task already in state
* - ``RTEMS_ILLEGAL_ON_SELF``
- illegal for calling task
* - ``RTEMS_ILLEGAL_ON_REMOTE_OBJECT``
- illegal for remote object
* - ``RTEMS_CALLED_FROM_ISR``
- invalid environment
* - ``RTEMS_INVALID_PRIORITY``
- invalid task priority
* - ``RTEMS_INVALID_CLOCK``
- invalid time buffer
* - ``RTEMS_INVALID_NODE``
- invalid node id
* - ``RTEMS_NOT_CONFIGURED``
- directive not configured
* - ``RTEMS_NOT_OWNER_OF_RESOURCE``
- not owner of resource
* - ``RTEMS_NOT_IMPLEMENTED``
- directive not implemented
* - ``RTEMS_INTERNAL_ERROR``
- RTEMS inconsistency detected
* - ``RTEMS_NO_MEMORY``
- could not get enough memory
.. _rtems_status_text:
STATUS_TEXT - Returns the enumeration name for a status code
------------------------------------------------------------
@ -68,9 +83,9 @@ STATUS_TEXT - Returns the enumeration name for a status code
.. index:: rtems_status_text
.. code:: c
.. code-block:: c
const char \*rtems_status_text(
const char *rtems_status_text(
rtems_status_code code
);
@ -81,8 +96,3 @@ The status code enumeration name or "?" in case the status code is invalid.
**DESCRIPTION:**
Returns the enumeration name for the specified status code.
.. COMMENT: Copyright 2015 embedded brains GmbH
.. COMMENT: All rights reserved.

View File

@ -1,16 +1,24 @@
.. COMMENT: COPYRIGHT (c) 1989-2011.
.. COMMENT: On-Line Applications Research Corporation (OAR).
.. COMMENT: All rights reserved.
Example Application
###################
.. code:: c
.. code-block:: c
:linenos:
/*
* This file contains an example of a simple RTEMS
* application. It instantiates the RTEMS Configuration
* Information using confdef.h and contains two tasks:
* a user initialization task and a simple task.
\*/
*/
#include <rtems.h>
rtems_task user_application(rtems_task_argument argument);
rtems_task init_task(
rtems_task_argument ignored
)
@ -18,49 +26,49 @@ Example Application
rtems_id tid;
rtems_status_code status;
rtems_name name;
name = rtems_build_name( 'A', 'P', 'P', '1' )
status = rtems_task_create(
name, 1, RTEMS_MINIMUM_STACK_SIZE,
RTEMS_NO_PREEMPT, RTEMS_FLOATING_POINT, &tid
);
if ( status != RTEMS_STATUS_SUCCESSFUL ) {
printf( "rtems_task_create failed with status of %d.\\n", status );
printf( "rtems_task_create failed with status of %d.\n", status );
exit( 1 );
}
status = rtems_task_start( tid, user_application, 0 );
if ( status != RTEMS_STATUS_SUCCESSFUL ) {
printf( "rtems_task_start failed with status of %d.\\n", status );
printf( "rtems_task_start failed with status of %d.\n", status );
exit( 1 );
}
status = rtems_task_delete( SELF ); /* should not return \*/
printf( "rtems_task_delete returned with status of %d.\\n", status );
status = rtems_task_delete( SELF ); /* should not return */
printf( "rtems_task_delete returned with status of %d.\n", status );
exit( 1 );
}
rtems_task user_application(rtems_task_argument argument)
{
/* application specific initialization goes here \*/
while ( 1 ) { /* infinite loop \*/
/* application specific initialization goes here */
while ( 1 ) { /* infinite loop */
/* APPLICATION CODE GOES HERE
*
* This code will typically include at least one
* directive which causes the calling task to
* give up the processor.
\*/
*/
}
}
/* The Console Driver supplies Standard I/O. \*/
/* The Console Driver supplies Standard I/O. */
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
/* The Clock Driver supplies the clock tick. \*/
/* The Clock Driver supplies the clock tick. */
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_MAXIMUM_TASKS 2
#define CONFIGURE_INIT_TASK_NAME rtems_build_name( 'E', 'X', 'A', 'M' )
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_INIT
#include <rtems/confdefs.h>
.. COMMENT: COPYRIGHT (c) 1989-2011.
.. COMMENT: On-Line Applications Research Corporation (OAR).
.. COMMENT: All rights reserved.

View File

@ -1,3 +1,7 @@
.. COMMENT: COPYRIGHT (c) 1989-2014.
.. COMMENT: On-Line Applications Research Corporation (OAR).
.. COMMENT: All rights reserved.
Linker Sets
###########
@ -7,46 +11,45 @@ Introduction
============
Linker sets are a flexible means to create arrays of items out of a set of
object files at link-time. For example its possible to define an item *I*
of type *T* in object file *A* and an item *J* of type *T*
in object file *B* to be a member of a linker set *S*. The linker
will then collect these two items *I* and *J* and place them in
consecutive memory locations, so that they can be accessed like a normal array
defined in one object file. The size of a linker set is defined by its begin
and end markers. A linker set may be empty. It should only contain items of
the same type.
object files at link-time. For example its possible to define an item *I* of
type *T* in object file *A* and an item *J* of type *T* in object file *B* to
be a member of a linker set *S*. The linker will then collect these two items
*I* and *J* and place them in consecutive memory locations, so that they can be
accessed like a normal array defined in one object file. The size of a linker
set is defined by its begin and end markers. A linker set may be empty. It
should only contain items of the same type.
The following macros are provided to create, populate and use linker sets.
- ``RTEMS_LINKER_SET_BEGIN`` - Designator of the linker set begin marker
- RTEMS_LINKER_SET_BEGIN_ - Designator of the linker set begin marker
- ``RTEMS_LINKER_SET_END`` - Designator of the linker set end marker
- RTEMS_LINKER_SET_END_ - Designator of the linker set end marker
- ``RTEMS_LINKER_SET_SIZE`` - The linker set size in characters
- RTEMS_LINKER_SET_SIZE_ - The linker set size in characters
- ``RTEMS_LINKER_ROSET_DECLARE`` - Declares a read-only linker set
- RTEMS_LINKER_ROSET_DECLARE_ - Declares a read-only linker set
- ``RTEMS_LINKER_ROSET`` - Defines a read-only linker set
- RTEMS_LINKER_ROSET_ - Defines a read-only linker set
- ``RTEMS_LINKER_ROSET_ITEM_DECLARE`` - Declares a read-only linker set item
- RTEMS_LINKER_ROSET_ITEM_DECLARE_ - Declares a read-only linker set item
- ``RTEMS_LINKER_ROSET_ITEM_REFERENCE`` - References a read-only linker set item
- RTEMS_LINKER_ROSET_ITEM_REFERENCE_ - References a read-only linker set item
- ``RTEMS_LINKER_ROSET_ITEM`` - Defines a read-only linker set item
- RTEMS_LINKER_ROSET_ITEM_ - Defines a read-only linker set item
- ``RTEMS_LINKER_ROSET_ITEM_ORDERED`` - Defines an ordered read-only linker set item
- RTEMS_LINKER_ROSET_ITEM_ORDERED_ - Defines an ordered read-only linker set item
- ``RTEMS_LINKER_RWSET_DECLARE`` - Declares a read-write linker set
- RTEMS_LINKER_RWSET_DECLARE_ - Declares a read-write linker set
- ``RTEMS_LINKER_RWSET`` - Defines a read-write linker set
- RTEMS_LINKER_RWSET_ - Defines a read-write linker set
- ``RTEMS_LINKER_RWSET_ITEM_DECLARE`` - Declares a read-write linker set item
- RTEMS_LINKER_RWSET_ITEM_DECLARE_ - Declares a read-write linker set item
- ``RTEMS_LINKER_RWSET_ITEM_REFERENCE`` - References a read-write linker set item
- RTEMS_LINKER_RWSET_ITEM_REFERENCE_ - References a read-write linker set item
- ``RTEMS_LINKER_RWSET_ITEM`` - Defines a read-write linker set item
- RTEMS_LINKER_RWSET_ITEM_ - Defines a read-write linker set item
- ``RTEMS_LINKER_RWSET_ITEM_ORDERED`` - Defines an ordered read-write linker set item
- RTEMS_LINKER_RWSET_ITEM_ORDERED_ - Defines an ordered read-write linker set item
Background
==========
@ -56,7 +59,8 @@ FreeBSD, for the GNU C constructor extension and for global C++ constructors.
They provide a space efficient and flexible means to initialize modules. A
linker set consists of
- dedicated input sections for the linker (e.g. ``.ctors`` and``.ctors.*`` in the case of global constructors),
- dedicated input sections for the linker (e.g. ``.ctors`` and ``.ctors.*`` in
the case of global constructors),
- a begin marker (e.g. provided by ``crtbegin.o``, and
@ -69,32 +73,34 @@ find all the collected data items (e.g. pointers to initialization functions).
In the linker command file of the GNU linker we need the following output
section descriptions.
.. code:: c
/* To be placed in a read-only memory region \*/
.. code-block:: c
/* To be placed in a read-only memory region */
.rtemsroset : {
KEEP (\*(SORT(.rtemsroset.*)))
}
/* To be placed in a read-write memory region \*/
/* To be placed in a read-write memory region */
.rtemsrwset : {
KEEP (\*(SORT(.rtemsrwset.*)))
}
The ``KEEP()`` ensures that a garbage collection by the linker will not
discard the content of this section. This would normally be the case since the
linker set items are not referenced directly. The ``SORT()`` directive
sorts the input sections lexicographically. Please note the lexicographical
order of the ``.begin``, ``.content`` and ``.end`` section name parts
in the RTEMS linker sets macros which ensures that the position of the begin
and end markers are right.
The ``KEEP()`` ensures that a garbage collection by the linker will not discard
the content of this section. This would normally be the case since the linker
set items are not referenced directly. The ``SORT()`` directive sorts the
input sections lexicographically. Please note the lexicographical order of the
``.begin``, ``.content`` and ``.end`` section name parts in the RTEMS linker
sets macros which ensures that the position of the begin and end markers are
right.
So, what is the benefit of using linker sets to initialize modules? It can be
used to initialize and include only those RTEMS managers and other components
which are used by the application. For example, in case an application uses
message queues, it must call ``rtems_message_queue_create()``. In the
module implementing this function, we can place a linker set item and register
the message queue handler constructor. Otherwise, in case the application does
not use message queues, there will be no reference to the``rtems_message_queue_create()`` function and the constructor is not
message queues, it must call ``rtems_message_queue_create()``. In the module
implementing this function, we can place a linker set item and register the
message queue handler constructor. Otherwise, in case the application does not
use message queues, there will be no reference to the
``rtems_message_queue_create()`` function and the constructor is not
registered, thus nothing of the message queue handler will be in the final
executable.
@ -103,6 +109,8 @@ For an example see test program :file:`sptests/splinkersets01`.
Directives
==========
.. _RTEMS_LINKER_SET_BEGIN:
RTEMS_LINKER_SET_BEGIN - Designator of the linker set begin marker
------------------------------------------------------------------
@ -110,9 +118,9 @@ RTEMS_LINKER_SET_BEGIN - Designator of the linker set begin marker
.. index:: RTEMS_LINKER_SET_BEGIN
.. code:: c
.. code-block:: c
volatile type \*begin = RTEMS_LINKER_SET_BEGIN( set );
volatile type *begin = RTEMS_LINKER_SET_BEGIN( set );
**DESCRIPTION:**
@ -121,9 +129,12 @@ identified by ``set``. The item at the begin marker address is the first
member of the linker set if it exists, e.g. the linker set is not empty. A
linker set is empty, if and only if the begin and end markers have the same
address.
The ``set`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies the linker set.
.. _RTEMS_LINKER_SET_END:
RTEMS_LINKER_SET_END - Designator of the linker set end marker
--------------------------------------------------------------
@ -131,16 +142,18 @@ RTEMS_LINKER_SET_END - Designator of the linker set end marker
.. index:: RTEMS_LINKER_SET_END
.. code:: c
.. code-block:: c
volatile type \*end = RTEMS_LINKER_SET_END( set );
volatile type *end = RTEMS_LINKER_SET_END( set );
**DESCRIPTION:**
This macro generates the designator of the end marker of the linker set
identified by ``set``. The item at the end marker address is not a member
of the linker set. The ``set`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies the linker set.
identified by ``set``. The item at the end marker address is not a member of
the linker set. The ``set`` parameter itself must be a valid C designator on
which no macro expansion is performed. It uniquely identifies the linker set.
.. _RTEMS_LINKER_SET_SIZE:
RTEMS_LINKER_SET_SIZE - The linker set size in characters
---------------------------------------------------------
@ -149,15 +162,17 @@ RTEMS_LINKER_SET_SIZE - The linker set size in characters
.. index:: RTEMS_LINKER_SET_SIZE
.. code:: c
.. code-block:: c
size_t size = RTEMS_LINKER_SET_SIZE( set );
**DESCRIPTION:**
This macro returns the size of the linker set identified by ``set`` in
characters. The ``set`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies the linker set.
characters. The ``set`` parameter itself must be a valid C designator on which
no macro expansion is performed. It uniquely identifies the linker set.
.. _RTEMS_LINKER_ROSET_DECLARE:
RTEMS_LINKER_ROSET_DECLARE - Declares a read-only linker set
------------------------------------------------------------
@ -166,16 +181,20 @@ RTEMS_LINKER_ROSET_DECLARE - Declares a read-only linker set
.. index:: RTEMS_LINKER_ROSET_DECLARE
.. code:: c
.. code-block:: c
RTEMS_LINKER_ROSET_DECLARE( set, type );
**DESCRIPTION:**
This macro generates declarations for the begin and end markers of a read-only
linker set identified by ``set``. The ``set`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies the linker set. The ``type`` parameter defines the type of the linker set items. The type
must be the same for all macro invocations of a particular linker set.
linker set identified by ``set``. The ``set`` parameter itself must be a valid
C designator on which no macro expansion is performed. It uniquely identifies
the linker set. The ``type`` parameter defines the type of the linker set
items. The type must be the same for all macro invocations of a particular
linker set.
.. _RTEMS_LINKER_ROSET:
RTEMS_LINKER_ROSET - Defines a read-only linker set
---------------------------------------------------
@ -184,16 +203,20 @@ RTEMS_LINKER_ROSET - Defines a read-only linker set
.. index:: RTEMS_LINKER_ROSET
.. code:: c
.. code-block:: c
RTEMS_LINKER_ROSET( set, type );
**DESCRIPTION:**
This macro generates definitions for the begin and end markers of a read-only
linker set identified by ``set``. The ``set`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies the linker set. The ``type`` parameter defines the type of the linker set items. The type
must be the same for all macro invocations of a particular linker set.
linker set identified by ``set``. The ``set`` parameter itself must be a valid
C designator on which no macro expansion is performed. It uniquely identifies
the linker set. The ``type`` parameter defines the type of the linker set
items. The type must be the same for all macro invocations of a particular
linker set.
.. _RTEMS_LINKER_ROSET_ITEM_DECLARE:
RTEMS_LINKER_ROSET_ITEM_DECLARE - Declares a read-only linker set item
----------------------------------------------------------------------
@ -202,17 +225,22 @@ RTEMS_LINKER_ROSET_ITEM_DECLARE - Declares a read-only linker set item
.. index:: RTEMS_LINKER_ROSET_ITEM_DECLARE
.. code:: c
.. code-block:: c
RTEMS_LINKER_ROSET_ITEM_DECLARE( set, type, item );
**DESCRIPTION:**
This macro generates a declaration of an item contained in the read-only linker
set identified by ``set``. The ``set`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies the linker set. The ``type`` parameter defines the type of the linker set items. The type
must be the same for all macro invocations of a particular linker set. The ``item`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies an item in the linker set.
set identified by ``set``. The ``set`` parameter itself must be a valid C
designator on which no macro expansion is performed. It uniquely identifies
the linker set. The ``type`` parameter defines the type of the linker set
items. The type must be the same for all macro invocations of a particular
linker set. The ``item`` parameter itself must be a valid C designator on which
no macro expansion is performed. It uniquely identifies an item in the linker
set.
.. _RTEMS_LINKER_ROSET_ITEM_REFERENCE:
RTEMS_LINKER_ROSET_ITEM_REFERENCE - References a read-only linker set item
--------------------------------------------------------------------------
@ -221,17 +249,22 @@ RTEMS_LINKER_ROSET_ITEM_REFERENCE - References a read-only linker set item
.. index:: RTEMS_LINKER_ROSET_ITEM_REFERENCE
.. code:: c
.. code-block:: c
RTEMS_LINKER_ROSET_ITEM_REFERENCE( set, type, item );
**DESCRIPTION:**
This macro generates a reference to an item contained in the read-only linker set
identified by ``set``. The ``set`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies the linker set. The ``type`` parameter defines the type of the linker set items. The type
must be the same for all macro invocations of a particular linker set. The ``item`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies an item in the linker set.
This macro generates a reference to an item contained in the read-only linker
set identified by ``set``. The ``set`` parameter itself must be a valid C
designator on which no macro expansion is performed. It uniquely identifies
the linker set. The ``type`` parameter defines the type of the linker set
items. The type must be the same for all macro invocations of a particular
linker set. The ``item`` parameter itself must be a valid C designator on which
no macro expansion is performed. It uniquely identifies an item in the linker
set.
.. _RTEMS_LINKER_ROSET_ITEM:
RTEMS_LINKER_ROSET_ITEM - Defines a read-only linker set item
-------------------------------------------------------------
@ -240,17 +273,22 @@ RTEMS_LINKER_ROSET_ITEM - Defines a read-only linker set item
.. index:: RTEMS_LINKER_ROSET_ITEM
.. code:: c
.. code-block:: c
RTEMS_LINKER_ROSET_ITEM( set, type, item );
**DESCRIPTION:**
This macro generates a definition of an item contained in the read-only linker set
identified by ``set``. The ``set`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies the linker set. The ``type`` parameter defines the type of the linker set items. The type
must be the same for all macro invocations of a particular linker set. The ``item`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies an item in the linker set.
This macro generates a definition of an item contained in the read-only linker
set identified by ``set``. The ``set`` parameter itself must be a valid C
designator on which no macro expansion is performed. It uniquely identifies
the linker set. The ``type`` parameter defines the type of the linker set
items. The type must be the same for all macro invocations of a particular
linker set. The ``item`` parameter itself must be a valid C designator on which
no macro expansion is performed. It uniquely identifies an item in the linker
set.
.. _RTEMS_LINKER_ROSET_ITEM_ORDERED:
RTEMS_LINKER_ROSET_ITEM_ORDERED - Defines an ordered read-only linker set item
------------------------------------------------------------------------------
@ -259,46 +297,55 @@ RTEMS_LINKER_ROSET_ITEM_ORDERED - Defines an ordered read-only linker set item
.. index:: RTEMS_LINKER_ROSET_ITEM_ORDERED
.. code:: c
.. code-block:: c
RTEMS_LINKER_ROSET_ITEM_ORDERED( set, type, item, order );
**DESCRIPTION:**
This macro generates a definition of an ordered item contained in the read-only
linker set identified by ``set``. The ``set`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies the linker set. The ``type`` parameter defines the type of the linker set items. The type
must be the same for all macro invocations of a particular linker set.
The ``item`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies an item in the linker set. The ``order`` parameter must be a valid linker input section name part on
which macro expansion is performed. The items are lexicographically ordered
according to the ``order`` parameter within a linker set. Ordered items are
placed before unordered items in the linker set.
linker set identified by ``set``. The ``set`` parameter itself must be a valid
C designator on which no macro expansion is performed. It uniquely identifies
the linker set. The ``type`` parameter defines the type of the linker set
items. The type must be the same for all macro invocations of a particular
linker set. The ``item`` parameter itself must be a valid C designator on
which no macro expansion is performed. It uniquely identifies an item in the
linker set. The ``order`` parameter must be a valid linker input section name
part on which macro expansion is performed. The items are lexicographically
ordered according to the ``order`` parameter within a linker set. Ordered
items are placed before unordered items in the linker set.
**NOTES:**
To be resilient to typos in the order parameter, it is recommended to use the
following construct in macros defining items for a particular linker set (see
enum in ``XYZ_ITEM()``).
.. code:: c
.. code-block:: c
#include <rtems/linkersets.h>
typedef struct {
int foo;
} xyz_item;
/* The XYZ-order defines \*/
/* The XYZ-order defines */
#define XYZ_ORDER_FIRST 0x00001000
#define XYZ_ORDER_AND_SO_ON 0x00002000
/* Defines an ordered XYZ-item \*/
#define XYZ_ITEM( item, order ) \\
enum { xyz_##item = order - order }; \\
RTEMS_LINKER_ROSET_ITEM_ORDERED( \\
xyz, const xyz_item \*, item, order \\
/* Defines an ordered XYZ-item */
#define XYZ_ITEM( item, order ) \
enum { xyz_##item = order - order }; \
RTEMS_LINKER_ROSET_ITEM_ORDERED( \
xyz, const xyz_item *, item, order \
) = { &item }
/* Example item \*/
/* Example item */
static const xyz_item some_item = { 123 };
XYZ_ITEM( some_item, XYZ_ORDER_FIRST );
.. _RTEMS_LINKER_RWSET_DECLARE:
RTEMS_LINKER_RWSET_DECLARE - Declares a read-write linker set
-------------------------------------------------------------
@ -306,16 +353,20 @@ RTEMS_LINKER_RWSET_DECLARE - Declares a read-write linker set
.. index:: RTEMS_LINKER_RWSET_DECLARE
.. code:: c
.. code-block:: c
RTEMS_LINKER_RWSET_DECLARE( set, type );
**DESCRIPTION:**
This macro generates declarations for the begin and end markers of a read-write
linker set identified by ``set``. The ``set`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies the linker set. The ``type`` parameter defines the type of the linker set items. The type
must be the same for all macro invocations of a particular linker set.
linker set identified by ``set``. The ``set`` parameter itself must be a valid
C designator on which no macro expansion is performed. It uniquely identifies
the linker set. The ``type`` parameter defines the type of the linker set
items. The type must be the same for all macro invocations of a particular
linker set.
.. _RTEMS_LINKER_RWSET:
RTEMS_LINKER_RWSET - Defines a read-write linker set
----------------------------------------------------
@ -324,16 +375,20 @@ RTEMS_LINKER_RWSET - Defines a read-write linker set
.. index:: RTEMS_LINKER_RWSET
.. code:: c
.. code-block:: c
RTEMS_LINKER_RWSET( set, type );
**DESCRIPTION:**
This macro generates definitions for the begin and end markers of a read-write
linker set identified by ``set``. The ``set`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies the linker set. The ``type`` parameter defines the type of the linker set items. The type
must be the same for all macro invocations of a particular linker set.
linker set identified by ``set``. The ``set`` parameter itself must be a valid
C designator on which no macro expansion is performed. It uniquely identifies
the linker set. The ``type`` parameter defines the type of the linker set
items. The type must be the same for all macro invocations of a particular
linker set.
.. _RTEMS_LINKER_RWSET_ITEM_DECLARE:
RTEMS_LINKER_RWSET_ITEM_DECLARE - Declares a read-write linker set item
-----------------------------------------------------------------------
@ -342,17 +397,22 @@ RTEMS_LINKER_RWSET_ITEM_DECLARE - Declares a read-write linker set item
.. index:: RTEMS_LINKER_RWSET_ITEM_DECLARE
.. code:: c
.. code-block:: c
RTEMS_LINKER_RWSET_ITEM_DECLARE( set, type, item );
**DESCRIPTION:**
This macro generates a declaration of an item contained in the read-write linker
set identified by ``set``. The ``set`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies the linker set. The ``type`` parameter defines the type of the linker set items. The type
must be the same for all macro invocations of a particular linker set. The ``item`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies an item in the linker set.
This macro generates a declaration of an item contained in the read-write
linker set identified by ``set``. The ``set`` parameter itself must be a valid
C designator on which no macro expansion is performed. It uniquely identifies
the linker set. The ``type`` parameter defines the type of the linker set
items. The type must be the same for all macro invocations of a particular
linker set. The ``item`` parameter itself must be a valid C designator on which
no macro expansion is performed. It uniquely identifies an item in the linker
set.
.. _RTEMS_LINKER_RWSET_ITEM_REFERENCE:
RTEMS_LINKER_RWSET_ITEM_REFERENCE - References a read-write linker set item
---------------------------------------------------------------------------
@ -361,17 +421,22 @@ RTEMS_LINKER_RWSET_ITEM_REFERENCE - References a read-write linker set item
.. index:: RTEMS_LINKER_RWSET_ITEM_REFERENCE
.. code:: c
.. code-block:: c
RTEMS_LINKER_RWSET_ITEM_REFERENCE( set, type, item );
**DESCRIPTION:**
This macro generates a reference to an item contained in the read-write linker set
identified by ``set``. The ``set`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies the linker set. The ``type`` parameter defines the type of the linker set items. The type
must be the same for all macro invocations of a particular linker set. The ``item`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies an item in the linker set.
This macro generates a reference to an item contained in the read-write linker
set identified by ``set``. The ``set`` parameter itself must be a valid C
designator on which no macro expansion is performed. It uniquely identifies
the linker set. The ``type`` parameter defines the type of the linker set
items. The type must be the same for all macro invocations of a particular
linker set. The ``item`` parameter itself must be a valid C designator on which
no macro expansion is performed. It uniquely identifies an item in the linker
set.
.. _RTEMS_LINKER_RWSET_ITEM:
RTEMS_LINKER_RWSET_ITEM - Defines a read-write linker set item
--------------------------------------------------------------
@ -380,17 +445,22 @@ RTEMS_LINKER_RWSET_ITEM - Defines a read-write linker set item
.. index:: RTEMS_LINKER_RWSET_ITEM
.. code:: c
.. code-block:: c
RTEMS_LINKER_RWSET_ITEM( set, type, item );
**DESCRIPTION:**
This macro generates a definition of an item contained in the read-write linker set
identified by ``set``. The ``set`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies the linker set. The ``type`` parameter defines the type of the linker set items. The type
must be the same for all macro invocations of a particular linker set. The ``item`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies an item in the linker set.
This macro generates a definition of an item contained in the read-write linker
set identified by ``set``. The ``set`` parameter itself must be a valid C
designator on which no macro expansion is performed. It uniquely identifies
the linker set. The ``type`` parameter defines the type of the linker set
items. The type must be the same for all macro invocations of a particular
linker set. The ``item`` parameter itself must be a valid C designator on which
no macro expansion is performed. It uniquely identifies an item in the linker
set.
.. _RTEMS_LINKER_RWSET_ITEM_ORDERED:
RTEMS_LINKER_RWSET_ITEM_ORDERED - Defines an ordered read-write linker set item
-------------------------------------------------------------------------------
@ -399,49 +469,48 @@ RTEMS_LINKER_RWSET_ITEM_ORDERED - Defines an ordered read-write linker set item
.. index:: RTEMS_LINKER_RWSET_ITEM_ORDERED
.. code:: c
.. code-block:: c
RTEMS_LINKER_RWSET_ITEM_ORDERED( set, type, item, order );
**DESCRIPTION:**
This macro generates a definition of an ordered item contained in the read-write
linker set identified by ``set``. The ``set`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies the linker set. The ``type`` parameter defines the type of the linker set items. The type
must be the same for all macro invocations of a particular linker set.
The ``item`` parameter itself must be a valid C designator on which no macro
expansion is performed. It uniquely identifies an item in the linker set. The ``order`` parameter must be a valid linker input section name part on
which macro expansion is performed. The items are lexicographically ordered
according to the ``order`` parameter within a linker set. Ordered items are
placed before unordered items in the linker set.
This macro generates a definition of an ordered item contained in the
read-write linker set identified by ``set``. The ``set`` parameter itself must
be a valid C designator on which no macro expansion is performed. It uniquely
identifies the linker set. The ``type`` parameter defines the type of the
linker set items. The type must be the same for all macro invocations of a
particular linker set. The ``item`` parameter itself must be a valid C
designator on which no macro expansion is performed. It uniquely identifies an
item in the linker set. The ``order`` parameter must be a valid linker input
section name part on which macro expansion is performed. The items are
lexicographically ordered according to the ``order`` parameter within a linker
set. Ordered items are placed before unordered items in the linker set.
**NOTES:**
To be resilient to typos in the order parameter, it is recommended to use the
following construct in macros defining items for a particular linker set (see
enum in ``XYZ_ITEM()``).
.. code:: c
.. code-block:: c
#include <rtems/linkersets.h>
typedef struct {
int foo;
} xyz_item;
/* The XYZ-order defines \*/
/* The XYZ-order defines */
#define XYZ_ORDER_FIRST 0x00001000
#define XYZ_ORDER_AND_SO_ON 0x00002000
/* Defines an ordered XYZ-item \*/
#define XYZ_ITEM( item, order ) \\
enum { xyz_##item = order - order }; \\
RTEMS_LINKER_RWSET_ITEM_ORDERED( \\
xyz, const xyz_item \*, item, order \\
/* Defines an ordered XYZ-item */
#define XYZ_ITEM( item, order ) \
enum { xyz_##item = order - order }; \
RTEMS_LINKER_RWSET_ITEM_ORDERED( \
xyz, const xyz_item \*, item, order \
) = { &item }
/* Example item \*/
/* Example item */
static const xyz_item some_item = { 123 };
XYZ_ITEM( some_item, XYZ_ORDER_FIRST );
.. COMMENT: COPYRIGHT (c) 1989-2014.
.. COMMENT: On-Line Applications Research Corporation (OAR).
.. COMMENT: All rights reserved.

View File

@ -1,3 +1,7 @@
.. COMMENT: COPYRIGHT (c) 1988-2008.
.. COMMENT: On-Line Applications Research Corporation (OAR).
.. COMMENT: All rights reserved.
Object Services
###############
@ -6,46 +10,44 @@ Object Services
Introduction
============
RTEMS provides a collection of services to assist in the
management and usage of the objects created and utilized
via other managers. These services assist in the
manipulation of RTEMS objects independent of the API used
to create them. The object related services provided by
RTEMS are:
RTEMS provides a collection of services to assist in the management and usage
of the objects created and utilized via other managers. These services assist
in the manipulation of RTEMS objects independent of the API used to create
them. The object related services provided by RTEMS are:
- build_id
- ``rtems_build_name`` - build object name from characters
- rtems_build_name_ - build object name from characters
- ``rtems_object_get_classic_name`` - lookup name from Id
- rtems_object_get_classic_name_ - lookup name from Id
- ``rtems_object_get_name`` - obtain object name as string
- rtems_object_get_name_ - obtain object name as string
- ``rtems_object_set_name`` - set object name
- rtems_object_set_name_ - set object name
- ``rtems_object_id_get_api`` - obtain API from Id
- rtems_object_id_get_api_ - obtain API from Id
- ``rtems_object_id_get_class`` - obtain class from Id
- rtems_object_id_get_class_ - obtain class from Id
- ``rtems_object_id_get_node`` - obtain node from Id
- rtems_object_id_get_node_ - obtain node from Id
- ``rtems_object_id_get_index`` - obtain index from Id
- rtems_object_id_get_index_ - obtain index from Id
- ``rtems_build_id`` - build object id from components
- rtems_build_id_ - build object id from components
- ``rtems_object_id_api_minimum`` - obtain minimum API value
- rtems_object_id_api_minimum_ - obtain minimum API value
- ``rtems_object_id_api_maximum`` - obtain maximum API value
- rtems_object_id_api_maximum_ - obtain maximum API value
- ``rtems_object_id_api_minimum_class`` - obtain minimum class value
- rtems_object_id_api_minimum_class_ - obtain minimum class value
- ``rtems_object_id_api_maximum_class`` - obtain maximum class value
- rtems_object_id_api_maximum_class_ - obtain maximum class value
- ``rtems_object_get_api_name`` - obtain API name
- rtems_object_get_api_name_ - obtain API name
- ``rtems_object_get_api_class_name`` - obtain class name
- rtems_object_get_api_class_name_ - obtain class name
- ``rtems_object_get_class_information`` - obtain class information
- rtems_object_get_class_information_ - obtain class information
Background
==========
@ -53,46 +55,39 @@ Background
APIs
----
RTEMS implements multiple APIs including an Internal API,
the Classic API, and the POSIX API. These
APIs share the common foundation of SuperCore objects and
thus share object management code. This includes a common
scheme for object Ids and for managing object names whether
those names be in the thirty-two bit form used by the Classic
API or C strings.
RTEMS implements multiple APIs including an Internal API, the Classic API, and
the POSIX API. These APIs share the common foundation of SuperCore objects and
thus share object management code. This includes a common scheme for object Ids
and for managing object names whether those names be in the thirty-two bit form
used by the Classic API or C strings.
The object Id contains a field indicating the API that
an object instance is associated with. This field
holds a numerically small non-zero integer.
The object Id contains a field indicating the API that an object instance is
associated with. This field holds a numerically small non-zero integer.
Object Classes
--------------
Each API consists of a collection of managers. Each manager
is responsible for instances of a particular object class.
Classic API Tasks and POSIX Mutexes example classes.
Each API consists of a collection of managers. Each manager is responsible for
instances of a particular object class. Classic API Tasks and POSIX Mutexes
example classes.
The object Id contains a field indicating the class that
an object instance is associated with. This field
holds a numerically small non-zero integer. In all APIs,
a class value of one is reserved for tasks or threads.
The object Id contains a field indicating the class that an object instance is
associated with. This field holds a numerically small non-zero integer. In
all APIs, a class value of one is reserved for tasks or threads.
Object Names
------------
Every RTEMS object which has an Id may also have a
name associated with it. Depending on the API, names
may be either thirty-two bit integers as in the Classic
API or strings as in the POSIX API.
Every RTEMS object which has an Id may also have a name associated with it.
Depending on the API, names may be either thirty-two bit integers as in the
Classic API or strings as in the POSIX API.
Some objects have Ids but do not have a defined way to associate
a name with them. For example, POSIX threads have
Ids but per POSIX do not have names. In RTEMS, objects
not defined to have thirty-two bit names may have string
names assigned to them via the ``rtems_object_set_name``
service. The original impetus in providing this service
was so the normally anonymous POSIX threads could have
a user defined name in CPU Usage Reports.
Some objects have Ids but do not have a defined way to associate a name with
them. For example, POSIX threads have Ids but per POSIX do not have names. In
RTEMS, objects not defined to have thirty-two bit names may have string names
assigned to them via the ``rtems_object_set_name`` service. The original
impetus in providing this service was so the normally anonymous POSIX threads
could have a user defined name in CPU Usage Reports.
Operations
==========
@ -100,9 +95,8 @@ Operations
Decomposing and Recomposing an Object Id
----------------------------------------
Services are provided to decompose an object Id into its
subordinate components. The following services are used
to do this:
Services are provided to decompose an object Id into its subordinate
components. The following services are used to do this:
- ``rtems_object_id_get_api``
@ -112,14 +106,15 @@ to do this:
- ``rtems_object_id_get_index``
The following C language example illustrates the
decomposition of an Id and printing the values.
The following C language example illustrates the decomposition of an Id and
printing the values.
.. code:: c
void printObjectId(rtems_id id)
{
printf(
"API=%d Class=%d Node=%d Index=%d\\n",
"API=%d Class=%d Node=%d Index=%d\n",
rtems_object_id_get_api(id),
rtems_object_id_get_class(id),
rtems_object_id_get_node(id),
@ -129,10 +124,10 @@ decomposition of an Id and printing the values.
This prints the components of the Ids as integers.
It is also possible to construct an arbitrary Id using
the ``rtems_build_id`` service. The following
C language example illustrates how to construct the
It is also possible to construct an arbitrary Id using the ``rtems_build_id``
service. The following C language example illustrates how to construct the
"next Id."
.. code:: c
rtems_id nextObjectId(rtems_id id)
@ -151,22 +146,24 @@ system or associated with an allocated object.
Printing an Object Id
---------------------
RTEMS also provides services to associate the API and Class
portions of an Object Id with strings. This allows the
application developer to provide more information about
an object in diagnostic messages.
RTEMS also provides services to associate the API and Class portions of an
Object Id with strings. This allows the application developer to provide more
information about an object in diagnostic messages.
In the following C language example, an Id is decomposed into its constituent
parts and "pretty-printed."
In the following C language example, an Id is decomposed into
its constituent parts and "pretty-printed."
.. code:: c
void prettyPrintObjectId(rtems_id id)
{
int tmpAPI, tmpClass;
tmpAPI = rtems_object_id_get_api(id),
tmpClass = rtems_object_id_get_class(id),
printf(
"API=%s Class=%s Node=%d Index=%d\\n",
"API=%s Class=%s Node=%d Index=%d\n",
rtems_object_get_api_name(tmpAPI),
rtems_object_get_api_class_name(tmpAPI, tmpClass),
rtems_object_id_get_node(id),
@ -177,6 +174,8 @@ its constituent parts and "pretty-printed."
Directives
==========
.. _rtems_build_name:
BUILD_NAME - Build object name from characters
----------------------------------------------
.. index:: build object name
@ -200,15 +199,16 @@ Returns a name constructed from the four characters.
**DESCRIPTION:**
This service takes the four characters provided as arguments
and constructs a thirty-two bit object name with ``c1``
in the most significant byte and ``c4`` in the least
significant byte.
This service takes the four characters provided as arguments and constructs a
thirty-two bit object name with ``c1`` in the most significant byte and ``c4``
in the least significant byte.
**NOTES:**
This directive is strictly local and does not impact task scheduling.
.. _rtems_object_get_classic_name:
OBJECT_GET_CLASSIC_NAME - Lookup name from id
---------------------------------------------
.. index:: get name from id
@ -216,30 +216,38 @@ OBJECT_GET_CLASSIC_NAME - Lookup name from id
**CALLING SEQUENCE:**
.. index:: rtems_build_name
.. index:: rtems_object_get_classic_name
.. code:: c
rtems_status_code rtems_object_get_classic_name(
rtems_id id,
rtems_name \*name
rtems_name *name
);
**DIRECTIVE STATUS CODES**
``RTEMS_SUCCESSFUL`` - name looked up successfully
``RTEMS_INVALID_ADDRESS`` - invalid name pointer
``RTEMS_INVALID_ID`` - invalid object id
.. list-table::
:class: rtems-table
* - ``RTEMS_SUCCESSFUL``
- name looked up successfully
* - ``RTEMS_INVALID_ADDRESS``
- invalid name pointer
* - ``RTEMS_INVALID_ID``
- invalid object id
**DESCRIPTION:**
This service looks up the name for the object ``id`` specified
and, if found, places the result in ``*name``.
This service looks up the name for the object ``id`` specified and, if found,
places the result in ``*name``.
**NOTES:**
This directive is strictly local and does not impact task scheduling.
.. _rtems_object_get_name:
OBJECT_GET_NAME - Obtain object name as string
----------------------------------------------
.. index:: get object name as string
@ -251,27 +259,29 @@ OBJECT_GET_NAME - Obtain object name as string
.. code:: c
char \*rtems_object_get_name(
char* rtems_object_get_name(
rtems_id id,
size_t length,
char \*name
char *name
);
**DIRECTIVE STATUS CODES**
Returns a pointer to the name if successful or ``NULL``
otherwise.
Returns a pointer to the name if successful or ``NULL`` otherwise.
**DESCRIPTION:**
This service looks up the name of the object specified by``id`` and places it in the memory pointed to by ``name``.
Every attempt is made to return name as a printable string even
if the object has the Classic API thirty-two bit style name.
This service looks up the name of the object specified by ``id`` and places it
in the memory pointed to by ``name``. Every attempt is made to return name as
a printable string even if the object has the Classic API thirty-two bit style
name.
**NOTES:**
This directive is strictly local and does not impact task scheduling.
.. _rtems_object_set_name:
OBJECT_SET_NAME - Set object name
---------------------------------
.. index:: set object name
@ -284,37 +294,42 @@ OBJECT_SET_NAME - Set object name
rtems_status_code rtems_object_set_name(
rtems_id id,
const char \*name
const char *name
);
**DIRECTIVE STATUS CODES**
``RTEMS_SUCCESSFUL`` - name looked up successfully
``RTEMS_INVALID_ADDRESS`` - invalid name pointer
``RTEMS_INVALID_ID`` - invalid object id
.. list-table::
:class: rtems-table
* - ``RTEMS_SUCCESSFUL``
- name looked up successfully
* - ``RTEMS_INVALID_ADDRESS``
- invalid name pointer
* - ``RTEMS_INVALID_ID``
- invalid object id
**DESCRIPTION:**
This service sets the name of ``id`` to that specified
by the string located at ``name``.
This service sets the name of ``id`` to that specified by the string located at
``name``.
**NOTES:**
This directive is strictly local and does not impact task scheduling.
If the object specified by ``id`` is of a class that
has a string name, this method will free the existing
name to the RTEMS Workspace and allocate enough memory
from the RTEMS Workspace to make a copy of the string
located at ``name``.
If the object specified by ``id`` is of a class that has a string name, this
method will free the existing name to the RTEMS Workspace and allocate enough
memory from the RTEMS Workspace to make a copy of the string located at
``name``.
If the object specified by ``id`` is of a class that
has a thirty-two bit integer style name, then the first
four characters in ``*name`` will be used to construct
the name.
name to the RTEMS Workspace and allocate enough memory
If the object specified by ``id`` is of a class that has a thirty-two bit
integer style name, then the first four characters in ``*name`` will be used to
construct the name. name to the RTEMS Workspace and allocate enough memory
from the RTEMS Workspace to make a copy of the string
.. _rtems_object_id_get_api:
OBJECT_ID_GET_API - Obtain API from Id
--------------------------------------
.. index:: obtain API from id
@ -343,6 +358,8 @@ This directive is strictly local and does not impact task scheduling.
This directive does NOT validate the ``id`` provided.
.. _rtems_object_id_get_class:
OBJECT_ID_GET_CLASS - Obtain Class from Id
------------------------------------------
.. index:: obtain class from object id
@ -371,6 +388,8 @@ This directive is strictly local and does not impact task scheduling.
This directive does NOT validate the ``id`` provided.
.. _rtems_object_id_get_node:
OBJECT_ID_GET_NODE - Obtain Node from Id
----------------------------------------
.. index:: obtain node from object id
@ -399,6 +418,8 @@ This directive is strictly local and does not impact task scheduling.
This directive does NOT validate the ``id`` provided.
.. _rtems_object_id_get_index:
OBJECT_ID_GET_INDEX - Obtain Index from Id
------------------------------------------
.. index:: obtain index from object id
@ -427,6 +448,8 @@ This directive is strictly local and does not impact task scheduling.
This directive does NOT validate the ``id`` provided.
.. _rtems_build_id:
BUILD_ID - Build Object Id From Components
------------------------------------------
.. index:: build object id from components
@ -450,14 +473,17 @@ Returns an object Id constructed from the provided arguments.
**DESCRIPTION:**
This service constructs an object Id from the provided``the_api``, ``the_class``, ``the_node``, and ``the_index``.
This service constructs an object Id from the provided ``the_api``,
``the_class``, ``the_node``, and ``the_index``.
**NOTES:**
This directive is strictly local and does not impact task scheduling.
This directive does NOT validate the arguments provided
or the Object id returned.
This directive does NOT validate the arguments provided or the Object id
returned.
.. _rtems_object_id_api_minimum:
OBJECT_ID_API_MINIMUM - Obtain Minimum API Value
------------------------------------------------
@ -477,13 +503,14 @@ Returns the minimum valid for the API portion of an object Id.
**DESCRIPTION:**
This service returns the minimum valid for the API portion of
an object Id.
This service returns the minimum valid for the API portion of an object Id.
**NOTES:**
This directive is strictly local and does not impact task scheduling.
.. _rtems_object_id_api_maximum:
OBJECT_ID_API_MAXIMUM - Obtain Maximum API Value
------------------------------------------------
.. index:: obtain maximum API value
@ -502,13 +529,14 @@ Returns the maximum valid for the API portion of an object Id.
**DESCRIPTION:**
This service returns the maximum valid for the API portion of
an object Id.
This service returns the maximum valid for the API portion of an object Id.
**NOTES:**
This directive is strictly local and does not impact task scheduling.
.. _rtems_object_api_minimum_class:
OBJECT_API_MINIMUM_CLASS - Obtain Minimum Class Value
-----------------------------------------------------
.. index:: obtain minimum class value
@ -527,18 +555,20 @@ OBJECT_API_MINIMUM_CLASS - Obtain Minimum Class Value
If ``api`` is not valid, -1 is returned.
If successful, this service returns the minimum valid for the class
portion of an object Id for the specified ``api``.
If successful, this service returns the minimum valid for the class portion of
an object Id for the specified ``api``.
**DESCRIPTION:**
This service returns the minimum valid for the class portion of
an object Id for the specified ``api``.
This service returns the minimum valid for the class portion of an object Id
for the specified ``api``.
**NOTES:**
This directive is strictly local and does not impact task scheduling.
.. _rtems_object_api_maximum_class:
OBJECT_API_MAXIMUM_CLASS - Obtain Maximum Class Value
-----------------------------------------------------
.. index:: obtain maximum class value
@ -557,18 +587,20 @@ OBJECT_API_MAXIMUM_CLASS - Obtain Maximum Class Value
If ``api`` is not valid, -1 is returned.
If successful, this service returns the maximum valid for the class
portion of an object Id for the specified ``api``.
If successful, this service returns the maximum valid for the class portion of
an object Id for the specified ``api``.
**DESCRIPTION:**
This service returns the maximum valid for the class portion of
an object Id for the specified ``api``.
This service returns the maximum valid for the class portion of an object Id
for the specified ``api``.
**NOTES:**
This directive is strictly local and does not impact task scheduling.
.. _rtems_object_get_api_name:
OBJECT_GET_API_NAME - Obtain API Name
-------------------------------------
.. index:: obtain API name
@ -579,7 +611,7 @@ OBJECT_GET_API_NAME - Obtain API Name
.. code:: c
const char \*rtems_object_get_api_name(
const char* rtems_object_get_api_name(
int api
);
@ -587,8 +619,8 @@ OBJECT_GET_API_NAME - Obtain API Name
If ``api`` is not valid, the string ``"BAD API"`` is returned.
If successful, this service returns a pointer to a string
containing the name of the specified ``api``.
If successful, this service returns a pointer to a string containing the name
of the specified ``api``.
**DESCRIPTION:**
@ -598,8 +630,9 @@ This service returns the name of the specified ``api``.
This directive is strictly local and does not impact task scheduling.
The string returned is from constant space. Do not modify
or free it.
The string returned is from constant space. Do not modify or free it.
.. _rtems_object_get_api_class_name:
OBJECT_GET_API_CLASS_NAME - Obtain Class Name
---------------------------------------------
@ -611,7 +644,7 @@ OBJECT_GET_API_CLASS_NAME - Obtain Class Name
.. code:: c
const char \*rtems_object_get_api_class_name(
const char *rtems_object_get_api_class_name(
int the_api,
int the_class
);
@ -622,20 +655,19 @@ If ``the_api`` is not valid, the string ``"BAD API"`` is returned.
If ``the_class`` is not valid, the string ``"BAD CLASS"`` is returned.
If successful, this service returns a pointer to a string
containing the name of the specified ``the_api``/``the_class`` pair.
If successful, this service returns a pointer to a string containing the name
of the specified ``the_api`` / ``the_class`` pair.
**DESCRIPTION:**
This service returns the name of the object class indicated by the
specified ``the_api`` and ``the_class``.
This service returns the name of the object class indicated by the specified
``the_api`` and ``the_class``.
**NOTES:**
This directive is strictly local and does not impact task scheduling.
The string returned is from constant space. Do not modify
or free it.
The string returned is from constant space. Do not modify or free it.
OBJECT_GET_CLASS_INFORMATION - Obtain Class Information
-------------------------------------------------------
@ -650,23 +682,29 @@ OBJECT_GET_CLASS_INFORMATION - Obtain Class Information
rtems_status_code rtems_object_get_class_information(
int the_api,
int the_class,
rtems_object_api_class_information \*info
rtems_object_api_class_information *info
);
**DIRECTIVE STATUS CODES**
``RTEMS_SUCCESSFUL`` - information obtained successfully
``RTEMS_INVALID_ADDRESS`` - ``info`` is NULL
``RTEMS_INVALID_NUMBER`` - invalid ``api`` or ``the_class``
.. list-table::
:class: rtems-table
If successful, the structure located at ``info`` will be filled
in with information about the specified ``api``/``the_class`` pairing.
* - ``RTEMS_SUCCESSFUL``
- information obtained successfully
* - ``RTEMS_INVALID_ADDRESS``
- ``info`` is NULL
* - ``RTEMS_INVALID_NUMBER``
- invalid ``api`` or ``the_class``
If successful, the structure located at ``info`` will be filled in with
information about the specified ``api`` / ``the_class`` pairing.
**DESCRIPTION:**
This service returns information about the object class indicated by the
specified ``api`` and ``the_class``. This structure is defined as
follows:
specified ``api`` and ``the_class``. This structure is defined as follows:
.. code:: c
typedef struct {
@ -680,10 +718,3 @@ follows:
**NOTES:**
This directive is strictly local and does not impact task scheduling.
.. COMMENT: COPYRIGHT (c) 1988-2008.
.. COMMENT: On-Line Applications Research Corporation (OAR).
.. COMMENT: All rights reserved.

View File

@ -1,3 +1,7 @@
.. COMMENT: COPYRIGHT (c) 1988-2012.
.. COMMENT: On-Line Applications Research Corporation (OAR).
.. COMMENT: All rights reserved.
Red-Black Trees
###############
@ -11,8 +15,6 @@ implementation. Within RTEMS, red-black trees are used when a binary search
tree is needed, including dynamic priority thread queues and non-contiguous
heap memory. The Red-Black Tree API provided by RTEMS is:
- build_id
- ``rtems_rtems_rbtree_node`` - Red-Black Tree node embedded in another struct
- ``rtems_rtems_rbtree_control`` - Red-Black Tree control node for an entire tree
@ -81,12 +83,12 @@ accesses a red-black tree instance at a time.
Nodes
-----
A red-black tree is made up from nodes that orginate from a red-black tree control
object. A node is of type ``rtems_rtems_rbtree_node``. The node
is designed to be part of a user data structure. To obtain the encapsulating
structure users can use the ``RTEMS_CONTAINER_OF`` macro.
The node can be placed anywhere within the user's structure and the macro will
calculate the structure's address from the node's address.
A red-black tree is made up from nodes that orginate from a red-black tree
control object. A node is of type ``rtems_rtems_rbtree_node``. The node is
designed to be part of a user data structure. To obtain the encapsulating
structure users can use the ``RTEMS_CONTAINER_OF`` macro. The node can be
placed anywhere within the user's structure and the macro will calculate the
structure's address from the node's address.
Controls
--------
@ -94,14 +96,15 @@ Controls
A red-black tree is rooted with a control object. Red-Black Tree control
provide the user with access to the nodes on the red-black tree. The
implementation does not require special checks for manipulating the root of the
red-black tree. To accomplish this the``rtems_rtems_rbtree_control`` structure is treated as a``rtems_rtems_rbtree_node`` structure with a ``NULL`` parent
red-black tree. To accomplish this the ``rtems_rtems_rbtree_control`` structure
is treated as a ``rtems_rtems_rbtree_node`` structure with a ``NULL`` parent
and left child pointing to the root.
Operations
==========
Examples for using the red-black trees
can be found in the testsuites/sptests/sprbtree01/init.c file.
Examples for using the red-black trees can be found in the
``testsuites/sptests/sprbtree01/init.c`` file.
Directives
==========
@ -110,12 +113,5 @@ Documentation for the Red-Black Tree Directives
-----------------------------------------------
.. index:: rbtree doc
Source documentation for the Red-Black Tree API can be found in the
generated Doxygen output for cpukit/sapi.
.. COMMENT: COPYRIGHT (c) 1988-2012.
.. COMMENT: On-Line Applications Research Corporation (OAR).
.. COMMENT: All rights reserved.
Source documentation for the Red-Black Tree API can be found in the generated
Doxygen output for ``cpukit/sapi``.

View File

@ -1,16 +1,22 @@
.. COMMENT: COPYRIGHT (c) 1988-2008.
.. COMMENT: On-Line Applications Research Corporation (OAR).
.. COMMENT: All rights reserved.
Stack Bounds Checker
####################
.. index:: stack
Introduction
============
The stack bounds checker is an RTEMS support component that determines
if a task has overrun its run-time stack. The routines provided
by the stack bounds checker manager are:
The stack bounds checker is an RTEMS support component that determines if a
task has overrun its run-time stack. The routines provided by the stack bounds
checker manager are:
- ``rtems_stack_checker_is_blown`` - Has the Current Task Blown its Stack
- rtems_stack_checker_is_blown_ - Has the Current Task Blown its Stack
- ``rtems_stack_checker_report_usage`` - Report Task Stack Usage
- rtems_stack_checker_report_usage_ - Report Task Stack Usage
Background
==========
@ -18,53 +24,52 @@ Background
Task Stack
----------
Each task in a system has a fixed size stack associated with it. This
stack is allocated when the task is created. As the task executes, the
stack is used to contain parameters, return addresses, saved registers,
and local variables. The amount of stack space required by a task
is dependent on the exact set of routines used. The peak stack usage
reflects the worst case of subroutine pushing information on the stack.
For example, if a subroutine allocates a local buffer of 1024 bytes, then
this data must be accounted for in the stack of every task that invokes that
routine.
Each task in a system has a fixed size stack associated with it. This stack is
allocated when the task is created. As the task executes, the stack is used to
contain parameters, return addresses, saved registers, and local variables.
The amount of stack space required by a task is dependent on the exact set of
routines used. The peak stack usage reflects the worst case of subroutine
pushing information on the stack. For example, if a subroutine allocates a
local buffer of 1024 bytes, then this data must be accounted for in the stack
of every task that invokes that routine.
Recursive routines make calculating peak stack usage difficult, if not
impossible. Each call to the recursive routine consumes *n* bytes
of stack space. If the routine recursives 1000 times, then ``1000 * *n*`` bytes of stack space are required.
impossible. Each call to the recursive routine consumes *n* bytes of stack
space. If the routine recursives 1000 times, then ``1000 * n`` bytes of
stack space are required.
Execution
---------
The stack bounds checker operates as a set of task extensions. At
task creation time, the task's stack is filled with a pattern to
indicate the stack is unused. As the task executes, it will overwrite
this pattern in memory. At each task switch, the stack bounds checker's
task switch extension is executed. This extension checks that:
The stack bounds checker operates as a set of task extensions. At task
creation time, the task's stack is filled with a pattern to indicate the stack
is unused. As the task executes, it will overwrite this pattern in memory. At
each task switch, the stack bounds checker's task switch extension is executed.
This extension checks that:
- the last ``n`` bytes of the task's stack have
not been overwritten. If this pattern has been damaged, it
indicates that at some point since this task was context
switch to the CPU, it has used too much stack space.
- the last ``n`` bytes of the task's stack have not been overwritten. If this
pattern has been damaged, it indicates that at some point since this task was
context switch to the CPU, it has used too much stack space.
- the current stack pointer of the task is not within
the address range allocated for use as the task's stack.
- the current stack pointer of the task is not within the address range
allocated for use as the task's stack.
If either of these conditions is detected, then a blown stack
error is reported using the ``printk`` routine.
If either of these conditions is detected, then a blown stack error is reported
using the ``printk`` routine.
The number of bytes checked for an overwrite is processor family dependent.
The minimum stack frame per subroutine call varies widely between processor
families. On CISC families like the Motorola MC68xxx and Intel ix86, all
that is needed is a return address. On more complex RISC processors,
the minimum stack frame per subroutine call may include space to save
a significant number of registers.
families. On CISC families like the Motorola MC68xxx and Intel ix86, all that
is needed is a return address. On more complex RISC processors, the minimum
stack frame per subroutine call may include space to save a significant number
of registers.
Another processor dependent feature that must be taken into account by
the stack bounds checker is the direction that the stack grows. On some
processor families, the stack grows up or to higher addresses as the
task executes. On other families, it grows down to lower addresses. The
stack bounds checker implementation uses the stack description definitions
provided by every RTEMS port to get for this information.
Another processor dependent feature that must be taken into account by the
stack bounds checker is the direction that the stack grows. On some processor
families, the stack grows up or to higher addresses as the task executes. On
other families, it grows down to lower addresses. The stack bounds checker
implementation uses the stack description definitions provided by every RTEMS
port to get for this information.
Operations
==========
@ -72,14 +77,16 @@ Operations
Initializing the Stack Bounds Checker
-------------------------------------
The stack checker is initialized automatically when its task
create extension runs for the first time.
The stack checker is initialized automatically when its task create extension
runs for the first time.
The application must include the stack bounds checker extension set in its set
of Initial Extensions. This set of extensions is defined as
``STACK_CHECKER_EXTENSION``. If using ``<rtems/confdefs.h>`` for Configuration
Table generation, then all that is necessary is to define the macro
``CONFIGURE_STACK_CHECKER_ENABLED`` before including ``<rtems/confdefs.h>`` as
shown below:
The application must include the stack bounds checker extension set
in its set of Initial Extensions. This set of extensions is
defined as ``STACK_CHECKER_EXTENSION``. If using ``<rtems/confdefs.h>``
for Configuration Table generation, then all that is necessary is
to define the macro ``CONFIGURE_STACK_CHECKER_ENABLED`` before including``<rtems/confdefs.h>`` as shown below:
.. code:: c
#define CONFIGURE_STACK_CHECKER_ENABLED
@ -89,20 +96,19 @@ to define the macro ``CONFIGURE_STACK_CHECKER_ENABLED`` before including``<rtems
Checking for Blown Task Stack
-----------------------------
The application may check whether the stack pointer of currently
executing task is within proper bounds at any time by calling
the ``rtems_stack_checker_is_blown`` method. This
method return ``FALSE`` if the task is operating within its
stack bounds and has not damaged its pattern area.
The application may check whether the stack pointer of currently executing task
is within proper bounds at any time by calling the
``rtems_stack_checker_is_blown`` method. This method return ``FALSE`` if the
task is operating within its stack bounds and has not damaged its pattern area.
Reporting Task Stack Usage
--------------------------
The application may dynamically report the stack usage for every task
in the system by calling the``rtems_stack_checker_report_usage`` routine.
This routine prints a table with the peak usage and stack size of
every task in the system. The following is an example of the
report generated:
The application may dynamically report the stack usage for every task in the
system by calling the ``rtems_stack_checker_report_usage`` routine. This
routine prints a table with the peak usage and stack size of every task in the
system. The following is an example of the report generated:
.. code:: c
ID NAME LOW HIGH AVAILABLE USED
@ -112,38 +118,40 @@ report generated:
0x08010004 TA3 0x003e0c40 0x003e3047 9096 1104
0xffffffff INTR 0x003ecfc0 0x003effbf 12160 128
Notice the last time. The task id is 0xffffffff and its name is "INTR".
Notice the last line. The task id is ``0xffffffff`` and its name is ``INTR``.
This is not actually a task, it is the interrupt stack.
When a Task Overflows the Stack
-------------------------------
When the stack bounds checker determines that a stack overflow has occurred,
it will attempt to print a message using ``printk`` identifying the
task and then shut the system down. If the stack overflow has caused
corruption, then it is possible that the message cannot be printed.
When the stack bounds checker determines that a stack overflow has occurred, it
will attempt to print a message using ``printk`` identifying the task and then
shut the system down. If the stack overflow has caused corruption, then it is
possible that the message cannot be printed.
The following is an example of the output generated:
.. code:: c
BLOWN STACK!!! Offending task(0x3eb360): id=0x08010002; name=0x54413120
stack covers range 0x003e5750 - 0x003e7b57 (9224 bytes)
Damaged pattern begins at 0x003e5758 and is 128 bytes long
The above includes the task id and a pointer to the task control block as
well as enough information so one can look at the task's stack and
see what was happening.
The above includes the task id and a pointer to the task control block as well
as enough information so one can look at the task's stack and see what was
happening.
Routines
========
This section details the stack bounds checker's routines.
A subsection is dedicated to each of routines
and describes the calling sequence, related constants, usage,
and status codes.
This section details the stack bounds checker's routines. A subsection is
dedicated to each of routines and describes the calling sequence, related
constants, usage, and status codes.
.. COMMENT: rtems_stack_checker_is_blown
.. _rtems_stack_checker_is_blown:
STACK_CHECKER_IS_BLOWN - Has Current Task Blown Its Stack
---------------------------------------------------------
@ -155,20 +163,27 @@ STACK_CHECKER_IS_BLOWN - Has Current Task Blown Its Stack
**STATUS CODES:**
``TRUE`` - Stack is operating within its stack limits
``FALSE`` - Current stack pointer is outside allocated area
.. list-table::
:class: rtems-table
* - ``TRUE``
- Stack is operating within its stack limits
* - ``FALSE``
- Current stack pointer is outside allocated area
**DESCRIPTION:**
This method is used to determine if the current stack pointer
of the currently executing task is within bounds.
This method is used to determine if the current stack pointer of the currently
executing task is within bounds.
**NOTES:**
This method checks the current stack pointer against
the high and low addresses of the stack memory allocated when
the task was created and it looks for damage to the high water
mark pattern for the worst case usage of the task being called.
This method checks the current stack pointer against the high and low addresses
of the stack memory allocated when the task was created and it looks for damage
to the high water mark pattern for the worst case usage of the task being
called.
.. _rtems_stack_checker_report_usage:
STACK_CHECKER_REPORT_USAGE - Report Task Stack Usage
----------------------------------------------------
@ -179,7 +194,9 @@ STACK_CHECKER_REPORT_USAGE - Report Task Stack Usage
void rtems_stack_checker_report_usage( void );
**STATUS CODES: NONE**
**STATUS CODES:**
NONE
**DESCRIPTION:**
@ -189,10 +206,3 @@ allocation of every task in the system.
**NOTES:**
NONE
.. COMMENT: COPYRIGHT (c) 1988-2007.
.. COMMENT: On-Line Applications Research Corporation (OAR).
.. COMMENT: All rights reserved.

View File

@ -1,3 +1,7 @@
.. COMMENT: COPYRIGHT (c) 2011.
.. COMMENT: On-Line Applications Research Corporation (OAR).
.. COMMENT: All rights reserved.
Timespec Helpers
################
@ -9,33 +13,33 @@ instances of the POSIX ``struct timespec`` structure.
The directives provided by the timespec helpers manager are:
- ``rtems_timespec_set`` - Set timespec's value
- rtems_timespec_set_ - Set timespec's value
- ``rtems_timespec_zero`` - Zero timespec's value
- rtems_timespec_zero_ - Zero timespec's value
- ``rtems_timespec_is_valid`` - Check if timespec is valid
- rtems_timespec_is_valid_ - Check if timespec is valid
- ``rtems_timespec_add_to`` - Add two timespecs
- rtems_timespec_add_to_ - Add two timespecs
- ``rtems_timespec_subtract`` - Subtract two timespecs
- rtems_timespec_subtract_ - Subtract two timespecs
- ``rtems_timespec_divide`` - Divide two timespecs
- rtems_timespec_divide_ - Divide two timespecs
- ``rtems_timespec_divide_by_integer`` - Divide timespec by integer
- rtems_timespec_divide_by_integer_ - Divide timespec by integer
- ``rtems_timespec_less_than`` - Less than operator
- rtems_timespec_less_than_ - Less than operator
- ``rtems_timespec_greater_than`` - Greater than operator
- rtems_timespec_greater_than_ - Greater than operator
- ``rtems_timespec_equal_to`` - Check if two timespecs are equal
- rtems_timespec_equal_to_ - Check if two timespecs are equal
- ``rtems_timespec_get_seconds`` - Obtain seconds portion of timespec
- rtems_timespec_get_seconds_ - Obtain seconds portion of timespec
- ``rtems_timespec_get_nanoseconds`` - Obtain nanoseconds portion of timespec
- rtems_timespec_get_nanoseconds_ - Obtain nanoseconds portion of timespec
- ``rtems_timespec_to_ticks`` - Convert timespec to number of ticks
- rtems_timespec_to_ticks_ - Convert timespec to number of ticks
- ``rtems_timespec_from_ticks`` - Convert ticks to timespec
- rtems_timespec_from_ticks_ - Convert ticks to timespec
Background
==========
@ -43,11 +47,13 @@ Background
Time Storage Conventions
------------------------
Time can be stored in many ways. One of them is the ``struct timespec``
format which is a structure that consists of the fields ``tv_sec``
to represent seconds and ``tv_nsec`` to represent nanoseconds. The``struct timeval`` structure is simular and consists of seconds (stored
in ``tv_sec``) and microseconds (stored in ``tv_usec``). Either``struct timespec`` or ``struct timeval`` can be used to represent
elapsed time, time of executing some operations, or time of day.
Time can be stored in many ways. One of them is the ``struct timespec`` format
which is a structure that consists of the fields ``tv_sec`` to represent
seconds and ``tv_nsec`` to represent nanoseconds. The``struct timeval``
structure is simular and consists of seconds (stored in ``tv_sec``) and
microseconds (stored in ``tv_usec``). Either``struct timespec`` or ``struct
timeval`` can be used to represent elapsed time, time of executing some
operations, or time of day.
Operations
==========
@ -55,309 +61,337 @@ Operations
Set and Obtain Timespec Value
-----------------------------
A user may write a specific time by passing the desired seconds and
nanoseconds values and the destination ``struct timespec`` using the``rtems_timespec_set`` directive.
A user may write a specific time by passing the desired seconds and nanoseconds
values and the destination ``struct timespec`` using the ``rtems_timespec_set``
directive.
The ``rtems_timespec_zero`` directive is used to zero the seconds
and nanoseconds portions of a ``struct timespec`` instance.
Users may obtain the seconds or nanoseconds portions of a ``struct
timespec`` instance with the ``rtems_timespec_get_seconds`` or``rtems_timespec_get_nanoseconds`` methods, respectively.
Users may obtain the seconds or nanoseconds portions of a ``struct timespec``
instance with the ``rtems_timespec_get_seconds`` or
``rtems_timespec_get_nanoseconds`` methods, respectively.
Timespec Math
-------------
A user can perform multiple operations on ``struct timespec``
instances. The helpers in this manager assist in adding, subtracting, and
performing divison on ``struct timespec`` instances.
A user can perform multiple operations on ``struct timespec`` instances. The
helpers in this manager assist in adding, subtracting, and performing divison
on ``struct timespec`` instances.
- Adding two ``struct timespec`` can be done using the``rtems_timespec_add_to`` directive. This directive is used mainly
to calculate total amount of time consumed by multiple operations.
- Adding two ``struct timespec`` can be done using the
``rtems_timespec_add_to`` directive. This directive is used mainly to
calculate total amount of time consumed by multiple operations.
- The ``rtems_timespec_subtract`` is used to subtract two``struct timespecs`` instances and determine the elapsed time between
those two points in time.
- The ``rtems_timespec_subtract`` is used to subtract two ``struct timespecs``
instances and determine the elapsed time between those two points in time.
- The ``rtems_timespec_divide`` is used to use to divide one``struct timespec`` instance by another. This calculates the percentage
with a precision to three decimal points.
- The ``rtems_timespec_divide`` is used to use to divide one ``struct
timespec`` instance by another. This calculates the percentage with a
precision to three decimal points.
- The ``rtems_timespec_divide_by_integer`` is used to divide a``struct timespec`` instance by an integer. It is commonly used in
benchmark calculations to dividing duration by the number of iterations
performed.
- The ``rtems_timespec_divide_by_integer`` is used to divide a ``struct
timespec`` instance by an integer. It is commonly used in benchmark
calculations to dividing duration by the number of iterations performed.
Comparing struct timespec Instances
-----------------------------------
A user can compare two ``struct timespec`` instances using the``rtems_timespec_less_than``, ``rtems_timespec_greater_than``
or ``rtems_timespec_equal_to`` routines.
A user can compare two ``struct timespec`` instances using the
``rtems_timespec_less_than``, ``rtems_timespec_greater_than`` or
``rtems_timespec_equal_to`` routines.
Conversions and Validity Check
------------------------------
Conversion to and from clock ticks may be performed by using the``rtems_timespec_to_ticks`` and ``rtems_timespec_from_ticks``
directives.
Conversion to and from clock ticks may be performed by using the
``rtems_timespec_to_ticks`` and ``rtems_timespec_from_ticks`` directives.
User can also check validity of timespec with``rtems_timespec_is_valid`` routine.
User can also check validity of timespec with ``rtems_timespec_is_valid``
routine.
Directives
==========
This section details the Timespec Helpers manager's directives.
A subsection is dedicated to each of this manager's directives
and describes the calling sequence, related constants, usage,
and status codes.
This section details the Timespec Helpers manager's directives. A subsection
is dedicated to each of this manager's directives and describes the calling
sequence, related constants, usage, and status codes.
.. _rtems_timespec_set:
TIMESPEC_SET - Set struct timespec Instance
-------------------------------------------
.. index:: set struct timespec instance
**CALLING SEQUENCE:**
.. code:: c
.. index:: rtems_timespec_set
.. code-block:: c
void rtems_timespec_set(
struct timespec \*time,
struct timespec *time,
time_t seconds,
uint32_t nanoseconds
);
.. index:: rtems_timespec_set
**STATUS CODES:**
NONE
**DESCRIPTION:**
This directive sets the ``struct timespec`` ``time`` value to the
desired ``seconds`` and ``nanoseconds`` values.
This directive sets the ``struct timespec`` *time* to the desired ``seconds``
and ``nanoseconds`` values.
**NOTES:**
This method does NOT check if ``nanoseconds`` is less than the
maximum number of nanoseconds in a second.
This method does NOT check if ``nanoseconds`` is less than the maximum number
of nanoseconds in a second.
.. _rtems_timespec_zero:
TIMESPEC_ZERO - Zero struct timespec Instance
---------------------------------------------
**CALLING SEQUENCE:**
.. code:: c
.. index:: rtems_timespec_zero
.. code-block:: c
void rtems_timespec_zero(
struct timespec \*time
struct timespec *time
);
.. index:: rtems_timespec_zero
**STATUS CODES:**
NONE
**DESCRIPTION:**
This routine sets the contents of the ``struct timespec`` instance``time`` to zero.
This routine sets the contents of the ``struct timespec`` instance ``time`` to
zero.
**NOTES:**
NONE
.. _rtems_timespec_is_valid:
TIMESPEC_IS_VALID - Check validity of a struct timespec instance
----------------------------------------------------------------
**CALLING SEQUENCE:**
.. code:: c
.. index:: rtems_timespec_is_valid
.. code-block:: c
bool rtems_timespec_is_valid(
const struct timespec \*time
const struct timespec *time
);
.. index:: rtems_timespec_is_valid
**STATUS CODES:**
This method returns ``true`` if the instance is valid, and ``false``
otherwise.
This method returns ``true`` if the instance is valid, and ``false`` otherwise.
**DESCRIPTION:**
This routine check validity of a ``struct timespec`` instance. It
checks if the nanoseconds portion of the ``struct timespec`` instanceis
in allowed range (less than the maximum number of nanoseconds per second).
This routine check validity of a ``struct timespec`` instance. It checks if the
nanoseconds portion of the ``struct timespec`` instanceis in allowed range
(less than the maximum number of nanoseconds per second).
**NOTES:**
.. _rtems_timespec_add_to:
TIMESPEC_ADD_TO - Add Two struct timespec Instances
---------------------------------------------------
**CALLING SEQUENCE:**
.. code:: c
.. index:: rtems_timespec_add_to
.. code-block:: c
uint32_t rtems_timespec_add_to(
struct timespec \*time,
const struct timespec \*add
struct timespec *time,
const struct timespec *add
);
.. index:: rtems_timespec_add_to
**STATUS CODES:**
The method returns the number of seconds ``time`` increased by.
**DESCRIPTION:**
This routine adds two ``struct timespec`` instances. The second argument is added to the first. The parameter ``time`` is the base time to which the ``add`` parameter is added.
This routine adds two ``struct timespec`` instances. The second argument is
added to the first. The parameter ``time`` is the base time to which the
``add`` parameter is added.
**NOTES:**
NONE
.. _rtems_timespec_subtract:
TIMESPEC_SUBTRACT - Subtract Two struct timespec Instances
----------------------------------------------------------
**CALLING SEQUENCE:**
.. code:: c
.. index:: rtems_timespec_subtract
.. code-block:: c
void rtems_timespec_subtract(
const struct timespec \*start,
const struct timespec \*end,
struct timespec \*result
const struct timespec *start,
const struct timespec *end,
struct timespec *result
);
.. index:: rtems_timespec_subtract
**STATUS CODES:**
NONE
**DESCRIPTION:**
This routine subtracts ``start`` from ``end`` saves the difference
in ``result``. The primary use of this directive is to calculate
elapsed time.
This routine subtracts ``start`` from ``end`` saves the difference in
``result``. The primary use of this directive is to calculate elapsed time.
**NOTES:**
It is possible to subtract when ``end`` is less than ``start``
and it produce negative ``result``. When doing this you should be
careful and remember that only the seconds portion of a ``struct
timespec`` instance is signed, which means that nanoseconds portion is
always increasing. Due to that when your timespec has seconds = -1 and
nanoseconds=500,000,000 it means that result is -0.5 second, NOT the
expected -1.5!
It is possible to subtract when ``end`` is less than ``start`` and it produce
negative ``result``. When doing this you should be careful and remember that
only the seconds portion of a ``struct timespec`` instance is signed, which
means that nanoseconds portion is always increasing. Due to that when your
timespec has seconds = -1 and nanoseconds = 500,000,000 it means that result is
-0.5 second, NOT the expected -1.5!
.. _rtems_timespec_divide:
TIMESPEC_DIVIDE - Divide Two struct timespec Instances
------------------------------------------------------
**CALLING SEQUENCE:**
.. code:: c
.. index:: rtems_timespec_divide
.. code-block:: c
void rtems_timespec_divide(
const struct timespec \*lhs,
const struct timespec \*rhs,
uint32_t \*ival_percentage,
uint32_t \*fval_percentage
const struct timespec *lhs,
const struct timespec *rhs,
uint32_t *ival_percentage,
uint32_t *fval_percentage
);
.. index:: rtems_timespec_divide
**STATUS CODES:**
NONE
**DESCRIPTION:**
This routine divides the ``struct timespec`` instance ``lhs`` by
the ``struct timespec`` instance ``rhs``. The result is returned
in the ``ival_percentage`` and ``fval_percentage``, representing
the integer and fractional results of the division respectively.
This routine divides the ``struct timespec`` instance ``lhs`` by the ``struct
timespec`` instance ``rhs``. The result is returned in the ``ival_percentage``
and ``fval_percentage``, representing the integer and fractional results of the
division respectively.
The ``ival_percentage`` is integer value of calculated percentage and ``fval_percentage`` is fractional part of calculated percentage.
The ``ival_percentage`` is integer value of calculated percentage and
``fval_percentage`` is fractional part of calculated percentage.
**NOTES:**
The intended use is calculating percentges to three decimal points.
When dividing by zero, this routine return both ``ival_percentage``
and ``fval_percentage`` equal zero.
When dividing by zero, this routine return both ``ival_percentage`` and
``fval_percentage`` equal zero.
The division is performed using exclusively integer operations.
.. _rtems_timespec_divide_by_integer:
TIMESPEC_DIVIDE_BY_INTEGER - Divide a struct timespec Instance by an Integer
----------------------------------------------------------------------------
**CALLING SEQUENCE:**
.. code:: c
.. index:: rtems_timespec_divide_by_integer
.. code-block:: c
int rtems_timespec_divide_by_integer(
const struct timespec \*time,
const struct timespec *time,
uint32_t iterations,
struct timespec \*result
struct timespec *result
);
.. index:: rtems_timespec_divide_by_integer
**STATUS CODES:**
NONE
**DESCRIPTION:**
This routine divides the ``struct timespec`` instance ``time`` by the integer value ``iterations``.
The result is saved in ``result``.
This routine divides the ``struct timespec`` instance ``time`` by the integer
value ``iterations``. The result is saved in ``result``.
**NOTES:**
The expected use is to assist in benchmark calculations where you
typically divide a duration (``time``) by a number of iterations what
gives average time.
The expected use is to assist in benchmark calculations where you typically
divide a duration (``time``) by a number of iterations what gives average time.
.. _rtems_timespec_less_than:
TIMESPEC_LESS_THAN - Less than operator
---------------------------------------
**CALLING SEQUENCE:**
.. code:: c
.. index:: rtems_timespec_less_than
.. code-block:: c
bool rtems_timespec_less_than(
const struct timespec \*lhs,
const struct timespec \*rhs
const struct timespec *lhs,
const struct timespec *rhs
);
.. index:: rtems_timespec_less_than
**STATUS CODES:**
This method returns ``struct true`` if ``lhs`` is less than``rhs`` and ``struct false`` otherwise.
This method returns ``struct true`` if ``lhs`` is less than``rhs`` and ``struct
false`` otherwise.
**DESCRIPTION:**
This method is the less than operator for ``struct timespec`` instances. The first parameter is the left hand side and the second is the right hand side of the comparison.
This method is the less than operator for ``struct timespec`` instances. The
first parameter is the left hand side and the second is the right hand side of
the comparison.
**NOTES:**
NONE
.. _rtems_timespec_greater_than:
TIMESPEC_GREATER_THAN - Greater than operator
---------------------------------------------
**CALLING SEQUENCE:**
.. code:: c
.. index:: rtems_timespec_greater_than
.. code-block:: c
bool rtems_timespec_greater_than(
const struct timespec \*_lhs,
const struct timespec \*_rhs
const struct timespec *_lhs,
const struct timespec *_rhs
);
.. index:: rtems_timespec_greater_than
**STATUS CODES:**
This method returns ``struct true`` if ``lhs`` is greater than``rhs`` and ``struct false`` otherwise.
This method returns ``struct true`` if ``lhs`` is greater than``rhs`` and
``struct false`` otherwise.
**DESCRIPTION:**
@ -367,23 +401,26 @@ This method is greater than operator for ``struct timespec`` instances.
NONE
.. _rtems_timespec_equal_to:
TIMESPEC_EQUAL_TO - Check equality of timespecs
-----------------------------------------------
**CALLING SEQUENCE:**
.. code:: c
.. index:: rtems_timespec_equal_to
.. code-block:: c
bool rtems_timespec_equal_to(
const struct timespec \*lhs,
const struct timespec \*rhs
const struct timespec *lhs,
const struct timespec *rhs
);
.. index:: rtems_timespec_equal_to
**STATUS CODES:**
This method returns ``struct true`` if ``lhs`` is equal to``rhs`` and ``struct false`` otherwise.
This method returns ``struct true`` if ``lhs`` is equal to``rhs`` and ``struct
false`` otherwise.
**DESCRIPTION:**
@ -393,45 +430,50 @@ This method is equality operator for ``struct timespec`` instances.
NONE
.. _rtems_timespec_get_seconds:
TIMESPEC_GET_SECONDS - Get Seconds Portion of struct timespec Instance
----------------------------------------------------------------------
**CALLING SEQUENCE:**
.. code:: c
.. index:: rtems_timespec_get_seconds
.. code-block:: c
time_t rtems_timespec_get_seconds(
struct timespec \*time
struct timespec *time
);
.. index:: rtems_timespec_get_seconds
**STATUS CODES:**
This method returns the seconds portion of the specified ``struct
timespec`` instance.
This method returns the seconds portion of the specified ``struct timespec``
instance.
**DESCRIPTION:**
This method returns the seconds portion of the specified ``struct timespec`` instance ``time``.
This method returns the seconds portion of the specified ``struct timespec``
instance ``time``.
**NOTES:**
NONE
.. _rtems_timespec_get_nanoseconds:
TIMESPEC_GET_NANOSECONDS - Get Nanoseconds Portion of the struct timespec Instance
----------------------------------------------------------------------------------
**CALLING SEQUENCE:**
.. code:: c
.. index:: rtems_timespec_get_nanoseconds
.. code-block:: c
uint32_t rtems_timespec_get_nanoseconds(
struct timespec \*_time
struct timespec *_time
);
.. index:: rtems_timespec_get_nanoseconds
**STATUS CODES:**
This method returns the nanoseconds portion of the specified ``struct
@ -439,46 +481,53 @@ timespec`` instance.
**DESCRIPTION:**
This method returns the nanoseconds portion of the specified timespec
which is pointed by ``_time``.
This method returns the nanoseconds portion of the specified timespec which is
pointed by ``_time``.
**NOTES:**
.. _rtems_timespec_to_ticks:
TIMESPEC_TO_TICKS - Convert struct timespec Instance to Ticks
-------------------------------------------------------------
**CALLING SEQUENCE:**
.. code:: c
.. index:: rtems_timespec_to_ticks
.. code-block:: c
uint32_t rtems_timespec_to_ticks(
const struct timespec \*time
const struct timespec *time
);
.. index:: rtems_timespec_to_ticks
**STATUS CODES:**
This directive returns the number of ticks computed.
**DESCRIPTION:**
This directive converts the ``time`` timespec to the corresponding number of clock ticks.
This directive converts the ``time`` timespec to the corresponding number of
clock ticks.
**NOTES:**
NONE
.. _rtems_timespec_from_ticks:
TIMESPEC_FROM_TICKS - Convert Ticks to struct timespec Representation
---------------------------------------------------------------------
**CALLING SEQUENCE:**
.. code:: c
.. index:: rtems_timespec_from_ticks
.. code-block:: c
void rtems_timespec_from_ticks(
uint32_t ticks,
struct timespec \*time
struct timespec *time
);
.. index:: rtems_timespec_from_ticks
@ -489,15 +538,9 @@ NONE
**DESCRIPTION:**
This routine converts the ``ticks`` to the corresponding ``struct timespec`` representation and stores it in ``time``.
This routine converts the ``ticks`` to the corresponding ``struct timespec``
representation and stores it in ``time``.
**NOTES:**
NONE
.. COMMENT: COPYRIGHT (c) 2011.
.. COMMENT: On-Line Applications Research Corporation (OAR).
.. COMMENT: All rights reserved.