summaryrefslogtreecommitdiffstats
path: root/c-user/user_extensions.rst
diff options
context:
space:
mode:
Diffstat (limited to 'c-user/user_extensions.rst')
-rw-r--r--c-user/user_extensions.rst563
1 files changed, 563 insertions, 0 deletions
diff --git a/c-user/user_extensions.rst b/c-user/user_extensions.rst
new file mode 100644
index 0000000..664d70a
--- /dev/null
+++ b/c-user/user_extensions.rst
@@ -0,0 +1,563 @@
+.. comment SPDX-License-Identifier: CC-BY-SA-4.0
+
+.. COMMENT: COPYRIGHT (c) 1988-2008.
+.. COMMENT: On-Line Applications Research Corporation (OAR).
+.. COMMENT: All rights reserved.
+
+.. _User Extensions Manager:
+
+User Extensions Manager
+#######################
+
+.. index:: user extensions
+
+Introduction
+============
+
+The RTEMS User Extensions Manager allows the application developer to augment
+the executive by allowing them to supply extension routines which are invoked
+at critical system events. The directives provided by the user extensions
+manager are:
+
+- rtems_extension_create_ - Create an extension set
+
+- rtems_extension_ident_ - Get ID of an extension set
+
+- rtems_extension_delete_ - Delete an extension set
+
+Background
+==========
+
+User extension routines are invoked when the following system events occur:
+
+- Task creation
+
+- Task initiation
+
+- Task reinitiation
+
+- Task deletion
+
+- Task context switch
+
+- Post task context switch
+
+- Task begin
+
+- Task exits
+
+- Fatal error detection
+
+These extensions are invoked as a function with arguments that are appropriate
+to the system event.
+
+Extension Sets
+--------------
+.. index:: extension set
+
+An extension set is defined as a set of routines which are invoked at each of
+the critical system events at which user extension routines are invoked.
+Together a set of these routines typically perform a specific functionality
+such as performance monitoring or debugger support. RTEMS is informed of the
+entry points which constitute an extension set via the following
+structure:.. index:: rtems_extensions_table
+
+.. code-block:: c
+
+ typedef struct {
+ rtems_task_create_extension thread_create;
+ rtems_task_start_extension thread_start;
+ rtems_task_restart_extension thread_restart;
+ rtems_task_delete_extension thread_delete;
+ rtems_task_switch_extension thread_switch;
+ rtems_task_begin_extension thread_begin;
+ rtems_task_exitted_extension thread_exitted;
+ rtems_fatal_extension fatal;
+ } rtems_extensions_table;
+
+RTEMS allows the user to have multiple extension sets active at the same time.
+First, a single static extension set may be defined as the application's User
+Extension Table which is included as part of the Configuration Table. This
+extension set is active for the entire life of the system and may not be
+deleted. This extension set is especially important because it is the only way
+the application can provided a FATAL error extension which is invoked if RTEMS
+fails during the initialize_executive directive. The static extension set is
+optional and may be configured as NULL if no static extension set is required.
+
+Second, the user can install dynamic extensions using the
+``rtems_extension_create`` directive. These extensions are RTEMS objects in
+that they have a name, an ID, and can be dynamically created and deleted. In
+contrast to the static extension set, these extensions can only be created and
+installed after the initialize_executive directive successfully completes
+execution. Dynamic extensions are useful for encapsulating the functionality
+of an extension set. For example, the application could use extensions to
+manage a special coprocessor, do performance monitoring, and to do stack bounds
+checking. Each of these extension sets could be written and installed
+independently of the others.
+
+All user extensions are optional and RTEMS places no naming restrictions on the
+user. The user extension entry points are copied into an internal RTEMS
+structure. This means the user does not need to keep the table after creating
+it, and changing the handler entry points dynamically in a table once created
+has no effect. Creating a table local to a function can save space in space
+limited applications.
+
+Extension switches do not effect the context switch overhead if no switch
+handler is installed.
+
+TCB Extension Area
+------------------
+.. index:: TCB extension area
+
+RTEMS provides for a pointer to a user-defined data area for each extension set
+to be linked to each task's control block. This set of pointers is an
+extension of the TCB and can be used to store additional data required by the
+user's extension functions.
+
+The TCB extension is an array of pointers in the TCB. The index into the table
+can be obtained from the extension id returned when the extension is
+created:
+
+.. index:: rtems extensions table index
+
+.. code-block:: c
+
+ index = rtems_object_id_get_index(extension_id);
+
+The number of pointers in the area is the same as the number of user extension
+sets configured. This allows an application to augment the TCB with
+user-defined information. For example, an application could implement task
+profiling by storing timing statistics in the TCB's extended memory area. When
+a task context switch is being executed, the ``TASK_SWITCH`` extension could
+read a real-time clock to calculate how long the task being swapped out has run
+as well as timestamp the starting time for the task being swapped in.
+
+If used, the extended memory area for the TCB should be allocated and the TCB
+extension pointer should be set at the time the task is created or started by
+either the ``TASK_CREATE`` or ``TASK_START`` extension. The application is
+responsible for managing this extended memory area for the TCBs. The memory
+may be reinitialized by the ``TASK_RESTART`` extension and should be
+deallocated by the ``TASK_DELETE`` extension when the task is deleted. Since
+the TCB extension buffers would most likely be of a fixed size, the RTEMS
+partition manager could be used to manage the application's extended memory
+area. The application could create a partition of fixed size TCB extension
+buffers and use the partition manager's allocation and deallocation directives
+to obtain and release the extension buffers.
+
+Extensions
+----------
+
+The sections that follow will contain a description of each extension. Each
+section will contain a prototype of a function with the appropriate calling
+sequence for the corresponding extension. The names given for the C function
+and its arguments are all defined by the user. The names used in the examples
+were arbitrarily chosen and impose no naming conventions on the user.
+
+TASK_CREATE Extension
+~~~~~~~~~~~~~~~~~~~~~
+
+The TASK_CREATE extension directly corresponds to the ``rtems_task_create``
+directive. If this extension is defined in any static or dynamic extension set
+and a task is being created, then the extension routine will automatically be
+invoked by RTEMS. The extension should have a prototype similar to the
+following:
+
+.. index:: rtems_task_create_extension
+.. index:: rtems_extension
+
+.. code-block:: c
+
+ bool user_task_create(
+ rtems_tcb *current_task,
+ rtems_tcb *new_task
+ );
+
+where ``current_task`` can be used to access the TCB for the currently
+executing task, and new_task can be used to access the TCB for the new task
+being created. This extension is invoked from the ``rtems_task_create``
+directive after ``new_task`` has been completely initialized, but before it is
+placed on a ready TCB chain.
+
+The user extension is expected to return the boolean value ``true`` if it
+successfully executed and ``false`` otherwise. A task create user extension
+will frequently attempt to allocate resources. If this allocation fails, then
+the extension should return ``false`` and the entire task create operation will
+fail.
+
+TASK_START Extension
+~~~~~~~~~~~~~~~~~~~~
+
+The ``TASK_START`` extension directly corresponds to the task_start directive.
+If this extension is defined in any static or dynamic extension set and a task
+is being started, then the extension routine will automatically be invoked by
+RTEMS. The extension should have a prototype similar to the following:
+
+.. index:: rtems_task_start_extension
+
+.. code-block:: c
+
+ void user_task_start(
+ rtems_tcb *current_task,
+ rtems_tcb *started_task
+ );
+
+where current_task can be used to access the TCB for the currently executing
+task, and started_task can be used to access the TCB for the dormant task being
+started. This extension is invoked from the task_start directive after
+started_task has been made ready to start execution, but before it is placed on
+a ready TCB chain.
+
+TASK_RESTART Extension
+~~~~~~~~~~~~~~~~~~~~~~
+
+The ``TASK_RESTART`` extension directly corresponds to the task_restart
+directive. If this extension is defined in any static or dynamic extension set
+and a task is being restarted, then the extension should have a prototype
+similar to the following:
+
+.. index:: rtems_task_restart_extension
+
+.. code-block:: c
+
+ void user_task_restart(
+ rtems_tcb *current_task,
+ rtems_tcb *restarted_task
+ );
+
+where current_task can be used to access the TCB for the currently executing
+task, and restarted_task can be used to access the TCB for the task being
+restarted. This extension is invoked from the task_restart directive after
+restarted_task has been made ready to start execution, but before it is placed
+on a ready TCB chain.
+
+TASK_DELETE Extension
+~~~~~~~~~~~~~~~~~~~~~
+
+The ``TASK_DELETE`` extension is associated with the task_delete directive. If
+this extension is defined in any static or dynamic extension set and a task is
+being deleted, then the extension routine will automatically be invoked by
+RTEMS. The extension should have a prototype similar to the
+following:
+
+.. index:: rtems_task_delete_extension
+
+.. code-block:: c
+
+ void user_task_delete(
+ rtems_tcb *current_task,
+ rtems_tcb *deleted_task
+ );
+
+where current_task can be used to access the TCB for the currently executing
+task, and deleted_task can be used to access the TCB for the task being
+deleted. This extension is invoked from the task_delete directive after the TCB
+has been removed from a ready TCB chain, but before all its resources including
+the TCB have been returned to their respective free pools. This extension
+should not call any RTEMS directives if a task is deleting itself (current_task
+is equal to deleted_task).
+
+TASK_SWITCH Extension
+~~~~~~~~~~~~~~~~~~~~~
+
+The ``TASK_SWITCH`` extension corresponds to a task context switch. If this
+extension is defined in any static or dynamic extension set and a task context
+switch is in progress, then the extension routine will automatically be invoked
+by RTEMS. The extension should have a prototype similar to the following:
+
+.. index:: rtems_task_switch_extension
+
+.. code-block:: c
+
+ void user_task_switch(
+ rtems_tcb *current_task,
+ rtems_tcb *heir_task
+ );
+
+where current_task can be used to access the TCB for the task that is being
+swapped out, and heir_task can be used to access the TCB for the task being
+swapped in. This extension is invoked from RTEMS' dispatcher routine after the
+current_task context has been saved, but before the heir_task context has been
+restored. This extension should not call any RTEMS directives.
+
+TASK_BEGIN Extension
+~~~~~~~~~~~~~~~~~~~~
+
+The ``TASK_BEGIN`` extension is invoked when a task begins execution. It is
+invoked immediately before the body of the starting procedure and executes in
+the context in the task. This user extension have a prototype similar to the
+following:
+
+.. index:: rtems_task_begin_extension
+
+.. code-block:: c
+
+ void user_task_begin(
+ rtems_tcb *current_task
+ );
+
+where current_task can be used to access the TCB for the currently executing
+task which has begun. The distinction between the ``TASK_BEGIN`` and
+TASK_START extension is that the ``TASK_BEGIN`` extension is executed in the
+context of the actual task while the TASK_START extension is executed in the
+context of the task performing the task_start directive. For most extensions,
+this is not a critical distinction.
+
+TASK_EXITTED Extension
+~~~~~~~~~~~~~~~~~~~~~~
+
+The ``TASK_EXITTED`` extension is invoked when a task exits the body of the
+starting procedure by either an implicit or explicit return statement. This
+user extension have a prototype similar to the following:
+
+.. index:: rtems_task_exitted_extension
+
+.. code-block:: c
+
+ void user_task_exitted(
+ rtems_tcb *current_task
+ );
+
+where current_task can be used to access the TCB for the currently executing
+task which has just exitted.
+
+Although exiting of task is often considered to be a fatal error, this
+extension allows recovery by either restarting or deleting the exiting task.
+If the user does not wish to recover, then a fatal error may be reported. If
+the user does not provide a ``TASK_EXITTED`` extension or the provided handler
+returns control to RTEMS, then the RTEMS default handler will be used. This
+default handler invokes the directive fatal_error_occurred with the
+``RTEMS_TASK_EXITTED`` directive status.
+
+FATAL Error Extension
+~~~~~~~~~~~~~~~~~~~~~
+
+The ``FATAL`` error extension is associated with the fatal_error_occurred
+directive. If this extension is defined in any static or dynamic extension set
+and the fatal_error_occurred directive has been invoked, then this extension
+will be called. This extension should have a prototype similar to the
+following:
+
+.. index:: rtems_fatal_extension
+
+.. code-block:: c
+
+ void user_fatal_error(
+ Internal_errors_Source the_source,
+ bool is_internal,
+ uint32_t the_error
+ );
+
+where the_error is the error code passed to the fatal_error_occurred
+directive. This extension is invoked from the fatal_error_occurred directive.
+
+If defined, the user's ``FATAL`` error extension is invoked before RTEMS'
+default fatal error routine is invoked and the processor is stopped. For
+example, this extension could be used to pass control to a debugger when a
+fatal error occurs. This extension should not call any RTEMS directives.
+
+Order of Invocation
+-------------------
+
+When one of the critical system events occur, the user extensions are invoked
+in either "forward" or "reverse" order. Forward order indicates that the
+static extension set is invoked followed by the dynamic extension sets in the
+order in which they were created. Reverse order means that the dynamic
+extension sets are invoked in the opposite of the order in which they were
+created followed by the static extension set. By invoking the extension sets
+in this order, extensions can be built upon one another. At the following
+system events, the extensions are invoked in forward order:
+
+#. Task creation
+
+#. Task initiation
+
+#. Task reinitiation
+
+#. Task deletion
+
+#. Task context switch
+
+#. Post task context switch
+
+#. Task begins to execute
+
+At the following system events, the extensions are invoked in reverse order:
+
+#. Task deletion
+
+#. Fatal error detection
+
+At these system events, the extensions are invoked in reverse order to insure
+that if an extension set is built upon another, the more complicated extension
+is invoked before the extension set it is built upon. For example, by invoking
+the static extension set last it is known that the "system" fatal error
+extension will be the last fatal error extension executed. Another example is
+use of the task delete extension by the Standard C Library. Extension sets
+which are installed after the Standard C Library will operate correctly even if
+they utilize the C Library because the C Library's ``TASK_DELETE`` extension is
+invoked after that of the other extensions.
+
+Operations
+==========
+
+Creating an Extension Set
+-------------------------
+
+The ``rtems_extension_create`` directive creates and installs an extension set
+by allocating a Extension Set Control Block (ESCB), assigning the extension set
+a user-specified name, and assigning it an extension set ID. Newly created
+extension sets are immediately installed and are invoked upon the next system
+even supporting an extension.
+
+Obtaining Extension Set IDs
+---------------------------
+
+When an extension set is created, RTEMS generates a unique extension set ID and
+assigns it to the created extension set until it is deleted. The extension ID
+may be obtained by either of two methods. First, as the result of an
+invocation of the ``rtems_extension_create`` directive, the extension set ID is
+stored in a user provided location. Second, the extension set ID may be
+obtained later using the ``rtems_extension_ident`` directive. The extension
+set ID is used by other directives to manipulate this extension set.
+
+Deleting an Extension Set
+-------------------------
+
+The ``rtems_extension_delete`` directive is used to delete an extension set.
+The extension set's control block is returned to the ESCB free list when it is
+deleted. An extension set can be deleted by a task other than the task which
+created the extension set. Any subsequent references to the extension's name
+and ID are invalid.
+
+Directives
+==========
+
+This section details the user extension 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_extension_create:
+
+EXTENSION_CREATE - Create a extension set
+-----------------------------------------
+.. index:: create an extension set
+
+**CALLING SEQUENCE:**
+
+.. index:: rtems_extension_create
+
+.. code-block:: c
+
+ rtems_status_code rtems_extension_create(
+ rtems_name name,
+ rtems_extensions_table *table,
+ rtems_id *id
+ );
+
+**DIRECTIVE STATUS CODES:**
+
+.. list-table::
+ :class: rtems-table
+
+ * - ``RTEMS_SUCCESSFUL``
+ - extension set created successfully
+ * - ``RTEMS_INVALID_NAME``
+ - invalid extension set name
+ * - ``RTEMS_TOO_MANY``
+ - too many extension sets created
+
+**DESCRIPTION:**
+
+This directive creates a extension set. The assigned extension set id is
+returned in id. This id is used to access the extension set with other user
+extension manager directives. For control and maintenance of the extension
+set, RTEMS allocates an ESCB from the local ESCB free pool and initializes it.
+
+**NOTES:**
+
+This directive will not cause the calling task to be
+preempted.
+
+.. _rtems_extension_ident:
+
+EXTENSION_IDENT - Get ID of a extension set
+-------------------------------------------
+.. index:: get ID of an extension set
+.. index:: obtain ID of an extension set
+
+**CALLING SEQUENCE:**
+
+.. index:: rtems_extension_ident
+
+.. code-block:: c
+
+ rtems_status_code rtems_extension_ident(
+ rtems_name name,
+ rtems_id *id
+ );
+
+**DIRECTIVE STATUS CODES:**
+
+.. list-table::
+ :class: rtems-table
+
+ * - ``RTEMS_SUCCESSFUL``
+ - extension set identified successfully
+ * - ``RTEMS_INVALID_NAME``
+ - extension set name not found
+
+**DESCRIPTION:**
+
+This directive obtains the extension set id associated with the extension set
+name to be acquired. If the extension set name is not unique, then the
+extension set id will match one of the extension sets with that name. However,
+this extension set id is not guaranteed to correspond to the desired extension
+set. The extension set id is used to access this extension set in other
+extension set related directives.
+
+**NOTES:**
+
+This directive will not cause the running task to be preempted.
+
+.. _rtems_extension_delete:
+
+EXTENSION_DELETE - Delete a extension set
+-----------------------------------------
+.. index:: delete an extension set
+
+**CALLING SEQUENCE:**
+
+.. index:: rtems_extension_delete
+
+.. code-block:: c
+
+ rtems_status_code rtems_extension_delete(
+ rtems_id id
+ );
+
+**DIRECTIVE STATUS CODES:**
+
+.. list-table::
+ :class: rtems-table
+
+ * - ``RTEMS_SUCCESSFUL``
+ - extension set deleted successfully
+ * - ``RTEMS_INVALID_ID``
+ - invalid extension set id
+
+**DESCRIPTION:**
+
+This directive deletes the extension set specified by ``id``. If the extension
+set is running, it is automatically canceled. The ESCB for the deleted
+extension set is reclaimed by RTEMS.
+
+**NOTES:**
+
+This directive will not cause the running task to be preempted.
+
+A extension set can be deleted by a task other than the task which created the
+extension set.
+
+**NOTES:**
+
+This directive will not cause the running task to be preempted.