summaryrefslogtreecommitdiffstats
path: root/c-user/user-extensions
diff options
context:
space:
mode:
Diffstat (limited to 'c-user/user-extensions')
-rw-r--r--c-user/user-extensions/background.rst407
-rw-r--r--c-user/user-extensions/directives.rst265
-rw-r--r--c-user/user-extensions/index.rst16
-rw-r--r--c-user/user-extensions/introduction.rst43
4 files changed, 731 insertions, 0 deletions
diff --git a/c-user/user-extensions/background.rst b/c-user/user-extensions/background.rst
new file mode 100644
index 0000000..c1430a9
--- /dev/null
+++ b/c-user/user-extensions/background.rst
@@ -0,0 +1,407 @@
+.. SPDX-License-Identifier: CC-BY-SA-4.0
+
+.. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR)
+
+Background
+==========
+
+User extensions (call-back functions) are invoked by the system when the
+following events occur
+
+- thread creation,
+
+- thread start,
+
+- thread restart,
+
+- thread switch,
+
+- thread begin,
+
+- thread exitted (return from thread entry function),
+
+- thread termination,
+
+- thread deletion, and
+
+- fatal error detection (system termination).
+
+The user extensions have event-specific arguments, invocation orders and
+execution contexts. Extension sets can be installed at run-time via
+:ref:`rtems_extension_create() <rtems_extension_create>` (dynamic extension
+sets) or at link-time via the application configuration option
+:ref:`CONFIGURE_INITIAL_EXTENSIONS <CONFIGURE_INITIAL_EXTENSIONS>` (initial
+extension sets).
+
+The execution context of user extensions varies. Some user extensions are
+invoked with ownership of the allocator mutex. The allocator mutex protects
+dynamic memory allocations and object creation/deletion. Some user extensions
+are invoked with thread dispatching disabled. The fatal error extension is
+invoked in an arbitrary context.
+
+.. index:: user extension set
+.. index:: rtems_extensions_table
+
+Extension Sets
+--------------
+
+User extensions are maintained as a set. All user extensions are optional and
+may be `NULL`. Together a set of these user extensions typically performs a
+specific functionality such as performance monitoring or debugger support. The
+extension set is defined via the following structure.
+
+.. 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_task_terminate_extension thread_terminate;
+ } rtems_extensions_table;
+
+.. index:: TCB extension area
+
+TCB Extension Area
+------------------
+
+There is no system-provided storage for the initial extension sets.
+
+The task control block (TCB) contains a pointer for each dynamic extension set.
+The pointer is initialized to `NULL` during thread initialization before the
+thread create extension is invoked. The pointer may be used by the dynamic
+extension set to maintain thread-specific data.
+
+The TCB extension is an array of pointers in the TCB. The index into the table
+can be obtained from the extension identifier returned when the extension
+object 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 dynamic 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 thread 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 thread create or thread start extension. The application is
+responsible for managing this extended memory area for the TCBs. The memory
+may be reinitialized by the thread restart extension and should be deallocated
+by the thread 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.
+
+Order of Invocation
+-------------------
+
+The user extensions are invoked in either :term:`extension forward order` or
+:term:`extension reverse order`. By invoking the user extensions in these
+orders, extensions can be built upon one another. At the following system
+events, the user extensions are invoked in `forward` order
+
+- thread creation,
+
+- thread start,
+
+- thread restart,
+
+- thread switch,
+
+- thread begin,
+
+- thread exitted (return from thread entry function), and
+
+- fatal error detection.
+
+At the following system events, the user extensions are invoked in `reverse`
+order:
+
+- thread termination, and
+
+- thread deletion.
+
+At these system events, the user extensions are invoked in reverse order to insure
+that if an extension set is built upon another, the more complicated user extension
+is invoked before the user extension it is built upon. An example is use of the
+thread 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 thread delete extension is
+invoked after that of the other thread delete extensions.
+
+.. index:: rtems_task_create_extension()
+
+Thread Create Extension
+-----------------------
+
+The thread create extension is invoked during thread creation, for example
+via :ref:`rtems_task_create() <rtems_task_create>` or :c:func:`pthread_create`.
+The thread create extension is defined as follows.
+
+.. code-block:: c
+
+ typedef bool ( *rtems_task_create_extension )(
+ rtems_tcb *executing,
+ rtems_tcb *created
+ );
+
+The :c:data:`executing` is a pointer to the TCB of the currently executing
+thread. The :c:data:`created` is a pointer to the TCB of the created thread.
+The created thread is completely initialized with respect to the operating
+system.
+
+The executing thread is the owner of the allocator mutex except during creation
+of the idle threads. Since the allocator mutex allows nesting the normal
+memory allocation routines can be used.
+
+A thread create extension will frequently attempt to allocate resources. If
+this allocation fails, then the thread create extension must return
+:c:data:`false` and the entire thread create operation will fail, otherwise it
+must return :c:data:`true`.
+
+The thread create extension is invoked in forward order with thread dispatching
+enabled (except during system initialization).
+
+.. index:: rtems_task_start_extension
+
+Thread Start Extension
+----------------------
+
+The thread start extension is invoked during a thread start, for example
+via :ref:`rtems_task_start() <rtems_task_start>` or :c:func:`pthread_create`.
+The thread start extension is defined as follows.
+
+.. code-block:: c
+
+ typedef void ( *rtems_task_start_extension )(
+ rtems_tcb *executing,
+ rtems_tcb *started
+ );
+
+The :c:data:`executing` is a pointer to the TCB of the currently executing
+thread. The :c:data:`started` is a pointer to the TCB of the started thread.
+It is invoked after the environment of the started thread has been loaded and the
+started thread has been made ready. So, in SMP configurations, the thread may
+already run on another processor before the thread start extension is actually
+invoked. Thread switch and thread begin extensions may run before or in
+parallel with the thread start extension in SMP configurations.
+
+The thread start extension is invoked in forward order with thread dispatching
+disabled.
+
+.. index:: rtems_task_restart_extension
+
+Thread Restart Extension
+------------------------
+
+The thread restart extension is invoked during a thread restart, for example
+via :ref:`rtems_task_restart() <rtems_task_start>`.
+The thread restart extension is defined as follows.
+
+.. code-block:: c
+
+ typedef void ( *rtems_task_restart_extension )(
+ rtems_tcb *executing,
+ rtems_tcb *restarted
+ );
+
+Both :c:data:`executing` and :c:data:`restarted` are pointers the TCB of the
+currently executing thread. It is invoked in the context of the executing
+thread right before the execution context is reloaded. The thread stack
+reflects the previous execution context.
+
+The thread restart extension is invoked in forward order with thread
+dispatching enabled (except during system initialization). The thread life is
+protected. Thread restart and delete requests issued by thread restart
+extensions lead to recursion. The POSIX cleanup handlers, POSIX key
+destructors and thread-local object destructors run in this context.
+
+.. index:: rtems_task_switch_extension
+
+Thread Switch Extension
+-----------------------
+
+The thread switch extension is defined as follows.
+
+.. code-block:: c
+
+ typedef void ( *rtems_task_switch_extension )(
+ rtems_tcb *executing,
+ rtems_tcb *heir
+ );
+
+The invocation conditions of the thread switch extension depend on whether RTEMS
+was configured for uniprocessor or SMP systems. A user must pay attention to
+the differences to correctly implement a thread switch extension.
+
+In uniprocessor configurations, the thread switch extension is invoked before
+the context switch from the currently executing thread to the heir thread. The
+:c:data:`executing` is a pointer to the TCB of the currently executing thread.
+The :c:data:`heir` is a pointer to the TCB of the heir thread. The context
+switch initiated through the multitasking start is not covered by the thread
+switch extension.
+
+In SMP configurations, the thread switch extension is invoked after the context
+switch to the new executing thread (previous heir thread). The
+:c:data:`executing` is a pointer to the TCB of the previously executing thread.
+Despite the name, this is not the currently executing thread. The
+:c:data:`heir` is a pointer to the TCB of the newly executing thread. This is
+the currently executing thread. The context switches initiated through the
+multitasking start are covered by the thread switch extension. The reason for
+the differences to uniprocessor configurations is that the context switch may
+update the heir thread of the processor, see :ref:`SMPThreadDispatchDetails`.
+The thread switch extensions are invoked with disabled interrupts and with
+ownership of a per-processor SMP lock. Thread switch extensions may run in
+parallel on multiple processors. It is recommended to use thread-local or
+per-processor data structures for thread switch extensions. A global SMP lock
+should be avoided for performance reasons.
+
+The thread switch extension is invoked in forward order with thread dispatching
+disabled.
+
+.. index:: rtems_task_begin_extension
+
+Thread Begin Extension
+----------------------
+
+The thread begin extension is invoked during a thread begin before the thread
+entry function is called. The thread begin extension is defined as follows.
+
+.. code-block:: c
+
+ typedef void ( *rtems_task_begin_extension )(
+ rtems_tcb *executing
+ );
+
+The :c:data:`executing` is a pointer to the TCB of the currently executing
+thread. The thread begin extension executes in a normal thread context and may
+allocate resources for the executing thread. In particular, it has access to
+thread-local storage of the executing thread.
+
+The thread begin extension is invoked in forward order with thread dispatching
+enabled. The thread switch extension may be called multiple times for this
+thread before or during the thread begin extension is invoked.
+
+.. index:: rtems_task_exitted_extension
+
+Thread Exitted Extension
+------------------------
+
+The thread exitted extension is invoked once the thread entry function returns.
+The thread exitted extension is defined as follows.
+
+.. code-block:: c
+
+ typedef void ( *rtems_task_exitted_extension )(
+ rtems_tcb *executing
+ );
+
+The :c:data:`executing` is a pointer to the TCB of the currently executing
+thread.
+
+This extension is invoked in forward order with thread dispatching enabled.
+
+.. index:: rtems_task_terminate_extension
+
+Thread Termination Extension
+----------------------------
+
+The thread termination extension is invoked in case a termination request is
+recognized by the currently executing thread. Termination requests may result
+due to calls of :ref:`rtems_task_delete() <rtems_task_delete>`,
+:c:func:`pthread_exit`, or :c:func:`pthread_cancel`. The thread termination
+extension is defined as follows.
+
+.. code-block:: c
+
+ typedef void ( *rtems_task_terminate_extension )(
+ rtems_tcb *executing
+ );
+
+The :c:data:`executing` is a pointer to the TCB of the currently executing
+thread.
+
+It is invoked in the context of the terminated thread right before the thread
+dispatch to the heir thread. The POSIX cleanup handlers, POSIX key destructors
+and thread-local object destructors run in this context. Depending on the
+order, the thread termination extension has access to thread-local storage and
+thread-specific data of POSIX keys.
+
+The thread terminate extension is invoked in reverse order with thread
+dispatching enabled. The thread life is protected. Thread restart and delete
+requests issued by thread terminate extensions lead to recursion.
+
+.. index:: rtems_task_delete_extension
+
+Thread Delete Extension
+-----------------------
+
+The thread delete extension is invoked in case a zombie thread is killed. A
+thread becomes a zombie thread after it terminated. The thread delete
+extension is defined as follows.
+
+.. code-block:: c
+
+ typedef void ( *rtems_task_delete_extension )(
+ rtems_tcb *executing,
+ rtems_tcb *deleted
+ );
+
+The :c:data:`executing` is a pointer to the TCB of the currently executing
+thread. The :c:data:`deleted` is a pointer to the TCB of the deleted thread.
+The :c:data:`executing` and :c:data:`deleted` pointers are never equal.
+
+The executing thread is the owner of the allocator mutex. Since the allocator
+mutex allows nesting the normal memory allocation routines can be used.
+
+The thread delete extension is invoked in reverse order with thread dispatching
+enabled.
+
+Please note that a thread delete extension is not immediately invoked with a
+call to :ref:`rtems_task_delete() <rtems_task_delete>` or similar. The thread
+must first terminate and this may take some time. The thread delete extension
+is invoked by :ref:`rtems_task_create() <rtems_task_create>` or similar as a
+result of a lazy garbage collection of zombie threads.
+
+.. index:: rtems_fatal_extension
+
+Fatal Error Extension
+---------------------
+
+The fatal error extension is invoked during :ref:`system termination
+<Terminate>`. The fatal error extension is defined as follows.
+
+.. code-block:: c
+
+ typedef void( *rtems_fatal_extension )(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+ );
+
+The :c:data:`source` parameter is the fatal source indicating the subsystem the
+fatal condition originated in. The :c:data:`always_set_to_false` parameter is
+always set to :c:data:`false` and provided only for backward compatibility
+reasons. The :c:data:`code` parameter is the fatal error code. This value
+must be interpreted with respect to the source.
+
+The fatal error extension is invoked in forward order.
+
+It is strongly advised to use initial extension sets to install a fatal error
+extension. Usually, the initial extension set of board support package
+provides a fatal error extension which resets the board. In this case, the
+dynamic fatal error extensions are not invoked.
diff --git a/c-user/user-extensions/directives.rst b/c-user/user-extensions/directives.rst
new file mode 100644
index 0000000..2c5648b
--- /dev/null
+++ b/c-user/user-extensions/directives.rst
@@ -0,0 +1,265 @@
+.. SPDX-License-Identifier: CC-BY-SA-4.0
+
+.. Copyright (C) 2020, 2021 embedded brains GmbH & Co. KG
+.. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR)
+
+.. This file is part of the RTEMS quality process and was automatically
+.. generated. If you find something that needs to be fixed or
+.. worded better please post a report or patch to an RTEMS mailing list
+.. or raise a bug report:
+..
+.. https://www.rtems.org/bugs.html
+..
+.. For information on updating and regenerating please refer to the How-To
+.. section in the Software Requirements Engineering chapter of the
+.. RTEMS Software Engineering manual. The manual is provided as a part of
+.. a release. For development sources please refer to the online
+.. documentation at:
+..
+.. https://docs.rtems.org
+
+.. _UserExtensionsManagerDirectives:
+
+Directives
+==========
+
+This section details the directives of the User Extensions Manager. A
+subsection is dedicated to each of this manager's directives and lists the
+calling sequence, parameters, description, return values, and notes of the
+directive.
+
+.. Generated from spec:/rtems/userext/if/create
+
+.. raw:: latex
+
+ \clearpage
+
+.. index:: rtems_extension_create()
+.. index:: create an extension set
+
+.. _InterfaceRtemsExtensionCreate:
+
+rtems_extension_create()
+------------------------
+
+Creates an extension set.
+
+.. rubric:: CALLING SEQUENCE:
+
+.. code-block:: c
+
+ rtems_status_code rtems_extension_create(
+ rtems_name name,
+ const rtems_extensions_table *extension_table,
+ rtems_id *id
+ );
+
+.. rubric:: PARAMETERS:
+
+``name``
+ This parameter is the object name of the extension set.
+
+``extension_table``
+ This parameter is the table with the extensions to be used by the extension
+ set.
+
+``id``
+ This parameter is the pointer to an :ref:`InterfaceRtemsId` object. When
+ the directive call is successful, the identifier of the created extension
+ set will be stored in this object.
+
+.. rubric:: DESCRIPTION:
+
+This directive creates an extension set which resides on the local node. The
+extension set has the user-defined object name specified in ``name``. The
+assigned object identifier is returned in ``id``. This identifier is used to
+access the extension set with other extension set related directives.
+
+The extension set is initialized using the extension table specified in
+``extension_table``.
+
+.. rubric:: RETURN VALUES:
+
+:c:macro:`RTEMS_SUCCESSFUL`
+ The requested operation was successful.
+
+:c:macro:`RTEMS_INVALID_NAME`
+ The ``name`` parameter was invalid.
+
+:c:macro:`RTEMS_INVALID_ADDRESS`
+ The ``extension_table`` parameter was `NULL
+ <https://en.cppreference.com/w/c/types/NULL>`_.
+
+:c:macro:`RTEMS_INVALID_ADDRESS`
+ The ``id`` parameter was `NULL
+ <https://en.cppreference.com/w/c/types/NULL>`_.
+
+:c:macro:`RTEMS_TOO_MANY`
+ There was no inactive object available to create an extension set. The
+ number of extension sets available to the application is configured through
+ the :ref:`CONFIGURE_MAXIMUM_USER_EXTENSIONS` application configuration
+ option.
+
+.. rubric:: NOTES:
+
+The user-provided extension table is not used after the return of the
+directive.
+
+Each extension of the extension table is optional and may be `NULL
+<https://en.cppreference.com/w/c/types/NULL>`_. All extensions except the task
+switch extension of the extension table are atomically and immediately
+installed. A task switch extension is separately installed after the other
+extensions. The extensions of the extension table are invoked upon the next
+system event supporting an extension.
+
+An alternative to dynamically created extension sets are initial extensions,
+see :ref:`CONFIGURE_INITIAL_EXTENSIONS`. Initial extensions are recommended
+for extension sets which provide a fatal error extension.
+
+For control and maintenance of the extension set, RTEMS allocates a
+:term:`ESCB` from the local ESCB free pool and initializes it.
+
+.. rubric:: CONSTRAINTS:
+
+The following constraints apply to this directive:
+
+* The directive may be called from within device driver initialization context.
+
+* The directive may be called from within task context.
+
+* The directive may obtain and release the object allocator mutex. This may
+ cause the calling task to be preempted.
+
+* The number of extension sets available to the application is configured
+ through the :ref:`CONFIGURE_MAXIMUM_USER_EXTENSIONS` application
+ configuration option.
+
+.. Generated from spec:/rtems/userext/if/delete
+
+.. raw:: latex
+
+ \clearpage
+
+.. index:: rtems_extension_delete()
+.. index:: delete an extension set
+
+.. _InterfaceRtemsExtensionDelete:
+
+rtems_extension_delete()
+------------------------
+
+Deletes the extension set.
+
+.. rubric:: CALLING SEQUENCE:
+
+.. code-block:: c
+
+ rtems_status_code rtems_extension_delete( rtems_id id );
+
+.. rubric:: PARAMETERS:
+
+``id``
+ This parameter is the extension set identifier.
+
+.. rubric:: DESCRIPTION:
+
+This directive deletes the extension set specified by ``id``.
+
+.. rubric:: RETURN VALUES:
+
+:c:macro:`RTEMS_SUCCESSFUL`
+ The requested operation was successful.
+
+:c:macro:`RTEMS_INVALID_ID`
+ There was no extension set associated with the identifier specified by
+ ``id``.
+
+.. rubric:: NOTES:
+
+The :term:`ESCB` for the deleted extension set is reclaimed by RTEMS.
+
+.. rubric:: CONSTRAINTS:
+
+The following constraints apply to this directive:
+
+* The directive may be called from within device driver initialization context.
+
+* The directive may be called from within task context.
+
+* The directive may obtain and release the object allocator mutex. This may
+ cause the calling task to be preempted.
+
+* The calling task does not have to be the task that created the object. Any
+ local task that knows the object identifier can delete the object.
+
+.. Generated from spec:/rtems/userext/if/ident
+
+.. raw:: latex
+
+ \clearpage
+
+.. index:: rtems_extension_ident()
+
+.. _InterfaceRtemsExtensionIdent:
+
+rtems_extension_ident()
+-----------------------
+
+Identifies an extension set by the object name.
+
+.. rubric:: CALLING SEQUENCE:
+
+.. code-block:: c
+
+ rtems_status_code rtems_extension_ident( rtems_name name, rtems_id *id );
+
+.. rubric:: PARAMETERS:
+
+``name``
+ This parameter is the object name to look up.
+
+``id``
+ This parameter is the pointer to an :ref:`InterfaceRtemsId` object. When
+ the directive call is successful, the object identifier of an object with
+ the specified name will be stored in this object.
+
+.. rubric:: DESCRIPTION:
+
+This directive obtains an extension set identifier associated with the
+extension set name specified in ``name``.
+
+.. rubric:: RETURN VALUES:
+
+:c:macro:`RTEMS_SUCCESSFUL`
+ The requested operation was successful.
+
+:c:macro:`RTEMS_INVALID_ADDRESS`
+ The ``id`` parameter was `NULL
+ <https://en.cppreference.com/w/c/types/NULL>`_.
+
+:c:macro:`RTEMS_INVALID_NAME`
+ The ``name`` parameter was 0.
+
+:c:macro:`RTEMS_INVALID_NAME`
+ There was no object with the specified name on the local node.
+
+.. rubric:: NOTES:
+
+If the extension set name is not unique, then the extension set identifier will
+match the first extension set with that name in the search order. However, this
+extension set identifier is not guaranteed to correspond to the desired
+extension set.
+
+The objects are searched from lowest to the highest index. Only the local node
+is searched.
+
+The extension set identifier is used with other extension related directives to
+access the extension set.
+
+.. rubric:: CONSTRAINTS:
+
+The following constraints apply to this directive:
+
+* The directive may be called from within device driver initialization context.
+
+* The directive will not cause the calling task to be preempted.
diff --git a/c-user/user-extensions/index.rst b/c-user/user-extensions/index.rst
new file mode 100644
index 0000000..54b0649
--- /dev/null
+++ b/c-user/user-extensions/index.rst
@@ -0,0 +1,16 @@
+.. SPDX-License-Identifier: CC-BY-SA-4.0
+
+.. Copyright (C) 2020 embedded brains GmbH & Co. KG
+
+.. index:: user extensions
+
+.. _RTEMSAPIClassicUserext:
+
+User Extensions Manager
+***********************
+
+.. toctree::
+
+ introduction
+ background
+ directives
diff --git a/c-user/user-extensions/introduction.rst b/c-user/user-extensions/introduction.rst
new file mode 100644
index 0000000..fab79e7
--- /dev/null
+++ b/c-user/user-extensions/introduction.rst
@@ -0,0 +1,43 @@
+.. SPDX-License-Identifier: CC-BY-SA-4.0
+
+.. Copyright (C) 2020, 2021 embedded brains GmbH & Co. KG
+.. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR)
+
+.. This file is part of the RTEMS quality process and was automatically
+.. generated. If you find something that needs to be fixed or
+.. worded better please post a report or patch to an RTEMS mailing list
+.. or raise a bug report:
+..
+.. https://www.rtems.org/bugs.html
+..
+.. For information on updating and regenerating please refer to the How-To
+.. section in the Software Requirements Engineering chapter of the
+.. RTEMS Software Engineering manual. The manual is provided as a part of
+.. a release. For development sources please refer to the online
+.. documentation at:
+..
+.. https://docs.rtems.org
+
+.. Generated from spec:/rtems/userext/if/group
+
+.. _UserExtensionsManagerIntroduction:
+
+Introduction
+============
+
+.. The following list was generated from:
+.. spec:/rtems/userext/if/create
+.. spec:/rtems/userext/if/delete
+.. spec:/rtems/userext/if/ident
+
+The 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:
+
+* :ref:`InterfaceRtemsExtensionCreate` - Creates an extension set.
+
+* :ref:`InterfaceRtemsExtensionDelete` - Deletes the extension set.
+
+* :ref:`InterfaceRtemsExtensionIdent` - Identifies an extension set by the
+ object name.