mirror of
https://git.rtems.org/rtems-docs/
synced 2025-05-15 02:16:41 +08:00
Clean up.
This commit is contained in:
parent
1762611192
commit
0d86b7111e
@ -1,3 +1,6 @@
|
||||
.. COMMENT: Copyright 2014 Gedare Bloom.
|
||||
.. COMMENT: All rights reserved.
|
||||
|
||||
Chains
|
||||
######
|
||||
|
||||
@ -7,129 +10,122 @@ 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
|
||||
{
|
||||
rtems_chain_node node;
|
||||
int bar;
|
||||
rtems_chain_node node;
|
||||
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);
|
||||
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,40 +133,42 @@ 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
|
||||
{
|
||||
rtems_chain_node node;
|
||||
uint8_t char* data;
|
||||
rtems_chain_node node;
|
||||
uint8_t char* data;
|
||||
} foo;
|
||||
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));
|
||||
if (!bar)
|
||||
return -1;
|
||||
bar->data = malloc (size);
|
||||
rtems_chain_append (&chain, &bar->node);
|
||||
foo* bar = malloc (sizeof (foo));
|
||||
if (!bar)
|
||||
return -1;
|
||||
bar->data = malloc (size);
|
||||
rtems_chain_append (&chain, &bar->node);
|
||||
}
|
||||
|
||||
The chain is initialized and the nodes allocated and appended to the
|
||||
@ -180,31 +178,34 @@ 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,
|
||||
rtems_chain_control* out)
|
||||
rtems_chain_control* chain,
|
||||
rtems_chain_control* out)
|
||||
{
|
||||
rtems_chain_node* node;
|
||||
foo* bar;
|
||||
rtems_chain_initialize_empty (out);
|
||||
node = chain->first;
|
||||
while (!rtems_chain_is_tail (chain, node))
|
||||
{
|
||||
bar = (foo*) node;
|
||||
rtems_chain_node* next_node = node->next;
|
||||
if (strcmp (match, bar->data) == 0)
|
||||
{
|
||||
rtems_chain_extract (node);
|
||||
rtems_chain_append (out, node);
|
||||
}
|
||||
node = next_node;
|
||||
}
|
||||
rtems_chain_node* node;
|
||||
foo* bar;
|
||||
|
||||
rtems_chain_initialize_empty (out);
|
||||
|
||||
node = chain->first;
|
||||
while (!rtems_chain_is_tail (chain, node))
|
||||
{
|
||||
bar = (foo*) node;
|
||||
rtems_chain_node* next_node = node->next;
|
||||
if (strcmp (match, bar->data) == 0)
|
||||
{
|
||||
rtems_chain_extract (node);
|
||||
rtems_chain_append (out, node);
|
||||
}
|
||||
node = next_node;
|
||||
}
|
||||
}
|
||||
|
||||
Directives
|
||||
@ -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,13 +225,13 @@ 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,
|
||||
size_t number_nodes,
|
||||
size_t node_size
|
||||
rtems_chain_control *the_chain,
|
||||
void *starting_address,
|
||||
size_t number_nodes,
|
||||
size_t node_size
|
||||
)
|
||||
|
||||
**RETURNS**
|
||||
@ -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.
|
||||
|
@ -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,71 +47,69 @@ 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
|
||||
rtems_cbs_server_id server_id
|
||||
);
|
||||
|
||||
Limitations
|
||||
@ -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,56 +172,62 @@ 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
|
||||
rtems_cbs_server_id server_id
|
||||
)
|
||||
{
|
||||
printk( "Budget overrun, fixing the task\\n" );
|
||||
return;
|
||||
printk( "Budget overrun, fixing the task\\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
rtems_task Tasks_Periodic(
|
||||
rtems_task_argument argument
|
||||
rtems_task_argument argument
|
||||
)
|
||||
{
|
||||
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( ¶ms, &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)
|
||||
break;
|
||||
/* Perform some periodic action \*/
|
||||
}
|
||||
rtems_rate_monotonic_delete( rmid );
|
||||
rtems_cbs_cleanup();
|
||||
exit( 1 );
|
||||
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( ¶ms, &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)
|
||||
break;
|
||||
/* Perform some periodic action \*/
|
||||
}
|
||||
|
||||
rtems_rate_monotonic_delete( rmid );
|
||||
rtems_cbs_cleanup();
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
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_budget_overrun budget_overrun_callback,
|
||||
rtems_cbs_server_id \*server_id
|
||||
rtems_cbs_parameters *params,
|
||||
rtems_cbs_budget_overrun budget_overrun_callback,
|
||||
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,33 +354,41 @@ 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,
|
||||
rtems_id task_id
|
||||
rtems_cbs_server_id server_id,
|
||||
rtems_id task_id
|
||||
);
|
||||
|
||||
**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,28 +397,36 @@ 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,
|
||||
rtems_id task_id
|
||||
rtems_cbs_server_id server_id,
|
||||
rtems_id task_id
|
||||
);
|
||||
|
||||
**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,28 +435,36 @@ 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
|
||||
rtems_cbs_server_id server_id
|
||||
);
|
||||
|
||||
**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_id task_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_server_id server_id,
|
||||
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_server_id server_id,
|
||||
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
|
||||
rtems_cbs_server_id server_id,
|
||||
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
|
||||
rtems_cbs_server_id server_id,
|
||||
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
|
||||
rtems_cbs_server_id server_id,
|
||||
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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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,10 +83,10 @@ STATUS_TEXT - Returns the enumeration name for a status code
|
||||
|
||||
.. index:: rtems_status_text
|
||||
|
||||
.. code:: c
|
||||
.. code-block:: c
|
||||
|
||||
const char \*rtems_status_text(
|
||||
rtems_status_code code
|
||||
const char *rtems_status_text(
|
||||
rtems_status_code code
|
||||
);
|
||||
|
||||
**DIRECTIVE STATUS CODES**
|
||||
@ -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.
|
||||
|
||||
|
@ -1,66 +1,74 @@
|
||||
.. 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
|
||||
rtems_task_argument ignored
|
||||
)
|
||||
{
|
||||
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 );
|
||||
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 );
|
||||
exit( 1 );
|
||||
}
|
||||
status = rtems_task_delete( SELF ); /* should not return \*/
|
||||
printf( "rtems_task_delete returned with status of %d.\\n", status );
|
||||
exit( 1 );
|
||||
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 );
|
||||
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 );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
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 CODE GOES HERE
|
||||
*
|
||||
* This code will typically include at least one
|
||||
* directive which causes the calling task to
|
||||
* give up the processor.
|
||||
\*/
|
||||
/* 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.
|
||||
|
||||
|
@ -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.*)))
|
||||
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.*)))
|
||||
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;
|
||||
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 \\
|
||||
) = { &item }
|
||||
/* Example item \*/
|
||||
|
||||
/* 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 */
|
||||
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;
|
||||
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 \\
|
||||
) = { &item }
|
||||
/* Example item \*/
|
||||
|
||||
/* 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 */
|
||||
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.
|
||||
|
||||
|
@ -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,37 +106,38 @@ 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",
|
||||
rtems_object_id_get_api(id),
|
||||
rtems_object_id_get_class(id),
|
||||
rtems_object_id_get_node(id),
|
||||
rtems_object_id_get_index(id)
|
||||
);
|
||||
printf(
|
||||
"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),
|
||||
rtems_object_id_get_index(id)
|
||||
);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return rtems_build_id(
|
||||
rtems_object_id_get_api(id),
|
||||
rtems_object_id_get_class(id),
|
||||
rtems_object_id_get_node(id),
|
||||
rtems_object_id_get_index(id) + 1
|
||||
);
|
||||
return rtems_build_id(
|
||||
rtems_object_id_get_api(id),
|
||||
rtems_object_id_get_class(id),
|
||||
rtems_object_id_get_node(id),
|
||||
rtems_object_id_get_index(id) + 1
|
||||
);
|
||||
}
|
||||
|
||||
Note that this Id may not be valid in this
|
||||
@ -151,32 +146,36 @@ 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",
|
||||
rtems_object_get_api_name(tmpAPI),
|
||||
rtems_object_get_api_class_name(tmpAPI, tmpClass),
|
||||
rtems_object_id_get_node(id),
|
||||
rtems_object_id_get_index(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",
|
||||
rtems_object_get_api_name(tmpAPI),
|
||||
rtems_object_get_api_class_name(tmpAPI, tmpClass),
|
||||
rtems_object_id_get_node(id),
|
||||
rtems_object_id_get_index(id)
|
||||
);
|
||||
}
|
||||
|
||||
Directives
|
||||
==========
|
||||
|
||||
.. _rtems_build_name:
|
||||
|
||||
BUILD_NAME - Build object name from characters
|
||||
----------------------------------------------
|
||||
.. index:: build object name
|
||||
@ -188,10 +187,10 @@ BUILD_NAME - Build object name from characters
|
||||
.. code:: c
|
||||
|
||||
rtems_name rtems_build_name(
|
||||
uint8_t c1,
|
||||
uint8_t c2,
|
||||
uint8_t c3,
|
||||
uint8_t c4
|
||||
uint8_t c1,
|
||||
uint8_t c2,
|
||||
uint8_t c3,
|
||||
uint8_t c4
|
||||
);
|
||||
|
||||
**DIRECTIVE STATUS CODES**
|
||||
@ -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_id id,
|
||||
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(
|
||||
rtems_id id,
|
||||
size_t length,
|
||||
char \*name
|
||||
char* rtems_object_get_name(
|
||||
rtems_id id,
|
||||
size_t length,
|
||||
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
|
||||
@ -283,38 +293,43 @@ OBJECT_SET_NAME - Set object name
|
||||
.. code:: c
|
||||
|
||||
rtems_status_code rtems_object_set_name(
|
||||
rtems_id id,
|
||||
const char \*name
|
||||
rtems_id id,
|
||||
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
|
||||
@ -326,7 +341,7 @@ OBJECT_ID_GET_API - Obtain API from Id
|
||||
.. code:: c
|
||||
|
||||
int rtems_object_id_get_api(
|
||||
rtems_id id
|
||||
rtems_id id
|
||||
);
|
||||
|
||||
**DIRECTIVE STATUS CODES**
|
||||
@ -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
|
||||
@ -354,7 +371,7 @@ OBJECT_ID_GET_CLASS - Obtain Class from Id
|
||||
.. code:: c
|
||||
|
||||
int rtems_object_id_get_class(
|
||||
rtems_id id
|
||||
rtems_id id
|
||||
);
|
||||
|
||||
**DIRECTIVE STATUS CODES**
|
||||
@ -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
|
||||
@ -382,7 +401,7 @@ OBJECT_ID_GET_NODE - Obtain Node from Id
|
||||
.. code:: c
|
||||
|
||||
int rtems_object_id_get_node(
|
||||
rtems_id id
|
||||
rtems_id id
|
||||
);
|
||||
|
||||
**DIRECTIVE STATUS CODES**
|
||||
@ -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
|
||||
@ -410,7 +431,7 @@ OBJECT_ID_GET_INDEX - Obtain Index from Id
|
||||
.. code:: c
|
||||
|
||||
int rtems_object_id_get_index(
|
||||
rtems_id id
|
||||
rtems_id id
|
||||
);
|
||||
|
||||
**DIRECTIVE STATUS CODES**
|
||||
@ -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
|
||||
@ -438,10 +461,10 @@ BUILD_ID - Build Object Id From Components
|
||||
.. code:: c
|
||||
|
||||
rtems_id rtems_build_id(
|
||||
int the_api,
|
||||
int the_class,
|
||||
int the_node,
|
||||
int the_index
|
||||
int the_api,
|
||||
int the_class,
|
||||
int the_node,
|
||||
int the_index
|
||||
);
|
||||
|
||||
**DIRECTIVE STATUS CODES**
|
||||
@ -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
|
||||
@ -520,25 +548,27 @@ OBJECT_API_MINIMUM_CLASS - Obtain Minimum Class Value
|
||||
.. code:: c
|
||||
|
||||
int rtems_object_api_minimum_class(
|
||||
int api
|
||||
int api
|
||||
);
|
||||
|
||||
**DIRECTIVE STATUS CODES**
|
||||
|
||||
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
|
||||
@ -550,25 +580,27 @@ OBJECT_API_MAXIMUM_CLASS - Obtain Maximum Class Value
|
||||
.. code:: c
|
||||
|
||||
int rtems_object_api_maximum_class(
|
||||
int api
|
||||
int api
|
||||
);
|
||||
|
||||
**DIRECTIVE STATUS CODES**
|
||||
|
||||
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,16 +611,16 @@ OBJECT_GET_API_NAME - Obtain API Name
|
||||
|
||||
.. code:: c
|
||||
|
||||
const char \*rtems_object_get_api_name(
|
||||
int api
|
||||
const char* rtems_object_get_api_name(
|
||||
int api
|
||||
);
|
||||
|
||||
**DIRECTIVE STATUS CODES**
|
||||
|
||||
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,9 +644,9 @@ OBJECT_GET_API_CLASS_NAME - Obtain Class Name
|
||||
|
||||
.. code:: c
|
||||
|
||||
const char \*rtems_object_get_api_class_name(
|
||||
int the_api,
|
||||
int the_class
|
||||
const char *rtems_object_get_api_class_name(
|
||||
int the_api,
|
||||
int the_class
|
||||
);
|
||||
|
||||
**DIRECTIVE STATUS CODES**
|
||||
@ -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
|
||||
-------------------------------------------------------
|
||||
@ -648,42 +680,41 @@ OBJECT_GET_CLASS_INFORMATION - Obtain Class Information
|
||||
.. code:: c
|
||||
|
||||
rtems_status_code rtems_object_get_class_information(
|
||||
int the_api,
|
||||
int the_class,
|
||||
rtems_object_api_class_information \*info
|
||||
int the_api,
|
||||
int the_class,
|
||||
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 {
|
||||
rtems_id minimum_id;
|
||||
rtems_id maximum_id;
|
||||
int maximum;
|
||||
bool auto_extend;
|
||||
int unallocated;
|
||||
rtems_id minimum_id;
|
||||
rtems_id maximum_id;
|
||||
int maximum;
|
||||
bool auto_extend;
|
||||
int unallocated;
|
||||
} rtems_object_api_class_information;
|
||||
|
||||
**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.
|
||||
|
||||
|
@ -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``.
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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,
|
||||
time_t seconds,
|
||||
uint32_t nanoseconds
|
||||
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,
|
||||
uint32_t iterations,
|
||||
struct timespec \*result
|
||||
const struct timespec *time,
|
||||
uint32_t iterations,
|
||||
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
|
||||
uint32_t ticks,
|
||||
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.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user