diff options
Diffstat (limited to 'cpukit/include/rtems/rtems')
48 files changed, 10346 insertions, 0 deletions
diff --git a/cpukit/include/rtems/rtems/asr.h b/cpukit/include/rtems/rtems/asr.h new file mode 100644 index 0000000000..edd5e2fe62 --- /dev/null +++ b/cpukit/include/rtems/rtems/asr.h @@ -0,0 +1,156 @@ +/** + * @file rtems/rtems/asr.h + * + * @defgroup ClassicASR ASR Support + * + * @ingroup ClassicRTEMS + * @brief Asynchronous Signal Handler + * + * This include file contains all the constants and structures associated + * with the Asynchronous Signal Handler. This Handler provides the low-level + * support required by the Signal Manager. + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_ASR_H +#define _RTEMS_RTEMS_ASR_H + +#include <rtems/rtems/modes.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicASR ASR Support + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the Classic API Signal + * Manager. + */ +/**@{*/ + +/** + * The following type defines the control block used to manage + * each signal set. + */ +typedef uint32_t rtems_signal_set; + +/** + * Return type for ASR Handler + */ +typedef void rtems_asr; + +/** + * The following type corresponds to the applications asynchronous + * signal processing routine. + */ +typedef rtems_asr ( *rtems_asr_entry )( + rtems_signal_set + ); + +/** + * The following defines the control structure used to manage + * signals. Each thread has a copy of this record. + */ +typedef struct { + /** This field indicates if are ASRs enabled currently. */ + bool is_enabled; + /** This field indicates if address of the signal handler function. */ + rtems_asr_entry handler; + /** This field indicates if the task mode the signal will run with. */ + Modes_Control mode_set; + /** This field indicates the signal set that is posted. */ + rtems_signal_set signals_posted; + /** This field indicates the signal set that is pending. */ + rtems_signal_set signals_pending; + /** This field indicates if nest level of signals being processed */ + uint32_t nest_level; +} ASR_Information; + +/* + * The following constants define the individual signals which may + * be used to compose a signal set. + */ + +/** This defines the bit in the signal set associated with signal 0. */ +#define RTEMS_SIGNAL_0 0x00000001 +/** This defines the bit in the signal set associated with signal 1. */ +#define RTEMS_SIGNAL_1 0x00000002 +/** This defines the bit in the signal set associated with signal 2. */ +#define RTEMS_SIGNAL_2 0x00000004 +/** This defines the bit in the signal set associated with signal 3. */ +#define RTEMS_SIGNAL_3 0x00000008 +/** This defines the bit in the signal set associated with signal 4. */ +#define RTEMS_SIGNAL_4 0x00000010 +/** This defines the bit in the signal set associated with signal 5. */ +#define RTEMS_SIGNAL_5 0x00000020 +/** This defines the bit in the signal set associated with signal 6. */ +#define RTEMS_SIGNAL_6 0x00000040 +/** This defines the bit in the signal set associated with signal 7. */ +#define RTEMS_SIGNAL_7 0x00000080 +/** This defines the bit in the signal set associated with signal 8. */ +#define RTEMS_SIGNAL_8 0x00000100 +/** This defines the bit in the signal set associated with signal 9. */ +#define RTEMS_SIGNAL_9 0x00000200 +/** This defines the bit in the signal set associated with signal 10. */ +#define RTEMS_SIGNAL_10 0x00000400 +/** This defines the bit in the signal set associated with signal 11. */ +#define RTEMS_SIGNAL_11 0x00000800 +/** This defines the bit in the signal set associated with signal 12. */ +#define RTEMS_SIGNAL_12 0x00001000 +/** This defines the bit in the signal set associated with signal 13. */ +#define RTEMS_SIGNAL_13 0x00002000 +/** This defines the bit in the signal set associated with signal 14. */ +#define RTEMS_SIGNAL_14 0x00004000 +/** This defines the bit in the signal set associated with signal 15. */ +#define RTEMS_SIGNAL_15 0x00008000 +/** This defines the bit in the signal set associated with signal 16. */ +#define RTEMS_SIGNAL_16 0x00010000 +/** This defines the bit in the signal set associated with signal 17. */ +#define RTEMS_SIGNAL_17 0x00020000 +/** This defines the bit in the signal set associated with signal 18. */ +#define RTEMS_SIGNAL_18 0x00040000 +/** This defines the bit in the signal set associated with signal 19. */ +#define RTEMS_SIGNAL_19 0x00080000 +/** This defines the bit in the signal set associated with signal 20. */ +#define RTEMS_SIGNAL_20 0x00100000 +/** This defines the bit in the signal set associated with signal 21. */ +#define RTEMS_SIGNAL_21 0x00200000 +/** This defines the bit in the signal set associated with signal 22. */ +#define RTEMS_SIGNAL_22 0x00400000 +/** This defines the bit in the signal set associated with signal 23. */ +#define RTEMS_SIGNAL_23 0x00800000 +/** This defines the bit in the signal set associated with signal 24. */ +#define RTEMS_SIGNAL_24 0x01000000 +/** This defines the bit in the signal set associated with signal 25. */ +#define RTEMS_SIGNAL_25 0x02000000 +/** This defines the bit in the signal set associated with signal 26. */ +#define RTEMS_SIGNAL_26 0x04000000 +/** This defines the bit in the signal set associated with signal 27. */ +#define RTEMS_SIGNAL_27 0x08000000 +/** This defines the bit in the signal set associated with signal 28. */ +#define RTEMS_SIGNAL_28 0x10000000 +/** This defines the bit in the signal set associated with signal 29. */ +#define RTEMS_SIGNAL_29 0x20000000 +/** This defines the bit in the signal set associated with signal 30. */ +#define RTEMS_SIGNAL_30 0x40000000 +/** This defines the bit in the signal set associated with signal 31. */ +#define RTEMS_SIGNAL_31 0x80000000 + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/asrimpl.h b/cpukit/include/rtems/rtems/asrimpl.h new file mode 100644 index 0000000000..141c34d4bb --- /dev/null +++ b/cpukit/include/rtems/rtems/asrimpl.h @@ -0,0 +1,99 @@ +/** + * @file + * + * @ingroup ClassicASRImpl + * + * @brief Classic ASR Implementation + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_ASRIMPL_H +#define _RTEMS_RTEMS_ASRIMPL_H + +#include <rtems/rtems/asr.h> + +#include <string.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicASRImpl Classic ASR Implementation + * + * @ingroup ClassicASR + * + * @{ + */ + +/** + * @brief ASR_Initialize + * + * This routine initializes the given RTEMS_ASR information record. + */ +RTEMS_INLINE_ROUTINE void _ASR_Initialize ( + ASR_Information *asr +) +{ + memset(asr, 0, sizeof(*asr)); +} + +/** + * @brief ASR_Is_null_handler + * + * This function returns TRUE if the given asr_handler is NULL and + * FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _ASR_Is_null_handler ( + rtems_asr_entry asr_handler +) +{ + return asr_handler == NULL; +} + +RTEMS_INLINE_ROUTINE rtems_signal_set _ASR_Swap_signals( ASR_Information *asr ) +{ + rtems_signal_set new_signals_posted; + + new_signals_posted = asr->signals_pending; + asr->signals_pending = asr->signals_posted; + asr->signals_posted = new_signals_posted; + + return new_signals_posted; +} + +RTEMS_INLINE_ROUTINE void _ASR_Post_signals( + rtems_signal_set signals, + rtems_signal_set *signal_set +) +{ + *signal_set |= signals; +} + +RTEMS_INLINE_ROUTINE rtems_signal_set _ASR_Get_posted_signals( + ASR_Information *asr +) +{ + rtems_signal_set signal_set; + + signal_set = asr->signals_posted; + asr->signals_posted = 0; + + return signal_set; +} + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/attr.h b/cpukit/include/rtems/rtems/attr.h new file mode 100644 index 0000000000..7e8fa4818a --- /dev/null +++ b/cpukit/include/rtems/rtems/attr.h @@ -0,0 +1,191 @@ +/** + * @file rtems/rtems/attr.h + * + * @defgroup ClassicAttributes Attributes + * + * @ingroup ClassicRTEMS + * @brief Object Attributes Handler + * + * This include file contains all information about the Object Attributes + * Handler. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_ATTR_H +#define _RTEMS_RTEMS_ATTR_H + +#include <rtems/score/basedefs.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicAttributes Attributes + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which defines and manages the + * set of Classic API object attributes. + */ +/**@{*/ + +/** + * This defines the type used to contain Classic API attributes. These + * are primarily used when creating objects. + */ +typedef uint32_t rtems_attribute; + +/** This is the default value for an attribute set. */ + +#define RTEMS_DEFAULT_ATTRIBUTES 0x00000000 + +/** + * This is the attribute constant to indicate local resource. + */ +#define RTEMS_LOCAL 0x00000000 + +/** + * This is the attribute constant to indicate global resource. + */ +#define RTEMS_GLOBAL 0x00000002 + +/** + * This is the attribute constant which reflects that blocking + * tasks will be managed using FIFO discipline. + */ +#define RTEMS_FIFO 0x00000000 + +/** + * This is the attribute constant which reflects that blocking + * tasks will be managed using task priority discipline. + */ +#define RTEMS_PRIORITY 0x00000004 + +/******************** RTEMS Task Specific Attributes *********************/ + +/** + * This attribute constant indicates that the task will not use the + * floating point hardware. If the architecture permits it, then + * the FPU will be disabled when the task is executing. + */ +#define RTEMS_NO_FLOATING_POINT 0x00000000 + +/** + * This attribute constant indicates that the task will use the + * floating point hardware. There will be a floating point + * context associated with this task. + */ +#define RTEMS_FLOATING_POINT 0x00000001 + +/***************** RTEMS Semaphore Specific Attributes ********************/ + +/** + * This is the mask for the attribute bits associated with the + * Classic API Semaphore Manager. + */ +#define RTEMS_SEMAPHORE_CLASS 0x00000030 + +/** + * This attribute constant indicates that the Classic API Semaphore + * instance created will be a counting semaphore. + */ +#define RTEMS_COUNTING_SEMAPHORE 0x00000000 + +/** + * This attribute constant indicates that the Classic API Semaphore + * instance created will be a proper binary semaphore or mutex. + */ +#define RTEMS_BINARY_SEMAPHORE 0x00000010 + +/** + * This attribute constant indicates that the Classic API Semaphore + * instance created will be a simple binary semaphore. + */ +#define RTEMS_SIMPLE_BINARY_SEMAPHORE 0x00000020 + +/** + * This attribute constant indicates that the Classic API Semaphore + * instance created will NOT use the Priority Inheritance Protocol. + */ +#define RTEMS_NO_INHERIT_PRIORITY 0x00000000 + +/** + * This attribute constant indicates that the Classic API Semaphore + * instance created will use the Priority Inheritance Protocol. + * + * @note The semaphore instance must be a binary semaphore. + */ +#define RTEMS_INHERIT_PRIORITY 0x00000040 + +/** + * This attribute constant indicates that the Classic API Semaphore + * instance created will NOT use the Priority Ceiling Protocol. + */ +#define RTEMS_NO_PRIORITY_CEILING 0x00000000 + +/** + * This attribute constant indicates that the Classic API Semaphore + * instance created will use the Priority Ceiling Protocol. + * + * @note The semaphore instance must be a binary semaphore. + */ +#define RTEMS_PRIORITY_CEILING 0x00000080 + +/** + * This attribute constant indicates that the Classic API Semaphore instance + * created will NOT use the Multiprocessor Resource Sharing Protocol. + */ +#define RTEMS_NO_MULTIPROCESSOR_RESOURCE_SHARING 0x00000000 + +/** + * This attribute constant indicates that the Classic API Semaphore instance + * created will use the Multiprocessor Resource Sharing Protocol. + * + * @note The semaphore instance must be a binary semaphore. + */ +#define RTEMS_MULTIPROCESSOR_RESOURCE_SHARING 0x00000100 + +/******************** RTEMS Barrier Specific Attributes ********************/ + +/** + * This attribute constant indicates that the Classic API Barrier + * instance created will use an automatic release protocol. + */ +#define RTEMS_BARRIER_AUTOMATIC_RELEASE 0x00000010 + +/** + * This attribute constant indicates that the Classic API Barrier + * instance created will use the manual release protocol. + */ +#define RTEMS_BARRIER_MANUAL_RELEASE 0x00000000 + +/**************** RTEMS Internal Task Specific Attributes ****************/ + +/** + * This attribute constant indicates that the task was created + * by the application using normal Classic API methods. + */ +#define RTEMS_APPLICATION_TASK 0x00000000 + +/** + * This attribute constant indicates that the task was created + * by RTEMS as a support task. + */ +#define RTEMS_SYSTEM_TASK 0x00008000 + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/attrimpl.h b/cpukit/include/rtems/rtems/attrimpl.h new file mode 100644 index 0000000000..bb8e5f8f58 --- /dev/null +++ b/cpukit/include/rtems/rtems/attrimpl.h @@ -0,0 +1,263 @@ +/** + * @file + * + * @ingroup ClassicAttributesImpl + * + * @brief Classic Attributes Implementation + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_ATTR_INL +#define _RTEMS_RTEMS_ATTR_INL + +#include <rtems/rtems/attr.h> +#include <rtems/score/cpu.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicAttributesImpl Classic Attributes Implementation + * + * @ingroup ClassicAttributes + * + * @{ + */ + +/****************** Forced Attributes in Configuration ****************/ + +/** + * This attribute constant indicates the attributes that are not + * supportable given the hardware configuration. + */ +#define ATTRIBUTES_NOT_SUPPORTED 0 + +/** + * This attribute constant indicates the attributes that are + * required given the hardware configuration. + */ +#if ( CPU_ALL_TASKS_ARE_FP == TRUE ) +#define ATTRIBUTES_REQUIRED RTEMS_FLOATING_POINT +#else +#define ATTRIBUTES_REQUIRED 0 +#endif + +/** + * @brief Sets the requested new_attributes in the attribute_set passed in. + * + * This function sets the requested new_attributes in the attribute_set + * passed in. The result is returned to the user. + */ +RTEMS_INLINE_ROUTINE rtems_attribute _Attributes_Set ( + rtems_attribute new_attributes, + rtems_attribute attribute_set +) +{ + return attribute_set | new_attributes; +} + +/** + * @brief Clears the requested new_attributes in the attribute_set + * passed in. + * + * This function clears the requested new_attributes in the attribute_set + * passed in. The result is returned to the user. + */ +RTEMS_INLINE_ROUTINE rtems_attribute _Attributes_Clear ( + rtems_attribute attribute_set, + rtems_attribute mask +) +{ + return attribute_set & ~mask; +} + +/** + * @brief Checks if the floating point attribute is + * enabled in the attribute_set. + * + * This function returns TRUE if the floating point attribute is + * enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_floating_point( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_FLOATING_POINT ) ? true : false; +} + +#if defined(RTEMS_MULTIPROCESSING) +/** + * @brief Checks if the global object attribute is enabled in + * the attribute_set. + * + * This function returns TRUE if the global object attribute is + * enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_global( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_GLOBAL ) ? true : false; +} +#endif + +/** + * @brief Checks if the priority attribute is enabled in the attribute_set. + * + * This function returns TRUE if the priority attribute is + * enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_priority( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_PRIORITY ) ? true : false; +} + +/** + * @brief Checks if the binary semaphore attribute is + * enabled in the attribute_set. + * + * This function returns TRUE if the binary semaphore attribute is + * enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_binary_semaphore( + rtems_attribute attribute_set +) +{ + return ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_BINARY_SEMAPHORE); +} + +/** + * @brief Checks if the simple binary semaphore attribute is + * enabled in the attribute_set + * + * This function returns TRUE if the simple binary semaphore attribute is + * enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_simple_binary_semaphore( + rtems_attribute attribute_set +) +{ + return + ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_SIMPLE_BINARY_SEMAPHORE); +} + +/** + * @brief Checks if the counting semaphore attribute is + * enabled in the attribute_set + * + * This function returns TRUE if the counting semaphore attribute is + * enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_counting_semaphore( + rtems_attribute attribute_set +) +{ + return ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_COUNTING_SEMAPHORE); +} + +/** + * @brief Checks if the priority inheritance attribute + * is enabled in the attribute_set + * + * This function returns TRUE if the priority inheritance attribute + * is enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_inherit_priority( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_INHERIT_PRIORITY ) ? true : false; +} + +/** + * @brief Returns true if the attribute set has at most one protocol, and false + * otherwise. + * + * The protocols are RTEMS_INHERIT_PRIORITY, RTEMS_PRIORITY_CEILING and + * RTEMS_MULTIPROCESSOR_RESOURCE_SHARING. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Has_at_most_one_protocol( + rtems_attribute attribute_set +) +{ + attribute_set &= RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY_CEILING + | RTEMS_MULTIPROCESSOR_RESOURCE_SHARING; + + return ( attribute_set & ( attribute_set - 1 ) ) == 0; +} + +/** + * @brief Checks if the priority ceiling attribute + * is enabled in the attribute_set + * + * This function returns TRUE if the priority ceiling attribute + * is enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_priority_ceiling( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_PRIORITY_CEILING ) ? true : false; +} + +/** + * @brief Checks if the Multiprocessor Resource Sharing Protocol attribute + * is enabled in the attribute_set + * + * This function returns TRUE if the Multiprocessor Resource Sharing Protocol + * attribute is enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_multiprocessor_resource_sharing( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_MULTIPROCESSOR_RESOURCE_SHARING ) != 0; +} + +/** + * @brief Checks if the barrier automatic release + * attribute is enabled in the attribute_set + * + * This function returns TRUE if the barrier automatic release + * attribute is enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_barrier_automatic( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_BARRIER_AUTOMATIC_RELEASE ) ? true : false; +} + +/** + * @brief Checks if the system task attribute + * is enabled in the attribute_set. + * + * This function returns TRUE if the system task attribute + * is enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_system_task( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_SYSTEM_TASK ) ? true : false; +} + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/barrier.h b/cpukit/include/rtems/rtems/barrier.h new file mode 100644 index 0000000000..2eea90fa41 --- /dev/null +++ b/cpukit/include/rtems/rtems/barrier.h @@ -0,0 +1,173 @@ +/** + * @file rtems/rtems/barrier.h + * + * @defgroup ClassicBarrier Barriers + * + * @ingroup ClassicRTEMS + * @brief Classic API Barrier Manager + * + * This include file contains all the constants and structures associated + * with the Barrier Manager. + * + * Directives provided are: + * + * - create a barrier + * - get an ID of a barrier + * - delete a barrier + * - wait for a barrier + * - signal a barrier + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_BARRIER_H +#define _RTEMS_RTEMS_BARRIER_H + +#include <rtems/rtems/types.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/attr.h> +#include <rtems/score/object.h> +#include <rtems/score/corebarrier.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicBarrier Barriers + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which implements the Classic API + * Barrier Manager. + */ +/**@{*/ + +/** + * This type defines the control block used to manage each barrier. + */ +typedef struct { + /** This is used to manage a barrier as an object. */ + Objects_Control Object; + /** This is used to implement the barrier. */ + CORE_barrier_Control Barrier; + /** This is used to specify the attributes of a barrier. */ + rtems_attribute attribute_set; +} Barrier_Control; + +/** + * @brief RTEMS Create Barrier + * + * Barrier Manager -- Create a Barrier Instance + * + * This routine implements the rtems_barrier_create directive. The + * barrier will have the name name. The starting count for + * the barrier is count. The attribute_set determines if + * the barrier is global or local and the thread queue + * discipline. It returns the id of the created barrier in ID. + * + * @param[in] name is the name of this barrier instance. + * @param[in] attribute_set specifies the attributes of this barrier instance. + * @param[in] maximum_waiters is the maximum number of threads which will + * be allowed to concurrently wait at the barrier. + * @param[out] id will contain the id of this barrier. + * + * @retval a status code indicating success or the reason for failure. + */ +rtems_status_code rtems_barrier_create( + rtems_name name, + rtems_attribute attribute_set, + uint32_t maximum_waiters, + rtems_id *id +); + +/** + * @brief RTEMS Barrier name to Id + * + * This routine implements the rtems_barrier_ident directive. + * This directive returns the barrier ID associated with name. + * If more than one barrier is named name, then the barrier + * to which the ID belongs is arbitrary. node indicates the + * extent of the search for the ID of the barrier named name. + * The search can be limited to a particular node or allowed to + * encompass all nodes. + * + * @param[in] name is the name of this barrier instance. + * @param[out] id will contain the id of this barrier. + * + * @retval a status code indicating success or the reason for failure. + */ +rtems_status_code rtems_barrier_ident( + rtems_name name, + rtems_id *id +); + +/** + * @brief RTEMS Delete Barrier + * + * This routine implements the rtems_barrier_delete directive. The + * barrier indicated by @a id is deleted. The barrier is freed back to the + * inactive barrier chain. + * + * + * @param[in] id indicates the barrier to delete + * + * @retval a status code indicating success or the reason for failure. + */ +rtems_status_code rtems_barrier_delete( + rtems_id id +); + +/** + * @brief RTEMS Barrier Wait + * + * This routine implements the rtems_barrier_wait directive. It + * attempts to wait at the barrier associated with @a id. The calling task + * may block waiting for the barrier with an optional timeout of @a timeout + * clock ticks. + * + * @param[in] id indicates the barrier to wait at. + * @param[in] timeout is the maximum length of time in ticks the calling + * thread is willing to block. + * + * @retval a status code indicating success or the reason for failure. + */ +rtems_status_code rtems_barrier_wait( + rtems_id id, + rtems_interval timeout +); + +/** + * @brief RTEMS Barrier Release + * + * Barrier Manager -- Release Tasks Waitng at a Barrier + * + * This routine implements the rtems_barrier_release directive. It + * unblocks all of the threads waiting on the barrier associated with + * @a id. The number of threads unblocked is returned in @a released. + * + * + * @param[in] id indicates the barrier to wait at. + * @param[out] released will contain the number of threads unblocked. + * + * @retval a status code indicating success or the reason for failure. + */ +rtems_status_code rtems_barrier_release( + rtems_id id, + uint32_t *released +); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/barrierimpl.h b/cpukit/include/rtems/rtems/barrierimpl.h new file mode 100644 index 0000000000..f0b53e0cab --- /dev/null +++ b/cpukit/include/rtems/rtems/barrierimpl.h @@ -0,0 +1,92 @@ +/** + * @file rtems/rtems/barrier.inl + * + * @defgroup ClassicBarrier Barriers + * + * @ingroup ClassicRTEMS + * @brief Inline Implementation from Barrier Manager + * + * This file contains the static inlin implementation of the inlined + * routines from the Barrier Manager. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_BARRIERIMPL_H +#define _RTEMS_RTEMS_BARRIERIMPL_H + +#include <rtems/rtems/barrier.h> +#include <rtems/score/corebarrierimpl.h> +#include <rtems/score/objectimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicBarrierImpl Classic Barrier Implementation + * + * @ingroup ClassicBarrier + * + * @{ + */ + +/** + * The following defines the information control block used to manage + * this class of objects. + */ +extern Objects_Information _Barrier_Information; + +/** + * @brief _Barrier_Allocate + * + * This function allocates a barrier control block from + * the inactive chain of free barrier control blocks. + */ +RTEMS_INLINE_ROUTINE Barrier_Control *_Barrier_Allocate( void ) +{ + return (Barrier_Control *) _Objects_Allocate( &_Barrier_Information ); +} + +/** + * @brief _Barrier_Free + * + * This routine frees a barrier control block to the + * inactive chain of free barrier control blocks. + */ +RTEMS_INLINE_ROUTINE void _Barrier_Free ( + Barrier_Control *the_barrier +) +{ + _CORE_barrier_Destroy( &the_barrier->Barrier ); + _Objects_Free( &_Barrier_Information, &the_barrier->Object ); +} + +RTEMS_INLINE_ROUTINE Barrier_Control *_Barrier_Get( + Objects_Id id, + Thread_queue_Context *queue_context +) +{ + _Thread_queue_Context_initialize( queue_context ); + return (Barrier_Control *) _Objects_Get( + id, + &queue_context->Lock_context.Lock_context, + &_Barrier_Information + ); +} + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/cache.h b/cpukit/include/rtems/rtems/cache.h new file mode 100644 index 0000000000..f1dc9bf03d --- /dev/null +++ b/cpukit/include/rtems/rtems/cache.h @@ -0,0 +1,370 @@ +/** + * @file + * + * @ingroup ClassicCache + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_CACHE_H +#define _RTEMS_RTEMS_CACHE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/system.h> +#include <sys/types.h> + +/** + * @defgroup ClassicCache Cache + * + * @ingroup ClassicRTEMS + * + * @brief The Cache Manager provides functions to perform maintenance + * operations for data and instruction caches. + * + * The actual actions of the Cache Manager operations depend on the hardware + * and the implementation provided by the CPU architecture port or a board + * support package. Cache implementations tend to be highly hardware + * dependent. + * + * @{ + */ + +/** + * @brief Returns the data cache line size in bytes. + * + * For multi-level caches this is the maximum of the cache line sizes of all + * levels. + * + * @retval 0 No data cache is present. + * @retval positive The data cache line size in bytes. + */ +size_t rtems_cache_get_data_line_size( void ); + +/** + * @brief Returns the instruction cache line size in bytes. + * + * For multi-level caches this is the maximum of the cache line sizes of all + * levels. + * + * @retval 0 No instruction cache is present. + * @retval positive The instruction cache line size in bytes. + */ +size_t rtems_cache_get_instruction_line_size( void ); + +/** + * @brief Returns the maximal cache line size of all cache kinds in bytes. + * + * Returns computed or obtained maximal cache line size of all + * all caches in the system. + * + * @retval 0 No cache is present + * @retval positive The maximal cache line size in bytes. + */ +size_t rtems_cache_get_maximal_line_size( void ); + +/** + * @brief Returns the data cache size in bytes. + * + * @param[in] level The cache level of interest. The cache level zero + * specifies the entire data cache. + * + * @returns The data cache size in bytes of the specified level. + */ +size_t rtems_cache_get_data_cache_size( uint32_t level ); + +/** + * @brief Returns the instruction cache size in bytes. + * + * @param[in] level The cache level of interest. The cache level zero + * specifies the entire instruction cache. + * + * @returns The instruction cache size in bytes of the specified level. + */ +size_t rtems_cache_get_instruction_cache_size( uint32_t level ); + +/** + * @brief Flushes multiple data cache lines. + * + * Dirty cache lines covering the area are transfered to memory. Depending on + * the cache implementation this may mark the lines as invalid. + * + * @param[in] addr The start address of the area to flush. + * @param[in] size The size in bytes of the area to flush. + */ +void rtems_cache_flush_multiple_data_lines( const void *addr, size_t size ); + +/** + * @brief Invalidates multiple data cache lines. + * + * The cache lines covering the area are marked as invalid. A later read + * access in the area will load the data from memory. + * + * In case the area is not aligned on cache line boundaries, then this + * operation may destroy unrelated data. + * + * @param[in] addr The start address of the area to invalidate. + * @param[in] size The size in bytes of the area to invalidate. + */ +void rtems_cache_invalidate_multiple_data_lines( + const void *addr, + size_t size +); + +/** + * @brief Invalidates multiple instruction cache lines. + * + * The cache lines covering the area are marked as invalid. A later + * instruction fetch from the area will result in a load from memory. + * In SMP mode, on processors without instruction cache snooping, this + * operation will invalidate the instruction cache lines on all processors. + * It should not be called from interrupt context in such case. + * + * @param[in] addr The start address of the area to invalidate. + * @param[in] size The size in bytes of the area to invalidate. + */ +void rtems_cache_invalidate_multiple_instruction_lines( + const void *addr, + size_t size +); + + +/** + * @brief Ensure necessary synchronization required after code changes + * + * When code is loaded or modified then many Harvard cache equipped + * systems require synchronization of main memory and or updated + * code in data cache to ensure visibility of change in all + * connected CPUs instruction memory view. This operation + * should be used by run time loader for example. + * + * @param[in] addr The start address of the area to invalidate. + * @param[in] size The size in bytes of the area to invalidate. + */ +void rtems_cache_instruction_sync_after_code_change( + const void * code_addr, + size_t n_bytes +); + +/** + * @brief Flushes the entire data cache. + * + * @see rtems_cache_flush_multiple_data_lines(). + */ +void rtems_cache_flush_entire_data( void ); + +/** + * @brief Invalidates the entire instruction cache. + * + * @see rtems_cache_invalidate_multiple_instruction_lines(). + */ +void rtems_cache_invalidate_entire_instruction( void ); + +/** + * This function is responsible for performing a data cache + * invalidate. It invalidates the entire cache. + */ +void rtems_cache_invalidate_entire_data( void ); + +/** + * This function freezes the data cache. + */ +void rtems_cache_freeze_data( void ); + +/** + * This function unfreezes the data cache. + */ +void rtems_cache_unfreeze_data( void ); + +/** + * This function enables the data cache. + */ +void rtems_cache_enable_data( void ); + +/** + * This function disables the data cache. + */ +void rtems_cache_disable_data( void ); + +/** + * This function freezes the instruction cache. + */ +void rtems_cache_freeze_instruction( void ); + +/** + * This function unfreezes the instruction cache. + */ +void rtems_cache_unfreeze_instruction( void ); + +/** + * This function enables the instruction cache. + */ +void rtems_cache_enable_instruction( void ); + +/** + * This function disables the instruction cache. + */ +void rtems_cache_disable_instruction( void ); + +/** + * This function is used to allocate storage that spans an + * integral number of cache blocks. + */ +void *rtems_cache_aligned_malloc ( size_t nbytes ); + +/** + * @brief Allocates a memory area of size @a size bytes from cache coherent + * memory. + * + * A size value of zero will return a unique address which may be freed with + * rtems_cache_coherent_free(). + * + * The memory allocated by this function can be released with a call to + * rtems_cache_coherent_free(). + * + * By default the C program heap allocator is used. In case special memory + * areas must be used, then the BSP or the application must add cache coherent + * memory areas for the allocator via rtems_cache_coherent_add_area(). + * + * This function must be called from driver initialization or task context + * only. + * + * @param[in] alignment If the alignment parameter is not equal to zero, the + * allocated memory area will begin at an address aligned by this value. + * @param[in] boundary If the boundary parameter is not equal to zero, the + * allocated memory area will comply with a boundary constraint. The + * boundary value specifies the set of addresses which are aligned by the + * boundary value. The interior of the allocated memory area will not + * contain an element of this set. The begin or end address of the area may + * be a member of the set. + * + * @retval NULL If no memory is available or the parameters are inconsistent. + * @retval other A pointer to the begin of the allocated memory area. + */ +void *rtems_cache_coherent_allocate( + size_t size, + uintptr_t alignment, + uintptr_t boundary +); + +/** + * @brief Frees memory allocated by rtems_cache_coherent_allocate(). + * + * This function must be called from driver initialization or task context + * only. + * + * @param[in] ptr A pointer returned by rtems_cache_coherent_allocate(). + */ +void rtems_cache_coherent_free( void *ptr ); + +/** + * @brief Adds a cache coherent memory area to the cache coherent allocator. + * + * This function must be called from BSP initialization, driver initialization + * or task context only. + * + * @param[in] area_begin The area begin address. + * @param[in] area_size The area size in bytes. + * + * @see rtems_cache_coherent_allocate(). + */ +void rtems_cache_coherent_add_area( + void *area_begin, + uintptr_t area_size +); + +#if defined( RTEMS_SMP ) + +/** + * @brief Flushes multiple data cache lines for a set of processors + * + * Dirty cache lines covering the area are transferred to memory. + * Depending on the cache implementation this may mark the lines as invalid. + * + * This operation should not be called from interrupt context. + * + * @param[in] addr The start address of the area to flush. + * @param[in] size The size in bytes of the area to flush. + * @param[in] setsize The size of the processor set. + * @param[in] set The target processor set. + */ +void rtems_cache_flush_multiple_data_lines_processor_set( + const void *addr, + size_t size, + const size_t setsize, + const cpu_set_t *set +); + +/** + * @brief Invalidates multiple data cache lines for a set of processors + * + * The cache lines covering the area are marked as invalid. A later read + * access in the area will load the data from memory. + * + * In case the area is not aligned on cache line boundaries, then this + * operation may destroy unrelated data. + * + * This operation should not be called from interrupt context. + * + * @param[in] addr The start address of the area to invalidate. + * @param[in] size The size in bytes of the area to invalidate. + * @param[in] setsize The size of the processor set. + * @param[in] set The target processor set. + */ +void rtems_cache_invalidate_multiple_data_lines_processor_set( + const void *addr, + size_t size, + const size_t setsize, + const cpu_set_t *set +); + +/** + * @brief Flushes the entire data cache for a set of processors + * + * This operation should not be called from interrupt context. + * + * @see rtems_cache_flush_multiple_data_lines(). + * + * @param[in] setsize The size of the processor set. + * @param[in] set The target processor set. + */ +void rtems_cache_flush_entire_data_processor_set( + const size_t setsize, + const cpu_set_t *set +); + +/** + * @brief Invalidates the entire cache for a set of processors + * + * This function is responsible for performing a data cache + * invalidate. It invalidates the entire cache for a set of + * processors. + * + * This operation should not be called from interrupt context. + * + * @param[in] setsize The size of the processor set. + * @param[in] set The target processor set. + */ +void rtems_cache_invalidate_entire_data_processor_set( + const size_t setsize, + const cpu_set_t *set +); + +#endif + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/clock.h b/cpukit/include/rtems/rtems/clock.h new file mode 100644 index 0000000000..a837b88700 --- /dev/null +++ b/cpukit/include/rtems/rtems/clock.h @@ -0,0 +1,318 @@ +/** + * @file rtems/rtems/clock.h + * + * @defgroup ClassicClock Clocks + * + * @ingroup ClassicRTEMS + * @brief Clock Manager API + * + * This include file contains all the constants and structures associated + * with the Clock Manager. This manager provides facilities to set, obtain, + * and continually update the current date and time. + * + * This manager provides directives to: + * + * - set the current date and time + * - obtain the current date and time + * - announce a clock tick + * - obtain the system uptime + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_CLOCK_H +#define _RTEMS_RTEMS_CLOCK_H + +#include <rtems/score/watchdog.h> +#include <rtems/score/tod.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/types.h> +#include <rtems/config.h> +#include <rtems/score/timecounterimpl.h> + +#include <sys/time.h> /* struct timeval */ + +/** + * @defgroup ClassicClock Clocks + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the Classic API Clock + * Manager. + */ +/**@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Obtain Current Time of Day (Classic TOD) + * + * This routine implements the rtems_clock_get_tod directive. It returns + * the current time of day in the format defined by RTEID. + * + * Clock Manager - rtems_clock_get_tod + * + * @param[in] time_buffer points to the time of day structure + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. If successful, the time_buffer will + * be filled in with the current time of day. + */ +rtems_status_code rtems_clock_get_tod( + rtems_time_of_day *time_buffer +); + +/** + * @brief Obtain TOD in struct timeval Format + * + * This routine implements the rtems_clock_get_tod_timeval + * directive. + * + * @param[in] time points to the struct timeval variable to fill in + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. If successful, the time will + * be filled in with the current time of day. + */ +rtems_status_code rtems_clock_get_tod_timeval( + struct timeval *time +); + +/** + * @brief Obtain Seconds Since Epoch + * + * This routine implements the rtems_clock_get_seconds_since_epoch + * directive. + * + * @param[in] the_interval points to the interval variable to fill in + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. If successful, the time_buffer will + * be filled in with the current time of day. + */ +rtems_status_code rtems_clock_get_seconds_since_epoch( + rtems_interval *the_interval +); + +/** + * @brief Gets the current ticks counter value. + * + * @return The current tick counter value. With a 1ms clock tick, this counter + * overflows after 50 days since boot. + */ +RTEMS_INLINE_ROUTINE rtems_interval rtems_clock_get_ticks_since_boot(void) +{ + return _Watchdog_Ticks_since_boot; +} + +/** + * @brief Returns the ticks counter value delta ticks in the future. + * + * @param[in] delta The ticks delta value. + * + * @return The tick counter value delta ticks in the future. + */ +RTEMS_INLINE_ROUTINE rtems_interval rtems_clock_tick_later( + rtems_interval delta +) +{ + return _Watchdog_Ticks_since_boot + delta; +} + +/** + * @brief Returns the ticks counter value at least delta microseconds in the + * future. + * + * @param[in] delta_in_usec The delta value in microseconds. + * + * @return The tick counter value at least delta microseconds in the future. + */ +RTEMS_INLINE_ROUTINE rtems_interval rtems_clock_tick_later_usec( + rtems_interval delta_in_usec +) +{ + rtems_interval us_per_tick = rtems_configuration_get_microseconds_per_tick(); + + /* + * Add one additional tick, since we don't know the time to the clock next + * tick. + */ + return _Watchdog_Ticks_since_boot + + (delta_in_usec + us_per_tick - 1) / us_per_tick + 1; +} + +/** + * @brief Returns true if the current ticks counter value indicates a time + * before the time specified by the tick value and false otherwise. + * + * @param[in] tick The tick value. + * + * This can be used to write busy loops with a timeout. + * + * @code + * status busy( void ) + * { + * rtems_interval timeout = rtems_clock_tick_later_usec( 10000 ); + * + * do { + * if ( ok() ) { + * return success; + * } + * } while ( rtems_clock_tick_before( timeout ) ); + * + * return timeout; + * } + * @endcode + * + * @retval true The current ticks counter value indicates a time before the + * time specified by the tick value. + * @retval false Otherwise. + */ +RTEMS_INLINE_ROUTINE bool rtems_clock_tick_before( + rtems_interval tick +) +{ + return (int32_t) ( tick - _Watchdog_Ticks_since_boot ) > 0; +} + +/** + * @brief Obtain Ticks Per Seconds + * + * This routine implements the rtems_clock_get_ticks_per_second + * directive. + * + * @retval This method returns the number of ticks per second. It cannot + * fail since RTEMS is always configured to know the number of + * ticks per second. + */ +rtems_interval rtems_clock_get_ticks_per_second(void); + +/* Optimized variant for C/C++ without function call overhead */ +#define rtems_clock_get_ticks_per_second() ( _Watchdog_Ticks_per_second ) + +/** + * @brief Set the Current TOD + * + * This routine implements the rtems_clock_set directive. It sets + * the current time of day to that in the time_buffer record. + * + * @param[in] time_buffer points to the new TOD + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + * + * @note Activities scheduled based upon the current time of day + * may be executed immediately if the time is moved forward. + */ +rtems_status_code rtems_clock_set( + const rtems_time_of_day *time_buffer +); + +/** + * @brief Announce a Clock Tick + * + * This routine implements the rtems_clock_tick directive. It is invoked + * to inform RTEMS of the occurrence of a clock tick. + * + * @retval This directive always returns RTEMS_SUCCESSFUL. + * + * @note This method is typically called from an ISR and is the basis + * for all timeouts and delays. This routine only works for leap-years + * through 2099. + */ +rtems_status_code rtems_clock_tick( void ); + +/** + * @brief Obtain the System Uptime + * + * This directive returns the system uptime. + * + * @param[in] uptime is a pointer to the time structure + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. If successful, the @a uptime will be + * filled in. + */ +rtems_status_code rtems_clock_get_uptime( + struct timespec *uptime +); + +/** + * @brief Gets the System Uptime in the Struct Timeval Format + * + * @param[out] uptime is a pointer to a struct timeval structure. + * + * @retval This methods returns the system uptime. + * + * @note Pointer must not be NULL. + */ +void rtems_clock_get_uptime_timeval( struct timeval *uptime ); + +/** + * @brief Returns the system uptime in seconds. + * + * @retval The system uptime in seconds. + */ +RTEMS_INLINE_ROUTINE time_t rtems_clock_get_uptime_seconds( void ) +{ + return _Timecounter_Time_uptime - 1; +} + +/** + * @brief Returns the system uptime in nanoseconds. + * + * @retval The system uptime in nanoseconds. + */ +uint64_t rtems_clock_get_uptime_nanoseconds( void ); + +/** + * @brief TOD Validate + * + * This support function returns true if @a the_tod contains + * a valid time of day, and false otherwise. + * + * @param[in] the_tod is the TOD structure to validate + * + * @retval This method returns true if the TOD is valid and false otherwise. + * + * @note This routine only works for leap-years through 2099. + */ +bool _TOD_Validate( + const rtems_time_of_day *the_tod +); + +/** + * @brief TOD to Seconds + * + * This function returns the number seconds between the epoch and @a the_tod. + * + * @param[in] the_tod is the TOD structure to convert to seconds + * + * @retval This method returns the number of seconds since epoch represented + * by @a the_tod + */ +Watchdog_Interval _TOD_To_seconds( + const rtems_time_of_day *the_tod +); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/config.h b/cpukit/include/rtems/rtems/config.h new file mode 100644 index 0000000000..77ee798d74 --- /dev/null +++ b/cpukit/include/rtems/rtems/config.h @@ -0,0 +1,142 @@ +/** + * @file rtems/rtems/config.h + * + * @defgroup ClassicConfig Configuration + * + * @ingroup ClassicRTEMS + * @brief Configuration Table + * + * This include file contains the table of user defined configuration + * parameters specific for the RTEMS API. + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_CONFIG_H +#define _RTEMS_RTEMS_CONFIG_H + +#include <rtems/rtems/types.h> +#include <rtems/rtems/tasks.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicConfig Configuration + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the application's configuration + * of the Classic API including the maximum number of each class of objects. + */ +/**@{*/ + +/** + * The following records define the Configuration Table. The + * information contained in this table is required in all + * RTEMS systems, whether single or multiprocessor. This + * table primarily defines the following: + * + * + required number of each object type + */ +typedef struct { + /** + * This field contains the maximum number of Classic API + * Tasks which are configured for this application. + */ + uint32_t maximum_tasks; + + /** + * This field contains the maximum number of Classic API + * Timers which are configured for this application. + */ + uint32_t maximum_timers; + + /** + * This field contains the maximum number of Classic API + * Semaphores which are configured for this application. + */ + uint32_t maximum_semaphores; + + /** + * This field contains the maximum number of Classic API + * Message Queues which are configured for this application. + */ + uint32_t maximum_message_queues; + + /** + * This field contains the maximum number of Classic API + * Partitions which are configured for this application. + */ + uint32_t maximum_partitions; + + /** + * This field contains the maximum number of Classic API + * Regions which are configured for this application. + */ + uint32_t maximum_regions; + + /** + * This field contains the maximum number of Classic API + * Dual Ported Memory Areas which are configured for this + * application. + */ + uint32_t maximum_ports; + + /** + * This field contains the maximum number of Classic API + * Rate Monotonic Periods which are configured for this + * application. + */ + uint32_t maximum_periods; + + /** + * This field contains the maximum number of Classic API + * Barriers which are configured for this application. + */ + uint32_t maximum_barriers; + + /** + * This field contains the number of Classic API Initialization + * Tasks which are configured for this application. + */ + uint32_t number_of_initialization_tasks; + + /** + * This field is the set of Classic API Initialization + * Tasks which are configured for this application. + */ + rtems_initialization_tasks_table *User_initialization_tasks_table; +} rtems_api_configuration_table; + +/** + * @brief RTEMS API Configuration Table + * + * This is the RTEMS API Configuration Table expected to be generated + * by confdefs.h. + */ +extern rtems_api_configuration_table Configuration_RTEMS_API; + +/**@}*/ + +/** + * This macro returns the number of Classic API semaphores configured. + */ +#define rtems_configuration_get_maximum_semaphores() \ + rtems_configuration_get_rtems_api_configuration()->maximum_semaphores + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/dpmem.h b/cpukit/include/rtems/rtems/dpmem.h new file mode 100644 index 0000000000..e582d2d359 --- /dev/null +++ b/cpukit/include/rtems/rtems/dpmem.h @@ -0,0 +1,179 @@ +/** + * @file rtems/rtems/dpmem.h + * + * @defgroup ClassicDPMEM Dual Ported Memory + * + * @ingroup ClassicRTEMS + * @brief Dual Ported Memory Manager + * + * This include file contains all the constants and structures associated + * with the Dual Ported Memory Manager. This manager provides a mechanism + * for converting addresses between internal and external representations + * for multiple dual-ported memory areas. + * + * Directives provided are: + * + * - create a port + * - get ID of a port + * - delete a port + * - convert external to internal address + * - convert internal to external address + * + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_DPMEM_H +#define _RTEMS_RTEMS_DPMEM_H + +#include <rtems/rtems/types.h> +#include <rtems/rtems/status.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicDPMEM Dual Ported Memory + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the + * Classic API Dual Ported Memory Manager. + */ +/**@{*/ + +/** + * The following structure defines the port control block. Each port + * has a control block associated with it. This control block contains + * all information required to support the port related operations. + */ +typedef struct { + /** This field is the object management portion of a Port instance. */ + Objects_Control Object; + /** This field is the base internal address of the port. */ + void *internal_base; + /** This field is the base external address of the port. */ + void *external_base; + /** This field is the length of dual-ported area of the port. */ + uint32_t length; +} Dual_ported_memory_Control; + +/** + * @brief Creates a port into a dual-ported memory area. + * + * This routine implements the rtems_port_create directive. The port + * will have the name @a name. The port maps onto an area of dual ported + * memory of length bytes which has internal_start and external_start + * as the internal and external starting addresses, respectively. + * It returns the id of the created port in ID. + * + * @param[in] name is the user defined port name + * @param[in] internal_start is the internal start address of port + * @param[in] external_start is the external start address of port + * @param[in] length is the physical length in bytes + * @param[out] id is the address of port id to set + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. If successful, the id will + * be filled in with the port id. + */ +rtems_status_code rtems_port_create( + rtems_name name, + void *internal_start, + void *external_start, + uint32_t length, + rtems_id *id +); + +/** + * @brief RTEMS Port Name to Id + * + * This routine implements the rtems_port_ident directive. This directive + * returns the port ID associated with name. If more than one port is + * named name, then the port to which the ID belongs is arbitrary. + * + * @param[in] name is the user defined port name + * @param[out] id is the pointer to port id + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful + */ +rtems_status_code rtems_port_ident( + rtems_name name, + rtems_id *id +); + +/** + * @brief RTEMS Delete Port + * + * This routine implements the rtems_port_delete directive. It deletes + * the port associated with ID. + * + * @param[in] id is the dual-ported memory area id + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + */ +rtems_status_code rtems_port_delete( + rtems_id id +); + +/** + * @brief RTEMS Port External to Internal + * + * This routine implements the rtems_port_external_to_internal directive. + * It returns the internal port address which maps to the provided + * external port address for the specified port ID. If the given external + * address is an invalid dual-ported address, then the internal address is + * set to the given external address. + * + * @param[in] id is the id of dp memory object + * @param[in] external is the external address + * @param[out] internal is the pointer of internal address to set + * + * @retval RTEMS_SUCCESSFUL + */ +rtems_status_code rtems_port_external_to_internal( + rtems_id id, + void *external, + void **internal +); + +/** + * @brief RTEMS Port Internal to External + * + * This routine implements the Port_internal_to_external directive. + * It returns the external port address which maps to the provided + * internal port address for the specified port ID. If the given + * internal address is an invalid dual-ported address, then the + * external address is set to the given internal address. + * + * @param[in] id is the id of dual-ported memory object + * @param[in] internal is the internal address to set + * @param[in] external is the pointer to external address + * + * @retval RTEMS_SUCCESSFUL and the external will be filled in + * with the external addresses + */ +rtems_status_code rtems_port_internal_to_external( + rtems_id id, + void *internal, + void **external +); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/dpmemimpl.h b/cpukit/include/rtems/rtems/dpmemimpl.h new file mode 100644 index 0000000000..52ac48c8dc --- /dev/null +++ b/cpukit/include/rtems/rtems/dpmemimpl.h @@ -0,0 +1,85 @@ +/** + * @file + * + * @ingroup ClassicDPMEMImpl + * + * @brief Dual Ported Memory Manager Implementation + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_DPMEM_INL +#define _RTEMS_RTEMS_DPMEM_INL + +#include <rtems/rtems/dpmem.h> +#include <rtems/score/objectimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicDPMEMImpl Dual Ported Memory Manager Implementation + * + * @ingroup ClassicDPMEM + * + * @{ + */ + +/** + * @brief Define the internal Dual Ported Memory information + * The following define the internal Dual Ported Memory information. + */ +extern Objects_Information _Dual_ported_memory_Information; + +/** + * @brief Allocates a port control block from the inactive chain + * of free port control blocks. + * + * This routine allocates a port control block from the inactive chain + * of free port control blocks. + */ +RTEMS_INLINE_ROUTINE Dual_ported_memory_Control + *_Dual_ported_memory_Allocate ( void ) +{ + return (Dual_ported_memory_Control *) + _Objects_Allocate( &_Dual_ported_memory_Information ); +} + +/** + * @brief Frees a port control block to the inactive chain + * of free port control blocks. + * + * This routine frees a port control block to the inactive chain + * of free port control blocks. + */ +RTEMS_INLINE_ROUTINE void _Dual_ported_memory_Free ( + Dual_ported_memory_Control *the_port +) +{ + _Objects_Free( &_Dual_ported_memory_Information, &the_port->Object ); +} + +RTEMS_INLINE_ROUTINE Dual_ported_memory_Control *_Dual_ported_memory_Get( + Objects_Id id, + ISR_lock_Context *lock_context +) +{ + return (Dual_ported_memory_Control *) + _Objects_Get( id, lock_context, &_Dual_ported_memory_Information ); +} + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTEMS_RTEMS_DPMEM_INL */ +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/event.h b/cpukit/include/rtems/rtems/event.h new file mode 100644 index 0000000000..1cd64c0cfa --- /dev/null +++ b/cpukit/include/rtems/rtems/event.h @@ -0,0 +1,526 @@ +/** + * @file rtems/rtems/event.h + * + * @defgroup ClassicEvent Events + * + * @ingroup ClassicRTEMS + * @brief Information Related to Event Manager + * + * This include file contains the information pertaining to the Event + * Manager. This manager provides a high performance method of communication + * and synchronization. + * + * Directives provided are: + * + * - send an event set to a task + * - receive event condition + * + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_EVENT_H +#define _RTEMS_RTEMS_EVENT_H + +#include <rtems/rtems/status.h> +#include <rtems/rtems/types.h> +#include <rtems/rtems/options.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicEventSet Event Set + * + * @ingroup ClassicEvent + * + * @{ + */ + +/** + * @brief Integer type to hold an event set of up to 32 events represented as + * a bit field. + */ +typedef uint32_t rtems_event_set; + +/** + * @brief Constant used to send or receive all events. + */ +#define RTEMS_ALL_EVENTS 0xFFFFFFFF + +/** @brief Defines the bit in the event set associated with event 0. */ +#define RTEMS_EVENT_0 0x00000001 +/** @brief Defines the bit in the event set associated with event 1. */ +#define RTEMS_EVENT_1 0x00000002 +/** @brief Defines the bit in the event set associated with event 2. */ +#define RTEMS_EVENT_2 0x00000004 +/** @brief Defines the bit in the event set associated with event 3. */ +#define RTEMS_EVENT_3 0x00000008 +/** @brief Defines the bit in the event set associated with event 4. */ +#define RTEMS_EVENT_4 0x00000010 +/** @brief Defines the bit in the event set associated with event 5. */ +#define RTEMS_EVENT_5 0x00000020 +/** @brief Defines the bit in the event set associated with event 6. */ +#define RTEMS_EVENT_6 0x00000040 +/** @brief Defines the bit in the event set associated with event 7. */ +#define RTEMS_EVENT_7 0x00000080 +/** @brief Defines the bit in the event set associated with event 8. */ +#define RTEMS_EVENT_8 0x00000100 +/** @brief Defines the bit in the event set associated with event 9. */ +#define RTEMS_EVENT_9 0x00000200 +/** @brief Defines the bit in the event set associated with event 10. */ +#define RTEMS_EVENT_10 0x00000400 +/** @brief Defines the bit in the event set associated with event 11. */ +#define RTEMS_EVENT_11 0x00000800 +/** @brief Defines the bit in the event set associated with event 12. */ +#define RTEMS_EVENT_12 0x00001000 +/** @brief Defines the bit in the event set associated with event 13. */ +#define RTEMS_EVENT_13 0x00002000 +/** @brief Defines the bit in the event set associated with event 14. */ +#define RTEMS_EVENT_14 0x00004000 +/** @brief Defines the bit in the event set associated with event 15. */ +#define RTEMS_EVENT_15 0x00008000 +/** @brief Defines the bit in the event set associated with event 16. */ +#define RTEMS_EVENT_16 0x00010000 +/** @brief Defines the bit in the event set associated with event 17. */ +#define RTEMS_EVENT_17 0x00020000 +/** @brief Defines the bit in the event set associated with event 18. */ +#define RTEMS_EVENT_18 0x00040000 +/** @brief Defines the bit in the event set associated with event 19. */ +#define RTEMS_EVENT_19 0x00080000 +/** @brief Defines the bit in the event set associated with event 20. */ +#define RTEMS_EVENT_20 0x00100000 +/** @brief Defines the bit in the event set associated with event 21. */ +#define RTEMS_EVENT_21 0x00200000 +/** @brief Defines the bit in the event set associated with event 22. */ +#define RTEMS_EVENT_22 0x00400000 +/** @brief Defines the bit in the event set associated with event 23. */ +#define RTEMS_EVENT_23 0x00800000 +/** @brief Defines the bit in the event set associated with event 24. */ +#define RTEMS_EVENT_24 0x01000000 +/** @brief Defines the bit in the event set associated with event 25. */ +#define RTEMS_EVENT_25 0x02000000 +/** @brief Defines the bit in the event set associated with event 26. */ +#define RTEMS_EVENT_26 0x04000000 +/** @brief Defines the bit in the event set associated with event 27. */ +#define RTEMS_EVENT_27 0x08000000 +/** @brief Defines the bit in the event set associated with event 29. */ +#define RTEMS_EVENT_28 0x10000000 +/** @brief Defines the bit in the event set associated with event 29. */ +#define RTEMS_EVENT_29 0x20000000 +/** @brief Defines the bit in the event set associated with event 30. */ +#define RTEMS_EVENT_30 0x40000000 +/** @brief Defines the bit in the event set associated with event 31. */ +#define RTEMS_EVENT_31 0x80000000 + +/** @} */ + +/** + * @defgroup ClassicEvent Events + * + * @ingroup ClassicRTEMS + * + * @brief The event manager provides a high performance method of intertask + * communication and synchronization. + * + * An event flag is used by a task (or ISR) to inform another task of the + * occurrence of a significant situation. Thirty-two event flags are + * associated with each task. A collection of one or more event flags is + * referred to as an event set. The data type rtems_event_set is used to + * manage event sets. + * + * The application developer should remember the following key characteristics + * of event operations when utilizing the event manager: + * + * - Events provide a simple synchronization facility. + * - Events are aimed at tasks. + * - Tasks can wait on more than one event simultaneously. + * - Events are independent of one another. + * - Events do not hold or transport data. + * - Events are not queued. In other words, if an event is sent more than once + * to a task before being received, the second and subsequent send + * operations to that same task have no effect. + * + * An event set is posted when it is directed (or sent) to a task. A pending + * event is an event that has been posted but not received. An event condition + * is used to specify the event set which the task desires to receive and the + * algorithm which will be used to determine when the request is satisfied. An + * event condition is satisfied based upon one of two algorithms which are + * selected by the user. The @ref RTEMS_EVENT_ANY algorithm states that an + * event condition is satisfied when at least a single requested event is + * posted. The @ref RTEMS_EVENT_ALL algorithm states that an event condition + * is satisfied when every requested event is posted. + * + * An event set or condition is built by a bitwise or of the desired events. + * The set of valid events is @ref RTEMS_EVENT_0 through @ref RTEMS_EVENT_31. + * If an event is not explicitly specified in the set or condition, then it is + * not present. Events are specifically designed to be mutually exclusive, + * therefore bitwise or and addition operations are equivalent as long as each + * event appears exactly once in the event set list. + * + * For example, when sending the event set consisting of @ref RTEMS_EVENT_6, + * @ref RTEMS_EVENT_15, and @ref RTEMS_EVENT_31, the event parameter to the + * rtems_event_send() directive should be @ref RTEMS_EVENT_6 | + * @ref RTEMS_EVENT_15 | @ref RTEMS_EVENT_31. + * + * @{ + */ + +/** + * @brief Constant used to receive the set of currently pending events in + * rtems_event_receive(). + */ +#define RTEMS_PENDING_EVENTS 0 + +/** + * @brief Sends an Event Set to the Target Task + * + * This directive sends an event set @a event_in to the task specified by + * @a id. + * + * Based upon the state of the target task, one of the following situations + * applies. The target task is + * - blocked waiting for events. + * If the waiting task's input event condition is + * - satisfied, then the task is made ready for execution. + * - not satisfied, then the event set is posted but left pending and the + * task remains blocked. + * - not waiting for events. + * - The event set is posted and left pending. + * + * Identical events sent to a task are not queued. In other words, the second, + * and subsequent, posting of an event to a task before it can perform an + * rtems_event_receive() has no effect. + * + * The calling task will be preempted if it has preemption enabled and a + * higher priority task is unblocked as the result of this directive. + * + * Sending an event set to a global task which does not reside on the local + * node will generate a request telling the remote node to send the event set + * to the appropriate task. + * + * @param[in] id Identifier of the target task. Specifying @ref RTEMS_SELF + * results in the event set being sent to the calling task. + * @param[in] event_in Event set sent to the target task. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID Invalid task identifier. + */ +rtems_status_code rtems_event_send ( + rtems_id id, + rtems_event_set event_in +); + +/** + * @brief Receives pending events. + * + * This directive attempts to receive the event condition specified in + * @a event_in. If @a event_in is set to @ref RTEMS_PENDING_EVENTS, then the + * current pending events are returned in @a event_out and left pending. The + * @ref RTEMS_WAIT and @ref RTEMS_NO_WAIT options in the @a option_set + * parameter are used to specify whether or not the task is willing to wait + * for the event condition to be satisfied. The @ref RTEMS_EVENT_ANY and @ref + * RTEMS_EVENT_ALL are used in the @a option_set parameter to specify whether + * at least a single event or the complete event set is necessary to satisfy + * the event condition. The @a event_out parameter is returned to the calling + * task with the value that corresponds to the events in @a event_in that were + * satisfied. + * + * A task can determine the pending event set by using a value of + * @ref RTEMS_PENDING_EVENTS for the input event set @a event_in. The pending + * events are returned to the calling task but the event set is left + * unaltered. + * + * A task can receive all of the currently pending events by using the a value + * of @ref RTEMS_ALL_EVENTS for the input event set @a event_in and + * @ref RTEMS_NO_WAIT | @ref RTEMS_EVENT_ANY for the option set @a option_set. + * The pending events are returned to the calling task and the event set is + * cleared. If no events are pending then the @ref RTEMS_UNSATISFIED status + * code will be returned. + * + * If pending events satisfy the event condition, then @a event_out is set to + * the satisfied events and the pending events in the event condition are + * cleared. If the event condition is not satisfied and @ref RTEMS_NO_WAIT is + * specified, then @a event_out is set to the currently satisfied events. If + * the calling task chooses to wait, then it will block waiting for the event + * condition. + * + * If the calling task must wait for the event condition to be satisfied, then + * the timeout parameter is used to specify the maximum interval to wait. If + * it is set to @ref RTEMS_NO_TIMEOUT, then the calling task will wait forever. + * + * This directive only affects the events specified in @a event_in. Any + * pending events that do not correspond to any of the events specified in + * @a event_in will be left pending. + * + * A clock tick is required to support the wait with time out functionality of + * this directive. + * + * @param[in] event_in Set of requested events (input events). + * @param[in] option_set Use a bitwise or of the following options + * - @ref RTEMS_WAIT - task will wait for event (default), + * - @ref RTEMS_NO_WAIT - task should not wait, + * - @ref RTEMS_EVENT_ALL - return after all events (default), and + * - @ref RTEMS_EVENT_ANY - return after any events. + * @param[in] ticks Time out in ticks. Use @ref RTEMS_NO_TIMEOUT to wait + * without a time out (potentially forever). + * @param[out] event_out Set of received events (output events). + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_UNSATISFIED Input events not satisfied (only with the + * @ref RTEMS_NO_WAIT option). + * @retval RTEMS_INVALID_ADDRESS The @a event_out pointer is @c NULL. + * @retval RTEMS_TIMEOUT Timed out waiting for events. + */ +rtems_status_code rtems_event_receive ( + rtems_event_set event_in, + rtems_option option_set, + rtems_interval ticks, + rtems_event_set *event_out +); + +/** @} */ + +/** + * @defgroup ClassicEventSystem System Events + * + * @ingroup ClassicEvent + * + * System events are similar to normal events. They offer a second set of + * events. These events are intended for internal RTEMS use and should not be + * used by applications (with the exception of the transient system event). + * + * The event @ref RTEMS_EVENT_SYSTEM_TRANSIENT is used for transient usage. + * See also @ref ClassicEventTransient. This event may be used by every entity + * that fulfils its usage pattern. + */ +/**@{**/ + +/** + * @brief Reserved system event for network SBWAIT usage. + */ +#define RTEMS_EVENT_SYSTEM_NETWORK_SBWAIT RTEMS_EVENT_24 + +/** + * @brief Reserved system event for network SOSLEEP usage. + */ +#define RTEMS_EVENT_SYSTEM_NETWORK_SOSLEEP RTEMS_EVENT_25 + +/** + * @brief Reserved system event for network socket close. + */ +#define RTEMS_EVENT_SYSTEM_NETWORK_CLOSE RTEMS_EVENT_26 + +/** + * @brief Reserved system event to resume server threads, e.g timer or + * interrupt server. + */ +#define RTEMS_EVENT_SYSTEM_SERVER_RESUME RTEMS_EVENT_29 + +/** + * @brief Reserved system event for the server threads, e.g timer or interrupt + * server. + */ +#define RTEMS_EVENT_SYSTEM_SERVER RTEMS_EVENT_30 + +/** + * @brief Reserved system event for transient usage. + */ +#define RTEMS_EVENT_SYSTEM_TRANSIENT RTEMS_EVENT_31 + +/** + * @brief See rtems_event_send(). + */ +rtems_status_code rtems_event_system_send( + rtems_id id, + rtems_event_set event_in +); + +/** + * @brief See rtems_event_receive(). + */ +rtems_status_code rtems_event_system_receive( + rtems_event_set event_in, + rtems_option option_set, + rtems_interval ticks, + rtems_event_set *event_out +); + +/** @} */ + +/** + * @defgroup ClassicEventTransient Transient Event + * + * @ingroup ClassicEvent + * + * The transient event can be used by a client task to issue a request to + * another task or interrupt service (server). The server can send the + * transient event to the client task to notify about a request completion, see + * rtems_event_transient_send(). The client task can wait for the transient + * event reception with rtems_event_transient_receive(). + * + * The user of the transient event must ensure that this event is not pending + * once the request is finished or cancelled. A successful reception of the + * transient event with rtems_event_transient_receive() will clear the + * transient event. If a reception with timeout is used the transient event + * state is undefined after a timeout return status. The transient event can + * be cleared unconditionally with the non-blocking + * rtems_event_transient_clear(). + * + * @msc + * hscale="1.6"; + * M [label="Main Task"], IDLE [label="Idle Task"], S [label="Server"], TIME [label="System Tick Handler"]; + * |||; + * --- [label="sequence with request completion"]; + * M box M [label="prepare request\nissue request\nrtems_event_transient_receive()"]; + * M=>>IDLE [label="blocking operation"]; + * IDLE=>>S [label="request completion"]; + * S box S [label="rtems_event_transient_send()"]; + * S=>>M [label="task is ready again"]; + * M box M [label="finish request"]; + * |||; + * --- [label="sequence with early request completion"]; + * M box M [label="prepare request\nissue request"]; + * M=>>S [label="request completion"]; + * S box S [label="rtems_event_transient_send()"]; + * S=>>M [label="transient event is now pending"]; + * M box M [label="rtems_event_transient_receive()\nfinish request"]; + * |||; + * --- [label="sequence with timeout event"]; + * M box M [label="prepare request\nissue request\nrtems_event_transient_receive()"]; + * M=>>IDLE [label="blocking operation"]; + * IDLE=>>TIME [label="timeout expired"]; + * TIME box TIME [label="cancel blocking operation"]; + * TIME=>>M [label="task is ready again"]; + * M box M [label="cancel request\nrtems_event_transient_clear()"]; + * @endmsc + * + * Suppose you have a task that wants to issue a certain request and then waits + * for request completion. It can create a request structure and store its + * task identifier there. Now it can place the request on a work queue of + * another task (or interrupt handler). Afterwards the task waits for the + * reception of the transient event. Once the server task is finished with the + * request it can send the transient event to the waiting task and wake it up. + * + * @code + * #include <assert.h> + * #include <rtems.h> + * + * typedef struct { + * rtems_id task_id; + * bool work_done; + * } request; + * + * void server(rtems_task_argument arg) + * { + * rtems_status_code sc; + * request *req = (request *) arg; + * + * req->work_done = true; + * + * sc = rtems_event_transient_send(req->task_id); + * assert(sc == RTEMS_SUCCESSFUL); + * + * sc = rtems_task_delete(RTEMS_SELF); + * assert(sc == RTEMS_SUCCESSFUL); + * } + * + * void issue_request_and_wait_for_completion(void) + * { + * rtems_status_code sc; + * rtems_id id; + * request req; + * + * req.task_id = rtems_task_self(); + * req.work_done = false; + * + * sc = rtems_task_create( + * rtems_build_name('S', 'E', 'R', 'V'), + * 1, + * RTEMS_MINIMUM_STACK_SIZE, + * RTEMS_DEFAULT_MODES, + * RTEMS_DEFAULT_ATTRIBUTES, + * &id + * ); + * assert(sc == RTEMS_SUCCESSFUL); + * + * sc = rtems_task_start(id, server, (rtems_task_argument) &req); + * assert(sc == RTEMS_SUCCESSFUL); + * + * sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT); + * assert(sc == RTEMS_SUCCESSFUL); + * + * assert(req.work_done); + * } + * @endcode + */ +/**@{**/ + +/** + * @brief See rtems_event_system_send(). + * + * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be sent. + */ +RTEMS_INLINE_ROUTINE rtems_status_code rtems_event_transient_send( + rtems_id id +) +{ + return rtems_event_system_send( id, RTEMS_EVENT_SYSTEM_TRANSIENT ); +} + +/** + * @brief See rtems_event_system_receive(). + * + * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be received. + */ +RTEMS_INLINE_ROUTINE rtems_status_code rtems_event_transient_receive( + rtems_option option_set, + rtems_interval ticks +) +{ + rtems_event_set event_out; + + return rtems_event_system_receive( + RTEMS_EVENT_SYSTEM_TRANSIENT, + RTEMS_EVENT_ALL | option_set, + ticks, + &event_out + ); +} + +/** + * @brief See rtems_event_system_receive(). + * + * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be cleared. + */ +RTEMS_INLINE_ROUTINE void rtems_event_transient_clear( void ) +{ + rtems_event_set event_out; + + rtems_event_system_receive( + RTEMS_EVENT_SYSTEM_TRANSIENT, + RTEMS_EVENT_ALL | RTEMS_NO_WAIT, + 0, + &event_out + ); +} + +/** @} */ + +typedef struct { + rtems_event_set pending_events; +} Event_Control; + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/eventimpl.h b/cpukit/include/rtems/rtems/eventimpl.h new file mode 100644 index 0000000000..933ea0fe2b --- /dev/null +++ b/cpukit/include/rtems/rtems/eventimpl.h @@ -0,0 +1,146 @@ +/** + * @file + * + * @ingroup ClassicEventImpl + * + * @brief Classic Event Implementation + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_EVENTIMPL_H +#define _RTEMS_RTEMS_EVENTIMPL_H + +#include <rtems/rtems/event.h> +#include <rtems/score/thread.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicEventImpl Classic Event Implementation + * + * @ingroup ClassicEvent + * + * @{ + */ + +/** + * This constant is passed as the event_in to the + * rtems_event_receive directive to determine which events are pending. + */ +#define EVENT_CURRENT 0 + +/** + * The following constant is the value of an event set which + * has no events pending. + */ +#define EVENT_SETS_NONE_PENDING 0 + +rtems_status_code _Event_Seize( + rtems_event_set event_in, + rtems_option option_set, + rtems_interval ticks, + rtems_event_set *event_out, + Thread_Control *executing, + Event_Control *event, + Thread_Wait_flags wait_class, + States_Control block_state, + ISR_lock_Context *lock_context +); + +rtems_status_code _Event_Surrender( + Thread_Control *the_thread, + rtems_event_set event_in, + Event_Control *event, + Thread_Wait_flags wait_class, + ISR_lock_Context *lock_context +); + +/** + * @brief Timeout Event + */ +void _Event_Timeout( + Objects_Id id, + void *arg +); + +RTEMS_INLINE_ROUTINE void _Event_Initialize( Event_Control *event ) +{ + event->pending_events = EVENT_SETS_NONE_PENDING; +} + +/** + * @brief Checks if on events are posted in the event_set. + * + * This function returns TRUE if on events are posted in the event_set, + * and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Event_sets_Is_empty( + rtems_event_set the_event_set +) +{ + return ( the_event_set == 0 ); +} + +/** + * @brief Posts the given new_events into the event_set passed in. + * + * This routine posts the given new_events into the event_set + * passed in. The result is returned to the user in event_set. + */ +RTEMS_INLINE_ROUTINE void _Event_sets_Post( + rtems_event_set the_new_events, + rtems_event_set *the_event_set +) +{ + *the_event_set |= the_new_events; +} + +/** + * @brief Returns the events in event_condition that are set in event_set. + * + * This function returns the events in event_condition which are + * set in event_set. + */ +RTEMS_INLINE_ROUTINE rtems_event_set _Event_sets_Get( + rtems_event_set the_event_set, + rtems_event_set the_event_condition +) +{ + return ( the_event_set & the_event_condition ); +} + +/** + * @brief Removes the events in mask from the event_set passed in. + * + * This function removes the events in mask from the event_set + * passed in. The result is returned to the user in event_set. + */ +RTEMS_INLINE_ROUTINE rtems_event_set _Event_sets_Clear( + rtems_event_set the_event_set, + rtems_event_set the_mask +) +{ + return ( the_event_set & ~(the_mask) ); +} + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/rtems/eventmp.h> +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/eventmp.h b/cpukit/include/rtems/rtems/eventmp.h new file mode 100644 index 0000000000..a80e60c4e0 --- /dev/null +++ b/cpukit/include/rtems/rtems/eventmp.h @@ -0,0 +1,101 @@ +/** + * @file rtems/rtems/eventmp.h + * + * @defgroup ClassicEventMP Event MP Support + * + * @ingroup ClassicRTEMS + * @brief Event Manager MP Support + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Event Manager. + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_EVENTMP_H +#define _RTEMS_RTEMS_EVENTMP_H + +#ifndef _RTEMS_RTEMS_EVENTIMPL_H +# error "Never use <rtems/rtems/eventmp.h> directly; include <rtems/rtems/eventimpl.h> instead." +#endif + +#include <rtems/score/mpciimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicEventMP Event MP Support + * + * @ingroup ClassicMP + * + * This encapsulates functionality related to the transparent multiprocessing + * support within the Classic API Event Manager. + */ +/**@{*/ + +/* + * @brief Event_MP_Send_process_packet + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + * + * @note This routine is not needed since there are no process + * packets to be sent by this manager. + */ + +/** + * @brief Issues a remote rtems_event_send() request. + */ +rtems_status_code _Event_MP_Send( + rtems_id id, + rtems_event_set event_in +); + +/** + * @brief Event MP Packet Process + * + * This routine performs the actions specific to this package for + * the request from another node. + */ +void _Event_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +); + +/* + * @brief Event_MP_Send_object_was_deleted + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + * + * This routine is not needed since there are no objects + * deleted by this manager. + */ + +/* + * @brief Event_MP_Send_extract_proxy + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + * + * This routine is not needed since there are no objects + * deleted by this manager. + */ + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of file */ diff --git a/cpukit/include/rtems/rtems/intr.h b/cpukit/include/rtems/rtems/intr.h new file mode 100644 index 0000000000..7f99d93883 --- /dev/null +++ b/cpukit/include/rtems/rtems/intr.h @@ -0,0 +1,373 @@ +/** + * @file rtems/rtems/intr.h + * + * @defgroup ClassicINTR Interrupts + * + * @ingroup ClassicRTEMS + * @brief Header file for Interrupt Manager + * + * This include file contains all the constants and structures associated with + * the Interrupt Manager. + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_INTR_H +#define _RTEMS_RTEMS_INTR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/rtems/status.h> +#include <rtems/score/isr.h> +#include <rtems/score/isrlock.h> + +/** + * @defgroup ClassicINTR Interrupts + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the Classic API Interrupt + * Manager. + */ +/**@{*/ + +/** + * @brief Interrupt level type. + */ +typedef ISR_Level rtems_interrupt_level; + +/** + * @brief Control block type used to manage the vectors. + */ +typedef ISR_Vector_number rtems_vector_number; + +/** + * @brief Return type for interrupt handler. + */ +typedef ISR_Handler rtems_isr; + +#if (CPU_SIMPLE_VECTORED_INTERRUPTS == FALSE) + +typedef ISR_Handler_entry rtems_isr_entry; + +#else +/** + * @brief Interrupt handler type. + * + * @see rtems_interrupt_catch() + */ +typedef rtems_isr ( *rtems_isr_entry )( + rtems_vector_number + ); + +/** + * @brief RTEMS Interrupt Catch + * + * This directive installs @a new_isr_handler as the RTEMS interrupt service + * routine for the interrupt vector with number @a vector. The previous RTEMS + * interrupt service routine is returned in @a old_isr_handler. + * + * @param[in] new_isr_handler is the address of interrupt service routine + * @param[in] vector is the interrupt vector number + * @param[in] old_isr_handler address at which to store previous ISR address + * + * @retval RTEMS_SUCCESSFUL and *old_isr_handler filled with previous ISR + * address + */ +rtems_status_code rtems_interrupt_catch( + rtems_isr_entry new_isr_handler, + rtems_vector_number vector, + rtems_isr_entry *old_isr_handler +); +#endif + +#if !defined(RTEMS_SMP) + +/** + * @brief Disable RTEMS Interrupt + * + * @note The interrupt level shall be of type @ref rtems_interrupt_level. + * + * This macro is only available on uni-processor configurations. The macro + * rtems_interrupt_local_disable() is available on all configurations. + */ +#define rtems_interrupt_disable( _isr_cookie ) \ + _ISR_Local_disable(_isr_cookie) + +/** + * @brief Enable RTEMS Interrupt + * + * @note The interrupt level shall be of type @ref rtems_interrupt_level. + * + * This macro is only available on uni-processor configurations. The macro + * rtems_interrupt_local_enable() is available on all configurations. + */ +#define rtems_interrupt_enable( _isr_cookie ) \ + _ISR_Local_enable(_isr_cookie) + +/** + * @brief Flash RTEMS Interrupt + * + * @note The interrupt level shall be of type @ref rtems_interrupt_level. + * + * This macro is only available on uni-processor configurations. The macro + * rtems_interrupt_local_disable() and rtems_interrupt_local_enable() is + * available on all configurations. + */ +#define rtems_interrupt_flash( _isr_cookie ) \ + _ISR_Local_flash(_isr_cookie) + +#endif /* RTEMS_SMP */ + +/** + * @brief This macro disables the interrupts on the current processor. + * + * On SMP configurations this will not ensure system wide mutual exclusion. + * Use interrupt locks instead. + * + * @param[in] _isr_cookie The previous interrupt level is returned. The type + * of this variable must be rtems_interrupt_level. + * + * @see rtems_interrupt_local_enable(). + */ +#define rtems_interrupt_local_disable( _isr_cookie ) \ + _ISR_Local_disable( _isr_cookie ) + +/** + * @brief This macro restores the previous interrupt level on the current + * processor. + * + * @param[in] _isr_cookie The previous interrupt level returned by + * rtems_interrupt_local_disable(). + */ +#define rtems_interrupt_local_enable( _isr_cookie ) \ + _ISR_Local_enable( _isr_cookie ) + +/** + * @brief RTEMS Interrupt Is in Progress + * + * A return value of true indicates that the caller is an interrupt service + * routine and @b not a thread. The directives available to an interrupt + * service routine are restricted. + */ +#define rtems_interrupt_is_in_progress() \ + _ISR_Is_in_progress() + +/** + * @brief This routine generates an interrupt. + * + * @note No implementation. + */ +#define rtems_interrupt_cause( _interrupt_to_cause ) + +/** + * @brief This routine clears the specified interrupt. + * + * @note No implementation. + */ +#define rtems_interrupt_clear( _interrupt_to_clear ) + +/** + * @defgroup ClassicINTRLocks Interrupt Locks + * + * @ingroup ClassicINTR + * + * @brief Low-level lock to protect critical sections accessed by threads and + * interrupt service routines. + * + * On single processor configurations the interrupt locks degrade to simple + * interrupt disable/enable sequences. No additional storage or objects are + * required. + * + * This synchronization primitive is supported on SMP configurations. Here SMP + * locks are used. + * @{ + */ + +/** + * @brief Interrupt lock control. + */ +typedef ISR_lock_Control rtems_interrupt_lock; + +/** + * @brief Local interrupt lock context for acquire and release pairs. + */ +typedef ISR_lock_Context rtems_interrupt_lock_context; + +/** + * @brief Defines an interrupt lock member. + * + * Do not add a ';' after this macro. + * + * @param _designator The designator for the interrupt lock. + */ +#define RTEMS_INTERRUPT_LOCK_MEMBER( _designator ) \ + ISR_LOCK_MEMBER( _designator ) + +/** + * @brief Declares an interrupt lock variable. + * + * Do not add a ';' after this macro. + * + * @param _qualifier The qualifier for the interrupt lock, e.g. extern. + * @param _designator The designator for the interrupt lock. + */ +#define RTEMS_INTERRUPT_LOCK_DECLARE( _qualifier, _designator ) \ + ISR_LOCK_DECLARE( _qualifier, _designator ) + +/** + * @brief Defines an interrupt lock variable. + * + * Do not add a ';' after this macro. + * + * @param _qualifier The qualifier for the interrupt lock, e.g. static. + * @param _designator The designator for the interrupt lock. + * @param _name The name for the interrupt lock. It must be a string. The + * name is only used if profiling is enabled. + */ +#define RTEMS_INTERRUPT_LOCK_DEFINE( _qualifier, _designator, _name ) \ + ISR_LOCK_DEFINE( _qualifier, _designator, _name ) + +/** + * @brief Defines an interrupt lock variable reference. + * + * Do not add a ';' after this macro. + * + * @param _designator The designator for the interrupt lock reference. + * @param _target The target for the interrupt lock reference. + */ +#define RTEMS_INTERRUPT_LOCK_REFERENCE( _designator, _target ) \ + ISR_LOCK_REFERENCE( _designator, _target ) + +/** + * @brief Initializer for static initialization of interrupt locks. + * + * @param _name The name for the interrupt lock. It must be a string. The + * name is only used if profiling is enabled. + */ +#define RTEMS_INTERRUPT_LOCK_INITIALIZER( _name ) ISR_LOCK_INITIALIZER( _name ) + +/** + * @brief Initializes an interrupt lock. + * + * Concurrent initialization leads to unpredictable results. + * + * @param[in,out] _lock The interrupt lock. + * @param[in] _name The name for the interrupt lock. This name must be a + * string persistent throughout the life time of this lock. The name is only + * used if profiling is enabled. + */ +#define rtems_interrupt_lock_initialize( _lock, _name ) \ + _ISR_lock_Initialize( _lock, _name ) + +/** + * @brief Destroys an interrupt lock. + * + * Concurrent destruction leads to unpredictable results. + * + * @param[in,out] _lock The interrupt lock control. + */ +#define rtems_interrupt_lock_destroy( _lock ) \ + _ISR_lock_Destroy( _lock ) + +/** + * @brief Disables interrupts on the current processor. + * + * This function can be used in thread and interrupt context. + * + * @param[in,out] _lock_context The local interrupt lock context for an acquire + * and release pair. + * + * @see rtems_interrupt_lock_acquire_isr(). + */ +#define rtems_interrupt_lock_interrupt_disable( _lock_context ) \ + _ISR_lock_ISR_disable( _lock_context ) + +/** + * @brief Acquires an interrupt lock. + * + * Interrupts will be disabled. On SMP configurations this function acquires + * an SMP lock. + * + * This function can be used in thread and interrupt context. + * + * @param[in,out] _lock The interrupt lock. + * @param[in,out] _lock_context The local interrupt lock context for an acquire + * and release pair. + * + * @see rtems_interrupt_lock_release(). + */ +#define rtems_interrupt_lock_acquire( _lock, _lock_context ) \ + _ISR_lock_ISR_disable_and_acquire( _lock, _lock_context ) + +/** + * @brief Releases an interrupt lock. + * + * The interrupt status will be restored. On SMP configurations this function + * releases an SMP lock. + * + * This function can be used in thread and interrupt context. + * + * @param[in,out] _lock The interrupt lock. + * @param[in,out] _lock_context The local interrupt lock context for an acquire + * and release pair. + * + * @see rtems_interrupt_lock_acquire(). + */ +#define rtems_interrupt_lock_release( _lock, _lock_context ) \ + _ISR_lock_Release_and_ISR_enable( _lock, _lock_context ) + +/** + * @brief Acquires an interrupt lock in the corresponding interrupt service + * routine. + * + * The interrupt status will remain unchanged. On SMP configurations this + * function acquires an SMP lock. + * + * In case the corresponding interrupt service routine can be interrupted by + * higher priority interrupts and these interrupts enter the critical section + * protected by this lock, then the result is unpredictable. + * + * @param[in,out] _lock The interrupt lock. + * @param[in,out] _lock_context The local interrupt lock context for an acquire + * and release pair. + * + * @see rtems_interrupt_lock_release_isr(). + */ +#define rtems_interrupt_lock_acquire_isr( _lock, _lock_context ) \ + _ISR_lock_Acquire( _lock, _lock_context ) + +/** + * @brief Releases an interrupt lock in the corresponding interrupt service + * routine. + * + * The interrupt status will remain unchanged. On SMP configurations this + * function releases an SMP lock. + * + * @param[in,out] _lock The interrupt lock. + * @param[in,out] _lock_context The local interrupt lock context for an acquire + * and release pair. + * + * @see rtems_interrupt_lock_acquire_isr(). + */ +#define rtems_interrupt_lock_release_isr( _lock, _lock_context ) \ + _ISR_lock_Release( _lock, _lock_context ) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/mainpage.h b/cpukit/include/rtems/rtems/mainpage.h new file mode 100644 index 0000000000..e2d51328cf --- /dev/null +++ b/cpukit/include/rtems/rtems/mainpage.h @@ -0,0 +1,927 @@ +/** + * @file rtems/rtems/mainpage.h + * + * This file exists to provide a top level description of RTEMS for Doxygen. + */ + +/* + * COPYRIGHT (c) 1989-2014. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +/** + * @mainpage + * + * The RTEMS real-time operating systems is a layered system with each of the + * public APIs implemented in terms of a common foundation layer called the + * SuperCore. This is the Doxygen generated documentation for the RTEMS CPU + * Kit including the Classic API, POSIX API and SuperCore. + */ + +/** + * @page RTEMSPreface RTEMS History and Introduction + * + * In recent years, the cost required to develop a software product has + * increased significantly while the target hardware costs have decreased. Now + * a larger portion of money is expended in developing, using, and maintaining + * software. The trend in computing costs is the complete dominance of software + * over hardware costs. Because of this, it is necessary that formal + * disciplines be established to increase the probability that software is + * characterized by a high degree of correctness, maintainability, and + * portability. In addition, these disciplines must promote practices that aid + * in the consistent and orderly development of a software system within + * schedule and budgetary constraints. To be effective, these disciplines must + * adopt standards which channel individual software efforts toward a common + * goal. + * + * The push for standards in the software development field has been met with + * various degrees of success. The Microprocessor Operating Systems Interfaces + * (MOSI) effort has experienced only limited success. As popular as the UNIX + * operating system has grown, the attempt to develop a standard interface + * definition to allow portable application development has only recently begun + * to produce the results needed in this area. Unfortunately, very little + * effort has been expended to provide standards addressing the needs of the + * real-time community. Several organizations have addressed this need during + * recent years. + * + * The Real Time Executive Interface Definition (RTEID) was developed by + * Motorola with technical input from Software Components Group. RTEID was + * adopted by the VMEbus International Trade Association (VITA) as a baseline + * draft for their proposed standard multiprocessor, real-time executive + * interface, Open Real-Time Kernel Interface Definition (ORKID). These two + * groups are currently working together with the IEEE P1003.4 committee to + * insure that the functionality of their proposed standards is adopted as the + * real-time extensions to POSIX. + * + * This emerging standard defines an interface for the development of real-time + * software to ease the writing of real-time application programs that are + * directly portable across multiple real-time executive implementations. This + * interface includes both the source code interfaces and run-time behavior as + * seen by a real-time application. It does not include the details of how a + * kernel implements these functions. The standard's goal is to serve as a + * complete definition of external interfaces so that application code that + * conforms to these interfaces will execute properly in all real-time + * executive environments. With the use of a standards compliant executive, + * routines that acquire memory blocks, create and manage message queues, + * establish and use semaphores, and send and receive signals need not be + * redeveloped for a different real-time environment as long as the new + * environment is compliant with the standard. Software developers need only + * concentrate on the hardware dependencies of the real-time system. + * Furthermore, most hardware dependencies for real-time applications can be + * localized to the device drivers. + * + * A compliant executive provides simple and flexible real-time + * multiprocessing. It easily lends itself to both tightly-coupled and + * loosely-coupled configurations (depending on the system hardware + * configuration). Objects such as tasks, queues, events, signals, semaphores, + * and memory blocks can be designated as global objects and accessed by any + * task regardless of which processor the object and the accessing task reside. + * + * The acceptance of a standard for real-time executives will produce the same + * advantages enjoyed from the push for UNIX standardization by AT&T's System V + * Interface Definition and IEEE's POSIX efforts. A compliant multiprocessing + * executive will allow close coupling between UNIX systems and real-time + * executives to provide the many benefits of the UNIX development environment + * to be applied to real-time software development. Together they provide the + * necessary laboratory environment to implement real-time, distributed, + * embedded systems using a wide variety of computer architectures. + * + * A study was completed in 1988, within the Research, Development, and + * Engineering Center, U.S. Army Missile Command, which compared the various + * aspects of the Ada programming language as they related to the application + * of Ada code in distributed and/or multiple processing systems. Several + * critical conclusions were derived from the study. These conclusions have a + * major impact on the way the Army develops application software for embedded + * applications. These impacts apply to both in-house software development and + * contractor developed software. + * + * A conclusion of the analysis, which has been previously recognized by other + * agencies attempting to utilize Ada in a distributed or multiprocessing + * environment, is that the Ada programming language does not adequately + * support multiprocessing. Ada does provide a mechanism for multi-tasking, + * however, this capability exists only for a single processor system. The + * language also does not have inherent capabilities to access global named + * variables, flags or program code. These critical features are essential in + * order for data to be shared between processors. However, these drawbacks do + * have workarounds which are sometimes awkward and defeat the intent of + * software maintainability and portability goals. + * + * Another conclusion drawn from the analysis, was that the run time executives + * being delivered with the Ada compilers were too slow and inefficient to be + * used in modern missile systems. A run time executive is the core part of the + * run time system code, or operating system code, that controls task + * scheduling, input/output management and memory management. Traditionally, + * whenever efficient executive (also known as kernel) code was required by the + * application, the user developed in-house software. This software was usually + * written in assembly language for optimization. + * + * Because of this shortcoming in the Ada programming language, software + * developers in research and development and contractors for project managed + * systems, are mandated by technology to purchase and utilize off-the-shelf + * third party kernel code. The contractor, and eventually the Government, must + * pay a licensing fee for every copy of the kernel code used in an embedded + * system. + * + * The main drawback to this development environment is that the Government + * does not own, nor has the right to modify code contained within the kernel. + * V&V techniques in this situation are more difficult than if the complete + * source code were available. Responsibility for system failures due to faulty + * software is yet another area to be resolved under this environment. + * + * The Guidance and Control Directorate began a software development effort to + * address these problems. A project to develop an experimental run time kernel + * was begun that will eliminate the major drawbacks of the Ada programming + * language mentioned above. The Real Time Executive for Multiprocessor Systems + * (RTEMS) provides full capabilities for management of tasks, interrupts, + * time, and multiple processors in addition to those features typical of + * generic operating systems. The code is Government owned, so no licensing + * fees are necessary. RTEMS has been implemented in both the Ada and C + * programming languages. It has been ported to the following processor + * families: + * + * - Altera NIOS II + * - Analog Devices Blackfin + * - ARM + * - Freescale (formerly Motorola) MC68xxx + * - Freescale (formerly Motorola) MC683xx + * - Freescale (formerly Motorola) ColdFire + * - Intel i386 and above + * - Lattice Semiconductor LM32 + * - MIPS + * - PowerPC + * - Renesas (formerly Hitachi) SuperH + * - Renesas (formerly Hitachi) H8/300 + * - SPARC + * - Texas Instruments C3x/C4x + * - UNIX + * + * Support for other processor families, including RISC, CISC, and DSP, is + * planned. Since almost all of RTEMS is written in a high level language, + * ports to additional processor families require minimal effort. + * + * RTEMS multiprocessor support is capable of handling either homogeneous or + * heterogeneous systems. The kernel automatically compensates for + * architectural differences (byte swapping, etc.) between processors. This + * allows a much easier transition from one processor family to another without + * a major system redesign. + * + * Since the proposed standards are still in draft form, RTEMS cannot and does + * not claim compliance. However, the status of the standard is being carefully + * monitored to guarantee that RTEMS provides the functionality specified in + * the standard. Once approved, RTEMS will be made compliant. + */ + +/** + * @page RTEMSOverview RTEMS Overview + * + * @section RTEMSOverviewSecIntroduction Introduction + * + * RTEMS, Real-Time Executive for Multiprocessor Systems, is a real-time + * executive (kernel) which provides a high performance environment for + * embedded military applications including the following features: + * + * - multitasking capabilities + * - homogeneous and heterogeneous multiprocessor systems + * - event-driven, priority-based, preemptive scheduling + * - optional rate monotonic scheduling + * - intertask communication and synchronization + * - priority inheritance + * - responsive interrupt management + * - dynamic memory allocation + * - high level of user configurability + * + * This manual describes the usage of RTEMS for applications written in the C + * programming language. Those implementation details that are processor + * dependent are provided in the Applications Supplement documents. A + * supplement document which addresses specific architectural issues that + * affect RTEMS is provided for each processor type that is supported. + * + * @section RTEMSOverviewSecRealtimeApplicationSystems Real-time Application Systems + * + * Real-time application systems are a special class of computer applications. + * They have a complex set of characteristics that distinguish them from other + * software problems. Generally, they must adhere to more rigorous + * requirements. The correctness of the system depends not only on the results + * of computations, but also on the time at which the results are produced. The + * most important and complex characteristic of real-time application systems + * is that they must receive and respond to a set of external stimuli within + * rigid and critical time constraints referred to as deadlines. Systems can be + * buried by an avalanche of interdependent, asynchronous or cyclical event + * streams. + * + * Deadlines can be further characterized as either hard or soft based upon the + * value of the results when produced after the deadline has passed. A deadline + * is hard if the results have no value or if their use will result in a + * catastrophic event. In contrast, results which are produced after a soft + * deadline may have some value. + * + * Another distinguishing requirement of real-time application systems is the + * ability to coordinate or manage a large number of concurrent activities. + * Since software is a synchronous entity, this presents special problems. One + * instruction follows another in a repeating synchronous cycle. Even though + * mechanisms have been developed to allow for the processing of external + * asynchronous events, the software design efforts required to process and + * manage these events and tasks are growing more complicated. + * + * The design process is complicated further by spreading this activity over a + * set of processors instead of a single processor. The challenges associated + * with designing and building real-time application systems become very + * complex when multiple processors are involved. New requirements such as + * interprocessor communication channels and global resources that must be + * shared between competing processors are introduced. The ramifications of + * multiple processors complicate each and every characteristic of a real-time + * system. + * + * @section RTEMSOverviewSecRealtimeExecutive Real-time Executive + * + * Fortunately, real-time operating systems or real-time executives serve as a + * cornerstone on which to build the application system. A real-time + * multitasking executive allows an application to be cast into a set of + * logical, autonomous processes or tasks which become quite manageable. Each + * task is internally synchronous, but different tasks execute independently, + * resulting in an asynchronous processing stream. Tasks can be dynamically + * paused for many reasons resulting in a different task being allowed to + * execute for a period of time. The executive also provides an interface to + * other system components such as interrupt handlers and device drivers. + * System components may request the executive to allocate and coordinate + * resources, and to wait for and trigger synchronizing conditions. The + * executive system calls effectively extend the CPU instruction set to support + * efficient multitasking. By causing tasks to travel through well-defined + * state transitions, system calls permit an application to demand-switch + * between tasks in response to real-time events. + * + * By proper grouping of responses to stimuli into separate tasks, a system can + * now asynchronously switch between independent streams of execution, directly + * responding to external stimuli as they occur. This allows the system design + * to meet critical performance specifications which are typically measured by + * guaranteed response time and transaction throughput. The multiprocessor + * extensions of RTEMS provide the features necessary to manage the extra + * requirements introduced by a system distributed across several processors. + * It removes the physical barriers of processor boundaries from the world of + * the system designer, enabling more critical aspects of the system to receive + * the required attention. Such a system, based on an efficient real-time, + * multiprocessor executive, is a more realistic model of the outside world or + * environment for which it is designed. As a result, the system will always be + * more logical, efficient, and reliable. + * + * By using the directives provided by RTEMS, the real-time applications + * developer is freed from the problem of controlling and synchronizing + * multiple tasks and processors. In addition, one need not develop, test, + * debug, and document routines to manage memory, pass messages, or provide + * mutual exclusion. The developer is then able to concentrate solely on the + * application. By using standard software components, the time and cost + * required to develop sophisticated real-time applications is significantly + * reduced. + * + * @section RTEMSOverviewSecApplicationArchitecture RTEMS Application Architecture + * + * One important design goal of RTEMS was to provide a bridge between two + * critical layers of typical real-time systems. As shown in the following + * figure, RTEMS serves as a buffer between the project dependent application + * code and the target hardware. Most hardware dependencies for real-time + * applications can be localized to the low level device drivers. + * + * @todo Image RTEMS Application Architecture + * + * The RTEMS I/O interface manager provides an efficient tool for incorporating + * these hardware dependencies into the system while simultaneously providing a + * general mechanism to the application code that accesses them. A well + * designed real-time system can benefit from this architecture by building a + * rich library of standard application components which can be used repeatedly + * in other real-time projects. + * + * @section RTEMSOverviewSecInternalArchitecture RTEMS Internal Architecture + * + * RTEMS can be viewed as a set of layered components that work in harmony to + * provide a set of services to a real-time application system. The executive + * interface presented to the application is formed by grouping directives into + * logical sets called resource managers. Functions utilized by multiple + * managers such as scheduling, dispatching, and object management are provided + * in the executive core. The executive core depends on a small set of CPU + * dependent routines. Together these components provide a powerful run time + * environment that promotes the development of efficient real-time application + * systems. The following figure illustrates this organization: + * + * @todo Image RTEMS Architecture + * + * Subsequent chapters present a detailed description of the capabilities + * provided by each of the following RTEMS managers: + * + * - initialization + * - task + * - interrupt + * - clock + * - timer + * - semaphore + * - message + * - event + * - signal + * - partition + * - region + * - dual ported memory + * - I/O + * - fatal error + * - rate monotonic + * - user extensions + * - multiprocessing + * + * @section RTEMSOverviewSecUserCustomization User Customization and Extensibility + * + * As 32-bit microprocessors have decreased in cost, they have become + * increasingly common in a variety of embedded systems. A wide range of custom + * and general-purpose processor boards are based on various 32-bit + * processors. RTEMS was designed to make no assumptions concerning the + * characteristics of individual microprocessor families or of specific support + * hardware. In addition, RTEMS allows the system developer a high degree of + * freedom in customizing and extending its features. + * + * RTEMS assumes the existence of a supported microprocessor and sufficient + * memory for both RTEMS and the real-time application. Board dependent + * components such as clocks, interrupt controllers, or I/O devices can be + * easily integrated with RTEMS. The customization and extensibility features + * allow RTEMS to efficiently support as many environments as possible. + * + * @section RTEMSOverviewSecPortability Portability + * + * The issue of portability was the major factor in the creation of RTEMS. + * Since RTEMS is designed to isolate the hardware dependencies in the specific + * board support packages, the real-time application should be easily ported to + * any other processor. The use of RTEMS allows the development of real-time + * applications which can be completely independent of a particular + * microprocessor architecture. + * + * @section RTEMSOverviewSecMemoryRequirements Memory Requirements + * + * Since memory is a critical resource in many real-time embedded systems, + * RTEMS was specifically designed to automatically leave out all services that + * are not required from the run-time environment. Features such as networking, + * various fileystems, and many other features are completely optional. This + * allows the application designer the flexibility to tailor RTEMS to most + * efficiently meet system requirements while still satisfying even the most + * stringent memory constraints. As a result, the size of the RTEMS executive + * is application dependent. + * + * RTEMS requires RAM to manage each instance of an RTEMS object that is + * created. Thus the more RTEMS objects an application needs, the more memory + * that must be reserved. See Configuring a System Determining Memory + * Requirements for more details. + * + * @todo Link to Configuring a SystemDetermining Memory Requirements + * + * RTEMS utilizes memory for both code and data space. Although RTEMS' data + * space must be in RAM, its code space can be located in either ROM or RAM. + * + * @section RTEMSOverviewSecAudience Audience + * + * This manual was written for experienced real-time software developers. + * Although some background is provided, it is assumed that the reader is + * familiar with the concepts of task management as well as intertask + * communication and synchronization. Since directives, user related data + * structures, and examples are presented in C, a basic understanding of the C + * programming language is required to fully understand the material presented. + * However, because of the similarity of the Ada and C RTEMS implementations, + * users will find that the use and behavior of the two implementations is very + * similar. A working knowledge of the target processor is helpful in + * understanding some of RTEMS' features. A thorough understanding of the + * executive cannot be obtained without studying the entire manual because many + * of RTEMS' concepts and features are interrelated. Experienced RTEMS users + * will find that the manual organization facilitates its use as a reference + * document. + */ + +/** + * @addtogroup ClassicAPI + * + * The facilities provided by RTEMS are built upon a foundation of very + * powerful concepts. These concepts must be understood before the application + * developer can efficiently utilize RTEMS. The purpose of this chapter is to + * familiarize one with these concepts. + * + * @section ClassicRTEMSSecObjects Objects + * + * RTEMS provides directives which can be used to dynamically create, delete, + * and manipulate a set of predefined object types. These types include tasks, + * message queues, semaphores, memory regions, memory partitions, timers, + * ports, and rate monotonic periods. The object-oriented nature of RTEMS + * encourages the creation of modular applications built upon re-usable + * "building block" routines. + * + * All objects are created on the local node as required by the application and + * have an RTEMS assigned ID. All objects have a user-assigned name. Although a + * relationship exists between an object's name and its RTEMS assigned ID, the + * name and ID are not identical. Object names are completely arbitrary and + * selected by the user as a meaningful "tag" which may commonly reflect the + * object's use in the application. Conversely, object IDs are designed to + * facilitate efficient object manipulation by the executive. + * + * @subsection ClassicRTEMSSubSecObjectNames Object Names + * + * An object name is an unsigned 32-bit entity associated with the + * object by the user. The data type @ref rtems_name is used to store object names. + * + * Although not required by RTEMS, object names are often composed of four + * ASCII characters which help identify that object. For example, a task which + * causes a light to blink might be called "LITE". The rtems_build_name() + * routine is provided to build an object name from four ASCII characters. The + * following example illustrates this: + * + * @code + * rtems_name my_name = rtems_build_name('L', 'I', 'T', 'E'); + * @endcode + * + * However, it is not required that the application use ASCII characters to + * build object names. For example, if an application requires one-hundred + * tasks, it would be difficult to assign meaningful ASCII names to each task. + * A more convenient approach would be to name them the binary values one + * through one-hundred, respectively. + * + * RTEMS provides a helper routine, rtems_object_get_name(), which can be used to + * obtain the name of any RTEMS object using just its ID. This routine attempts + * to convert the name into a printable string. + * + * @subsection ClassicRTEMSSubSecObjectIdentifiers Object Identifiers + * + * An object ID is a unique unsigned integer value which uniquely identifies an + * object instance. Object IDs are passed as arguments to many directives in + * RTEMS and RTEMS translates the ID to an internal object pointer. The + * efficient manipulation of object IDs is critical to the performance of RTEMS + * services. Because of this, there are two object ID formats defined. Each + * target architecture specifies which format it will use. There is a 32-bit + * format which is used for most of the supported architectures and supports + * multiprocessor configurations. There is also a simpler 16-bit format which + * is appropriate for smaller target architectures and does not support + * multiprocessor configurations. + * + * @subsubsection ClassicRTEMSSubSec32BitObjectIdentifierFormat 32-Bit Object Identifier Format + * + * The 32-bit format for an object ID is composed of four parts: API, + * object class, node, and index. The data type @ref rtems_id is used to store + * object IDs. + * + * <table> + * <tr> + * <th>Bits</th> + * <td>31</td><td>30</td><td>29</td><td>28</td><td>27</td><td>26</td><td>25</td><td>24</td> + * <td>23</td><td>22</td><td>21</td><td>20</td><td>19</td><td>18</td><td>17</td><td>16</td> + * <td>15</td><td>14</td><td>13</td><td>12</td><td>11</td><td>10</td><td>09</td><td>08</td> + * <td>07</td><td>06</td><td>05</td><td>04</td><td>03</td><td>02</td><td>01</td><td>00</td> + * </tr> + * <tr> + * <th>Contents</th> + * <td colspan=5>Class</td><td colspan=3>API</td><td colspan=8>Node</td><td colspan=16>Object Index</td> + * </tr> + * </table> + * + * The most significant five bits are the object class. The next three bits + * indicate the API to which the object class belongs. The next eight bits + * (16 .. 23) are the number of the node on which this object was created. The + * node number is always one (1) in a single processor system. The least + * significant 16-bits form an identifier within a particular object type. + * This identifier, called the object index, ranges in value from one to the + * maximum number of objects configured for this object type. + * + * @subsubsection ClassicRTEMSSubSec16BitObjectIdentifierFormat 16-Bit Object Identifier Format + * + * The 16-bit format for an object ID is composed of three parts: API, object + * class, and index. The data type @ref rtems_id is used to store object IDs. + * + * <table> + * <tr> + * <th>Bits</th> + * <td>15</td><td>14</td><td>13</td><td>12</td><td>11</td><td>10</td><td>09</td><td>08</td> + * <td>07</td><td>06</td><td>05</td><td>04</td><td>03</td><td>02</td><td>01</td><td>00</td> + * </tr> + * <tr> + * <th>Contents</th> + * <td colspan=5>Class</td><td colspan=3>API</td><td colspan=8>Object Index</td> + * </tr> + * </table> + * + * The 16-bit format is designed to be as similar as possible to the 32-bit + * format. The differences are limited to the eliminatation of the node field + * and reduction of the index field from 16-bits to 8-bits. Thus the 16-bit + * format only supports up to 255 object instances per API/Class combination + * and single processor systems. As this format is typically utilized by 16-bit + * processors with limited address space, this is more than enough object + * instances. + * + * @subsection ClassicRTEMSSubSecObjectIdentiferDescription Object Identifer Description + * + * The components of an object ID make it possible to quickly locate any object + * in even the most complicated multiprocessor system. Object ID's are + * associated with an object by RTEMS when the object is created and the + * corresponding ID is returned by the appropriate object create directive. The + * object ID is required as input to all directives involving objects, except + * those which create an object or obtain the ID of an object. + * + * The object identification directives can be used to dynamically obtain a + * particular object's ID given its name. This mapping is accomplished by + * searching the name table associated with this object type. If the name is + * non-unique, then the ID associated with the first occurrence of the name + * will be returned to the application. Since object IDs are returned when the + * object is created, the object identification directives are not necessary in + * a properly designed single processor application. + * + * In addition, services are provided to portably examine the subcomponents of + * an RTEMS ID. These services are described in detail later in this manual but + * are prototyped as follows: + * + * - rtems_object_id_get_api() + * - rtems_object_id_get_class() + * - rtems_object_id_get_node() + * - rtems_object_id_get_index() + * + * An object control block is a data structure defined by RTEMS which contains + * the information necessary to manage a particular object type. For efficiency + * reasons, the format of each object type's control block is different. + * However, many of the fields are similar in function. The number of each type + * of control block is application dependent and determined by the values + * specified in the user's Configuration Table. An object control block is + * allocated at object create time and freed when the object is deleted. With + * the exception of user extension routines, object control blocks are not + * directly manipulated by user applications. + * + * @section ClassicRTEMSSecComSync Communication and Synchronization + * + * In real-time multitasking applications, the ability for cooperating + * execution threads to communicate and synchronize with each other is + * imperative. A real-time executive should provide an application with the + * following capabilities + * + * - data transfer between cooperating tasks, + * - data transfer between tasks and ISRs, + * - synchronization of cooperating tasks, and + * - synchronization of tasks and ISRs. + * + * Most RTEMS managers can be used to provide some form of communication and/or + * synchronization. However, managers dedicated specifically to communication + * and synchronization provide well established mechanisms which directly map + * to the application's varying needs. This level of flexibility allows the + * application designer to match the features of a particular manager with the + * complexity of communication and synchronization required. The following + * managers were specifically designed for communication and synchronization: + * + * - @ref ClassicSem + * - @ref ClassicMessageQueue + * - @ref ClassicEvent + * - @ref ClassicSignal + * + * The semaphore manager supports mutual exclusion involving the + * synchronization of access to one or more shared user resources. Binary + * semaphores may utilize the optional priority inheritance algorithm to avoid + * the problem of priority inversion. The message manager supports both + * communication and synchronization, while the event manager primarily + * provides a high performance synchronization mechanism. The signal manager + * supports only asynchronous communication and is typically used for exception + * handling. + * + * @section ClassicRTEMSSecTime Time + * + * The development of responsive real-time applications requires an + * understanding of how RTEMS maintains and supports time-related operations. + * The basic unit of time in RTEMS is known as a tick. The frequency of clock + * ticks is completely application dependent and determines the granularity and + * accuracy of all interval and calendar time operations. + * + * By tracking time in units of ticks, RTEMS is capable of supporting interval + * timing functions such as task delays, timeouts, timeslicing, the delayed + * execution of timer service routines, and the rate monotonic scheduling of + * tasks. An interval is defined as a number of ticks relative to the current + * time. For example, when a task delays for an interval of ten ticks, it is + * implied that the task will not execute until ten clock ticks have occurred. + * All intervals are specified using data type @ref rtems_interval. + * + * A characteristic of interval timing is that the actual interval period may + * be a fraction of a tick less than the interval requested. This occurs + * because the time at which the delay timer is set up occurs at some time + * between two clock ticks. Therefore, the first countdown tick occurs in less + * than the complete time interval for a tick. This can be a problem if the + * clock granularity is large. + * + * The rate monotonic scheduling algorithm is a hard real-time scheduling + * methodology. This methodology provides rules which allows one to guarantee + * that a set of independent periodic tasks will always meet their deadlines -- + * even under transient overload conditions. The rate monotonic manager + * provides directives built upon the Clock Manager's interval timer support + * routines. + * + * Interval timing is not sufficient for the many applications which require + * that time be kept in wall time or true calendar form. Consequently, RTEMS + * maintains the current date and time. This allows selected time operations to + * be scheduled at an actual calendar date and time. For example, a task could + * request to delay until midnight on New Year's Eve before lowering the ball + * at Times Square. The data type @ref rtems_time_of_day is used to specify + * calendar time in RTEMS services. See Clock Manager Time and Date Data + * Structures. + * + * @todo Link to Clock Manager Time and Date Data Structures + * + * Obviously, the directives which use intervals or wall time cannot operate + * without some external mechanism which provides a periodic clock tick. This + * clock tick is typically provided by a real time clock or counter/timer + * device. + * + * @section ClassicRTEMSSecMemoryManagement Memory Management + * + * RTEMS memory management facilities can be grouped into two classes: dynamic + * memory allocation and address translation. Dynamic memory allocation is + * required by applications whose memory requirements vary through the + * application's course of execution. Address translation is needed by + * applications which share memory with another CPU or an intelligent + * Input/Output processor. The following RTEMS managers provide facilities to + * manage memory: + * + * - @ref ClassicRegion + * - @ref ClassicPart + * - @ref ClassicDPMEM + * + * RTEMS memory management features allow an application to create simple + * memory pools of fixed size buffers and/or more complex memory pools of + * variable size segments. The partition manager provides directives to manage + * and maintain pools of fixed size entities such as resource control blocks. + * Alternatively, the region manager provides a more general purpose memory + * allocation scheme that supports variable size blocks of memory which are + * dynamically obtained and freed by the application. The dual-ported memory + * manager provides executive support for address translation between internal + * and external dual-ported RAM address space. + */ + +/** + * @addtogroup ClassicTasks + * + * @section ClassicTasksSecTaskDefinition Task Definition + * + * Many definitions of a task have been proposed in computer literature. + * Unfortunately, none of these definitions encompasses all facets of the + * concept in a manner which is operating system independent. Several of the + * more common definitions are provided to enable each user to select a + * definition which best matches their own experience and understanding of the + * task concept: + * + * - a "dispatchable" unit. + * - an entity to which the processor is allocated. + * - an atomic unit of a real-time, multiprocessor system. + * - single threads of execution which concurrently compete for resources. + * - a sequence of closely related computations which can execute concurrently + * with other computational sequences. + * + * From RTEMS' perspective, a task is the smallest thread of execution which + * can compete on its own for system resources. A task is manifested by the + * existence of a task control block (TCB). + * + * @section ClassicTasksSecTaskControlBlock Task Control Block + * + * The Task Control Block (TCB) is an RTEMS defined data structure which + * contains all the information that is pertinent to the execution of a task. + * During system initialization, RTEMS reserves a TCB for each task configured. + * A TCB is allocated upon creation of the task and is returned to the TCB free + * list upon deletion of the task. + * + * The TCB's elements are modified as a result of system calls made by the + * application in response to external and internal stimuli. TCBs are the only + * RTEMS internal data structure that can be accessed by an application via + * user extension routines. The TCB contains a task's name, ID, current + * priority, current and starting states, execution mode, TCB user extension + * pointer, scheduling control structures, as well as data required by a + * blocked task. + * + * A task's context is stored in the TCB when a task switch occurs. When the + * task regains control of the processor, its context is restored from the TCB. + * When a task is restarted, the initial state of the task is restored from the + * starting context area in the task's TCB. + * + * @section ClassicTasksSecTaskStates Task States + * + * A task may exist in one of the following five states: + * + * - executing - Currently scheduled to the CPU + * - ready - May be scheduled to the CPU + * - blocked - Unable to be scheduled to the CPU + * - dormant - Created task that is not started + * - non-existent - Uncreated or deleted task + * + * An active task may occupy the executing, ready, blocked or dormant state, + * otherwise the task is considered non-existent. One or more tasks may be + * active in the system simultaneously. Multiple tasks communicate, + * synchronize, and compete for system resources with each other via system + * calls. The multiple tasks appear to execute in parallel, but actually each + * is dispatched to the CPU for periods of time determined by the RTEMS + * scheduling algorithm. The scheduling of a task is based on its current state + * and priority. + * + * @section ClassicTasksSecTaskPriority Task Priority + * + * A task's priority determines its importance in relation to the other tasks + * executing on the same processor. RTEMS supports 255 levels of priority + * ranging from 1 to 255. The data type rtems_task_priority() is used to store + * task priorities. + * + * Tasks of numerically smaller priority values are more important tasks than + * tasks of numerically larger priority values. For example, a task at priority + * level 5 is of higher privilege than a task at priority level 10. There is no + * limit to the number of tasks assigned to the same priority. + * + * Each task has a priority associated with it at all times. The initial value + * of this priority is assigned at task creation time. The priority of a task + * may be changed at any subsequent time. + * + * Priorities are used by the scheduler to determine which ready task will be + * allowed to execute. In general, the higher the logical priority of a task, + * the more likely it is to receive processor execution time. + * + * @section ClassicTasksSecTaskMode Task Mode + * + * A task's execution mode is a combination of the following four components: + * + * - preemption + * - ASR processing + * - timeslicing + * - interrupt level + * + * It is used to modify RTEMS' scheduling process and to alter the execution + * environment of the task. The data type rtems_task_mode() is used to manage + * the task execution mode. + * + * The preemption component allows a task to determine when control of the + * processor is relinquished. If preemption is disabled (@c + * RTEMS_NO_PREEMPT), the task will retain control of the + * processor as long as it is in the executing state -- even if a higher + * priority task is made ready. If preemption is enabled (@c RTEMS_PREEMPT) + * and a higher priority task is made ready, then the processor will be + * taken away from the current task immediately and given to the higher + * priority task. + * + * The timeslicing component is used by the RTEMS scheduler to determine how + * the processor is allocated to tasks of equal priority. If timeslicing is + * enabled (@c RTEMS_TIMESLICE), then RTEMS will limit the amount of time the + * task can execute before the processor is allocated to another ready task of + * equal priority. The length of the timeslice is application dependent and + * specified in the Configuration Table. If timeslicing is disabled (@c + * RTEMS_NO_TIMESLICE), then the task will be allowed to + * execute until a task of higher priority is made ready. If @c + * RTEMS_NO_PREEMPT is selected, then the timeslicing component is ignored by + * the scheduler. + * + * The asynchronous signal processing component is used to determine when + * received signals are to be processed by the task. If signal processing is + * enabled (@c RTEMS_ASR), then signals sent to the task will be processed + * the next time the task executes. If signal processing is disabled (@c + * RTEMS_NO_ASR), then all signals received by the task will + * remain posted until signal processing is enabled. This component affects + * only tasks which have established a routine to process asynchronous signals. + * + * The interrupt level component is used to determine which interrupts will be + * enabled when the task is executing. @c RTEMS_INTERRUPT_LEVEL(n) specifies + * that the task will execute at interrupt level n. + * + * - @ref RTEMS_PREEMPT - enable preemption (default) + * - @ref RTEMS_NO_PREEMPT - disable preemption + * - @ref RTEMS_NO_TIMESLICE - disable timeslicing (default) + * - @ref RTEMS_TIMESLICE - enable timeslicing + * - @ref RTEMS_ASR - enable ASR processing (default) + * - @ref RTEMS_NO_ASR - disable ASR processing + * - @ref RTEMS_INTERRUPT_LEVEL(0) - enable all interrupts (default) + * - @ref RTEMS_INTERRUPT_LEVEL(n) - execute at interrupt level n + * + * The set of default modes may be selected by specifying the @ref + * RTEMS_DEFAULT_MODES constant. + * + * @section ClassicTasksSecAccessingTaskArguments Accessing Task Arguments + * + * All RTEMS tasks are invoked with a single argument which is specified when + * they are started or restarted. The argument is commonly used to communicate + * startup information to the task. The simplest manner in which to define a + * task which accesses it argument is: + * + * @code + * rtems_task user_task( + * rtems_task_argument argument + * ); + * @endcode + * + * Application tasks requiring more information may view this single argument + * as an index into an array of parameter blocks. + * + * @section ClassicTasksSecFloatingPointConsiderations Floating Point Considerations + * + * Creating a task with the @ref RTEMS_FLOATING_POINT attribute flag results in + * additional memory being allocated for the TCB to store the state of the + * numeric coprocessor during task switches. This additional memory is NOT + * allocated for @ref RTEMS_NO_FLOATING_POINT tasks. Saving and restoring the + * context of a @c RTEMS_FLOATING_POINT task takes longer than that of a @c + * RTEMS_NO_FLOATING_POINT task because of the relatively large amount of time + * required for the numeric coprocessor to save or restore its computational + * state. + * + * Since RTEMS was designed specifically for embedded military applications + * which are floating point intensive, the executive is optimized to avoid + * unnecessarily saving and restoring the state of the numeric coprocessor. The + * state of the numeric coprocessor is only saved when a @c + * RTEMS_FLOATING_POINT task is dispatched and that task was not the last task + * to utilize the coprocessor. In a system with only one @c + * RTEMS_FLOATING_POINT task, the state of the numeric coprocessor will never + * be saved or restored. + * + * Although the overhead imposed by @c RTEMS_FLOATING_POINT tasks is minimal, + * some applications may wish to completely avoid the overhead associated with + * @c RTEMS_FLOATING_POINT tasks and still utilize a numeric coprocessor. By + * preventing a task from being preempted while performing a sequence of + * floating point operations, a @c RTEMS_NO_FLOATING_POINT task can utilize + * the numeric coprocessor without incurring the overhead of a @c + * RTEMS_FLOATING_POINT context switch. This approach also avoids the + * allocation of a floating point context area. However, if this approach is + * taken by the application designer, NO tasks should be created as @c + * RTEMS_FLOATING_POINT tasks. Otherwise, the floating point context will not + * be correctly maintained because RTEMS assumes that the state of the numeric + * coprocessor will not be altered by @c RTEMS_NO_FLOATING_POINT tasks. + * + * If the supported processor type does not have hardware floating capabilities + * or a standard numeric coprocessor, RTEMS will not provide built-in support + * for hardware floating point on that processor. In this case, all tasks are + * considered @c RTEMS_NO_FLOATING_POINT whether created as @c + * RTEMS_FLOATING_POINT or @c RTEMS_NO_FLOATING_POINT tasks. A floating point + * emulation software library must be utilized for floating point operations. + * + * On some processors, it is possible to disable the floating point unit + * dynamically. If this capability is supported by the target processor, then + * RTEMS will utilize this capability to enable the floating point unit only + * for tasks which are created with the @c RTEMS_FLOATING_POINT attribute. + * The consequence of a @c RTEMS_NO_FLOATING_POINT task attempting to access + * the floating point unit is CPU dependent but will generally result in an + * exception condition. + * + * @section ClassicTasksSecPerTaskVariables Per Task Variables + * + * Per task variables are no longer available. In particular the + * rtems_task_variable_add(), rtems_task_variable_get() and + * rtems_task_variable_delete() functions are neither declared nor defined + * anymore. Use thread local storage or POSIX Keys instead. + * + * @section ClassicTasksSecBuildingTaskAttributeSet Building a Task Attribute Set + * + * In general, an attribute set is built by a bitwise OR of the desired + * components. The set of valid task attribute components is listed below: + * + * - @ref RTEMS_NO_FLOATING_POINT - does not use coprocessor (default) + * - @ref RTEMS_FLOATING_POINT - uses numeric coprocessor + * - @ref RTEMS_LOCAL - local task (default) + * - @ref RTEMS_GLOBAL - global task + * + * Attribute values are specifically designed to be mutually exclusive, + * therefore bitwise OR and addition operations are equivalent as long as each + * attribute appears exactly once in the component list. A component listed as + * a default is not required to appear in the component list, although it is a + * good programming practice to specify default components. If all defaults are + * desired, then @ref RTEMS_DEFAULT_ATTRIBUTES should be used. This example + * demonstrates the attribute_set parameter needed to create a local task which + * utilizes the numeric coprocessor. The attribute_set parameter could be @c + * RTEMS_FLOATING_POINT or @c RTEMS_LOCAL | @c RTEMS_FLOATING_POINT. The + * attribute_set parameter can be set to @c RTEMS_FLOATING_POINT because @c + * RTEMS_LOCAL is the default for all created tasks. If the task were global + * and used the numeric coprocessor, then the attribute_set parameter would be + * @c RTEMS_GLOBAL | @c RTEMS_FLOATING_POINT. + * + * @section ClassicTasksSecBuildingModeAndMask Building a Mode and Mask + * + * In general, a mode and its corresponding mask is built by a bitwise OR of + * the desired components. The set of valid mode constants and each mode's + * corresponding mask constant is listed below: + * + * <table> + * <tr><th>Mode Constant</th><th>Mask Constant</th><th>Description</th></tr> + * <tr><td>@ref RTEMS_PREEMPT</td><td>@ref RTEMS_PREEMPT_MASK</td><td>enables preemption</td></tr> + * <tr><td>@ref RTEMS_NO_PREEMPT</td><td>@ref RTEMS_PREEMPT_MASK</td><td>disables preemption</td></tr> + * <tr><td>@ref RTEMS_NO_TIMESLICE</td><td>@ref RTEMS_TIMESLICE_MASK</td><td>disables timeslicing</td></tr> + * <tr><td>@ref RTEMS_TIMESLICE</td><td>@ref RTEMS_TIMESLICE_MASK</td><td>enables timeslicing</td></tr> + * <tr><td>@ref RTEMS_ASR</td><td>@ref RTEMS_ASR_MASK</td><td>enables ASR processing</td></tr> + * <tr><td>@ref RTEMS_NO_ASR</td><td>@ref RTEMS_ASR_MASK</td><td>disables ASR processing</td></tr> + * <tr><td>@ref RTEMS_INTERRUPT_LEVEL(0)</td><td>@ref RTEMS_INTERRUPT_MASK</td><td>enables all interrupts</td></tr> + * <tr><td>@ref RTEMS_INTERRUPT_LEVEL(n)</td><td>@ref RTEMS_INTERRUPT_MASK</td><td>sets interrupts level n</td></tr> + * </table> + * + * Mode values are specifically designed to be mutually exclusive, therefore + * bitwise OR and addition operations are equivalent as long as each mode + * appears exactly once in the component list. A mode component listed as a + * default is not required to appear in the mode component list, although it is + * a good programming practice to specify default components. If all defaults + * are desired, the mode @ref RTEMS_DEFAULT_MODES and the mask @ref + * RTEMS_ALL_MODE_MASKS should be used. + * + * The following example demonstrates the mode and mask parameters used with + * the rtems_task_mode() directive to place a task at interrupt level 3 and + * make it non-preemptible. The mode should be set to @c + * RTEMS_INTERRUPT_LEVEL(3) | @c RTEMS_NO_PREEMPT to indicate the desired + * preemption mode and interrupt level, while the mask parameter should be set + * to @c RTEMS_INTERRUPT_MASK | @c RTEMS_PREEMPT_MASK to indicate that + * the calling task's interrupt level and preemption mode are being altered. + */ + + /** + * @defgroup LocalPackages Local Packages + * + * @brief Local packages. + */ diff --git a/cpukit/include/rtems/rtems/message.h b/cpukit/include/rtems/rtems/message.h new file mode 100644 index 0000000000..8ae9e156a1 --- /dev/null +++ b/cpukit/include/rtems/rtems/message.h @@ -0,0 +1,270 @@ +/** + * @file rtems/rtems/message.h + * + * @defgroup ClassicMessageQueue Message Queues + * + * @ingroup ClassicRTEMS + * @brief Message Queue Manager + * + * This include file contains all the constants and structures associated + * with the Message Queue Manager. This manager provides a mechanism for + * communication and synchronization between tasks using messages. + * + * Directives provided are: + * + * - create a queue + * - get ID of a queue + * - delete a queue + * - put a message at the rear of a queue + * - put a message at the front of a queue + * - broadcast N messages to a queue + * - receive message from a queue + * - flush all messages on a queue + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_MESSAGE_H +#define _RTEMS_RTEMS_MESSAGE_H + +#include <rtems/rtems/types.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/attr.h> +#include <rtems/score/object.h> +#include <rtems/score/coremsg.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup ClassicMessageQueueImpl + * + * The following records define the control block used to manage + * each message queue. + */ +typedef struct { + /** This field is the inherited object characteristics. */ + Objects_Control Object; + /** This field is the instance of the SuperCore Message Queue. */ + CORE_message_queue_Control message_queue; + /** This field is the attribute set as defined by the API. */ + rtems_attribute attribute_set; +} Message_queue_Control; + +/** + * @defgroup ClassicMessageQueue Message Queues + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the Classic API Message Queue + * Manager. + */ +/**@{*/ + +/** + * @brief RTEMS Create Message Queue + * + * This routine implements the rtems_message_queue_create directive. The + * message queue will have the @a name. If the @a attribute_set indicates + * that the message queue is to be limited in the number of messages + * that can be outstanding, then @a count indicates the maximum number of + * messages that will be held. It returns the id of the created + * message queue in @a id. + * + * @param[in] name is the user defined queue name + * @param[in] count is the maximum message and reserved buffer count + * @param[in] max_message_size is the maximum size of each message + * @param[in] attribute_set is the process method + * @param[in] id is the pointer to queue + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. If successful, the @a id will + * be filled in with the queue id. + */ +rtems_status_code rtems_message_queue_create( + rtems_name name, + uint32_t count, + size_t max_message_size, + rtems_attribute attribute_set, + rtems_id *id +); + +/** + * @brief RTEMS Message Queue Name to Id + * + * This routine implements the rtems_message_queue_ident directive. + * This directive returns the message queue ID associated with NAME. + * If more than one message queue is named name, then the message + * queue to which the ID belongs is arbitrary. node indicates the + * extent of the search for the ID of the message queue named name. + * The search can be limited to a particular node or allowed to + * encompass all nodes. + * + * @param[in] name is the user defined message queue name + * @param[in] node is the node(s) to be searched + * @param[in] id is the pointer to message queue id + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and + * *id filled with the message queue id + */ +rtems_status_code rtems_message_queue_ident( + rtems_name name, + uint32_t node, + rtems_id *id +); + +/** + * @brief RTEMS Delete Message Queue + * + * This routine implements the rtems_message_queue_delete directive. The + * message queue indicated by ID is deleted. + * + * @param[in] id is the queue id + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful + */ +rtems_status_code rtems_message_queue_delete( + rtems_id id +); + +/** + * @brief rtems_message_queue_send + * + * Message Queue Manager - rtems_message_queue_send + * + * This routine implements the rtems_message_queue_send directive. + * This directive sends the message buffer to the message queue + * indicated by ID. If one or more tasks is blocked waiting + * to receive a message from this message queue, then one will + * receive the message. The task selected to receive the + * message is based on the task queue discipline algorithm in + * use by this particular message queue. If no tasks are waiting, + * then the message buffer will be placed at the REAR of the + * chain of pending messages for this message queue. + */ +rtems_status_code rtems_message_queue_send( + rtems_id id, + const void *buffer, + size_t size +); + +/** + * @brief RTEMS Urgent Message Queue + * + * This routine implements the rtems_message_queue_urgent directive. + * This directive has the same behavior as rtems_message_queue_send + * except that if no tasks are waiting, the message buffer will + * be placed at the FRONT of the chain of pending messages rather + * than at the REAR. + * + * @param[in] id is the pointer to message queue + * @param[in] buffer is the pointer to message buffer + * @param[in] size is the size of message to send urgently + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful + */ +rtems_status_code rtems_message_queue_urgent( + rtems_id id, + const void *buffer, + size_t size +); + +/** + * @brief RTEMS Broadcast Message Queue + * + * This routine implements the rtems_message_queue_broadcast directive. + * This directive sends the message buffer to all of the tasks blocked + * waiting for a message on the message queue indicated by ID. + * If no tasks are waiting, then the message buffer will not be queued. + * + * @param[in] id is the pointer to message queue + * @param[in] buffer is the pointer to message buffer + * @param[in] size is the size of message to broadcast + * @param[in] count pointer to area to store number of threads made ready + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and + * *count filled in with number of threads made ready + */ +rtems_status_code rtems_message_queue_broadcast( + rtems_id id, + const void *buffer, + size_t size, + uint32_t *count +); + +/** + * @brief RTEMS Message Queue Receive + * + * This routine implements the rtems_message_queue_receive directive. + * This directive is invoked when the calling task wishes to receive + * a message from the message queue indicated by ID. The received + * message is to be placed in buffer. If no messages are outstanding + * and the option_set indicates that the task is willing to block, + * then the task will be blocked until a message arrives or until, + * optionally, timeout clock ticks have passed. + * + * @param[in] id is the queue id + * @param[in] buffer is the pointer to message buffer + * @param[in] size is the size of message receive + * @param[in] option_set is the options on receive + * @param[in] timeout is the number of ticks to wait + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + */ +rtems_status_code rtems_message_queue_receive( + rtems_id id, + void *buffer, + size_t *size, + rtems_option option_set, + rtems_interval timeout +); + +/** + * @brief rtems_message_queue_flush + * + * This routine implements the rtems_message_queue_flush directive. + * This directive takes all outstanding messages for the message + * queue indicated by ID and returns them to the inactive message + * chain. The number of messages flushed is returned in COUNT. + * + * Message Queue Manager + */ +rtems_status_code rtems_message_queue_flush( + rtems_id id, + uint32_t *count +); + +/** + * @brief RTEMS Message Queue Get Number Pending + * + * Message Queue Manager + * + * This routine implements the rtems_message_queue_get_number_pending + * directive. This directive returns the number of pending + * messages for the message queue indicated by ID + * chain. The number of messages pending is returned in COUNT. + */ +rtems_status_code rtems_message_queue_get_number_pending( + rtems_id id, + uint32_t *count +); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/messageimpl.h b/cpukit/include/rtems/rtems/messageimpl.h new file mode 100644 index 0000000000..df7cea6829 --- /dev/null +++ b/cpukit/include/rtems/rtems/messageimpl.h @@ -0,0 +1,120 @@ +/** + * @file rtems/rtems/message.inl + * + * This include file contains the static inline implementation of all + * inlined routines in the Message Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_MESSAGEIMPL_H +#define _RTEMS_RTEMS_MESSAGEIMPL_H + +#include <rtems/rtems/message.h> +#include <rtems/score/objectimpl.h> +#include <rtems/score/coremsgimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicMessageQueueImpl Classic Message Queue Implementation + * + * @ingroup ClassicMessageQueue + * + * @{ + */ + +/** + * The following enumerated type details the modes in which a message + * may be submitted to a message queue. The message may be posted + * in a send or urgent fashion. + */ +typedef enum { + /** + * This value indicates the user wants to send the message using the + * normal message insertion protocol (FIFO or priority). + */ + MESSAGE_QUEUE_SEND_REQUEST = 0, + /** + * This value indicates the user considers the message to be urgent + * and wants it inserted at the head of the pending message queue. + */ + MESSAGE_QUEUE_URGENT_REQUEST = 1 +} Message_queue_Submit_types; + +/** + * The following defines the information control block used to + * manage this class of objects. + */ +extern Objects_Information _Message_queue_Information; + +/** + * @brief Message_queue_Submit + * + * This routine implements the directives rtems_message_queue_send + * and rtems_message_queue_urgent. It processes a message that is + * to be submitted to the designated message queue. The message will + * either be processed as a send send message which it will be inserted + * at the rear of the queue or it will be processed as an urgent message + * which will be inserted at the front of the queue. + */ +rtems_status_code _Message_queue_Submit( + rtems_id id, + const void *buffer, + size_t size, + Message_queue_Submit_types submit_type +); + +/** + * @brief Deallocates a message queue control block into + * the inactive chain of free message queue control blocks. + * + * This routine deallocates a message queue control block into + * the inactive chain of free message queue control blocks. + */ +RTEMS_INLINE_ROUTINE void _Message_queue_Free ( + Message_queue_Control *the_message_queue +) +{ + _Objects_Free( &_Message_queue_Information, &the_message_queue->Object ); +} + +RTEMS_INLINE_ROUTINE Message_queue_Control *_Message_queue_Get( + Objects_Id id, + Thread_queue_Context *queue_context +) +{ + _Thread_queue_Context_initialize( queue_context ); + return (Message_queue_Control *) _Objects_Get( + id, + &queue_context->Lock_context.Lock_context, + &_Message_queue_Information + ); +} + +RTEMS_INLINE_ROUTINE Message_queue_Control *_Message_queue_Allocate( void ) +{ + return (Message_queue_Control *) + _Objects_Allocate( &_Message_queue_Information ); +} + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/rtems/msgmp.h> +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/modes.h b/cpukit/include/rtems/rtems/modes.h new file mode 100644 index 0000000000..547ae13e05 --- /dev/null +++ b/cpukit/include/rtems/rtems/modes.h @@ -0,0 +1,132 @@ +/** + * @file rtems/rtems/modes.h + * + * @defgroup ClassicModes Modes + * + * @ingroup ClassicRTEMS + * @brief RTEMS thread and RTEMS_ASR modes + * + * This include file contains all constants and structures associated + * with the RTEMS thread and RTEMS_ASR modes. + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_MODES_H +#define _RTEMS_RTEMS_MODES_H + +#include <rtems/score/cpu.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicModes Modes + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the task modes supported + * by the Classic API Task Manager. + */ +/**@{*/ + +/** + * The following type defines the control block used to manage + * each a mode set. + */ +typedef uint32_t Modes_Control; + +/** + * The following constants define the individual modes and masks + * which may be used to compose a mode set and to alter modes. + */ +#define RTEMS_ALL_MODE_MASKS 0x0000ffff + +/** + * This mode constant is the default mode set. + */ +#define RTEMS_DEFAULT_MODES 0x00000000 + +/** + * This mode constant is used when the user wishes to obtain their + * current execution mode. + */ +#define RTEMS_CURRENT_MODE 0 + +/** This mode constant corresponds to the timeslice enable/disable bit. */ +#define RTEMS_TIMESLICE_MASK 0x00000200 + +/** This mode constant corresponds to the preemption enable/disable bit. */ +#define RTEMS_PREEMPT_MASK 0x00000100 + +/** This mode constant corresponds to the signal enable/disable bit. */ +#define RTEMS_ASR_MASK 0x00000400 + +/** This mode constant corresponds to the interrupt enable/disable bits. */ +#define RTEMS_INTERRUPT_MASK CPU_MODES_INTERRUPT_MASK + +/** This mode constant is used to indicate preemption is enabled. */ +#define RTEMS_PREEMPT 0x00000000 +/** This mode constant is used to indicate preemption is disabled. */ +#define RTEMS_NO_PREEMPT 0x00000100 + +/** This mode constant is used to indicate timeslicing is disabled. */ +#define RTEMS_NO_TIMESLICE 0x00000000 +/** This mode constant is used to indicate timeslicing is enabled. */ +#define RTEMS_TIMESLICE 0x00000200 + +/** This mode constant is used to indicate signal processing is enabled. */ +#define RTEMS_ASR 0x00000000 +/** This mode constant is used to indicate signal processing is disabled. */ +#define RTEMS_NO_ASR 0x00000400 + +/** + * @brief RTEMS_INTERRUPT_LEVEL + * + * This function returns the processor dependent interrupt + * level which corresponds to the requested interrupt level. + * + * @note RTEMS supports 256 interrupt levels using the least + * significant eight bits of MODES.CONTROL. On any + * particular CPU, fewer than 256 levels may be supported. + */ +#define RTEMS_INTERRUPT_LEVEL( _mode_set ) \ + ( (_mode_set) & RTEMS_INTERRUPT_MASK ) + +/** + * @brief Interrupt Mask Variable + * + * This variable is used by bindings from languages other than C and C++. + */ +extern const uint32_t rtems_interrupt_mask; + +/** + * @brief Body for RTEMS_INTERRUPT_LEVEL Macro + * + * @param[in] level is the desired interrupt level + * + * @retval This methods returns a mode with the desired interrupt + * @a level in the proper bitfield location. + * + * @note This variable is used by bindings from languages other than + * C and C++. + */ +Modes_Control rtems_interrupt_level_body( + uint32_t level +); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/modesimpl.h b/cpukit/include/rtems/rtems/modesimpl.h new file mode 100644 index 0000000000..8c1acc7cb9 --- /dev/null +++ b/cpukit/include/rtems/rtems/modesimpl.h @@ -0,0 +1,146 @@ +/** + * @file + * + * @ingroup ClassicModesImpl + * + * @brief Classic Modes Implementation + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_MODESIMPL_H +#define _RTEMS_RTEMS_MODESIMPL_H + +#include <rtems/rtems/modes.h> +#include <rtems/score/isrlevel.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicModesImpl Classic Modes Implementation + * + * @ingroup ClassicModes + * + * @{ + */ + +/** + * @brief Checks if any of the mode flags in mask are set in mode_set. + * + * This function returns TRUE if any of the mode flags in mask + * are set in mode_set, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Modes_Mask_changed ( + Modes_Control mode_set, + Modes_Control masks +) +{ + return ( mode_set & masks ) ? true : false; +} + +/** + * @brief Checks if mode_set says that Asynchronous Signal Processing is disabled. + * + * This function returns TRUE if mode_set indicates that Asynchronous + * Signal Processing is disabled, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Modes_Is_asr_disabled ( + Modes_Control mode_set +) +{ + return (mode_set & RTEMS_ASR_MASK) == RTEMS_NO_ASR; +} + +/** + * @brief Checks if mode_set indicates that preemption is enabled. + * + * This function returns TRUE if mode_set indicates that preemption + * is enabled, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Modes_Is_preempt ( + Modes_Control mode_set +) +{ + return (mode_set & RTEMS_PREEMPT_MASK) == RTEMS_PREEMPT; +} + +/** + * @brief Checks if mode_set indicates that timeslicing is enabled. + * + * This function returns TRUE if mode_set indicates that timeslicing + * is enabled, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Modes_Is_timeslice ( + Modes_Control mode_set +) +{ + return (mode_set & RTEMS_TIMESLICE_MASK) == RTEMS_TIMESLICE; +} + +/** + * @brief Gets the interrupt level portion of the mode_set. + * + * This function returns the interrupt level portion of the mode_set. + */ +RTEMS_INLINE_ROUTINE ISR_Level _Modes_Get_interrupt_level ( + Modes_Control mode_set +) +{ + return ( mode_set & RTEMS_INTERRUPT_MASK ); +} + +/** + * @brief Sets the current interrupt level to that specified in the mode_set. + * + * This routine sets the current interrupt level to that specified + * in the mode_set. + */ +RTEMS_INLINE_ROUTINE void _Modes_Set_interrupt_level ( + Modes_Control mode_set +) +{ + _ISR_Set_level( _Modes_Get_interrupt_level( mode_set ) ); +} + +/** + * @brief Changes the modes in old_mode_set indicated by + * mask to the requested values in new_mode_set. + * + * This routine changes the modes in old_mode_set indicated by + * mask to the requested values in new_mode_set. The resulting + * mode set is returned in out_mode_set and the modes that changed + * is returned in changed. + */ +RTEMS_INLINE_ROUTINE void _Modes_Change ( + Modes_Control old_mode_set, + Modes_Control new_mode_set, + Modes_Control mask, + Modes_Control *out_mode_set, + Modes_Control *changed +) +{ + Modes_Control _out_mode; + + _out_mode = old_mode_set; + _out_mode &= ~mask; + _out_mode |= new_mode_set & mask; + *changed = _out_mode ^ old_mode_set; + *out_mode_set = _out_mode; +} + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/mp.h b/cpukit/include/rtems/rtems/mp.h new file mode 100644 index 0000000000..f1b93b6751 --- /dev/null +++ b/cpukit/include/rtems/rtems/mp.h @@ -0,0 +1,54 @@ +/** + * @file rtems/rtems/mp.h + * + * @defgroup ClassicMP Multiprocessing + * + * @ingroup ClassicRTEMS + * @brief Multiprocessing Manager + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Manager. + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_MP_H +#define _RTEMS_RTEMS_MP_H + +/** + * @defgroup ClassicMP Multiprocessing + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the distributed + * Multiprocessing support in the Classic API. + */ +/**@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief RTEMS Multiprocessing Announce + * + * This routine implements the MULTIPROCESSING_ANNOUNCE directive. + * It is invoked by the MPCI layer to indicate that an MPCI packet + * has been received. + */ +void rtems_multiprocessing_announce ( void ); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/msgmp.h b/cpukit/include/rtems/rtems/msgmp.h new file mode 100644 index 0000000000..3dabd8d46b --- /dev/null +++ b/cpukit/include/rtems/rtems/msgmp.h @@ -0,0 +1,211 @@ +/** + * @file rtems/rtems/msgmp.h + * + * @brief Message Manager MP Support + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Message Manager. + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_MSGMP_H +#define _RTEMS_RTEMS_MSGMP_H + +#ifndef _RTEMS_RTEMS_MESSAGEIMPL_H +# error "Never use <rtems/rtems/msgmp.h> directly; include <rtems/rtems/messageimpl.h> instead." +#endif + +#include <rtems/score/mpciimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicMsgMP Message Queue MP Support + * + * @ingroup ClassicMP + * + * This encapsulates functionality related to the transparent multiprocessing + * support within the Classic API Message Queue Manager. + */ +/*{*/ + +/** + * The following enumerated type defines the list of + * remote message queue operations. + */ +typedef enum { + MESSAGE_QUEUE_MP_ANNOUNCE_CREATE = 0, + MESSAGE_QUEUE_MP_ANNOUNCE_DELETE = 1, + MESSAGE_QUEUE_MP_EXTRACT_PROXY = 2, + MESSAGE_QUEUE_MP_RECEIVE_REQUEST = 3, + MESSAGE_QUEUE_MP_RECEIVE_RESPONSE = 4, + MESSAGE_QUEUE_MP_SEND_REQUEST = 5, + MESSAGE_QUEUE_MP_SEND_RESPONSE = 6, + MESSAGE_QUEUE_MP_URGENT_REQUEST = 7, + MESSAGE_QUEUE_MP_URGENT_RESPONSE = 8, + MESSAGE_QUEUE_MP_BROADCAST_REQUEST = 9, + MESSAGE_QUEUE_MP_BROADCAST_RESPONSE = 10, + MESSAGE_QUEUE_MP_FLUSH_REQUEST = 11, + MESSAGE_QUEUE_MP_FLUSH_RESPONSE = 12, + MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST = 13, + MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE = 14 +} Message_queue_MP_Remote_operations; + +/** + * The following data structure defines the packet used to perform + * remote message queue operations. + */ +typedef struct { + rtems_packet_prefix Prefix; + Message_queue_MP_Remote_operations operation; + rtems_name name; + rtems_option option_set; + Objects_Id proxy_id; + uint32_t count; + size_t size; + uint32_t pad0; + CORE_message_queue_Buffer Buffer; +} Message_queue_MP_Packet; + +#define MESSAGE_QUEUE_MP_PACKET_SIZE \ + offsetof(Message_queue_MP_Packet, Buffer.buffer) + +RTEMS_INLINE_ROUTINE bool _Message_queue_MP_Is_remote( Objects_Id id ) +{ + return _Objects_MP_Is_remote( id, &_Message_queue_Information ); +} + +/** + * @brief Message_queue_Core_message_queue_mp_support + * + * Input parameters: + * the_thread - the remote thread the message was submitted to + * id - id of the message queue + * + * Output parameters: NONE + */ +void _Message_queue_Core_message_queue_mp_support ( + Thread_Control *the_thread, + rtems_id id +); + +/** + * @brief _Message_queue_MP_Send_process_packet + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + */ +void _Message_queue_MP_Send_process_packet ( + Message_queue_MP_Remote_operations operation, + Objects_Id message_queue_id, + rtems_name name, + Objects_Id proxy_id +); + +/** + * @brief Issues a remote rtems_message_queue_broadcast() request. + */ +rtems_status_code _Message_queue_MP_Broadcast( + rtems_id id, + const void *buffer, + size_t size, + uint32_t *count +); + +/** + * @brief Issues a remote rtems_message_queue_flush() request. + */ +rtems_status_code _Message_queue_MP_Flush( + rtems_id id, + uint32_t *count +); + +/** + * @brief Issues a remote rtems_message_queue_get_number_pending() request. + */ +rtems_status_code _Message_queue_MP_Get_number_pending( + rtems_id id, + uint32_t *count +); + +/** + * @brief Issues a remote rtems_message_queue_receive() request. + */ +rtems_status_code _Message_queue_MP_Receive( + rtems_id id, + void *buffer, + size_t *size, + rtems_option option_set, + rtems_interval timeout +); + +/** + * @brief Issues a remote rtems_message_queue_send() request. + */ +rtems_status_code _Message_queue_MP_Send( + rtems_id id, + const void *buffer, + size_t size +); + +/** + * @brief Issues a remote rtems_message_queue_urgent() request. + */ +rtems_status_code _Message_queue_MP_Urgent( + rtems_id id, + const void *buffer, + size_t size +); + +/** + * + * @brief _Message_queue_MP_Process_packet + * + * This routine performs the actions specific to this package for + * the request from another node. + */ +void _Message_queue_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +); + +/** + * @brief _Message_queue_MP_Send_object_was_deleted + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + */ +void _Message_queue_MP_Send_object_was_deleted ( + Thread_Control *the_proxy, + Objects_Id mp_id +); + +/** + * @brief _Message_queue_MP_Send_extract_proxy + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + */ +void _Message_queue_MP_Send_extract_proxy ( + Thread_Control *the_thread, + Objects_Id id +); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of file */ diff --git a/cpukit/include/rtems/rtems/object.h b/cpukit/include/rtems/rtems/object.h new file mode 100644 index 0000000000..2652915462 --- /dev/null +++ b/cpukit/include/rtems/rtems/object.h @@ -0,0 +1,370 @@ +/** + * @file rtems/rtems/object.h + * + * @defgroup ClassicClassInfo Object Class Information + * + * @ingroup ClassicRTEMS + * @brief Classic API interfaces to Object Services + * + * This include file defines Classic API interfaces to Object Services. + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_OBJECT_H +#define _RTEMS_RTEMS_OBJECT_H + +#include <stdint.h> +#include <rtems/score/object.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicClassInfo Object Class Information + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the Classic API Object + * Class Services. + */ +/**@{*/ + +/** + * This structure is used to return information to the application + * about the objects configured for a specific API/Class combination. + */ +typedef struct { + /** This field is the minimum valid object Id for this class. */ + rtems_id minimum_id; + /** This field is the maximum valid object Id for this class. */ + rtems_id maximum_id; + /** This field is the number of object instances configured for this class. */ + uint32_t maximum; + /** This field indicates if the class is configured for auto-extend. */ + bool auto_extend; + /** This field is the number of currently unallocated objects. */ + uint32_t unallocated; +} rtems_object_api_class_information; + +/** + * @brief Build Object Id + * + * This function returns an object id composed of the + * specified @a api, @a class, @a node, + * and @a index. + * + * @param[in] _api indicates the api to use for the Id + * @param[in] _class indicates the class to use for the Id + * @param[in] _node indicates the node to use for the Id + * @param[in] _index indicates the index to use for the Id + * + * @retval This method returns an object Id built from the + * specified values. + * + * @note A body is also provided. + */ +#define rtems_build_id( _api, _class, _node, _index ) \ + _Objects_Build_id( _api, _class, _node, _index ) + +/** + * @brief Build Thirty-Two Bit Object Name + * + * RTEMS Object Helper -- Build an Object Id + * + * This function returns an object name composed of the four characters + * C1, C2, C3, and C4. + * + * @param[in] _C1 is the first character of the name + * @param[in] _C2 is the second character of the name + * @param[in] _C3 is the third character of the name + * @param[in] _C4 is the fourth character of the name + * + * @note This must be implemented as a macro for use in + * Configuration Tables. A body is also provided. + * + */ +#define rtems_build_name( _C1, _C2, _C3, _C4 ) \ + _Objects_Build_name( _C1, _C2, _C3, _C4 ) + +/** + * @brief Obtain Name of Object + * + * This directive returns the name associated with the specified + * object ID. + * + * @param[in] id is the Id of the object to obtain the name of. + * @param[out] name will be set to the name of the object + * + * @note The object must be have a name of the 32-bit form. + * + * @retval @a *name will contain user defined object name + * @retval @a RTEMS_SUCCESSFUL - if successful + * @retval error code - if unsuccessful + */ +rtems_status_code rtems_object_get_classic_name( + rtems_id id, + rtems_name *name +); + +/** + * @brief Obtain Object Name as String + * + * This directive returns the name associated with the specified + * object ID. + * + * @param[in] id is the Id of the object to obtain the name of + * @param[in] length is the length of the output name buffer + * @param[out] name will be set to the name of the object + * + * @retval @a *name will contain user defined object name + * @retval @a name - if successful + * @retval @a NULL - if unsuccessful + */ +char *rtems_object_get_name( + rtems_id id, + size_t length, + char *name +); + +/** + * @brief Set Name of Object + * + * This method allows the caller to set the name of an + * object. This can be used to set the name of objects + * which do not have a naming scheme per their API. + * + * RTEMS Object Helper -- Set Name of Object as String + * + * @param[in] id is the Id of the object to obtain the name of + * @param[out] name will be set to the name of the object + * + * @retval @a *name will contain user defined object name + * @retval @a RTEMS_SUCCESSFUL - if successful + * @retval error code - if unsuccessful + */ +rtems_status_code rtems_object_set_name( + rtems_id id, + const char *name +); + +/** + * @brief Get API Portion of Object Id + * + * RTEMS Object Helper -- Extract API From Id + * + * This function returns the API portion of the Id. + * + * @param[in] _id is the Id of the object to obtain the API from + * + * @retval This method returns the API portion of the provided + * @a _id. + * + * @note This method does NOT validate the @a _id provided. + * + * @note A body is also provided. + */ +#define rtems_object_id_get_api( _id ) \ + _Objects_Get_API( _id ) + +/** + * @brief Get Class Portion of Object Id + * + * This function returns the class portion of the @a _id ID. + * + * @param[in] _id is the Id of the object to obtain the class from + * + * @retval This method returns the class portion of the provided + * @a _id. + * + * @note This method does NOT validate the @a _id provided. + * + * @note A body is also provided. + */ +#define rtems_object_id_get_class( _id ) \ + _Objects_Get_class( _id ) + +/** + * @brief Get Node Portion of Object Id + * + * This function returns the node portion of the ID. + * + * @param[in] _id is the Id of the object to obtain the node from + * + * @retval This method returns the node portion of the provided + * @a _id. + * + * @note This method does NOT validate the @a _id provided. + * + * @note A body is also provided. + */ +#define rtems_object_id_get_node( _id ) \ + _Objects_Get_node( _id ) + +/** + * @brief Get Index Portion of Object Id + * + * This function returns the index portion of the ID. + * + * @param[in] _id is the Id of the object to obtain the index from + * + * @retval This method returns the index portion of the provided + * @a _id. + * + * @note This method does NOT validate the @a _id provided. + * + * @note A body is also provided. + */ +#define rtems_object_id_get_index( _id ) \ + _Objects_Get_index( _id ) + +/** + * @brief Get Lowest Valid API Index + * + * This method returns the lowest valid value for the API + * portion of an RTEMS object Id. + * + * @retval This method returns the least valid value for + * the API portion of an RTEMS object Id. + * + * @note A body is also provided. + */ +#define rtems_object_id_api_minimum() \ + OBJECTS_INTERNAL_API + +/** + * @brief Get Highest Valid API Index + * + * This method returns the highest valid value for the API + * portion of an RTEMS object Id. + * + * @retval This method returns the greatest valid value for + * the API portion of an RTEMS object Id. + * + * @note A body is also provided. + */ +#define rtems_object_id_api_maximum() \ + OBJECTS_APIS_LAST + +/** + * @brief Get Lowest Valid Class Value + * + * This method returns the lowest valid value Class for the + * specified @a api. Each API supports a different number + * of object classes. + * + * @param[in] api is the API to obtain the minimum class of + * + * @retval This method returns the least valid value for + * class number for the specified @a api. + * RTEMS Object Helper -- Get Least Valid Class for an API + */ +int rtems_object_api_minimum_class( + int api +); + +/** + * @brief Get Highest Valid Class Value + * + * This method returns the highest valid value Class for the + * specified @a api. Each API supports a different number + * of object classes. + * + * @param[in] api is the API to obtain the maximum class of + * + * @retval This method returns the greatet valid value for + * class number for the specified @a api. + */ +int rtems_object_api_maximum_class( + int api +); + + +/** + * @brief Get Highest Valid Class Value + * + * This method returns the lowest valid value Class for the + * specified @a api. Each API supports a different number + * of object classes. + * + * @param[in] api is the API to obtain the maximum class of + * + * @retval This method returns the least valid value for + * class number for the specified @a api. + */ +int rtems_object_id_api_maximum_class( + int api +); + +/** + * @brief Get API Name + * + * This method returns a string containing the name of the + * specified @a api. + * + * @param[in] api is the API to obtain the name of + * + * @retval If successful, this method returns the name of + * the specified @a api. Otherwise, it returns + * the string "BAD API" + */ +const char *rtems_object_get_api_name( + int api +); + +/** + * @brief Get Class Name + * + * This method returns a string containing the name of the + * @a class from the specified @a api. + * + * @param[in] the_api is the API for the class + * @param[in] the_class is the class to obtain the name of + * + * @retval If successful, this method returns the name of + * the specified @a class. Otherwise, it returns + * the string "BAD CLASS" + */ +const char *rtems_object_get_api_class_name( + int the_api, + int the_class +); + +/** + * @brief Get Class Information + * + * This method returns a string containing the name of the + * @a the_class from the specified @a api. + * + * @param[in] the_api is the API for the class + * @param[in] the_class is the class to obtain information about + * @param[in] info points to the information structure to fill in + * + * @retval If successful, this method returns the name of + * RTEMS_SUCCESSFUL with @a *info filled in. Otherwise, + * a status is returned to indicate the error. + * + */ +rtems_status_code rtems_object_get_class_information( + int the_api, + int the_class, + rtems_object_api_class_information *info +); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/options.h b/cpukit/include/rtems/rtems/options.h new file mode 100644 index 0000000000..752aefda2e --- /dev/null +++ b/cpukit/include/rtems/rtems/options.h @@ -0,0 +1,83 @@ +/** + * @file rtems/rtems/options.h + * + * @defgroup ClassicOptions Classic API Options + * + * @ingroup ClassicRTEMS + * @brief Options Available on Many Directives + * + * This include file contains information which defines the + * options available on many directives. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_OPTIONS_H +#define _RTEMS_RTEMS_OPTIONS_H + +#include <rtems/score/basedefs.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicOptions Classic API Options + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the options argument + * to Classic API blocking operations. The primary option is whether + * or not a task is willing to wait for the operation to complete. + */ +/**@{*/ + +/** + * The following type defines the control block used to manage + * option sets. + */ +typedef uint32_t rtems_option; + +/** + * The following constants define the individual options which may + * be used to compose an option set. + */ +#define RTEMS_DEFAULT_OPTIONS 0x00000000 + +/** + * This option constants indicates that the task is to wait on resource. + */ +#define RTEMS_WAIT 0x00000000 +/** + * This option constants indicates that the task is to not wait on + * the resource. If it is not available, return immediately with + * a status to indicate unsatisfied. + */ +#define RTEMS_NO_WAIT 0x00000001 + +/** + * This option constants indicates that the task wishes to wait until + * all events of interest are available. + */ +#define RTEMS_EVENT_ALL 0x00000000 + +/** + * This option constants indicates that the task wishes to wait until + * ANY events of interest are available. + */ +#define RTEMS_EVENT_ANY 0x00000002 + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/optionsimpl.h b/cpukit/include/rtems/rtems/optionsimpl.h new file mode 100644 index 0000000000..0263fcf78d --- /dev/null +++ b/cpukit/include/rtems/rtems/optionsimpl.h @@ -0,0 +1,67 @@ +/** + * @file + * + * @ingroup ClassicOptionsImpl + * + * @brief Classic Options Implementation + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_OPTIONSIMPL_H +#define _RTEMS_RTEMS_OPTIONSIMPL_H + +#include <rtems/rtems/options.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicOptionsImpl Classic Options Implementation + * + * @ingroup ClassicOptions + * + * @{ + */ + +/** + * @brief Checks if the RTEMS_NO_WAIT option is enabled in option_set. + * + * This function returns TRUE if the RTEMS_NO_WAIT option is enabled in + * option_set, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Options_Is_no_wait ( + rtems_option option_set +) +{ + return (option_set & RTEMS_NO_WAIT) ? true : false; +} + +/** + * @brief Checks if the RTEMS_EVENT_ANY option is enabled in OPTION_SET. + * + * This function returns TRUE if the RTEMS_EVENT_ANY option is enabled in + * OPTION_SET, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Options_Is_any ( + rtems_option option_set +) +{ + return (option_set & RTEMS_EVENT_ANY) ? true : false; +} + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/part.h b/cpukit/include/rtems/rtems/part.h new file mode 100644 index 0000000000..5b840cc96c --- /dev/null +++ b/cpukit/include/rtems/rtems/part.h @@ -0,0 +1,174 @@ +/** + * @file rtems/rtems/part.h + * + * @defgroup ClassicPart Partitions + * + * @ingroup ClassicRTEMS + * @brief Partition Manager + * + * This include file contains all the constants and structures associated + * with the Partition Manager. This manager provides facilities to + * dynamically allocate memory in fixed-sized units which are returned + * as buffers. + * + * Directives provided are: + * + * - create a partition + * - get an ID of a partition + * - delete a partition + * - get a buffer from a partition + * - return a buffer to a partition + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_PART_H +#define _RTEMS_RTEMS_PART_H + +#include <rtems/rtems/attr.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/types.h> +#include <rtems/score/isrlock.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicPart Partitions + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the + * Classic API Partition Manager. + */ +/**@{*/ + +/** + * The following defines the control block used to manage each partition. + */ +typedef struct { + /** This field is the object management portion of a Partition instance. */ + Objects_Control Object; + /** This field is the lock of the Partition. */ + ISR_LOCK_MEMBER( Lock ) + /** This field is the physical starting address of the Partition. */ + void *starting_address; + /** This field is the size of the Partition in bytes. */ + intptr_t length; + /** This field is the size of each buffer in bytes */ + uint32_t buffer_size; + /** This field is the attribute set provided at create time. */ + rtems_attribute attribute_set; + /** This field is the of allocated buffers. */ + uint32_t number_of_used_blocks; + /** This field is the chain used to manage unallocated buffers. */ + Chain_Control Memory; +} Partition_Control; + +/** + * @brief RTEMS Partition Create + * + * Partition Manager + * + * This routine implements the rtems_partition_create directive. The + * partition will have the name name. The memory area managed by + * the partition is of length bytes and starts at starting_address. + * The memory area will be divided into as many buffers of + * buffer_size bytes as possible. The attribute_set determines if + * the partition is global or local. It returns the id of the + * created partition in ID. + */ +rtems_status_code rtems_partition_create( + rtems_name name, + void *starting_address, + uint32_t length, + uint32_t buffer_size, + rtems_attribute attribute_set, + rtems_id *id +); + +/** + * @brief RTEMS Partition Ident + * + * This routine implements the rtems_partition_ident directive. + * This directive returns the partition ID associated with name. + * If more than one partition is named name, then the partition + * to which the ID belongs is arbitrary. node indicates the + * extent of the search for the ID of the partition named name. + * The search can be limited to a particular node or allowed to + * encompass all nodes. + * + * @param[in] name is the user defined partition name + * @param[in] node is(are) the node(s) to be searched + * @param[in] id is the pointer to partition id + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and + * *id filled in with the partition id + */ +rtems_status_code rtems_partition_ident( + rtems_name name, + uint32_t node, + rtems_id *id +); + +/** + * @brief RTEMS Delete Partition + * + * This routine implements the rtems_partition_delete directive. The + * partition indicated by ID is deleted, provided that none of its buffers + * are still allocated. + * + * @param[in] id is the partition id + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + */ +rtems_status_code rtems_partition_delete( + rtems_id id +); + +/** + * @brief RTEMS Get Partition Buffer + * + * This routine implements the rtems_partition_get_buffer directive. It + * attempts to allocate a buffer from the partition associated with ID. + * If a buffer is allocated, its address is returned in buffer. + * + * @param[in] id is the partition id + * @param[out] buffer is the pointer to buffer address + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful + */ +rtems_status_code rtems_partition_get_buffer( + rtems_id id, + void **buffer +); + +/** + * @brief rtems_partition_return_buffer + * + * This routine implements the rtems_partition_return_buffer directive. It + * frees the buffer to the partition associated with ID. The buffer must + * have been previously allocated from the same partition. + */ +rtems_status_code rtems_partition_return_buffer( + rtems_id id, + void *buffer +); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/partimpl.h b/cpukit/include/rtems/rtems/partimpl.h new file mode 100644 index 0000000000..13ee86b4c2 --- /dev/null +++ b/cpukit/include/rtems/rtems/partimpl.h @@ -0,0 +1,223 @@ +/** + * @file + * + * @ingroup ClassicPartImpl + * + * @brief Classic Partition Manager Implementation + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_PARTIMPL_H +#define _RTEMS_RTEMS_PARTIMPL_H + +#include <rtems/rtems/part.h> +#include <rtems/score/chainimpl.h> +#include <rtems/score/objectimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicPartImpl Classic Partition Manager Implementation + * + * @ingroup ClassicPart + * + * @{ + */ + +/** + * The following defines the information control block used to + * manage this class of objects. + */ +extern Objects_Information _Partition_Information; + +/** + * @brief Allocate a buffer from the_partition. + * + * This function attempts to allocate a buffer from the_partition. + * If successful, it returns the address of the allocated buffer. + * Otherwise, it returns NULL. + */ +RTEMS_INLINE_ROUTINE void *_Partition_Allocate_buffer ( + Partition_Control *the_partition +) +{ + return _Chain_Get_unprotected( &the_partition->Memory ); +} + +/** + * @brief Frees the_buffer to the_partition. + * + * This routine frees the_buffer to the_partition. + */ +RTEMS_INLINE_ROUTINE void _Partition_Free_buffer ( + Partition_Control *the_partition, + Chain_Node *the_buffer +) +{ + _Chain_Append_unprotected( &the_partition->Memory, the_buffer ); +} + +/** + * @brief Checks whether is on a valid buffer boundary for the_partition. + * + * This function returns TRUE if the_buffer is on a valid buffer + * boundary for the_partition, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Partition_Is_buffer_on_boundary ( + void *the_buffer, + Partition_Control *the_partition +) +{ + uint32_t offset; + + offset = (uint32_t) _Addresses_Subtract( + the_buffer, + the_partition->starting_address + ); + + return ((offset % the_partition->buffer_size) == 0); +} + +/** + * @brief Checks whether the_buffer is a valid buffer from the_partition. + * + * This function returns TRUE if the_buffer is a valid buffer from + * the_partition, otherwise FALSE is returned. + */ +RTEMS_INLINE_ROUTINE bool _Partition_Is_buffer_valid ( + Chain_Node *the_buffer, + Partition_Control *the_partition +) +{ + void *starting; + void *ending; + + starting = the_partition->starting_address; + ending = _Addresses_Add_offset( starting, the_partition->length ); + + return ( + _Addresses_Is_in_range( the_buffer, starting, ending ) && + _Partition_Is_buffer_on_boundary( the_buffer, the_partition ) + ); +} + +/** + * @brief Checks if partition is buffer size aligned. + * + * This function returns TRUE if the use of the specified buffer_size + * will result in the allocation of buffers whose first byte is + * properly aligned, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Partition_Is_buffer_size_aligned ( + uint32_t buffer_size +) +{ + return ((buffer_size % CPU_PARTITION_ALIGNMENT) == 0); +} + +/** + * @brief Allocates a partition control block from the + * inactive chain of free partition control blocks. + * + * This function allocates a partition control block from + * the inactive chain of free partition control blocks. + */ +RTEMS_INLINE_ROUTINE Partition_Control *_Partition_Allocate ( void ) +{ + return (Partition_Control *) _Objects_Allocate( &_Partition_Information ); +} + +RTEMS_INLINE_ROUTINE void _Partition_Initialize( + Partition_Control *the_partition, + void *starting_address, + uint32_t length, + uint32_t buffer_size, + rtems_attribute attribute_set +) +{ + the_partition->starting_address = starting_address; + the_partition->length = length; + the_partition->buffer_size = buffer_size; + the_partition->attribute_set = attribute_set; + the_partition->number_of_used_blocks = 0; + + _Chain_Initialize( + &the_partition->Memory, + starting_address, + length / buffer_size, + buffer_size + ); + + _ISR_lock_Initialize( &the_partition->Lock, "Partition" ); +} + +RTEMS_INLINE_ROUTINE void _Partition_Destroy( + Partition_Control *the_partition +) +{ + _ISR_lock_Destroy( &the_partition->Lock ); +} + +/** + * @brief Frees a partition control block to the + * inactive chain of free partition control blocks. + * + * This routine frees a partition control block to the + * inactive chain of free partition control blocks. + */ +RTEMS_INLINE_ROUTINE void _Partition_Free ( + Partition_Control *the_partition +) +{ + _Objects_Free( &_Partition_Information, &the_partition->Object ); +} + +RTEMS_INLINE_ROUTINE Partition_Control *_Partition_Get( + Objects_Id id, + ISR_lock_Context *lock_context +) +{ + return (Partition_Control *) _Objects_Get( + id, + lock_context, + &_Partition_Information + ); +} + +RTEMS_INLINE_ROUTINE void _Partition_Acquire_critical( + Partition_Control *the_partition, + ISR_lock_Context *lock_context +) +{ + _ISR_lock_Acquire( &the_partition->Lock, lock_context ); +} + +RTEMS_INLINE_ROUTINE void _Partition_Release( + Partition_Control *the_partition, + ISR_lock_Context *lock_context +) +{ + _ISR_lock_Release_and_ISR_enable( &the_partition->Lock, lock_context ); +} + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/rtems/partmp.h> +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/partmp.h b/cpukit/include/rtems/rtems/partmp.h new file mode 100644 index 0000000000..b9eaa08b8c --- /dev/null +++ b/cpukit/include/rtems/rtems/partmp.h @@ -0,0 +1,144 @@ +/** + * @file rtems/rtems/partmp.h + * + * @brief MP Support in Partition Manager + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Partition Manager. + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_PARTMP_H +#define _RTEMS_RTEMS_PARTMP_H + +#ifndef _RTEMS_RTEMS_PARTIMPL_H +# error "Never use <rtems/rtems/partmp.h> directly; include <rtems/rtems/partimpl.h> instead." +#endif + +#include <rtems/score/mpciimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicPartMP Partition MP Support + * + * @ingroup ClassicMP + * + * This encapsulates functionality related to the transparent multiprocessing + * support within the Classic API Partition Manager. + */ +/*{*/ + +/** + * The following enumerated type defines the list of + * remote partition operations. + */ +typedef enum { + PARTITION_MP_ANNOUNCE_CREATE = 0, + PARTITION_MP_ANNOUNCE_DELETE = 1, + PARTITION_MP_EXTRACT_PROXY = 2, + PARTITION_MP_GET_BUFFER_REQUEST = 3, + PARTITION_MP_GET_BUFFER_RESPONSE = 4, + PARTITION_MP_RETURN_BUFFER_REQUEST = 5, + PARTITION_MP_RETURN_BUFFER_RESPONSE = 6 +} Partition_MP_Remote_operations; + +/** + * The following data structure defines the packet used to perform + * remote partition operations. + */ +typedef struct { + rtems_packet_prefix Prefix; + Partition_MP_Remote_operations operation; + rtems_name name; + void *buffer; + Objects_Id proxy_id; +} Partition_MP_Packet; + +RTEMS_INLINE_ROUTINE bool _Partition_MP_Is_remote( Objects_Id id ) +{ + return _Objects_MP_Is_remote( id, &_Partition_Information ); +} + +/** + * @brief Partition_MP_Send_process_packet + * + * Multiprocessing Support for the Partition Manager + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + */ +void _Partition_MP_Send_process_packet ( + Partition_MP_Remote_operations operation, + Objects_Id partition_id, + rtems_name name, + Objects_Id proxy_id +); + +/** + * @brief Issues a remote rtems_partition_get_buffer() request. + */ +rtems_status_code _Partition_MP_Get_buffer( + rtems_id id, + void **buffer +); + +/** + * @brief Issues a remote rtems_partition_return_buffer() request. + */ +rtems_status_code _Partition_MP_Return_buffer( + rtems_id id, + void *buffer +); + +/** + * + * @brief Partition_MP_Process_packet + * + * This routine performs the actions specific to this package for + * the request from another node. + */ +void _Partition_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +); + +/* + * @brief Partition_MP_Send_object_was_deleted + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + * + * This routine is not needed by the Partition since a partition + * cannot be deleted when buffers are in use. + */ + +/** + * @brief Partition_MP_Send_extract_proxy + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + */ +void _Partition_MP_Send_extract_proxy ( + Thread_Control *the_thread, + Objects_Id id +); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of file */ diff --git a/cpukit/include/rtems/rtems/ratemon.h b/cpukit/include/rtems/rtems/ratemon.h new file mode 100644 index 0000000000..ca48a92983 --- /dev/null +++ b/cpukit/include/rtems/rtems/ratemon.h @@ -0,0 +1,430 @@ +/** + * @file rtems/rtems/ratemon.h + * + * @defgroup ClassicRateMon Rate Monotonic Scheduler + * + * @ingroup ClassicRTEMS + * @brief Classic API Rate Monotonic Manager. + * + * This include file contains all the constants, structures, and + * prototypes associated with the Rate Monotonic Manager. This manager + * provides facilities to implement threads which execute in a periodic + * fashion. + * + * Directives provided are: + * + * - create a rate monotonic timer + * - cancel a period + * - delete a rate monotonic timer + * - conclude current and start the next period + * - obtain status information on a period + * - obtain the number of postponed jobs + */ + +/* COPYRIGHT (c) 1989-2009, 2016. + * On-Line Applications Research Corporation (OAR). + * COPYRIGHT (c) 2016-2017 Kuan-Hsun Chen. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_RATEMON_H +#define _RTEMS_RTEMS_RATEMON_H + +#include <rtems/rtems/types.h> +#include <rtems/rtems/status.h> +#include <rtems/score/thread.h> +#include <rtems/score/watchdog.h> + +struct rtems_printer; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicRateMon Rate Monotonic Scheduler + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the Classic API Rate + * Monotonic Manager. + * + * Statistics are kept for each period and can be obtained or printed via + * API calls. The statistics kept include minimum, maximum and average times + * for both cpu usage and wall time. The statistics indicate the execution + * and wall time used by the owning thread between successive calls to + * rtems_rate_monotonic_period. + */ +/**@{*/ + +/** + * This is the public type used for the rate monotonic timing + * statistics. + */ +#include <rtems/score/timespec.h> + +typedef struct timespec rtems_rate_monotonic_period_time_t; + +/** + * This is the internal type used for the rate monotonic timing + * statistics. + */ +#include <rtems/score/timestamp.h> + +/** + * The following enumerated type defines the states in which a + * period may be. + */ +typedef enum { + /** + * This value indicates the period is off the watchdog chain, + * and has never been initialized. + */ + RATE_MONOTONIC_INACTIVE, + + /** + * This value indicates the period is on the watchdog chain, and + * running. The owner should be executed or blocked waiting on + * another object. + */ + RATE_MONOTONIC_ACTIVE, + + /** + * This value indicates the period is off the watchdog chain, and + * has expired. The owner is still executing and has taken too much + * all time to complete this iteration of the period. + */ + RATE_MONOTONIC_EXPIRED +} rtems_rate_monotonic_period_states; + +/** + * The following constant is the interval passed to the rate_monontonic_period + * directive to obtain status information. + */ +#define RTEMS_PERIOD_STATUS WATCHDOG_NO_TIMEOUT + +/** + * The following defines the PUBLIC data structure that has the + * statistics kept on each period instance. + * + * @note The public structure uses struct timespec while the + * internal one uses Timestamp_Control. + */ +typedef struct { + /** This field contains the number of periods executed. */ + uint32_t count; + /** This field contains the number of periods missed. */ + uint32_t missed_count; + + /** This field contains the least amount of CPU time used in a period. */ + rtems_thread_cpu_usage_t min_cpu_time; + /** This field contains the highest amount of CPU time used in a period. */ + rtems_thread_cpu_usage_t max_cpu_time; + /** This field contains the total amount of wall time used in a period. */ + rtems_thread_cpu_usage_t total_cpu_time; + + /** This field contains the least amount of wall time used in a period. */ + rtems_rate_monotonic_period_time_t min_wall_time; + /** This field contains the highest amount of wall time used in a period. */ + rtems_rate_monotonic_period_time_t max_wall_time; + /** This field contains the total amount of CPU time used in a period. */ + rtems_rate_monotonic_period_time_t total_wall_time; +} rtems_rate_monotonic_period_statistics; + +/** + * The following defines the INTERNAL data structure that has the + * statistics kept on each period instance. + */ +typedef struct { + /** This field contains the number of periods executed. */ + uint32_t count; + /** This field contains the number of periods missed. */ + uint32_t missed_count; + + /** This field contains the least amount of CPU time used in a period. */ + Timestamp_Control min_cpu_time; + /** This field contains the highest amount of CPU time used in a period. */ + Timestamp_Control max_cpu_time; + /** This field contains the total amount of wall time used in a period. */ + Timestamp_Control total_cpu_time; + + /** This field contains the least amount of wall time used in a period. */ + Timestamp_Control min_wall_time; + /** This field contains the highest amount of wall time used in a period. */ + Timestamp_Control max_wall_time; + /** This field contains the total amount of CPU time used in a period. */ + Timestamp_Control total_wall_time; +} Rate_monotonic_Statistics; + +/** + * The following defines the period status structure. + */ +typedef struct { + /** This is the Id of the thread using this period. */ + rtems_id owner; + + /** This is the current state of this period. */ + rtems_rate_monotonic_period_states state; + + /** + * This is the length of wall time that has passed since this period + * was last initiated. If the period is expired or has not been initiated, + * then this field has no meaning. + */ + rtems_rate_monotonic_period_time_t since_last_period; + + /** + * This is the amount of CPU time that has been used since this period + * was last initiated. If the period is expired or has not been initiated, + * then this field has no meaning. + */ + rtems_thread_cpu_usage_t executed_since_last_period; + + /** This is the count of postponed jobs of this period. */ + uint32_t postponed_jobs_count; +} rtems_rate_monotonic_period_status; + +/** + * @brief The following structure defines the control block used to manage each + * period. + * + * State changes are protected by the default thread lock of the owner thread. + * The owner thread is the thread that created the period object. The owner + * thread field is immutable after object creation. + */ +typedef struct { + /** This field is the object management portion of a Period instance. */ + Objects_Control Object; + + /** + * @brief Protects the rate monotonic period state. + */ + ISR_LOCK_MEMBER( Lock ) + + /** This is the timer used to provide the unblocking mechanism. */ + Watchdog_Control Timer; + + /** This field indicates the current state of the period. */ + rtems_rate_monotonic_period_states state; + + /** + * @brief A priority node for use by the scheduler job release and cancel + * operations. + */ + Priority_Node Priority; + + /** + * This field contains the length of the next period to be + * executed. + */ + uint32_t next_length; + + /** + * This field contains a pointer to the TCB for the thread + * which owns and uses this period instance. + */ + Thread_Control *owner; + + /** + * This field contains the cpu usage value of the owning thread when + * the period was initiated. It is used to compute the period's + * statistics. + */ + Timestamp_Control cpu_usage_period_initiated; + + /** + * This field contains the wall time value when the period + * was initiated. It is used to compute the period's statistics. + */ + Timestamp_Control time_period_initiated; + + /** + * This field contains the statistics maintained for the period. + */ + Rate_monotonic_Statistics Statistics; + + /** + * This field contains the number of postponed jobs. + * When the watchdog timeout, this variable will be increased immediately. + */ + uint32_t postponed_jobs; + + /** + * This field contains the tick of the latest deadline decided by the period + * watchdog. + */ + uint64_t latest_deadline; +} Rate_monotonic_Control; + +/** + * @brief Create a Period + * + * Rate Monotonic Manager + * + * This routine implements the rate_monotonic_create directive. The + * period will have the name name. It returns the id of the + * created period in ID. + */ +rtems_status_code rtems_rate_monotonic_create( + rtems_name name, + rtems_id *id +); + +/** + * @brief RTEMS Rate Monotonic Name to Id + * + * This routine implements the rtems_rate_monotonic_ident directive. + * It returns the period ID associated with name. If more than one period + * is named name, then the period to which the ID belongs is arbitrary. + * + * @param[in] name is the user defined period name + * @param[in] id is the pointer to period id + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. If successful, the id will + * be filled in with the region id. + */ +rtems_status_code rtems_rate_monotonic_ident( + rtems_name name, + rtems_id *id +); + +/** + * @brief RTEMS Rate Monotonic Cancel + * + * This routine implements the rtems_rate_monotonic_cancel directive. This + * directive stops the period associated with ID from continuing to + * run. + * + * @param[in] id is the rate monotonic id + * + * @retval RTEMS_SUCCESSFUL if successful and caller is not the owning thread + * or error code if unsuccessful + * + */ +rtems_status_code rtems_rate_monotonic_cancel( + rtems_id id +); + +/** + * @brief RTEMS Delete Rate Monotonic + * + * This routine implements the rtems_rate_monotonic_delete directive. The + * period indicated by ID is deleted. + * + * @param[in] id is the rate monotonic id + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + */ +rtems_status_code rtems_rate_monotonic_delete( + rtems_id id +); + +/** + * @brief RTEMS Rate Monotonic Get Status + * + * This routine implements the rtems_rate_monotonic_get_status directive. + * Information about the period indicated by ID is returned. + * + * @param[in] id is the rate monotonic id + * @param[in] status is the pointer to status control block + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + * + */ +rtems_status_code rtems_rate_monotonic_get_status( + rtems_id id, + rtems_rate_monotonic_period_status *status +); + +/** + * @brief RTEMS Rate Monotonic Get Statistics + * + * This routine implements the rtems_rate_monotonic_get_statistics directive. + * Statistics gathered from the use of this period are returned. + * + * @param[in] id is the rate monotonic id + * @param[in] statistics is the pointer to statistics control block + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful + */ +rtems_status_code rtems_rate_monotonic_get_statistics( + rtems_id id, + rtems_rate_monotonic_period_statistics *statistics +); + +/** + * @brief RTEMS Rate Monotonic Reset Statistics + * + * Rate Monotonic Manager -- Reset Statistics + * + * This routine allows a thread to reset the statistics information + * on a specific period instance. + */ +rtems_status_code rtems_rate_monotonic_reset_statistics( + rtems_id id +); + +/** + * @brief rtems_rate_monotonic_reset_all_statistics + * + * This routine allows a thread to reset the statistics information + * on ALL period instances. + */ +void rtems_rate_monotonic_reset_all_statistics( void ); + +/** + * @brief RTEMS Report Rate Monotonic Statistics + * + * This routine allows a thread to print the statistics information + * on ALL period instances which have non-zero counts using the RTEMS + * printer. The implementation of this directive straddles the fence + * between inside and outside of RTEMS. It is presented as part of + * the Manager but actually uses other services of the Manager. + */ +void rtems_rate_monotonic_report_statistics_with_plugin( + const struct rtems_printer *printer +); + +/** + * @brief RTEMS Report Rate Monotonic Statistics + * + * This routine allows a thread to print the statistics information + * on ALL period instances which have non-zero counts using printk. + */ +void rtems_rate_monotonic_report_statistics( void ); + +/** + * @brief RTEMS Rate Monotonic Period + * + * This routine implements the rtems_rate_monotonic_period directive. When + * length is non-zero, this directive initiates the period associated with + * ID from continuing for a period of length. If length is zero, then + * result is set to indicate the current state of the period. + * + * @param[in] id is the rate monotonic id + * @param[in] length is the length of period (in ticks) + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful + */ +rtems_status_code rtems_rate_monotonic_period( + rtems_id id, + rtems_interval length +); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/ratemonimpl.h b/cpukit/include/rtems/rtems/ratemonimpl.h new file mode 100644 index 0000000000..ba38a3e61a --- /dev/null +++ b/cpukit/include/rtems/rtems/ratemonimpl.h @@ -0,0 +1,158 @@ +/** + * @file + * + * @ingroup ClassicRateMonImpl + * + * @brief Classic Rate Monotonic Scheduler Implementation + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * Copyright (c) 2016 embedded brains GmbH. + * COPYRIGHT (c) 2016 Kuan-Hsun Chen. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_RATEMONIMPL_H +#define _RTEMS_RTEMS_RATEMONIMPL_H + +#include <rtems/rtems/ratemon.h> +#include <rtems/score/objectimpl.h> +#include <rtems/score/schedulerimpl.h> +#include <rtems/score/threadimpl.h> +#include <rtems/score/watchdogimpl.h> + +#include <string.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicRateMonImpl Classic Rate Monotonic Scheduler Implementation + * + * @ingroup ClassicRateMon + * + * @{ + */ + +#define RATE_MONOTONIC_INTEND_TO_BLOCK \ + ( THREAD_WAIT_CLASS_PERIOD | THREAD_WAIT_STATE_INTEND_TO_BLOCK ) + +#define RATE_MONOTONIC_BLOCKED \ + ( THREAD_WAIT_CLASS_PERIOD | THREAD_WAIT_STATE_BLOCKED ) + +#define RATE_MONOTONIC_READY_AGAIN \ + ( THREAD_WAIT_CLASS_PERIOD | THREAD_WAIT_STATE_READY_AGAIN ) + +/** + * @brief Rate Monotonic Period Class Management Structure + * + * This instance of Objects_Information is used to manage the + * set of rate monotonic period instances. + */ +extern Objects_Information _Rate_monotonic_Information; + +/** + * @brief Allocates a period control block from + * the inactive chain of free period control blocks. + * + * This function allocates a period control block from + * the inactive chain of free period control blocks. + */ +RTEMS_INLINE_ROUTINE Rate_monotonic_Control *_Rate_monotonic_Allocate( void ) +{ + return (Rate_monotonic_Control *) + _Objects_Allocate( &_Rate_monotonic_Information ); +} + +RTEMS_INLINE_ROUTINE void _Rate_monotonic_Acquire_critical( + Rate_monotonic_Control *the_period, + ISR_lock_Context *lock_context +) +{ + _ISR_lock_Acquire( &the_period->Lock, lock_context ); +} + +RTEMS_INLINE_ROUTINE void _Rate_monotonic_Release( + Rate_monotonic_Control *the_period, + ISR_lock_Context *lock_context +) +{ + _ISR_lock_Release_and_ISR_enable( &the_period->Lock, lock_context ); +} + +RTEMS_INLINE_ROUTINE Rate_monotonic_Control *_Rate_monotonic_Get( + Objects_Id id, + ISR_lock_Context *lock_context +) +{ + return (Rate_monotonic_Control *) + _Objects_Get( id, lock_context, &_Rate_monotonic_Information ); +} + +void _Rate_monotonic_Timeout( Watchdog_Control *watchdog ); + +/** + * @brief _Rate_monotonic_Get_status( + * + * This routine is invoked to compute the elapsed wall time and cpu + * time for a period. + * + * @param[in] the_period points to the period being operated upon. + * @param[out] wall_since_last_period is set to the wall time elapsed + * since the period was initiated. + * @param[out] cpu_since_last_period is set to the cpu time used by the + * owning thread since the period was initiated. + * + * @retval This routine returns true if the status can be determined + * and false otherwise. + */ +bool _Rate_monotonic_Get_status( + const Rate_monotonic_Control *the_period, + Timestamp_Control *wall_since_last_period, + Timestamp_Control *cpu_since_last_period +); + +void _Rate_monotonic_Restart( + Rate_monotonic_Control *the_period, + Thread_Control *owner, + ISR_lock_Context *lock_context +); + +void _Rate_monotonic_Cancel( + Rate_monotonic_Control *the_period, + Thread_Control *owner, + ISR_lock_Context *lock_context +); + +RTEMS_INLINE_ROUTINE void _Rate_monotonic_Reset_min_time( + Timestamp_Control *min_time +) +{ + _Timestamp_Set( min_time, 0x7fffffff, 0x7fffffff ); +} + +RTEMS_INLINE_ROUTINE void _Rate_monotonic_Reset_statistics( + Rate_monotonic_Control *the_period +) +{ + Rate_monotonic_Statistics *statistics; + + statistics = &the_period->Statistics; + memset( statistics, 0, sizeof( *statistics ) ); + _Rate_monotonic_Reset_min_time( &statistics->min_wall_time ); + _Rate_monotonic_Reset_min_time( &statistics->min_cpu_time ); +} + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/region.h b/cpukit/include/rtems/rtems/region.h new file mode 100644 index 0000000000..4772e2835b --- /dev/null +++ b/cpukit/include/rtems/rtems/region.h @@ -0,0 +1,298 @@ +/** + * @file rtems/rtems/region.h + * + * @defgroup ClassicRegion Regions + * + * @ingroup ClassicRTEMS + * @brief Region Manager + * + * This include file contains all the constants and structures associated + * with the Region Manager. This manager provides facilities to dynamically + * allocate memory in variable sized units which are returned as segments. + * + * Directives provided are: + * + * - create a region + * - get an ID of a region + * - delete a region + * - get a segment from a region + * - return a segment to a region + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_REGION_H +#define _RTEMS_RTEMS_REGION_H + +#include <rtems/rtems/attr.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/types.h> +#include <rtems/score/heap.h> +#include <rtems/score/threadq.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicRegion Regions + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the Classic API Region + * Manager. + */ +/**@{*/ + +/** + * The following records define the control block used to manage + * each region. + */ + +typedef struct { + Objects_Control Object; + Thread_queue_Control Wait_queue; /* waiting threads */ + const Thread_queue_Operations *wait_operations; + uintptr_t maximum_segment_size; /* in bytes */ + rtems_attribute attribute_set; + Heap_Control Memory; +} Region_Control; + +/** + * @brief rtems_region_create + * + * Region Manager + * + * This routine implements the rtems_region_create directive. The + * region will have the name name. The memory area managed by + * the region is of length bytes and starts at starting_address. + * The memory area will be divided into as many allocatable units of + * page_size bytes as possible. The attribute_set determines which + * thread queue discipline is used by the region. It returns the + * id of the created region in ID. + */ +rtems_status_code rtems_region_create( + rtems_name name, + void *starting_address, + uintptr_t length, + uintptr_t page_size, + rtems_attribute attribute_set, + rtems_id *id +); + +/** + * @brief RTEMS Extend Region + * + * This routine implements the rtems_region_extend directive. The + * region will have the name name. The memory area managed by + * the region will be attempted to be grown by length bytes using + * the memory starting at starting_address. + * + * @param[in] id is the id of region to grow + * @param[in] starting_address starting address of memory area for extension + * @param[in] length is the physical length in bytes to grow the region + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + */ +rtems_status_code rtems_region_extend( + rtems_id id, + void *starting_address, + uintptr_t length +); + +/** + * @brief RTEMS Region Name to Id + * + * This routine implements the rtems_region_ident directive. + * This directive returns the region ID associated with name. + * If more than one region is named name, then the region + * to which the ID belongs is arbitrary. + * + * @param[in] name is the user defined region name + * @param[in] id is the pointer to region id + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. If successful, the id will + * be filled in with the region id. + */ +rtems_status_code rtems_region_ident( + rtems_name name, + rtems_id *id +); + +/** + * @brief RTEMS Get Region Information + * + * This routine implements the rtems_region_get_information directive. + * This directive returns information about the heap associated with + * this region. + * + * @param[in] id is the region id + * @param[in] the_info is the pointer to region information block + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and + * *id filled with the region information block + */ +rtems_status_code rtems_region_get_information( + rtems_id id, + Heap_Information_block *the_info +); + +/** + * @brief RTEMS Get Region Free Information + * + * This routine implements the rtems_region_get_free_information directive. + * This directive returns information about the free blocks in the + * heap associated with this region. Information about the used blocks + * will be returned as zero. + * + * @param[in] id is the region id + * @param[in] the_info is the pointer to region information block + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. If successful, the the_info will + * be filled in with the region information block. + */ +rtems_status_code rtems_region_get_free_information( + rtems_id id, + Heap_Information_block *the_info +); + +/** + * @brief RTEMS Delete Region + * + * This routine implements the rtems_region_delete directive. The + * region indicated by ID is deleted, provided that none of its segments are + * still allocated. + * + * @param[in] id is the region id + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + */ +rtems_status_code rtems_region_delete( + rtems_id id +); + +/** + * @brief RTEMS Get Region Segment + * + * This routine implements the rtems_region_get_segment directive. It + * attempts to allocate a segment from the region associated with @a id. + * If a segment of the requested @a size size can be allocated, its address + * is returned in @a segment. If no segment is available, then the task + * may return immediately or block waiting for a segment with an optional + * timeout of @a timeout clock ticks. Whether the task blocks or returns + * immediately is based on the no_wait option in the @a option_set. + * + * @param[in] id is the region id + * @param[in] size is the segment size in bytes + * @param[in] option_set is the wait option + * @param[in] timeout is the number of ticks to wait (0 means wait forever) + * @param[in] segment is the pointer to segment address + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. If successful, the segment will + * be filled in with the segment address. + */ +rtems_status_code rtems_region_get_segment( + rtems_id id, + uintptr_t size, + rtems_option option_set, + rtems_interval timeout, + void **segment +); + +/** + * @brief RTEMS Get Region Segment Size + * + * This routine implements the rtems_region_get_segment_size directive. It + * returns the size in bytes of the specified user memory area. + * + * @param[in] id is the region id + * @param[in] segment is the segment address + * @param[in] size is the pointer to segment size in bytes + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. If successful, the size will + * be filled in with the segment size in bytes. + */ +rtems_status_code rtems_region_get_segment_size( + rtems_id id, + void *segment, + uintptr_t *size +); + +/** + * @brief RTEMS Return Region Segment + * + * This routine implements the rtems_region_return_segment directive. It + * frees the segment to the region associated with ID. The segment must + * have been previously allocated from the same region. If freeing the + * segment results in enough memory being available to satisfy the + * rtems_region_get_segment of the first blocked task, then that task and as + * many subsequent tasks as possible will be unblocked with their requests + * satisfied. + * + * @param[in] id is the region id + * @param[in] segment is the pointer to segment address + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful + */ +rtems_status_code rtems_region_return_segment( + rtems_id id, + void *segment +); + +/** + * @brief Resize RTEMS Region Segment + * + * This routine implements the rtems_region_resize_segment directive. It + * tries to resize segment in the region associated with 'id' to the new size + * 'size' in place. The first 'size' or old size bytes of the segment + * (whatever is less) are guaranteed to remain unmodified. The segment must + * have been previously allocated from the same region. If resizing the + * segment results in enough memory being available to satisfy the + * rtems_region_get_segment of the first blocked task, then that task and as + * many subsequent tasks as possible will be unblocked with their requests + * satisfied. + * + * @param[in] id is the region id + * @param[in] segment is the pointer to segment address + * @param[in] size is the new required size + * @retval RTEMS_SUCCESSFUL if operation successful, RTEMS_UNSATISFIED if the + * the segment can't be resized in place or any other code at failure + * + * @note On RTEMS_SUCCESSFUL or RTEMS_UNSATISFIED exit it returns into the + * 'old_size' the old size in bytes of the user memory area of the + * specified segment. + */ +rtems_status_code rtems_region_resize_segment( + rtems_id id, + void *segment, + uintptr_t size, + uintptr_t *old_size +); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/regionimpl.h b/cpukit/include/rtems/rtems/regionimpl.h new file mode 100644 index 0000000000..178b7ea32b --- /dev/null +++ b/cpukit/include/rtems/rtems/regionimpl.h @@ -0,0 +1,142 @@ +/** + * @file + * + * @ingroup ClassicRegionImpl + * + * @brief Classic Region Manager Implementation + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_REGIONIMPL_H +#define _RTEMS_RTEMS_REGIONIMPL_H + +#include <rtems/rtems/region.h> +#include <rtems/score/apimutex.h> +#include <rtems/score/heapimpl.h> +#include <rtems/score/objectimpl.h> +#include <rtems/score/threadqimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicRegionImpl Classic Region Manager Implementation + * + * @ingroup ClassicRegion + * + * @{ + */ + +#define REGION_OF_THREAD_QUEUE_QUEUE( queue ) \ + RTEMS_CONTAINER_OF( queue, Region_Control, Wait_queue.Queue ) + +/** + * The following defines the information control block used to + * manage this class of objects. + */ +extern Objects_Information _Region_Information; + +/** + * @brief Region_Allocate + * + * This function allocates a region control block from + * the inactive chain of free region control blocks. + */ +RTEMS_INLINE_ROUTINE Region_Control *_Region_Allocate( void ) +{ + return (Region_Control *) _Objects_Allocate( &_Region_Information ); +} + +/** + * @brief Region_Free + * + * This routine frees a region control block to the + * inactive chain of free region control blocks. + */ +RTEMS_INLINE_ROUTINE void _Region_Free ( + Region_Control *the_region +) +{ + _Thread_queue_Destroy( &the_region->Wait_queue ); + _Objects_Free( &_Region_Information, &the_region->Object ); +} + +RTEMS_INLINE_ROUTINE Region_Control *_Region_Get_and_lock( Objects_Id id ) +{ + Region_Control *the_region; + + _RTEMS_Lock_allocator(); + + the_region = (Region_Control *) + _Objects_Get_no_protection( id, &_Region_Information ); + + if ( the_region != NULL ) { + /* Keep allocator lock */ + return the_region; + } + + _RTEMS_Unlock_allocator(); + return NULL; +} + +RTEMS_INLINE_ROUTINE void _Region_Unlock( Region_Control *the_region ) +{ + (void) the_region; + _RTEMS_Unlock_allocator(); +} + +/** + * @brief Region_Allocate_segment + * + * This function attempts to allocate a segment from the_region. + * If successful, it returns the address of the allocated segment. + * Otherwise, it returns NULL. + */ +RTEMS_INLINE_ROUTINE void *_Region_Allocate_segment ( + Region_Control *the_region, + uintptr_t size +) +{ + return _Heap_Allocate( &the_region->Memory, size ); +} + +/** + * @brief Region_Free_segment + * + * This function frees the_segment to the_region. + */ +RTEMS_INLINE_ROUTINE bool _Region_Free_segment ( + Region_Control *the_region, + void *the_segment +) +{ + return _Heap_Free( &the_region->Memory, the_segment ); +} + +/** + * @brief Process Region Queue + * + * This is a helper routine which is invoked any time memory is + * freed. It looks at the set of waiting tasks and attempts to + * satisfy all outstanding requests. + * + * @param[in] the_region is the the region + */ +extern void _Region_Process_queue(Region_Control *the_region); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/sem.h b/cpukit/include/rtems/rtems/sem.h new file mode 100644 index 0000000000..41b0061979 --- /dev/null +++ b/cpukit/include/rtems/rtems/sem.h @@ -0,0 +1,278 @@ +/** + * @file + * + * @ingroup ClassicSem + * + * @brief Classic Semaphores API + * + * This include file contains all the constants and structures associated + * with the Semaphore Manager. This manager utilizes standard Dijkstra + * counting semaphores to provide synchronization and mutual exclusion + * capabilities. + * + * Directives provided are: + * + * - create a semaphore + * - get an ID of a semaphore + * - delete a semaphore + * - acquire a semaphore + * - release a semaphore + * - flush a semaphore + * - set ceiling priority for a semaphore + */ + +/* + * COPYRIGHT (c) 1989-2008, 2016. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_SEM_H +#define _RTEMS_RTEMS_SEM_H + +#include <rtems/rtems/types.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/tasks.h> +#include <rtems/rtems/attr.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/object.h> +#include <rtems/score/coresem.h> +#include <rtems/score/mrsp.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicSem Semaphores + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the Classic API + * Semaphore Manager. + */ +/**@{*/ + +/** + * The following defines the control block used to manage each semaphore. + */ +typedef struct { + /** This field is the object management portion of a Semaphore instance. */ + Objects_Control Object; + + /** + * This contains the memory associated with the SuperCore Semaphore or + * Mutex instance that provides the primary functionality of each + * Classic API Semaphore instance. The structure used is dependent + * on the attributes specified by the user on the create directive. + * + * @note Only one of these has meaning in a particular Classic API + * Semaphore instance. + */ + union { + /** + * @brief The thread queue present in all other variants. + */ + Thread_queue_Control Wait_queue; + + /** + * This is the SuperCore Mutex instance associated with this Classic + * API Semaphore instance. + */ + CORE_ceiling_mutex_Control Mutex; + + /** + * This is the SuperCore Semaphore instance associated with this Classic + * API Semaphore instance. + */ + CORE_semaphore_Control Semaphore; + +#if defined(RTEMS_SMP) + MRSP_Control MRSP; +#endif + } Core_control; + + /** + * @brief The semaphore variant. + * + * @see Semaphore_Variant. + */ + unsigned int variant : 3; + + /** + * @brief The semaphore thread queue discipline. + * + * @see Semaphore_Discipline. + */ + unsigned int discipline : 1; + +#if defined(RTEMS_MULTIPROCESSING) + unsigned int is_global : 1; +#endif +} Semaphore_Control; + +/** + * @brief rtems_semaphore_create + * + * This routine implements the rtems_semaphore_create directive. The + * semaphore will have the name name. The starting count for + * the semaphore is count. The attribute_set determines if + * the semaphore is global or local and the thread queue + * discipline. It returns the id of the created semaphore in ID. + */ +rtems_status_code rtems_semaphore_create( + rtems_name name, + uint32_t count, + rtems_attribute attribute_set, + rtems_task_priority priority_ceiling, + rtems_id *id +); + +/** + * @brief RTEMS Semaphore Name to Id + * + * This routine implements the rtems_semaphore_ident directive. + * This directive returns the semaphore ID associated with name. + * If more than one semaphore is named name, then the semaphore + * to which the ID belongs is arbitrary. node indicates the + * extent of the search for the ID of the semaphore named name. + * The search can be limited to a particular node or allowed to + * encompass all nodes. + * + * @param[in] name is the user defined semaphore name + * @param[in] node is(are) the node(s) to be searched + * @param[in] id is the pointer to semaphore id + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and + * *id filled in with the semaphore id + */ +rtems_status_code rtems_semaphore_ident( + rtems_name name, + uint32_t node, + rtems_id *id +); + +/** + * @brief RTEMS Delete Semaphore + * + * This routine implements the rtems_semaphore_delete directive. The + * semaphore indicated by ID is deleted. + * + * @param[in] id is the semaphore id + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + */ +rtems_status_code rtems_semaphore_delete( + rtems_id id +); + +/** + * @brief RTEMS Obtain Semaphore + * + * This routine implements the rtems_semaphore_obtain directive. It + * attempts to obtain a unit from the semaphore associated with ID. + * If a unit can be allocated, the calling task will return immediately. + * If no unit is available, then the task may return immediately or + * block waiting for a unit with an optional timeout of timeout + * clock ticks. Whether the task blocks or returns immediately + * is based on the RTEMS_NO_WAIT option in the option_set. + * + * @param[in] id is the semaphore id + * @param[in] option_set is the wait option + * @param[in] timeout is the number of ticks to wait (0 means wait forever) + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + */ +rtems_status_code rtems_semaphore_obtain( + rtems_id id, + rtems_option option_set, + rtems_interval timeout +); + +/** + * @brief RTEMS Semaphore Release + * + * This routine implements the rtems_semaphore_release directive. It + * frees a unit to the semaphore associated with ID. If a task was + * blocked waiting for a unit from this semaphore, then that task will + * be readied and the unit given to that task. Otherwise, the unit + * will be returned to the semaphore. + */ +rtems_status_code rtems_semaphore_release( + rtems_id id +); + +/** + * @brief RTEMS Semaphore Flush + * + * This method is the implementation of the flush directive + * of the Semaphore Manager. + * + * This directive allows a thread to flush the threads + * pending on the semaphore. + * + * @param[in] id is the semaphore id + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful + */ +rtems_status_code rtems_semaphore_flush( + rtems_id id +); + +/** + * @brief Sets the priority value with respect to the specified scheduler of a + * semaphore. + * + * The special priority value @ref RTEMS_CURRENT_PRIORITY can be used to get + * the current priority value without changing it. + * + * The interpretation of the priority value depends on the protocol of the + * semaphore object. + * + * - The Multiprocessor Resource Sharing Protocol needs a ceiling priority per + * scheduler instance. This operation can be used to specify these priority + * values. + * - For the Priority Ceiling Protocol the ceiling priority is used with this + * operation. + * - For other protocols this operation is not defined. + * + * @param[in] semaphore_id Identifier of the semaphore. + * @param[in] scheduler_id Identifier of the scheduler. + * @param[in] new_priority The new priority value. Use + * @ref RTEMS_CURRENT_PRIORITY to not set a new priority and only get the + * current priority. + * @param[out] old_priority Reference to store the old priority value. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID Invalid semaphore or scheduler identifier. + * @retval RTEMS_INVALID_ADDRESS The old priority reference is @c NULL. + * @retval RTEMS_INVALID_PRIORITY The new priority value is invalid. + * @retval RTEMS_NOT_DEFINED The set priority operation is not defined for the + * protocol of this semaphore object. + * @retval RTEMS_ILLEGAL_ON_REMOTE_OBJECT Not supported for remote semaphores. + * + * @see rtems_scheduler_ident() and rtems_task_set_priority(). + */ +rtems_status_code rtems_semaphore_set_priority( + rtems_id semaphore_id, + rtems_id scheduler_id, + rtems_task_priority new_priority, + rtems_task_priority *old_priority +); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/semimpl.h b/cpukit/include/rtems/rtems/semimpl.h new file mode 100644 index 0000000000..6d0f156e5c --- /dev/null +++ b/cpukit/include/rtems/rtems/semimpl.h @@ -0,0 +1,120 @@ +/** + * @file + * + * @ingroup ClassicSem + * + * @brief Classic Semaphores Implementation + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_SEMIMPL_H +#define _RTEMS_RTEMS_SEMIMPL_H + +#include <rtems/rtems/sem.h> +#include <rtems/score/coremuteximpl.h> +#include <rtems/score/coresemimpl.h> +#include <rtems/score/mrspimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Classic semaphore variants. + * + * Must be in synchronization with Semaphore_Control::variant. + */ +typedef enum { + SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY, + SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING, + SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL, + SEMAPHORE_VARIANT_SIMPLE_BINARY, + SEMAPHORE_VARIANT_COUNTING +#if defined(RTEMS_SMP) + , + SEMAPHORE_VARIANT_MRSP +#endif +} Semaphore_Variant; + +typedef enum { + SEMAPHORE_DISCIPLINE_PRIORITY, + SEMAPHORE_DISCIPLINE_FIFO +} Semaphore_Discipline; + +/** + * The following defines the information control block used to manage + * this class of objects. + */ +extern Objects_Information _Semaphore_Information; + +RTEMS_INLINE_ROUTINE const Thread_queue_Operations *_Semaphore_Get_operations( + const Semaphore_Control *the_semaphore +) +{ + if ( the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY ) { + return &_Thread_queue_Operations_priority_inherit; + } + + if ( the_semaphore->discipline == SEMAPHORE_DISCIPLINE_PRIORITY ) { + return &_Thread_queue_Operations_priority; + } + + return &_Thread_queue_Operations_FIFO; +} + +/** + * @brief Allocates a semaphore control block from + * the inactive chain of free semaphore control blocks. + * + * This function allocates a semaphore control block from + * the inactive chain of free semaphore control blocks. + */ +RTEMS_INLINE_ROUTINE Semaphore_Control *_Semaphore_Allocate( void ) +{ + return (Semaphore_Control *) _Objects_Allocate( &_Semaphore_Information ); +} + +/** + * @brief Frees a semaphore control block to the + * inactive chain of free semaphore control blocks. + * + * This routine frees a semaphore control block to the + * inactive chain of free semaphore control blocks. + */ +RTEMS_INLINE_ROUTINE void _Semaphore_Free ( + Semaphore_Control *the_semaphore +) +{ + _Objects_Free( &_Semaphore_Information, &the_semaphore->Object ); +} + +RTEMS_INLINE_ROUTINE Semaphore_Control *_Semaphore_Get( + Objects_Id id, + Thread_queue_Context *queue_context +) +{ + _Thread_queue_Context_initialize( queue_context ); + return (Semaphore_Control *) _Objects_Get( + id, + &queue_context->Lock_context.Lock_context, + &_Semaphore_Information + ); +} + +#ifdef __cplusplus +} +#endif + +#ifdef RTEMS_MULTIPROCESSING +#include <rtems/rtems/semmp.h> +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/semmp.h b/cpukit/include/rtems/rtems/semmp.h new file mode 100644 index 0000000000..9d7669f43e --- /dev/null +++ b/cpukit/include/rtems/rtems/semmp.h @@ -0,0 +1,171 @@ +/** + * @file rtems/rtems/semmp.h + * + * @defgroup ClassicSEM Semaphore MP Support + * + * @ingroup ClassicRTEMS + * @brief Semaphore Manager MP Support + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Semaphore Manager. + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_SEMMP_H +#define _RTEMS_RTEMS_SEMMP_H + +#ifndef _RTEMS_RTEMS_SEMIMPL_H +# error "Never use <rtems/rtems/semmp.h> directly; include <rtems/rtems/semimpl.h> instead." +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicSEM Semaphore MP Support + * + * @ingroup ClassicMP + * + * This encapsulates functionality related to the transparent multiprocessing + * support within the Classic API Semaphore Manager. + */ +/**@{*/ + +/** + * The following enumerated type defines the list of + * remote semaphore operations. + */ +typedef enum { + SEMAPHORE_MP_ANNOUNCE_CREATE = 0, + SEMAPHORE_MP_ANNOUNCE_DELETE = 1, + SEMAPHORE_MP_EXTRACT_PROXY = 2, + SEMAPHORE_MP_OBTAIN_REQUEST = 3, + SEMAPHORE_MP_OBTAIN_RESPONSE = 4, + SEMAPHORE_MP_RELEASE_REQUEST = 5, + SEMAPHORE_MP_RELEASE_RESPONSE = 6 +} Semaphore_MP_Remote_operations; + +/** + * The following data structure defines the packet used to perform + * remote semaphore operations. + */ +typedef struct { + rtems_packet_prefix Prefix; + Semaphore_MP_Remote_operations operation; + rtems_name name; + rtems_option option_set; + Objects_Id proxy_id; +} Semaphore_MP_Packet; + +RTEMS_INLINE_ROUTINE bool _Semaphore_MP_Is_remote( Objects_Id id ) +{ + return _Objects_MP_Is_remote( id, &_Semaphore_Information ); +} + +/** + * @brief Semaphore MP Send Process Packet + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + */ +void _Semaphore_MP_Send_process_packet ( + Semaphore_MP_Remote_operations operation, + Objects_Id semaphore_id, + rtems_name name, + Objects_Id proxy_id +); + +/** + * @brief Issues a remote rtems_semaphore_obtain() request. + */ +rtems_status_code _Semaphore_MP_Obtain( + rtems_id id, + rtems_option option_set, + rtems_interval timeout +); + +/** + * @brief Issues a remote rtems_semaphore_release() request. + */ +rtems_status_code _Semaphore_MP_Release( rtems_id id ); + +/** + * @brief Semaphore MP Process Packet + * + * This routine performs the actions specific to this package for + * the request from another node. + */ +void _Semaphore_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +); + +/** + * @brief Semaphore MP Send Object was Deleted + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + */ +void _Semaphore_MP_Send_object_was_deleted ( + Thread_Control *the_proxy, + Objects_Id mp_id +); + +/** + * @brief Semaphore MP Send Extract Proxy + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + */ +void _Semaphore_MP_Send_extract_proxy ( + Thread_Control *the_thread, + Objects_Id id +); + +/** + * @brief Semaphore Core Mutex MP Support + * + * This function processes the global actions necessary for remote + * accesses to a global semaphore based on a core mutex. This function + * is called by the core. + * + * @param[in] the_thread the remote thread the semaphore was surrendered to + * @param[in] id is the id of the surrendered semaphore + */ +void _Semaphore_Core_mutex_mp_support ( + Thread_Control *the_thread, + Objects_Id id +); + +/** + * @brief Semaphore Core MP Support + * + * This function processes the global actions necessary for remote + * accesses to a global semaphore based on a core semaphore. This function + * is called by the core. + * + * @param[in] the_thread the remote thread the semaphore was surrendered to + * @param[in] id is the id of the surrendered semaphore + */ +void _Semaphore_Core_semaphore_mp_support ( + Thread_Control *the_thread, + Objects_Id id +); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of file */ diff --git a/cpukit/include/rtems/rtems/signal.h b/cpukit/include/rtems/rtems/signal.h new file mode 100644 index 0000000000..f7b7000d9a --- /dev/null +++ b/cpukit/include/rtems/rtems/signal.h @@ -0,0 +1,83 @@ +/** + * @file + * + * @ingroup ClassicSignal + * + * @brief Signals API + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_SIGNAL_H +#define _RTEMS_RTEMS_SIGNAL_H + +#include <rtems/rtems/asr.h> +#include <rtems/rtems/modes.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicSignal Signals + * + * @ingroup ClassicRTEMS + * + * Directives provided are: + * + * + establish an asynchronous signal routine + * + send a signal set to a task + */ +/**@{*/ + +/** + * @brief RTEMS Catch Signal + * + * This routine implements the rtems_signal_catch directive. This directive + * is used to establish asr_handler as the Asynchronous Signal Routine + * (RTEMS_ASR) for the calling task. The asr_handler will execute with a + * mode of mode_set. + * + * @param[in] asr_handler is the address of asynchronous signal routine (asr) + * ( NULL indicates asr is invalid ) + * @param[in] mode_set is the mode value for asr + * + * @retval RTEMS_SUCCESSFUL + */ +rtems_status_code rtems_signal_catch( + rtems_asr_entry asr_handler, + rtems_mode mode_set +); + +/** + * @brief RTEMS Send Signal + * + * This routine implements the rtems_signal_send directive. This directive + * sends the signal_set to the task specified by ID. + * + * @param[in] id is the thread thread id + * @param[in] signal_set is the signal set + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful + */ +rtems_status_code rtems_signal_send( + rtems_id id, + rtems_signal_set signal_set +); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/signalimpl.h b/cpukit/include/rtems/rtems/signalimpl.h new file mode 100644 index 0000000000..61848ae95c --- /dev/null +++ b/cpukit/include/rtems/rtems/signalimpl.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @ingroup ClassicSignalImpl + * + * @brief Signals Implementation + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_SIGNALIMPL_H +#define _RTEMS_RTEMS_SIGNALIMPL_H + +#include <rtems/rtems/signal.h> +#include <rtems/score/thread.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicSignalImpl Signals Implementation + * + * @ingroup ClassicSignal + */ +/**@{*/ + +void _Signal_Action_handler( + Thread_Control *executing, + Thread_Action *action, + ISR_lock_Context *lock_context +); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/rtems/signalmp.h> +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/signalmp.h b/cpukit/include/rtems/rtems/signalmp.h new file mode 100644 index 0000000000..57b8682c58 --- /dev/null +++ b/cpukit/include/rtems/rtems/signalmp.h @@ -0,0 +1,98 @@ +/** + * @file rtems/rtems/signalmp.h + * + * @brief Signal MP Support + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Signal Manager. + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_SIGNALMP_H +#define _RTEMS_RTEMS_SIGNALMP_H + +#ifndef _RTEMS_RTEMS_SIGNALIMPL_H +# error "Never use <rtems/rtems/signalmp.h> directly; include <rtems/rtems/signalimpl.h> instead." +#endif + +#include <rtems/score/mpciimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicSignalMP Signal MP Support + * + * @ingroup ClassicMP + * + * This encapsulates functionality related to the transparent multiprocessing + * support within the Classic API Signal Manager. + */ +/*{*/ + +/* + * @brief Signal_MP_Send_process_packet + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + * + * This routine is not needed since there are no process + * packets to be sent by this manager. + */ + +/** + * @brief Issues a remote rtems_signal_send() request. + */ +rtems_status_code _Signal_MP_Send( + rtems_id id, + rtems_signal_set signal_set +); + +/** + * @brief Signal MP Process Packet + * + * This routine performs the actions specific to this package for + * the request from another node. + */ +void _Signal_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +); + +/* + * @brief Signal_MP_Send_object_was_deleted + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + * + * This routine is not needed since there are no objects + * deleted by this manager. + */ + +/* + * @brief Signal_MP_Send_extract_proxy + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + * + * This routine is not needed since there are no objects + * deleted by this manager. + */ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of file */ diff --git a/cpukit/include/rtems/rtems/smp.h b/cpukit/include/rtems/rtems/smp.h new file mode 100644 index 0000000000..aeb0df6f46 --- /dev/null +++ b/cpukit/include/rtems/rtems/smp.h @@ -0,0 +1,78 @@ +/** + * @file + * + * @ingroup ClassicSMP + * + * @brief SMP Services API + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_SMP_H +#define _RTEMS_RTEMS_SMP_H + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicSMP SMP Services + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which is useful for SMP applications. + * + * @{ + */ + +/** + * @brief Returns the count of processors in the system. + * + * On uni-processor configurations a value of one will be returned. + * + * On SMP configurations this returns the value of a global variable set during + * system initialization to indicate the count of utilized processors. The + * processor count depends on the physically or virtually available processors + * and application configuration. The value will always be less than or equal + * to the maximum count of application configured processors. + * + * @return The count of processors being utilized. + */ +uint32_t rtems_get_processor_count(void); + +/** + * @brief Returns the index of the current processor. + * + * On uni-processor configurations a value of zero will be returned. + * + * On SMP configurations an architecture specific method is used to obtain the + * index of the current processor in the system. The set of processor indices + * is the range of integers starting with zero up to the processor count minus + * one. + * + * Outside of sections with disabled thread dispatching the current processor + * index may change after every instruction since the thread may migrate from + * one processor to another. Sections with disabled interrupts are sections + * with thread dispatching disabled. + * + * @return The index of the current processor. + */ +uint32_t rtems_get_current_processor(void); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/status.h b/cpukit/include/rtems/rtems/status.h new file mode 100644 index 0000000000..c54404ba14 --- /dev/null +++ b/cpukit/include/rtems/rtems/status.h @@ -0,0 +1,263 @@ +/** + * @file rtems/rtems/status.h + * + * @defgroup ClassicStatus Status Codes + * + * @ingroup ClassicRTEMS + * @brief Status Codes Returned from Executive Directives + * + * This include file contains the status codes returned from the + * executive directives. + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_STATUS_H +#define _RTEMS_RTEMS_STATUS_H + +#include <rtems/score/basedefs.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicStatus Status Codes + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the status codes returned + * by Classic API directives. + */ +/**@{*/ + +/** + * @brief Classic API Status + * + * This enumerates the possible status values returned b + * Classic API directives. + */ +typedef enum { + /** + * This is the status to indicate successful completion. + */ + RTEMS_SUCCESSFUL = 0, + /** + * This is the status to indicate that a thread exited. + */ + RTEMS_TASK_EXITTED = 1, + /** + * This is the status to indicate multiprocessing is not configured. + */ + RTEMS_MP_NOT_CONFIGURED = 2, + /** + * This is the status to indicate that the object name was invalid. + */ + RTEMS_INVALID_NAME = 3, + /** + * This is the status to indicate that the object Id was invalid. + */ + RTEMS_INVALID_ID = 4, + /** + * This is the status to indicate you have attempted to create too many + * instances of a particular object class. + */ + RTEMS_TOO_MANY = 5, + /** + * This is the status to indicate that a blocking directive timed out. + */ + RTEMS_TIMEOUT = 6, + /** + * This is the status to indicate the the object was deleted + * while the task was blocked waiting. + */ + RTEMS_OBJECT_WAS_DELETED = 7, + /** + * This is the status to indicate that the specified size was invalid. + */ + RTEMS_INVALID_SIZE = 8, + /** + * This is the status to indicate that the specified address is invalid. + */ + RTEMS_INVALID_ADDRESS = 9, + /** + * This is the status to indicate that the specified number was invalid. + */ + RTEMS_INVALID_NUMBER = 10, + /** + * This is the status to indicate that the item has not been initialized. + */ + RTEMS_NOT_DEFINED = 11, + /** + * This is the status to indicate that the object still has + * resources in use. + */ + RTEMS_RESOURCE_IN_USE = 12, + /** + * This is the status to indicate that the request was not satisfied. + */ + RTEMS_UNSATISFIED = 13, + /** + * This is the status to indicate that a thread is in wrong state + * was in the wrong execution state for the requested operation. + */ + RTEMS_INCORRECT_STATE = 14, + /** + * This is the status to indicate thread was already suspended. + */ + RTEMS_ALREADY_SUSPENDED = 15, + /** + * This is the status to indicate that the operation is illegal + * on calling thread. + */ + RTEMS_ILLEGAL_ON_SELF = 16, + /** + * This is the status to indicate illegal for remote object. + */ + RTEMS_ILLEGAL_ON_REMOTE_OBJECT = 17, + /** + * This is the status to indicate that the operation should not be + * called from from this excecution environment. + */ + RTEMS_CALLED_FROM_ISR = 18, + /** + * This is the status to indicate that an invalid thread priority + * was provided. + */ + RTEMS_INVALID_PRIORITY = 19, + /** + * This is the status to indicate that the specified date/time was invalid. + */ + RTEMS_INVALID_CLOCK = 20, + /** + * This is the status to indicate that the specified node Id was invalid. + */ + RTEMS_INVALID_NODE = 21, + /** + * This is the status to indicate that the directive was not configured. + */ + RTEMS_NOT_CONFIGURED = 22, + /** + * This is the status to indicate that the caller is not the + * owner of the resource. + */ + RTEMS_NOT_OWNER_OF_RESOURCE = 23, + /** + * This is the status to indicate the the directive or requested + * portion of the directive is not implemented. This is a hint + * that you have stumbled across an opportunity to submit code + * to the RTEMS Project. + */ + RTEMS_NOT_IMPLEMENTED = 24, + /** + * This is the status to indicate that an internal RTEMS inconsistency + * was detected. + */ + RTEMS_INTERNAL_ERROR = 25, + /** + * This is the status to indicate that the directive attempted to allocate + * memory but was unable to do so. + */ + RTEMS_NO_MEMORY = 26, + /** + * This is the status to indicate an driver IO error. + */ + RTEMS_IO_ERROR = 27, + /** + * This is the status is used internally to RTEMS when performing + * operations on behalf of remote tasks. This is referred to as + * proxying operations and this status indicates that the operation + * could not be completed immediately and the "proxy is blocking." + * + * @note This status will @b NOT be returned to the user. + */ + RTEMS_PROXY_BLOCKING = 28 +} rtems_status_code; + +/** + * This is the lowest valid value for a Classic API status code. + */ +#define RTEMS_STATUS_CODES_FIRST RTEMS_SUCCESSFUL + +/** + * This is the highest valid value for a Classic API status code. + */ +#define RTEMS_STATUS_CODES_LAST RTEMS_PROXY_BLOCKING + +/** + * @brief Checks if the status code is equal to RTEMS_SUCCESSFUL. + * + * This function returns TRUE if the status code is equal to RTEMS_SUCCESSFUL, + * and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool rtems_is_status_successful( + rtems_status_code code +) +{ + return (code == RTEMS_SUCCESSFUL); +} + +/** + * @brief Checks if the status code1 is equal to code2. + * + * This function returns TRUE if the status code1 is equal to code2, + * and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool rtems_are_statuses_equal( + rtems_status_code code1, + rtems_status_code code2 +) +{ + return (code1 == code2); +} + +/** + * @brief RTEMS Status Code to Errno Mapping Function + * + * This function recieves an RTEMS status code and returns an + * errno error code. The retval values show the mappings between + * rtems_status_codes and errno error codes. + * + * @retval 0 RTEMS_SUCCESSFUL + * @retval EIO RTEMS_TASK_EXITED, RTEMS_MP_NOT_CONFIGURED, RTEMS_INVALID_ID, + * RTEMS_TOO_MANY, RTEMS_OBJECT_WAS_DELETED, RTEMS_INVALID_SIZE, + * RTEMS_INVALID_ADDRESS, RTEMS_NOT_DEFINED, RTEMS_INCORRECT_STATE, + * RTEMS_ILLEGAL_ON_SELF, RTEMS_ILLEGAL_ON_REMOTE_OBJECT, + * RTEMS_CALLED_FROM_ISR, RTEMS_INVALID_PRIORITY, RTEMS_INTERNAL_ERROR, + * RTEMS_IO_ERROR, RTEMS_PROXY_BLOCKING + * @retval EINVAL RTEMS_INVALID_NAME, RTEMS_INVALID_CLOCK, RTEMS_INVALID_NODE + * @retval ETIMEDOUT RTEMS_TIMEOUT + * @retval EBADF RTEMS_INVALID_NUMBER + * @retval EBUSY RTEMS_RESOURCE_IN_USE + * @retval ENODEV RTEMS_UNSATISFIED + * @retval ENOSYS RTEMS_NOT_IMPLEMENTED, RTEMS_NOT_CONFIGURED + * @retval ENOMEM RTEMS_NO_MEMORY + */ +int rtems_status_code_to_errno(rtems_status_code sc); + +/** + * @brief Returns a text for a status code. + * + * The text for each status code is the enumerator constant. + * + * @param[in] code The status code. + * + * @retval text The status code text. + * @retval "?" The passed status code is invalid. + */ +const char *rtems_status_text( rtems_status_code code ); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/statusimpl.h b/cpukit/include/rtems/rtems/statusimpl.h new file mode 100644 index 0000000000..8a51bb8b19 --- /dev/null +++ b/cpukit/include/rtems/rtems/statusimpl.h @@ -0,0 +1,64 @@ +/** + * @file + * + * @ingroup ClassicStatusImpl + * + * @brief Classic Status Implementation + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_STATUSIMPL_H +#define _RTEMS_RTEMS_STATUSIMPL_H + +#include <rtems/rtems/status.h> +#include <rtems/score/threadimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicStatusImpl Classic Status Implementation + * + * @ingroup ClassicStatus + * + * @{ + */ + +/** + * @brief Status Object Name Errors to Status Array + * + * This array is used to map SuperCore Object Handler return + * codes to Classic API status codes. + */ +extern const rtems_status_code _Status_Object_name_errors_to_status[]; + +RTEMS_INLINE_ROUTINE rtems_status_code _Status_Get( + Status_Control status +) +{ + return (rtems_status_code) STATUS_GET_CLASSIC( status ); +} + +RTEMS_INLINE_ROUTINE rtems_status_code _Status_Get_after_wait( + const Thread_Control *executing +) +{ + return _Status_Get( _Thread_Wait_get_status( executing ) ); +} + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/support.h b/cpukit/include/rtems/rtems/support.h new file mode 100644 index 0000000000..4ebb50cbdf --- /dev/null +++ b/cpukit/include/rtems/rtems/support.h @@ -0,0 +1,170 @@ +/** + * @file + * + * @defgroup ClassicRTEMSWorkspace Workspace + * + * @ingroup ClassicRTEMS + * @brief Classic API support. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_SUPPORT_H +#define _RTEMS_RTEMS_SUPPORT_H + +#include <rtems/rtems/types.h> +#include <rtems/config.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup ClassicRTEMS + */ +/**@{**/ + +/** + * @brief Returns the number of micro seconds for the milli seconds value @a _ms. + */ +#define RTEMS_MILLISECONDS_TO_MICROSECONDS(_ms) ((_ms) * 1000UL) + +/** + * @brief Returns the number of ticks for the milli seconds value @a _ms. + */ +#define RTEMS_MILLISECONDS_TO_TICKS(_ms) \ + (RTEMS_MILLISECONDS_TO_MICROSECONDS(_ms) / \ + rtems_configuration_get_microseconds_per_tick()) + +/** + * @brief Returns the number of ticks for the micro seconds value @a _us. + */ +#define RTEMS_MICROSECONDS_TO_TICKS(_us) \ + ((_us) / rtems_configuration_get_microseconds_per_tick()) + +/** + * @brief Returns @c true if the name is valid, and @c false otherwise. + */ +RTEMS_INLINE_ROUTINE bool rtems_is_name_valid ( + rtems_name name +) +{ + return ( name != 0 ); +} + +/** + * @brief Breaks the object name into the four component characters @a c1, + * @a c2, @a c3, and @a c4. + */ +RTEMS_INLINE_ROUTINE void rtems_name_to_characters( + rtems_name name, + char *c1, + char *c2, + char *c3, + char *c4 +) +{ + *c1 = (char) ((name >> 24) & 0xff); + *c2 = (char) ((name >> 16) & 0xff); + *c3 = (char) ((name >> 8) & 0xff); + *c4 = (char) ( name & 0xff); +} + +/** @} */ + +/** + * @defgroup ClassicRTEMSWorkspace Workspace + * + * @ingroup ClassicRTEMS + * + * Workspace definitions. + */ +/**@{**/ + +/** + * @brief Gets Workspace Information + * + * Returns information about the heap that is used as the RTEMS Executive + * Workspace in @a the_info. + * + * Returns @c true if successful, and @a false otherwise. + */ +bool rtems_workspace_get_information( + Heap_Information_block *the_info +); + +/** + * @brief Allocates Memory from the Workspace + * + * A number of @a bytes bytes will be allocated from the RTEMS Executive + * Workspace and returned in @a pointer. + * + * Returns @c true if successful, and @a false otherwise. + */ +bool rtems_workspace_allocate( + size_t bytes, + void **pointer +); + +/** + * @brief Frees Memory Allocated from the Workspace + * + * This frees the memory indicated by @a pointer that was allocated from the + * RTEMS Executive Workspace. + * + * Returns @c true if successful, and @a false otherwise. + */ +bool rtems_workspace_free( + void *pointer +); + +/** + * @brief Greedy allocate that empties the workspace. + * + * Afterwards the heap has at most @a block_count allocatable blocks of sizes + * specified by @a block_sizes. The @a block_sizes must point to an array with + * @a block_count members. All other blocks are used. + * + * @see rtems_workspace_greedy_free(). + */ +void *rtems_workspace_greedy_allocate( + const uintptr_t *block_sizes, + size_t block_count +); + +/** + * @brief Greedy allocate all blocks except the largest free block. + * + * Afterwards the heap has at most one allocatable block. This block is the + * largest free block if it exists. The allocatable size of this block is + * stored in @a allocatable_size. All other blocks are used. + * + * @see rtems_workspace_greedy_free(). + */ +void *rtems_workspace_greedy_allocate_all_except_largest( + uintptr_t *allocatable_size +); + +/** + * @brief Frees space of a greedy allocation. + * + * The @a opaque argument must be the return value of + * rtems_workspace_greedy_allocate() or + * rtems_workspace_greedy_allocate_all_except_largest(). + */ +void rtems_workspace_greedy_free( void *opaque ); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/taskmp.h b/cpukit/include/rtems/rtems/taskmp.h new file mode 100644 index 0000000000..e2d70a924e --- /dev/null +++ b/cpukit/include/rtems/rtems/taskmp.h @@ -0,0 +1,132 @@ +/** + * @file rtems/rtems/taskmp.h + * + * @defgroup ClassicTaskMP Task MP Support + * + * @ingroup ClassicRTEMS + * @brief Task Manager MP Support + * + * This include file contains all the constants and structures associated + * with the multiprocessing support in the task manager. + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_TASKMP_H +#define _RTEMS_RTEMS_TASKMP_H + +#ifndef _RTEMS_RTEMS_TASKSIMPL_H +# error "Never use <rtems/rtems/taskmp.h> directly; include <rtems/rtems/tasksimpl.h> instead." +#endif + +#include <rtems/score/mpciimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicTaskMP Task MP Support + * + * @ingroup ClassicMP + * + * This encapsulates functionality related to the transparent multiprocessing + * support within the Classic API Task Manager. + */ +/**@{*/ + +/** + * The following enumerated type defines the list of + * remote task operations. + */ +typedef enum { + RTEMS_TASKS_MP_ANNOUNCE_CREATE = 0, + RTEMS_TASKS_MP_ANNOUNCE_DELETE = 1, + RTEMS_TASKS_MP_SUSPEND_REQUEST = 2, + RTEMS_TASKS_MP_SUSPEND_RESPONSE = 3, + RTEMS_TASKS_MP_RESUME_REQUEST = 4, + RTEMS_TASKS_MP_RESUME_RESPONSE = 5, + RTEMS_TASKS_MP_SET_PRIORITY_REQUEST = 6, + RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE = 7, +} RTEMS_tasks_MP_Remote_operations; + +/** + * @brief RTEMS Tasks MP Send Process Packet + * + * Multiprocessing Support for the RTEMS Task Manager + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + */ +void _RTEMS_tasks_MP_Send_process_packet ( + RTEMS_tasks_MP_Remote_operations operation, + Objects_Id task_id, + rtems_name name +); + +/** + * @brief Issues a remote rtems_task_set_priority() request. + */ +rtems_status_code _RTEMS_tasks_MP_Set_priority( + rtems_id id, + rtems_task_priority new_priority, + rtems_task_priority *old_priority +); + +/** + * @brief Issues a remote rtems_task_suspend() request. + */ +rtems_status_code _RTEMS_tasks_MP_Suspend( rtems_id id ); + +/** + * @brief Issues a remote rtems_task_resume() request. + */ +rtems_status_code _RTEMS_tasks_MP_Resume( rtems_id id ); + +/** + * @brief _RTEMS_tasks_MP_Process_packet + * + * This routine performs the actions specific to this package for + * the request from another node. + */ +void _RTEMS_tasks_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +); + +/** + * @brief _RTEMS_tasks_MP_Send_object_was_deleted + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + * + * This routine is not needed by RTEMS_tasks since a task + * cannot be deleted when segments are in use. + */ + +/* + * _RTEMS_tasks_MP_Send_extract_proxy + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + * + * This routine is not needed since there are no objects + * deleted by this manager. + * + */ + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of file */ diff --git a/cpukit/include/rtems/rtems/tasks.h b/cpukit/include/rtems/rtems/tasks.h new file mode 100644 index 0000000000..585f4c449c --- /dev/null +++ b/cpukit/include/rtems/rtems/tasks.h @@ -0,0 +1,716 @@ +/** + * @file rtems/rtems/tasks.h + * + * @defgroup ClassicTasks Tasks + * + * @ingroup ClassicRTEMS + * @brief RTEMS Tasks + * + * This include file contains all constants and structures associated + * with RTEMS tasks. This manager provides a comprehensive set of directives + * to create, delete, and administer tasks. + * + * Directives provided are: + * + * - create a task + * - get an ID of a task + * - start a task + * - restart a task + * - delete a task + * - suspend a task + * - resume a task + * - set a task's priority + * - change the current task's mode + * - wake up after interval + * - wake up when specified + */ + +/* + * COPYRIGHT (c) 1989-2014. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_TASKS_H +#define _RTEMS_RTEMS_TASKS_H + +#include <rtems/score/object.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/types.h> +#include <rtems/rtems/event.h> +#include <rtems/rtems/asr.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/status.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicTasks Tasks + * + * @ingroup ClassicRTEMS + * + * This encapsulates the functionality of the Classic API Task Manager. + * This functionality includes task services such as creation, deletion, + * delays, suspend/resume, and manipulation of execution mode and priority. + */ +/**@{*/ + +/** + * Constant to be used as the ID of current task + */ +#define RTEMS_SELF OBJECTS_ID_OF_SELF + +/** + * This constant is passed to the rtems_task_wake_after directive as the + * interval when a task wishes to yield the CPU. + */ +#define RTEMS_YIELD_PROCESSOR WATCHDOG_NO_TIMEOUT + +/** + * Define the type for an RTEMS API task priority. + */ +typedef uint32_t rtems_task_priority; + +/** + * This is the constant used with the rtems_task_set_priority + * directive to indicate that the caller wants to obtain its + * current priority rather than set it as the name of the + * directive indicates. + */ +#define RTEMS_NO_PRIORITY RTEMS_CURRENT_PRIORITY + +/** + * This constant is the least valid value for a Classic API + * task priority. + */ +#define RTEMS_MINIMUM_PRIORITY (PRIORITY_MINIMUM + 1) + +/** + * This constant is the maximum valid value for a Classic API + * task priority. + * + * @note This is actually the priority of the IDLE thread so + * using this priority will result in having a task + * which never executes. This could be useful if you + * want to ensure that a task does not executes during + * certain operations such as a system mode change. + */ +#define RTEMS_MAXIMUM_PRIORITY ((rtems_task_priority) PRIORITY_MAXIMUM) + +/** + * The following constant is passed to rtems_task_set_priority when the + * caller wants to obtain the current priority. + */ +#define RTEMS_CURRENT_PRIORITY PRIORITY_MINIMUM + +/** + * External API name for Thread_Control + */ +typedef Thread_Control rtems_tcb; + +/** + * The following defines the "return type" of an RTEMS task. + */ +typedef void rtems_task; + +/** + * The following defines the argument to an RTEMS task. + */ +typedef Thread_Entry_numeric_type rtems_task_argument; + +/** + * The following defines the type for the entry point of an RTEMS task. + */ +typedef rtems_task ( *rtems_task_entry )( + rtems_task_argument + ); + +/** + * The following records define the Initialization Tasks Table. + * Each entry contains the information required by RTEMS to + * create and start a user task automatically at executive + * initialization time. + */ +typedef struct { + /** This is the Initialization Task's name. */ + rtems_name name; + /** This is the Initialization Task's stack size. */ + size_t stack_size; + /** This is the Initialization Task's priority. */ + rtems_task_priority initial_priority; + /** This is the Initialization Task's attributes. */ + rtems_attribute attribute_set; + /** This is the Initialization Task's entry point. */ + rtems_task_entry entry_point; + /** This is the Initialization Task's initial mode. */ + rtems_mode mode_set; + /** This is the Initialization Task's argument. */ + rtems_task_argument argument; +} rtems_initialization_tasks_table; + +/** + * @brief RTEMS Task Create + * + * This routine implements the rtems_task_create directive. The task + * will have the name name. The attribute_set can be used to indicate + * that the task will be globally accessible or utilize floating point. + * The task's stack will be stack_size bytes. The task will begin + * execution with initial_priority and initial_modes. It returns the + * id of the created task in ID. + * + * @param[in] name is the user defined thread name + * @param[in] initial_priority is the thread priority + * @param[in] stack_size is the stack size in bytes + * @param[in] initial_modes is the initial thread mode + * @param[in] attribute_set is the thread attributes + * @param[in] id is the pointer to thread id + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful + * and *id thread id filled in + */ +rtems_status_code rtems_task_create( + rtems_name name, + rtems_task_priority initial_priority, + size_t stack_size, + rtems_mode initial_modes, + rtems_attribute attribute_set, + rtems_id *id +); + +/** + * @brief RTEMS Task Name to Id + * + * This routine implements the rtems_task_ident directive. + * This directive returns the task ID associated with name. + * If more than one task is named name, then the task to + * which the ID belongs is arbitrary. node indicates the + * extent of the search for the ID of the task named name. + * The search can be limited to a particular node or allowed to + * encompass all nodes. + * + * @param[in] name is the user defined thread name + * @param[in] node is(are) the node(s) to be searched + * @param[in] id is the pointer to thread id + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. If successful, the id will + * be filled in with the thread id. + */ +rtems_status_code rtems_task_ident( + rtems_name name, + uint32_t node, + rtems_id *id +); + +/** + * @brief RTEMS Delete Task + * + * This routine implements the rtems_task_delete directive. The + * task indicated by ID is deleted. The executive halts execution + * of the thread and frees the thread control block. + * + * @param[in] id is the thread id + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error and id is not the requesting thread. Status code is + * returned indicating the source of the error. Nothing + * is returned if id is the requesting thread (always succeeds). + */ +rtems_status_code rtems_task_delete( + rtems_id id +); + +/** + * @brief RTEMS Task Mode + * + * This routine implements the rtems_task_mode directive. The current + * values of the modes indicated by mask of the calling task are changed + * to that indicated in mode_set. The former mode of the task is + * returned in mode_set. + * + * @param[in] mode_set is the new mode + * @param[in] mask is the mask + * @param[in] previous_mode_set is the address of previous mode set + * + * @retval RTEMS_SUCCESSFUL and previous_mode_set filled in with the + * previous mode set + */ +rtems_status_code rtems_task_mode( + rtems_mode mode_set, + rtems_mode mask, + rtems_mode *previous_mode_set +); + +/** + * @brief RTEMS Task Restart + * + * This routine implements the rtems_task_restart directive. The + * task associated with ID is restarted at its initial entry + * point with the new argument. + * + * @param[in] id is the thread id + * @param[in] arg is the thread argument + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful + */ +rtems_status_code rtems_task_restart( + rtems_id id, + uint32_t arg +); + +/** + * @brief RTEMS Suspend Task + * + * This routine implements the rtems_task_suspend directive. The + * SUSPENDED state is set for task associated with ID. Note that the + * suspended state can be in addition to other waiting states. + * + * @param[in] id is the thread id + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + */ +rtems_status_code rtems_task_suspend( + rtems_id id +); + +/** + * @brief RTEMS Resume Task + * + * This routine implements the rtems_task_resume Directive. The + * SUSPENDED state is cleared for task associated with ID. + * + * @param[in] id is the thread id + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + */ +rtems_status_code rtems_task_resume( + rtems_id id +); + +/** + * @brief RTEMS Set Task Priority + * + * This routine implements the rtems_task_set_priority directive. The + * current priority of the task associated with ID is set to + * new_priority. The former priority of that task is returned + * in old_priority. + * + * @param[in] id is the thread to extract + * @param[in] new_priority is the thread to extract + * @param[in] old_priority is the thread to extract + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and + * and *old_priority filled in with the previous previous priority + */ +rtems_status_code rtems_task_set_priority( + rtems_id id, + rtems_task_priority new_priority, + rtems_task_priority *old_priority +); + +/** + * @brief Gets the current priority of the specified task with respect to the + * specified scheduler instance. + * + * The current priority reflects temporary priority adjustments due to locking + * protocols, the rate-monotonic period objects on some schedulers and other + * mechanisms. + * + * @param[in] task_id Identifier of the task. Use @ref RTEMS_SELF to select + * the executing task. + * @param[in] scheduler_id Identifier of the scheduler instance. + * @param[out] priority Returns the current priority of the specified task with + * respect to the specified scheduler instance. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_ILLEGAL_ON_REMOTE_OBJECT Directive is illegal on remote tasks. + * @retval RTEMS_INVALID_ADDRESS The priority parameter is @c NULL. + * @retval RTEMS_INVALID_ID Invalid task or scheduler identifier. + * @retval RTEMS_NOT_DEFINED The task has no priority within the specified + * scheduler instance. This error is only possible on SMP configurations. + * + * @see rtems_scheduler_ident(). + */ +rtems_status_code rtems_task_get_priority( + rtems_id task_id, + rtems_id scheduler_id, + rtems_task_priority *priority +); + +/** + * @brief RTEMS Start Task + * + * RTEMS Task Manager + * + * This routine implements the rtems_task_start directive. The + * starting execution point of the task associated with ID is + * set to entry_point with the initial argument. + */ +rtems_status_code rtems_task_start( + rtems_id id, + rtems_task_entry entry_point, + rtems_task_argument argument +); + +/** + * @brief RTEMS Task Wake When + * + * This routine implements the rtems_task_wake_when directive. The + * calling task is blocked until the current time of day is + * equal to that indicated by time_buffer. + * + * @param[in] time_buffer is the pointer to the time and date structure + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful + */ +rtems_status_code rtems_task_wake_when( + rtems_time_of_day *time_buffer +); + +/** + * @brief RTEMS Task Wake After + * + * This routine implements the rtems_task_wake_after directive. The + * calling task is blocked until the indicated number of clock + * ticks have occurred. + * + * @param[in] ticks is the number of ticks to wait + * @retval RTEMS_SUCCESSFUL + */ +rtems_status_code rtems_task_wake_after( + rtems_interval ticks +); + +/** + * @brief rtems_task_is_suspended + * + * This directive returns a status indicating whether or not + * the specified task is suspended. + */ +rtems_status_code rtems_task_is_suspended( + rtems_id id +); + +/** + * @brief Gets the processor affinity set of a task. + * + * @param[in] id Identifier of the task. Use @ref RTEMS_SELF to select the + * executing task. + * @param[in] cpusetsize Size of the specified affinity set buffer in + * bytes. This value must be positive. + * @param[out] cpuset The current processor affinity set of the task. A set + * bit in the affinity set means that the task can execute on this processor + * and a cleared bit means the opposite. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ADDRESS The @a cpuset parameter is @c NULL. + * @retval RTEMS_INVALID_ID Invalid task identifier. + * @retval RTEMS_INVALID_NUMBER The affinity set buffer is too small for the + * current processor affinity set of the task. + */ +rtems_status_code rtems_task_get_affinity( + rtems_id id, + size_t cpusetsize, + cpu_set_t *cpuset +); + +/** + * @brief Sets the processor affinity set of a task. + * + * This function will not change the scheduler of the task. The intersection + * of the processor affinity set and the set of processors owned by the + * scheduler of the task must be non-empty. It is not an error if the + * processor affinity set contains processors that are not part of the set of + * processors owned by the scheduler instance of the task. A task will simply + * not run under normal circumstances on these processors since the scheduler + * ignores them. Some locking protocols may temporarily use processors that + * are not included in the processor affinity set of the task. It is also not + * an error if the processor affinity set contains processors that are not part + * of the system. + * + * @param[in] id Identifier of the task. Use @ref RTEMS_SELF to select the + * executing task. + * @param[in] cpusetsize Size of the specified affinity set buffer in + * bytes. This value must be positive. + * @param[in] cpuset The new processor affinity set for the task. A set bit in + * the affinity set means that the task can execute on this processor and a + * cleared bit means the opposite. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ADDRESS The @a cpuset parameter is @c NULL. + * @retval RTEMS_INVALID_ID Invalid task identifier. + * @retval RTEMS_INVALID_NUMBER Invalid processor affinity set. + */ +rtems_status_code rtems_task_set_affinity( + rtems_id id, + size_t cpusetsize, + const cpu_set_t *cpuset +); + +/** + * @brief Gets the scheduler of a task. + * + * @param[in] task_id Identifier of the task. Use @ref RTEMS_SELF to select + * the executing task. + * @param[out] scheduler_id Identifier of the scheduler instance. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ADDRESS The @a scheduler_id parameter is @c NULL. + * @retval RTEMS_INVALID_ID Invalid task identifier. + */ +rtems_status_code rtems_task_get_scheduler( + rtems_id task_id, + rtems_id *scheduler_id +); + +/** + * @brief Sets the scheduler instance of a task. + * + * Initially, the scheduler instance of a task is set to the scheduler instance + * of the task that created it. This directive allows to move a task from its + * current scheduler instance to another specified by the scheduler identifier. + * + * @param[in] task_id Identifier of the task. Use @ref RTEMS_SELF to select + * the executing task. + * @param[in] scheduler_id Identifier of the scheduler instance. + * @param[in] priority The task priority with respect to the new scheduler + * instance. The real and initial priority of the task is set to this value. + * The initial priority is used by rtems_task_restart() for example. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_ILLEGAL_ON_REMOTE_OBJECT Directive is illegal on remote tasks. + * @retval RTEMS_INVALID_ID Invalid task or scheduler identifier. + * @retval RTEMS_INVALID_PRIORITY Invalid priority. + * @retval RTEMS_RESOURCE_IN_USE The task owns resources which deny a scheduler + * change. + * + * @see rtems_scheduler_ident(). + */ +rtems_status_code rtems_task_set_scheduler( + rtems_id task_id, + rtems_id scheduler_id, + rtems_task_priority priority +); + +/** + * @brief RTEMS Get Self Task Id + * + * This directive returns the ID of the currently executing task. + */ +rtems_id rtems_task_self(void); + +/** + * @brief Task visitor. + * + * @param[in] tcb The task control block. + * @param[in] arg The visitor argument. + * + * @retval true Stop the iteration. + * @retval false Otherwise. + * + * @see rtems_task_iterate(). + */ +typedef bool ( *rtems_task_visitor )( rtems_tcb *tcb, void *arg ); + +/** + * @brief Iterates over all tasks in the system. + * + * This operation covers all tasks of all APIs. + * + * Must be called from task context. This operation obtains and releases the + * objects allocator lock. The task visitor is called while owning the objects + * allocator lock. It is possible to perform blocking operations in the task + * visitor, however, take care that no deadlocks via the object allocator lock + * can occur. + * + * @param[in] visitor The task visitor. + * @param[in] arg The visitor argument. + */ +void rtems_task_iterate( + rtems_task_visitor visitor, + void *arg +); + +/** + * @brief Identifies a scheduler by its name. + * + * The scheduler name is determined by the scheduler configuration. + * + * @param[in] name The scheduler name. + * @param[out] id The scheduler identifier associated with the name. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ADDRESS The @a id parameter is @c NULL. + * @retval RTEMS_INVALID_NAME Invalid scheduler name. + */ +rtems_status_code rtems_scheduler_ident( + rtems_name name, + rtems_id *id +); + +/** + * @brief Identifies a scheduler by a processor index. + * + * @param[in] cpu_index The processor index. + * @param[out] id The scheduler identifier associated with the processor index. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ADDRESS The @a id parameter is @c NULL. + * @retval RTEMS_INVALID_NAME Invalid processor index. + * @retval RTEMS_INCORRECT_STATE The processor index is valid, however, this + * processor is not owned by a scheduler. + */ +rtems_status_code rtems_scheduler_ident_by_processor( + uint32_t cpu_index, + rtems_id *id +); + +/** + * @brief Identifies a scheduler by a processor set. + * + * The scheduler is selected according to the highest numbered online processor + * in the specified processor set. + * + * @param[in] cpusetsize Size of the specified processor set buffer in + * bytes. This value must be positive. + * @param[out] cpuset The processor set to identify the scheduler. + * @param[out] id The scheduler identifier associated with the processor set. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ADDRESS The @a id parameter is @c NULL. + * @retval RTEMS_INVALID_SIZE Invalid processor set size. + * @retval RTEMS_INVALID_NAME The processor set contains no online processor. + * @retval RTEMS_INCORRECT_STATE The processor set is valid, however, the + * highest numbered online processor in the specified processor set is not + * owned by a scheduler. + */ +rtems_status_code rtems_scheduler_ident_by_processor_set( + size_t cpusetsize, + const cpu_set_t *cpuset, + rtems_id *id +); + +/** + * @brief Gets the set of processors owned by the specified scheduler instance. + * + * @param[in] scheduler_id Identifier of the scheduler instance. + * @param[in] cpusetsize Size of the specified processor set buffer in + * bytes. This value must be positive. + * @param[out] cpuset The processor set owned by the scheduler. A set bit in + * the processor set means that this processor is owned by the scheduler and a + * cleared bit means the opposite. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ADDRESS The @a cpuset parameter is @c NULL. + * @retval RTEMS_INVALID_ID Invalid scheduler instance identifier. + * @retval RTEMS_INVALID_NUMBER The processor set buffer is too small for the + * set of processors owned by the scheduler. + */ +rtems_status_code rtems_scheduler_get_processor_set( + rtems_id scheduler_id, + size_t cpusetsize, + cpu_set_t *cpuset +); + +/** + * @brief Adds a processor to the set of processors owned by the specified + * scheduler instance. + * + * Must be called from task context. This operation obtains and releases the + * objects allocator lock. + * + * @param[in] scheduler_id Identifier of the scheduler instance. + * @param[in] cpu_index Index of the processor to add. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID Invalid scheduler instance identifier. + * @retval RTEMS_NOT_CONFIGURED The processor is not configured to be used by + * the application. + * @retval RTEMS_INCORRECT_STATE The processor is configured to be used by + * the application, however, it is not online. + * @retval RTEMS_RESOURCE_IN_USE The processor is already assigned to a + * scheduler instance. + */ +rtems_status_code rtems_scheduler_add_processor( + rtems_id scheduler_id, + uint32_t cpu_index +); + +/** + * @brief Removes a processor from set of processors owned by the specified + * scheduler instance. + * + * Must be called from task context. This operation obtains and releases the + * objects allocator lock. Removing a processor from a scheduler is a complex + * operation that involves all tasks of the system. + * + * @param[in] scheduler_id Identifier of the scheduler instance. + * @param[in] cpu_index Index of the processor to add. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID Invalid scheduler instance identifier. + * @retval RTEMS_INVALID_NUMBER The processor is not owned by the specified + * scheduler instance. + * @retval RTEMS_RESOURCE_IN_USE The set of processors owned by the specified + * scheduler instance would be empty after the processor removal and there + * exists a non-idle task that uses this scheduler instance as its home + * scheduler instance. + */ +rtems_status_code rtems_scheduler_remove_processor( + rtems_id scheduler_id, + uint32_t cpu_index +); + +/**@}*/ + +/** + * This is the API specific information required by each thread for + * the RTEMS API to function correctly. + * + */ +typedef struct { + /** This field contains the event control for this task. */ + Event_Control Event; + /** This field contains the system event control for this task. */ + Event_Control System_event; + /** This field contains the Classic API Signal information for this task. */ + ASR_Information Signal; + + /** + * @brief Signal post-switch action in case signals are pending. + */ + Thread_Action Signal_action; +} RTEMS_API_Control; + +/** + * @brief _RTEMS_tasks_Initialize_user_tasks_body + * + * This routine creates and starts all configured user + * initialization threads. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * RTEMS Task Manager + */ + +extern void _RTEMS_tasks_Initialize_user_tasks_body( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/tasksimpl.h b/cpukit/include/rtems/rtems/tasksimpl.h new file mode 100644 index 0000000000..b0432351f3 --- /dev/null +++ b/cpukit/include/rtems/rtems/tasksimpl.h @@ -0,0 +1,131 @@ +/** + * @file + * + * @ingroup ClassicTasksImpl + * + * @brief Classic Tasks Manager Implementation + */ + +/* COPYRIGHT (c) 1989-2014. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_TASKSIMPL_H +#define _RTEMS_RTEMS_TASKSIMPL_H + +#include <rtems/rtems/tasks.h> +#include <rtems/score/objectimpl.h> +#include <rtems/score/schedulerimpl.h> +#include <rtems/score/threadimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicTasksImpl Classic Tasks Manager Implementation + * + * @ingroup ClassicTasks + * + * @{ + */ + +/** + * The following instantiates the information control block used to + * manage this class of objects. + */ +extern Thread_Information _RTEMS_tasks_Information; + +/** + * @brief RTEMS User Task Initialization + * + * This routine creates and starts all configured user + * initialization threads. + */ +void _RTEMS_tasks_Initialize_user_tasks( void ); + +RTEMS_INLINE_ROUTINE Thread_Control *_RTEMS_tasks_Allocate(void) +{ + _Objects_Allocator_lock(); + + _Thread_Kill_zombies(); + + return (Thread_Control *) + _Objects_Allocate_unprotected( &_RTEMS_tasks_Information.Objects ); +} + +/** + * @brief Frees a task control block. + * + * This routine frees a task control block to the + * inactive chain of free task control blocks. + */ +RTEMS_INLINE_ROUTINE void _RTEMS_tasks_Free ( + Thread_Control *the_task +) +{ + _Objects_Free( + _Objects_Get_information_id( the_task->Object.id ), + &the_task->Object + ); +} + +/** + * @brief Converts the RTEMS API priority to the corresponding SuperCore + * priority and validates it. + * + * The RTEMS API system priority is accepted as valid. + * + * @param[in] scheduler The scheduler instance. + * @param[in] priority The RTEMS API priority to convert and validate. + * @param[out] valid Indicates if the RTEMS API priority is valid and a + * corresponding SuperCore priority in the specified scheduler instance + * exists. + * + * @return The corresponding SuperCore priority. + */ +RTEMS_INLINE_ROUTINE Priority_Control _RTEMS_Priority_To_core( + const Scheduler_Control *scheduler, + rtems_task_priority priority, + bool *valid +) +{ + *valid = ( priority <= scheduler->maximum_priority ); + + return _Scheduler_Map_priority( scheduler, (Priority_Control) priority ); +} + +/** + * @brief Converts the SuperCore priority to the corresponding RTEMS API + * priority. + * + * @param[in] scheduler The scheduler instance. + * @param[in] priority The SuperCore priority to convert. + * + * @return The corresponding RTEMS API priority. + */ +RTEMS_INLINE_ROUTINE rtems_task_priority _RTEMS_Priority_From_core( + const Scheduler_Control *scheduler, + Priority_Control priority +) +{ + return (rtems_task_priority) + _Scheduler_Unmap_priority( scheduler, priority ); +} + +/**@}*/ + +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/rtems/taskmp.h> +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/timer.h b/cpukit/include/rtems/rtems/timer.h new file mode 100644 index 0000000000..032c49525a --- /dev/null +++ b/cpukit/include/rtems/rtems/timer.h @@ -0,0 +1,384 @@ +/** + * @file rtems/rtems/timer.h + * + * @defgroup ClassicTimer Timers + * + * @ingroup ClassicRTEMS + * @brief Instantiate RTEMS Timer Data + * + * This include file contains all the constants, structures, and + * prototypes associated with the Timer Manager. This manager provides + * facilities to configure, initiate, cancel, and delete timers which will + * fire at specified intervals of time. + * + * Directives provided are: + * + * - create a timer + * - get an ID of a timer + * - delete a timer + * - set timer to fire in context of clock tick + * - after a number of ticks have passed + * - when a specified date and time has been reached + * - initiate the timer server task + * - set timer to fire in context of the timer server task + * - after a number of ticks have passed + * - when a specified date and time has been reached + * - reset a timer + * - cancel a time + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * Copyright (c) 2009, 2016 embedded brains GmbH. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_TIMER_H +#define _RTEMS_RTEMS_TIMER_H + +#include <rtems/rtems/attr.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/tasks.h> +#include <rtems/rtems/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicTimer Timers + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the Classic API Timer + * Manager. This manager provides functionality which allows the + * application to schedule the execution of methods at a specified + * time in the future. These methods may be scheduled based upon + * interval or wall time and may be executed in either the clock tick + * ISR or in a special dedicated timer server task. + */ +/**@{*/ + +#define TIMER_CLASS_BIT_TIME_OF_DAY 0x1 + +#define TIMER_CLASS_BIT_ON_TASK 0x2 + +#define TIMER_CLASS_BIT_NOT_DORMANT 0x4 + +/** + * The following enumerated type details the classes to which a timer + * may belong. + */ +typedef enum { + /** + * This value indicates the timer is currently not in use. + */ + TIMER_DORMANT, + + /** + * This value indicates the timer is currently in use as an interval + * timer which will fire in the clock tick ISR. + */ + TIMER_INTERVAL = TIMER_CLASS_BIT_NOT_DORMANT, + + /** + * This value indicates the timer is currently in use as an interval + * timer which will fire in the timer server task. + */ + TIMER_INTERVAL_ON_TASK = + TIMER_CLASS_BIT_NOT_DORMANT | TIMER_CLASS_BIT_ON_TASK, + + /** + * This value indicates the timer is currently in use as an time of day + * timer which will fire in the clock tick ISR. + */ + TIMER_TIME_OF_DAY = + TIMER_CLASS_BIT_NOT_DORMANT | TIMER_CLASS_BIT_TIME_OF_DAY, + + /** + * This value indicates the timer is currently in use as an time of day + * timer which will fire in the timer server task. + */ + TIMER_TIME_OF_DAY_ON_TASK = + TIMER_CLASS_BIT_NOT_DORMANT | TIMER_CLASS_BIT_TIME_OF_DAY | + TIMER_CLASS_BIT_ON_TASK +} Timer_Classes; + +/** + * The following types define a pointer to a timer service routine. + */ +typedef void rtems_timer_service_routine; + +/** + * This type defines the type used to manage and indirectly invoke + * Timer Service Routines (TSRs). This defines the prototype and interface + * for a function which is to be used as a TSR. + */ +typedef rtems_timer_service_routine ( *rtems_timer_service_routine_entry )( + rtems_id, + void * + ); + +/** + * The following records define the control block used to manage + * each timer. + */ +typedef struct { + /** This field is the object management portion of a Timer instance. */ + Objects_Control Object; + /** This field is the Watchdog instance which will be the scheduled. */ + Watchdog_Control Ticker; + /** This field indicates what type of timer this currently is. */ + Timer_Classes the_class; + /** This field is the timer service routine. */ + rtems_timer_service_routine_entry routine; + /** This field is the timer service routine user data. */ + void *user_data; + /** This field is the timer interval in ticks or seconds. */ + Watchdog_Interval initial; + /** This field is the timer start time point in ticks. */ + Watchdog_Interval start_time; + /** This field is the timer stop time point in ticks. */ + Watchdog_Interval stop_time; +} Timer_Control; + +/** + * @brief RTEMS Create Timer + * + * This routine implements the rtems_timer_create directive. The + * timer will have the name name. It returns the id of the + * created timer in ID. + * + * @param[in] name is the timer name + * @param[out] id is the pointer to timer id + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful + */ +rtems_status_code rtems_timer_create( + rtems_name name, + rtems_id *id +); + +/** + * @brief RTEMS Timer Name to Id + * + * This routine implements the rtems_timer_ident directive. + * This directive returns the timer ID associated with name. + * If more than one timer is named name, then the timer + * to which the ID belongs is arbitrary. + * + * @param[in] name is the user defined message queue name + * @param[in] id is the pointer to timer id + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and + * id filled with the message queue id + */ +rtems_status_code rtems_timer_ident( + rtems_name name, + rtems_id *id +); + +/** + * @brief rtems_timer_cancel + * + * This routine implements the rtems_timer_cancel directive. It is used + * to stop the timer associated with ID from firing. + */ +rtems_status_code rtems_timer_cancel( + rtems_id id +); + +/** + * @brief RTEMS Delete Timer + * + * This routine implements the rtems_timer_delete directive. The + * timer indicated by ID is deleted. + * + * @param[in] id is the timer id + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + */ +rtems_status_code rtems_timer_delete( + rtems_id id +); + +/** + * @brief RTEMS Timer Fire After + * + * This routine implements the rtems_timer_fire_after directive. It + * initiates the timer associated with ID to fire in ticks clock ticks. + * When the timer fires, the routine will be invoked in the context + * of the rtems_clock_tick directive which is normally invoked as + * part of servicing a periodic interupt. + * + * @param[in] id is the timer id + * @param[in] ticks is the interval until routine is fired + * @param[in] routine is the routine to schedule + * @param[in] user_data is the passed as argument to routine when it is fired + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + */ +rtems_status_code rtems_timer_fire_after( + rtems_id id, + rtems_interval ticks, + rtems_timer_service_routine_entry routine, + void *user_data +); + +/** + * @brief RTEMS Timer Server Fire After + * + * This routine implements the rtems_timer_server_fire_after directive. It + * initiates the timer associated with ID to fire in ticks clock + * ticks. When the timer fires, the routine will be invoked by the + * Timer Server in the context of a task NOT IN THE CONTEXT of the + * clock tick interrupt. + * + * @param[in] id is the timer id + * @param[in] ticks is the interval until routine is fired + * @param[in] routine is the routine to schedule + * @param[in] user_data is the passed as argument to routine when it is fired + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + */ +rtems_status_code rtems_timer_server_fire_after( + rtems_id id, + rtems_interval ticks, + rtems_timer_service_routine_entry routine, + void *user_data +); + +/** + * @brief RTEMS Timer Fire When + * + * This routine implements the rtems_timer_fire_when directive. It + * initiates the timer associated with ID to fire at wall_time + * When the timer fires, the routine will be invoked in the context + * of the rtems_clock_tick directive which is normally invoked as + * part of servicing a periodic interupt. + * + * @param[in] id is the timer id + * @param[in] wall_time is the time of day to fire timer + * @param[in] routine is the routine to schedule + * @param[in] user_data is the passed as argument to routine when it is fired + * + * @retval This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + */ +rtems_status_code rtems_timer_fire_when( + rtems_id id, + rtems_time_of_day *wall_time, + rtems_timer_service_routine_entry routine, + void *user_data +); + +/** + * @brief RTEMS Timer Server Fire When Directive + * + * Timer Manager - RTEMS Timer Server Fire When Directive + * + * This routine implements the rtems_timer_server_fire_when directive. It + * initiates the timer associated with ID to fire at wall_time + * When the timer fires, the routine will be invoked by the + * Timer Server in the context of a task NOT IN THE CONTEXT of the + * clock tick interrupt. + */ +rtems_status_code rtems_timer_server_fire_when( + rtems_id id, + rtems_time_of_day *wall_time, + rtems_timer_service_routine_entry routine, + void *user_data +); + +/** + * @brief RTEMS Timer Reset + * + * Timer Manager - RTEMS Timer Reset + * + * This routine implements the rtems_timer_reset directive. It is used + * to reinitialize the interval timer associated with ID just as if + * rtems_timer_fire_after were re-invoked with the same arguments that + * were used to initiate this timer. + */ +rtems_status_code rtems_timer_reset( + rtems_id id +); + +/** + * @brief Initiates the timer server. + * + * This directive creates and starts the server for task-based timers. + * It must be invoked before any task-based timers can be initiated. + * + * @param priority The timer server task priority. + * @param stack_size The stack size in bytes for the timer server task. + * @param attribute_set The timer server task attributes. + * + * @return This method returns RTEMS_SUCCESSFUL if successful and an + * error code otherwise. + */ +rtems_status_code rtems_timer_initiate_server( + rtems_task_priority priority, + size_t stack_size, + rtems_attribute attribute_set +); + +/** + * This is the default value for the priority of the Timer Server. + * When given this priority, a special high priority not accessible + * via the Classic API is used. + */ +#define RTEMS_TIMER_SERVER_DEFAULT_PRIORITY (uint32_t) -1 + +/** + * This is the structure filled in by the timer get information + * service. + */ +typedef struct { + /** This indicates the current type of the timer. */ + Timer_Classes the_class; + /** This indicates the initial requested interval. */ + Watchdog_Interval initial; + /** This indicates the time the timer was initially scheduled. */ + Watchdog_Interval start_time; + /** This indicates the time the timer is scheduled to fire. */ + Watchdog_Interval stop_time; +} rtems_timer_information; + +/** + * @brief RTEMS Get Timer Information + * + * This routine implements the rtems_timer_get_information directive. + * This directive returns information about the timer. + * + * @param[in] id is the timer id + * @param[in] the_info is the pointer to timer information block + * + * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and + * *the_info region information block filled in + */ +rtems_status_code rtems_timer_get_information( + rtems_id id, + rtems_timer_information *the_info +); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/timerimpl.h b/cpukit/include/rtems/rtems/timerimpl.h new file mode 100644 index 0000000000..d8581bfcd8 --- /dev/null +++ b/cpukit/include/rtems/rtems/timerimpl.h @@ -0,0 +1,209 @@ +/** + * @file + * + * @ingroup ClassicTimerImpl + * + * @brief Classic Timer Implementation + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * Copyright (c) 2016 embedded brains GmbH. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_TIMER_INL +#define _RTEMS_RTEMS_TIMER_INL + +#include <rtems/rtems/timer.h> +#include <rtems/score/objectimpl.h> +#include <rtems/score/thread.h> +#include <rtems/score/watchdogimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicTimerImpl Classic Timer Implementation + * + * @ingroup ClassicTimer + * + * @{ + */ + +typedef struct Timer_server_Control { + ISR_LOCK_MEMBER( Lock ) + + Chain_Control Pending; + + Objects_Id server_id; +} Timer_server_Control; + +/** + * @brief Pointer to default timer server control block. + * + * This value is @c NULL when the default timer server is not initialized. + */ +extern Timer_server_Control *volatile _Timer_server; + +/** + * The following defines the information control block used to manage + * this class of objects. + */ +extern Objects_Information _Timer_Information; + +/** + * @brief Timer_Allocate + * + * This function allocates a timer control block from + * the inactive chain of free timer control blocks. + */ +RTEMS_INLINE_ROUTINE Timer_Control *_Timer_Allocate( void ) +{ + return (Timer_Control *) _Objects_Allocate( &_Timer_Information ); +} + +/** + * @brief Timer_Free + * + * This routine frees a timer control block to the + * inactive chain of free timer control blocks. + */ +RTEMS_INLINE_ROUTINE void _Timer_Free ( + Timer_Control *the_timer +) +{ + _Objects_Free( &_Timer_Information, &the_timer->Object ); +} + +RTEMS_INLINE_ROUTINE Timer_Control *_Timer_Get( + Objects_Id id, + ISR_lock_Context *lock_context +) +{ + return (Timer_Control *) _Objects_Get( + id, + lock_context, + &_Timer_Information + ); +} + +RTEMS_INLINE_ROUTINE Per_CPU_Control *_Timer_Acquire_critical( + Timer_Control *the_timer, + ISR_lock_Context *lock_context +) +{ + Per_CPU_Control *cpu; + + cpu = _Watchdog_Get_CPU( &the_timer->Ticker ); + _Watchdog_Per_CPU_acquire_critical( cpu, lock_context ); + + return cpu; +} + +RTEMS_INLINE_ROUTINE void _Timer_Release( + Per_CPU_Control *cpu, + ISR_lock_Context *lock_context +) +{ + _Watchdog_Per_CPU_release_critical( cpu, lock_context ); + _ISR_lock_ISR_enable( lock_context ); +} + +RTEMS_INLINE_ROUTINE bool _Timer_Is_interval_class( + Timer_Classes the_class +) +{ + Timer_Classes mask = + TIMER_CLASS_BIT_NOT_DORMANT | TIMER_CLASS_BIT_TIME_OF_DAY; + + return ( the_class & mask ) == TIMER_CLASS_BIT_NOT_DORMANT; +} + +RTEMS_INLINE_ROUTINE bool _Timer_Is_on_task_class( + Timer_Classes the_class +) +{ + Timer_Classes mask = + TIMER_CLASS_BIT_NOT_DORMANT | TIMER_CLASS_BIT_ON_TASK; + + return ( the_class & mask ) == mask; +} + +RTEMS_INLINE_ROUTINE Per_CPU_Watchdog_index _Timer_Watchdog_header_index( + Timer_Classes the_class +) +{ + return ( the_class & TIMER_CLASS_BIT_TIME_OF_DAY ); +} + +RTEMS_INLINE_ROUTINE Watchdog_Interval _Timer_Get_CPU_ticks( + const Per_CPU_Control *cpu +) +{ + return (Watchdog_Interval) cpu->Watchdog.ticks; +} + +rtems_status_code _Timer_Fire( + rtems_id id, + rtems_interval interval, + rtems_timer_service_routine_entry routine, + void *user_data, + Timer_Classes the_class, + Watchdog_Service_routine_entry adaptor +); + +rtems_status_code _Timer_Fire_after( + rtems_id id, + rtems_interval ticks, + rtems_timer_service_routine_entry routine, + void *user_data, + Timer_Classes the_class, + Watchdog_Service_routine_entry adaptor +); + +rtems_status_code _Timer_Fire_when( + rtems_id id, + const rtems_time_of_day *wall_time, + rtems_timer_service_routine_entry routine, + void *user_data, + Timer_Classes the_class, + Watchdog_Service_routine_entry adaptor +); + +void _Timer_Cancel( Per_CPU_Control *cpu, Timer_Control *the_timer ); + +void _Timer_Routine_adaptor( Watchdog_Control *the_watchdog ); + +void _Timer_server_Routine_adaptor( Watchdog_Control *the_watchdog ); + +RTEMS_INLINE_ROUTINE void _Timer_server_Acquire_critical( + Timer_server_Control *timer_server, + ISR_lock_Context *lock_context +) +{ + _ISR_lock_Acquire( &timer_server->Lock, lock_context ); +} + +RTEMS_INLINE_ROUTINE void _Timer_server_Release_critical( + Timer_server_Control *timer_server, + ISR_lock_Context *lock_context +) +{ + _ISR_lock_Release( &timer_server->Lock, lock_context ); +} + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/rtems/types.h b/cpukit/include/rtems/rtems/types.h new file mode 100644 index 0000000000..82c0edd3c3 --- /dev/null +++ b/cpukit/include/rtems/rtems/types.h @@ -0,0 +1,235 @@ +/** + * @file + * + * @defgroup ClassicTypes Types + * + * @ingroup ClassicRTEMS + * @brief Types used by Classic API. + */ + +/* COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_RTEMS_TYPES_H +#define _RTEMS_RTEMS_TYPES_H + +/* + * RTEMS basic type definitions + */ + +#include <stdint.h> +#include <rtems/score/heap.h> +#include <rtems/score/object.h> +#include <rtems/score/priority.h> +#include <rtems/score/watchdog.h> +#include <rtems/rtems/modes.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup ClassicRTEMS + */ +/**@{**/ + +#ifdef RTEMS_DEPRECATED_TYPES +/** + * @brief Single precision float type. + * + * @deprecated Use @c float instead. + */ +typedef single_precision rtems_single; + +/** + * @brief Double precision float type. + * + * @deprecated Use @c double instead. + */ +typedef double_precision rtems_double; + +/** + * @brief RTEMS boolean type. + * + * @deprecated Use @c bool instead + */ +typedef boolean rtems_boolean; +#endif + +/** + * @brief Classic API @ref ClassicRTEMSSubSecObjectNames "object name" type. + * + * Contains the name of a Classic API object. It is an unsigned 32-bit integer + * which can be treated as a numeric value or initialized using + * rtems_build_name() to contain four ASCII characters. + */ +typedef uint32_t rtems_name; + +/** + * @brief Used to manage and manipulate + * @ref ClassicRTEMSSubSecObjectIdentifiers "RTEMS object identifiers". + */ +typedef Objects_Id rtems_id; + +/** + * @brief Invalid object identifier value. + * + * No object can have this identifier value. + */ +#define RTEMS_ID_NONE OBJECTS_ID_NONE + +/** + * @brief Public name for task context area. + */ +typedef Context_Control rtems_context; + +#if (CPU_HARDWARE_FP == TRUE) || (CPU_SOFTWARE_FP == TRUE) +/** + * @brief Public name for task floating point context area. + */ +typedef Context_Control_fp rtems_context_fp; +#endif + +#if (CPU_ISR_PASSES_FRAME_POINTER == TRUE) +/** + * @brief Defines the format of the interrupt stack frame as it appears to a + * user ISR. + * + * This data structure is only provided if the interrupt stack frame is passed + * to the ISR handler. + * + * @see rtems_interrupt_catch(). + */ +typedef CPU_Interrupt_frame rtems_interrupt_frame; +#endif + +/** + * @brief Information structure returned by the Heap Handler via the Region + * Manager. + */ +typedef Heap_Information_block region_information_block; + +/** + * @brief Used to manage and manipulate intervals specified by + * @ref ClassicRTEMSSecTime "clock ticks". + */ +typedef Watchdog_Interval rtems_interval; + +/** + * @brief Represents the CPU usage per thread. + * + * When using nanoseconds granularity timing, RTEMS may internally use a + * variety of representations. + */ +typedef struct timespec rtems_thread_cpu_usage_t; + +/** + * @brief Data structure to manage and manipulate calendar + * @ref ClassicRTEMSSecTime "time". + */ +typedef struct { + /** + * @brief Year, A.D. + */ + uint32_t year; + /** + * @brief Month, 1 .. 12. + */ + uint32_t month; + /** + * @brief Day, 1 .. 31. + */ + uint32_t day; + /** + * @brief Hour, 0 .. 23. + */ + uint32_t hour; + /** + * @brief Minute, 0 .. 59. + */ + uint32_t minute; + /** + * @brief Second, 0 .. 59. + */ + uint32_t second; + /** + * @brief Elapsed ticks between seconds. + */ + uint32_t ticks; +} rtems_time_of_day; + +/** + * @brief Task mode type. + */ +typedef Modes_Control rtems_mode; + +/* + * MPCI related entries + */ +#if defined(RTEMS_MULTIPROCESSING) +/** + * @brief Set of MPCI packet classes which are internally dispatched to the + * managers. + */ +typedef MP_packet_Classes rtems_mp_packet_classes; + +/** + * @brief Prefix found at the beginning of each MPCI packet sent between nodes. + */ +typedef MP_packet_Prefix rtems_packet_prefix; + +/** + * @brief Indirect pointer to the initialization entry point for an MPCI + * handler. + */ +typedef MPCI_initialization_entry rtems_mpci_initialization_entry; + +/** + * @brief Indirect pointer to the get_packet entry point for an MPCI handler. + */ +typedef MPCI_get_packet_entry rtems_mpci_get_packet_entry; + +/** + * @brief Indirect pointer to the return_packet entry point for an MPCI + * handler. + */ +typedef MPCI_return_packet_entry rtems_mpci_return_packet_entry; + +/** + * @brief Indirect pointer to the send_packet entry point for an MPCI handler. + */ +typedef MPCI_send_entry rtems_mpci_send_packet_entry; + +/** + * @brief Indirect pointer to the receive entry point for an MPCI handler. + */ +typedef MPCI_receive_entry rtems_mpci_receive_packet_entry; + +/** + * @brief Return type from every MPCI handler routine. + */ +typedef MPCI_Entry rtems_mpci_entry; + +/** + * @brief Structure which is used to configure an MPCI handler. + */ +typedef MPCI_Control rtems_mpci_table; + +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ |