RTEMS Classic API Guide (6.17c582f).#
The authors have used their best efforts in preparing this material. These efforts include the development, research, and testing of the theories and programs to determine their effectiveness. No warranty of any kind, expressed or implied, with regard to the software or the material contained in this document is provided. No liability arising out of the application or use of any product described in this document is assumed. The authors reserve the right to revise this material and to make changes from time to time in the content hereof without obligation to notify anyone of such revision or changes.
The RTEMS Project is hosted at https://www.rtems.org. Any inquiries concerning RTEMS, its related support components, or its documentation should be directed to the RTEMS Project community.
1. Preface#
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 [Mot88]. 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) [VIT90]. These two groups worked together with the IEEE P1003.4 committee to ensure that the functionality of their proposed standards is adopted as the real-time extensions to POSIX.
This proposed 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:
Adapteva Epiphany
Altera NIOS II
Analog Devices Blackfin
Atmel AVR
ARM
Freescale (formerly Motorola) MC68xxx
Freescale (formerly Motorola) MC683xx
Freescale (formerly Motorola) ColdFire
Intel i386 and above
Lattice Semiconductor LM32
NEC V850
MIPS
Moxie Processor
OpenRISC
PowerPC
Renesas (formerly Hitachi) SuperH
Renesas (formerly Hitachi) H8/300
Renesas M32C
SPARC v7, v8, and V9
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.
This document is a detailed users guide for a functionally compliant real-time multiprocessor executive. It describes the user interface and run-time behavior of Release 4.10.99.0 of the C interface to RTEMS.
2. Overview#
2.1. 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.
2.2. 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.
2.3. 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.
2.4. 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.
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.
2.5. 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:
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
2.6. User Customization and Extensibility#
As thirty-two 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 thirty-two 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.
2.7. 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.
2.8. 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.
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.
2.9. 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.
2.10. Conventions#
The following conventions are used in this manual:
Significant words or phrases as well as all directive names are printed in bold type.
Items in bold capital letters are constants defined by RTEMS. Each language interface provided by RTEMS includes a file containing the standard set of constants, data types, and structure definitions which can be incorporated into the user application.
A number of type definitions are provided by RTEMS and can be found in rtems.h.
The characters “0x” preceding a number indicates that the number is in hexadecimal format. Any other numbers are assumed to be in decimal format.
2.11. Manual Organization#
This first chapter has presented the introductory and background material for the RTEMS executive. The remaining chapters of this manual present a detailed description of RTEMS and the environment, including run time behavior, it creates for the user.
A chapter is dedicated to each manager and provides a detailed discussion of each RTEMS manager and the directives which it provides. The presentation format for each directive includes the following sections:
Calling sequence
Directive status codes
Description
Notes
The following provides an overview of the remainder of this manual:
- Chapter 3:
Key Concepts: presents an introduction to the ideas which are common across multiple RTEMS managers.
- Chapter 4:
RTEMS Data Types: describes the fundamental data types shared by the services in the RTEMS Classic API.
- Chapter 5:
Scheduling Concepts: details the various RTEMS scheduling algorithms and task state transitions.
- Chapter 6:
Initialization Manager: describes the functionality and directives provided by the Initialization Manager.
- Chapter 7:
Task Manager: describes the functionality and directives provided by the Task Manager.
- Chapter 8:
Interrupt Manager: describes the functionality and directives provided by the Interrupt Manager.
- Chapter 9:
Clock Manager: describes the functionality and directives provided by the Clock Manager.
- Chapter 10:
Timer Manager: describes the functionality and directives provided by the Timer Manager.
- Chapter 11:
Rate Monotonic Manager: describes the functionality and directives provided by the Rate Monotonic Manager.
- Chapter 12:
Semaphore Manager: describes the functionality and directives provided by the Semaphore Manager.
- Chapter 13:
Barrier Manager: describes the functionality and directives provided by the Barrier Manager.
- Chapter 14:
Message Manager: describes the functionality and directives provided by the Message Manager.
- Chapter 15:
Event Manager: describes the functionality and directives provided by the Event Manager.
- Chapter 16:
Signal Manager: describes the functionality and directives provided by the Signal Manager.
- Chapter 17:
Partition Manager: describes the functionality and directives provided by the Partition Manager.
- Chapter 18:
Region Manager: describes the functionality and directives provided by the Region Manager.
- Chapter 19:
Dual-Ported Memory Manager: describes the functionality and directives provided by the Dual-Ported Memory Manager.
- Chapter 20:
I/O Manager: describes the functionality and directives provided by the I/O Manager.
- Chapter 21:
Fatal Error Manager: describes the functionality and directives provided by the Fatal Error Manager.
- Chapter 22:
Board Support Packages: defines the functionality required of user-supplied board support packages.
- Chapter 23:
User Extensions: shows the user how to extend RTEMS to incorporate custom features.
- Chapter 24:
Configuring a System: details the process by which one tailors RTEMS for a particular single-processor or multiprocessor application.
- Chapter 25:
Self-Contained Objects: contains information about objects like threads, mutexes and semaphores.
- Chapter 26:
Multiprocessing Manager: presents a conceptual overview of the multiprocessing capabilities provided by RTEMS as well as describing the Multiprocessing Communications Interface Layer and Multiprocessing Manager directives.
- Chapter 27:
Symmetric Multiprocessing (SMP): information regarding the SMP features.
- Chapter 28:
PCI Library: information about using the PCI bus in RTEMS.
- Chapter 29:
Stack Bounds Checker: presents the capabilities of the RTEMS task stack checker which can report stack usage as well as detect bounds violations.
- Chapter 30:
CPU Usage Statistics: presents the capabilities of the CPU Usage statistics gathered on a per task basis along with the mechanisms for reporting and resetting the statistics.
- Chapter 31:
Object Services: presents a collection of helper services useful when manipulating RTEMS objects. These include methods to assist in obtaining an object’s name in printable form. Additional services are provided to decompose an object Id and determine which API and object class it belongs to.
- Chapter 32:
Chains: presents the methods provided to build, iterate and manipulate doubly-linked chains. This manager makes the chain implementation used internally by RTEMS to user space applications.
- Chapter 33:
Red-Black Trees: information about how to use the Red-Black Tree API.
- Chapter 34:
Timespec Helpers: presents a set of helper services useful when manipulating POSIX
struct timespec
instances.- Chapter 35:
Constant Bandwidth Server Scheduler API.
- Chapter 36:
Ada Support: information about Ada programming language support.
- Chapter 37:
Directive Status Codes: provides a definition of each of the directive status codes referenced in this manual.
- Chapter 38:
Linker Sets: information about linker set features.
- Chapter 39:
Example Application: provides a template for simple RTEMS applications.
- Chapter 40:
Glossary: defines terms used throughout this manual.
- Chapter 41:
References: References.
- Chapter 42:
Index: Index.
3. Key Concepts#
3.1. Introduction#
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.
3.2. 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.
3.2.1. Object Names#
An object name is an unsigned thirty-two bit entity associated with the object by the user. The data type 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:
rtems_name my_name;
my_name = rtems_build_name( 'L', 'I', 'T', 'E' );
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.
The following example illustrates the use of this method to print an object name:
#include <rtems.h>
#include <rtems/bspIo.h>
void print_name(rtems_id id)
{
char buffer[10]; /* name assumed to be 10 characters or less */
char *result;
result = rtems_object_get_name( id, sizeof(buffer), buffer );
printk( "ID=0x%08x name=%s\n", id, ((result) ? result : "no name") );
}
3.2.2. Object Ids#
an object id is a unique 32-bit 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 some rtems services.
There are multiple directives with names of the form rtems_@CLASS@_ident
that take a name as argument and return the associated id if the name is found. The following is the set of name to id services: which can look up an object
rtems_extension_ident()
rtems_barrier_ident()
rtems_port_ident()
rtems_message_queue_ident()
rtems_partition_ident()
rtems_region_ident()
rtems_semaphore_ident()
rtems_task_ident()
rtems_timer_ident()
3.2.3. Local and Global Scope#
RTEMS supports uniprocessing, distributed multiprocessing, and Symmetric Multiprocessing (SMP) configurations. A uniprocessor system includes only a single processor in a single node. Distributed multiprocessor systems include multiple nodes, each of which is a single processor and is usually referred to as just multiprocessor mode for historical reasons. SMP systems consist of multiple processors cores in a single node.
In distributed multiprocessing configurations, there are multiple nodes in the system and object instances may be visible on just the creating node or to all nodes. If visible only to the creating node, this is referred to as local scope and corresponds to the RTEMS_LOCAL attribute setting which is the default. If RTEMS GLOBAL is specified as part of the object attributes, then the object instance has global scope and the object id can be used anywhere in the system to identify that object instance.
In uniprocessing and SMP configurations, there is only one node in the system and object instances are locally scoped to that node. Any attempt to create with the RTEMS_GLOBAL attribute is an error.
3.2.3.1. Object ID Format#
The thirty-two bit format for an object ID is composed of four parts: API, object class, node, and index. The data type rtems_id
is used to store object IDs.
31 27 26 24 23 16 15 0
+---------+-------+--------------+-------------------------------+
| | | | |
| Class | API | Node | Index |
| | | | |
+---------+-------+--------------+-------------------------------+
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 sixteen bits form an identifier within a particular object type. This identifier, called the object index, ranges in value from 1 to the maximum number of objects configured for this object type.
None of the fields in an object id may be zero except for the special case of RTEMS_SELF to indicate the currently running thread.
3.2.4. Object ID 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:
Objects_APIs rtems_object_id_get_api( rtems_id );
uint32_t rtems_object_id_get_class( rtems_id );
uint32_t rtems_object_id_get_node( rtems_id );
uint16_t rtems_object_id_get_index( rtems_id );
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.
3.3. 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
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:
Semaphore
Message Queue
Event
Signal
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.
3.4. Locking Protocols#
RTEMS supports the four locking protocols
for synchronization objects providing mutual-exclusion (mutex). The OMIP is only available in SMP configurations and replaces the priority inheritance protocol in this case. One aim of the locking protocols is to avoid priority inversion.
Since RTEMS 5.1, priority updates due to the locking protocols take place immediately and are propagated recursively. The mutex owner and wait for mutex relationships define a directed acyclic graph (DAG). The run-time of the mutex obtain, release and timeout operations depend on the complexity of this resource dependency graph.
3.4.1. Priority Inversion#
Priority inversion is a form of indefinite postponement which is common in multitasking, preemptive executives with shared resources. Priority inversion occurs when a high priority tasks requests access to shared resource which is currently allocated to a low priority task. The high priority task must block until the low priority task releases the resource. This problem is exacerbated when the low priority task is prevented from executing by one or more medium priority tasks. Because the low priority task is not executing, it cannot complete its interaction with the resource and release that resource. The high priority task is effectively prevented from executing by lower priority tasks.
3.4.2. Immediate Ceiling Priority Protocol (ICPP)#
Each mutex using the Immediate Ceiling Priority Protocol (ICPP) has a ceiling priority. The priority of the mutex owner is immediately raised to the ceiling priority of the mutex. In case the thread owning the mutex releases the mutex, then the normal priority of the thread is restored. This locking protocol is beneficial for schedulability analysis, see also [BW01].
This protocol avoids the possibility of changing the priority of the mutex owner multiple times since the ceiling priority must be set to the one of highest priority thread which will ever attempt to acquire that mutex. This requires an overall knowledge of the application as a whole. The need to identify the highest priority thread which will attempt to obtain a particular mutex can be a difficult task in a large, complicated system. Although the priority ceiling protocol is more efficient than the priority inheritance protocol with respect to the maximum number of thread priority changes which may occur while a thread owns a particular mutex, the priority inheritance protocol is more forgiving in that it does not require this apriori information.
3.4.3. Priority Inheritance Protocol#
The priority of the mutex owner is raised to the highest priority of all threads that currently wait for ownership of this mutex [SRL90]. Since RTEMS 5.1, priority updates due to the priority inheritance protocol take place immediately and are propagated recursively. This means the priority inheritance is transitive since RTEMS 5.1. If a task A owning a priority inheritance mutex blocks on another priority inheritance mutex, then the owner of this mutex inherits the priority of the task A.
3.4.4. Multiprocessor Resource Sharing Protocol (MrsP)#
The Multiprocessor Resource Sharing Protocol (MrsP) is a generalization of the priority ceiling protocol to clustered scheduling [BW13]. One of the design goals of MrsP is to enable an effective schedulability analysis using the sporadic task model. Each mutex using the MrsP has a ceiling priority for each scheduler instance. The priority of the mutex owner is immediately raised to the ceiling priority of the mutex defined for its home scheduler instance. In case the thread owning the mutex releases the mutex, then the normal priority of the thread is restored. Threads that wait for mutex ownership are not blocked with respect to the scheduler and instead perform a busy wait. The MrsP uses temporary thread migrations to foreign scheduler instances in case of a preemption of the mutex owner. This locking protocol is available since RTEMS 4.11. It was re-implemented in RTEMS 5.1 to overcome some shortcomings of the original implementation [CBHM15].
3.4.5. O(m) Independence-Preserving Protocol (OMIP)#
The \(O(m)\) Independence-Preserving Protocol (OMIP) is a generalization of the priority inheritance protocol to clustered scheduling which avoids the non-preemptive sections present with priority boosting [Bra13]. The \(m\) denotes the number of processors in the system. Similar to the uniprocessor priority inheritance protocol, the OMIP mutexes do not need any external configuration data, e.g. a ceiling priority. This makes them a good choice for general purpose libraries that need internal locking. The complex part of the implementation is contained in the thread queues and shared with the MrsP support. This locking protocol is available since RTEMS 5.1.
3.5. Thread Queues#
In case more than one thread may wait on a synchronization object, e.g. a semaphore or a message queue, then the waiting threads are added to a data structure called the thread queue. Thread queues are named task wait queues in the Classic API. There are two thread queuing disciplines available which define the order of the threads on a particular thread queue. Threads can wait in FIFO or priority order.
In uniprocessor configurations, the priority queuing discipline just orders the threads according to their current priority and in FIFO order in case of equal priorities. However, in SMP configurations, the situation is a bit more difficult due to the support for clustered scheduling. It makes no sense to compare the priority values of two different scheduler instances. Thus, it is impossible to simply use one plain priority queue for threads of different clusters. Two levels of queues can be used as one way to solve the problem. The top-level queue provides FIFO ordering and contains priority queues. Each priority queue is associated with a scheduler instance and contains only threads of this scheduler instance. Threads are enqueued in the priority queues corresponding to their scheduler instances. To dequeue a thread, the highest priority thread of the first priority queue is selected. Once this is done, the first priority queue is appended to the top-level FIFO queue. This guarantees fairness with respect to the scheduler instances.
Such a two-level queue needs a considerable amount of memory if fast enqueue and dequeue operations are desired. Providing this storage per thread queue would waste a lot of memory in typical applications. Instead, each thread has a queue attached which resides in a dedicated memory space independent of other memory used for the thread (this approach was borrowed from FreeBSD). In case a thread needs to block, there are two options
the object already has a queue, then the thread enqueues itself to this already present queue and the queue of the thread is added to a list of free queues for this object, or
otherwise, the queue of the thread is given to the object and the thread enqueues itself to this queue.
In case the thread is dequeued, there are two options
the thread is the last thread in the queue, then it removes this queue from the object and reclaims it for its own purpose, or
otherwise, the thread removes one queue from the free list of the object and reclaims it for its own purpose.
Since there are usually more objects than threads, this actually reduces the memory demands. In addition the objects only contain a pointer to the queue structure. This helps to hide implementation details. Inter-cluster priority queues are available since RTEMS 5.1.
A doubly-linked list (chain) is used to implement the FIFO queues yielding a \(O(1)\) worst-case time complexity for enqueue and dequeue operations.
A red-black tree is used to implement the priority queues yielding a \(O(log(n))\) worst-case time complexity for enqueue and dequeue operations with \(n\) being the count of threads already on the queue.
3.6. 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 clock tick or simply tick. The tick interval is defined by the application configuration option CONFIGURE_MICROSECONDS_PER_TICK. The tick interval defines the basic resolution of all interval and calendar time operations. 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 provided by the clock driver. The tick precision and stability depends on the clock driver and interrupt latency. Most clock drivers provide a timecounter to measure the time with a higher resolution than the tick.
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 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 tick resolution 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 rtems_time_of_day
is used to specify calendar time in RTEMS services. See Time and Date Data Structures.
3.7. Timer and Timeouts#
Timer and timeout services are a standard component of an operating system. The use cases fall roughly into two categories:
Timeouts – used to detect if some operations need more time than expected. Since the unexpected happens hopefully rarely, timeout timers are usually removed before they expire. The critical operations are insert and removal. For example, they are important for the performance of a network stack.
Timers – used to carry out some work in the future. They usually expire and need a high resolution. An example use case is a time driven scheduler, e.g. rate-monotonic or EDF.
In RTEMS versions prior to 5.1 the timer and timeout support was implemented by means of delta chains. This implementation was unfit for SMP systems due to several reasons. The new implementation present since RTEMS 5.1 uses a red-black tree with the expiration time as the key. This leads to \(O(log(n))\) worst-case insert and removal operations for \(n\) active timer or timeouts. Each processor provides its own timer and timeout service point so that it scales well with the processor count of the system. For each operation it is sufficient to acquire and release a dedicated SMP lock only once. The drawback is that a 64-bit integer type is required internally for the intervals to avoid a potential overflow of the key values.
An alternative to the red-black tree based implementation would be the use of a timer wheel based algorithm [VL87] which is used in Linux and FreeBSD [VC95] for example. A timer wheel based algorithm offers \(O(1)\) worst-case time complexity for insert and removal operations. The drawback is that the run-time of the clock tick procedure is unpredictable due to the use of a hash table or cascading.
The red-black tree approach was selected for RTEMS, since it offers a more predictable run-time behaviour. However, this sacrifices the constant insert and removal operations offered by the timer wheel algorithms. See also [GN06]. The implementation can re-use the red-black tree support already used in other areas, e.g. for the thread priority queues. Less code is a good thing for size, testing and verification.
3.8. 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:
Region
Partition
Dual Ported Memory
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.
4. RTEMS Data Types#
4.1. Introduction#
This chapter contains a complete list of the RTEMS primitive data types in alphabetical order. This is intended to be an overview and the user is encouraged to look at the appropriate chapters in the manual for more information about the usage of the various data types.
4.2. List of Data Types#
The following is a complete list of the RTEMS primitive data types in alphabetical order:
4.2.1. BSP_output_char_function_type#
Polled character output functions shall have this type.
4.2.2. BSP_polling_getchar_function_type#
Polled character input functions shall have this type.
4.2.3. Timer_Classes#
The timer class indicates how the timer was most recently fired.
ENUMERATORS:
- TIMER_DORMANT
This timer class indicates that the timer was never in use.
- TIMER_INTERVAL
This timer class indicates that the timer is currently in use as an interval timer which will fire in the context of the clock tick ISR.
- TIMER_INTERVAL_ON_TASK
This timer class indicates that the timer is currently in use as an interval timer which will fire in the context of the Timer Server task.
- TIMER_TIME_OF_DAY
This timer class indicates that the timer is currently in use as an time of day timer which will fire in the context of the clock tick ISR.
- TIMER_TIME_OF_DAY_ON_TASK
This timer class indicates that the timer is currently in use as an time of day timer which will fire in the context of the Timer Server task.
4.2.4. rtems_api_configuration_table#
This structure contains a summary of the Classic API configuration.
MEMBERS:
- maximum_tasks
This member contains the maximum number of Classic API Tasks configured for this application. See CONFIGURE_MAXIMUM_TASKS.
- notepads_enabled
This member is true, if the Classic API Notepads are enabled, otherwise it is false.
- maximum_timers
This member contains the maximum number of Classic API Timers configured for this application. See CONFIGURE_MAXIMUM_TIMERS.
- maximum_semaphores
This member contains the maximum number of Classic API Semaphores configured for this application. See CONFIGURE_MAXIMUM_SEMAPHORES.
- maximum_message_queues
This member contains the maximum number of Classic API Message Queues configured for this application. See CONFIGURE_MAXIMUM_MESSAGE_QUEUES.
- maximum_partitions
This member contains the maximum number of Classic API Partitions configured for this application. See CONFIGURE_MAXIMUM_PARTITIONS.
- maximum_regions
This member contains the maximum number of Classic API Regions configured for this application. See CONFIGURE_MAXIMUM_REGIONS.
- maximum_ports
This member contains the maximum number of Classic API Dual-Ported Memories configured for this application. See CONFIGURE_MAXIMUM_PORTS.
- maximum_periods
This member contains the maximum number of Classic API Rate Monotonic Periods configured for this application. See CONFIGURE_MAXIMUM_PERIODS.
- maximum_barriers
This member contains the maximum number of Classic API Barriers configured for this application. See CONFIGURE_MAXIMUM_BARRIERS.
- number_of_initialization_tasks
This member contains the number of Classic API Initialization Tasks configured for this application. See CONFIGURE_RTEMS_INIT_TASKS_TABLE.
- User_initialization_tasks_table
This member contains the pointer to Classic API Initialization Tasks Table of this application. See CONFIGURE_RTEMS_INIT_TASKS_TABLE.
DESCRIPTION:
Use rtems_configuration_get_rtems_api_configuration() to get the configuration table.
4.2.5. rtems_asr#
This type defines the return type of routines which are used to process asynchronous signals.
NOTES:
This type can be used to document asynchronous signal routines in the source code.
4.2.6. rtems_asr_entry#
This type defines the prototype of routines which are used to process asynchronous signals.
4.2.7. rtems_assert_context#
This structure provides the context in which an assertion failed.
MEMBERS:
- file
This member provides the file name of the source code file containing the failed assertion statement.
- line
This member provides the line number in the source code file containing the failed assertion statement.
- function
This member provides the function name containing the failed assertion statement.
- failed_expression
This member provides the expression of the failed assertion statement.
4.2.8. rtems_attribute#
This type represents Classic API attributes.
NOTES:
Attributes are primarily used when creating objects.
4.2.9. rtems_device_driver#
This type shall be used in device driver entry declarations and definitions.
NOTES:
Device driver entries return an rtems_status_code
status code. This type definition helps to document device driver entries in the source code.
4.2.10. rtems_device_driver_entry#
Device driver entries shall have this type.
4.2.11. rtems_device_major_number#
This integer type represents the major number of devices.
NOTES:
The major number of a device is determined by rtems_io_register_driver() and the application configuration (see CONFIGURE_MAXIMUM_DRIVERS) .
4.2.12. rtems_device_minor_number#
This integer type represents the minor number of devices.
NOTES:
The minor number of devices is managed by the device driver.
4.2.13. rtems_driver_address_table#
This structure contains the device driver entries.
MEMBERS:
- initialization_entry
This member is the device driver initialization entry. This entry is called by rtems_io_initialize().
- open_entry
This member is the device driver open entry. This entry is called by rtems_io_open().
- close_entry
This member is the device driver close entry. This entry is called by rtems_io_close().
- read_entry
This member is the device driver read entry. This entry is called by rtems_io_read().
- write_entry
This member is the device driver write entry. This entry is called by rtems_io_write().
- control_entry
This member is the device driver control entry. This entry is called by rtems_io_control().
DESCRIPTION:
This structure is used to register a device driver via rtems_io_register_driver().
4.2.14. rtems_event_set#
This integer type represents a bit field which can hold exactly 32 individual events.
4.2.15. rtems_exception_frame#
This structure represents an architecture-dependent exception frame.
4.2.16. rtems_extensions_table#
The extensions table contains a set of extensions which may be registered in the system through the CONFIGURE_INITIAL_EXTENSIONS application configuration option or the rtems_extension_create() directive.
4.2.17. rtems_fatal_code#
This integer type represents system termination codes.
DESCRIPTION:
This integer type is large enough to store a 32-bit integer or a pointer.
NOTES:
The interpretation of a system termination code depends on the system termination source, see rtems_fatal_source.
4.2.18. rtems_fatal_extension#
Fatal extensions are invoked when the system should terminate.
PARAMETERS:
source
This parameter is the system termination source. The source indicates the component which caused the system termination request, see rtems_fatal_source. The system termination code may provide additional information related to the system termination request.
always_set_to_false
This parameter is a value equal to
false
.code
This parameter is the system termination code. This value must be interpreted with respect to the source.
NOTES:
The fatal extensions are invoked in extension forward order and with maskable interrupts disabled.
The fatal extension should be extremely careful with respect to the RTEMS directives it calls. Depending on the system termination source, the system may be in an undefined and corrupt state.
It is recommended to register fatal extensions through initial extension sets, see CONFIGURE_INITIAL_EXTENSIONS.
4.2.19. rtems_fatal_source#
This enumeration represents system termination sources.
NOTES:
The system termination code may provide additional information depending on the system termination source, see rtems_fatal_code.
4.2.20. rtems_id#
This type represents RTEMS object identifiers.
4.2.21. rtems_initialization_tasks_table#
This structure defines the properties of the Classic API user initialization task.
MEMBERS:
- name
This member defines the task name.
- stack_size
This member defines the task stack size in bytes.
- initial_priority
This member defines the initial task priority.
- attribute_set
This member defines the attribute set of the task.
- entry_point
This member defines the entry point of the task.
- mode_set
This member defines the initial modes of the task.
- argument
This member defines the entry point argument of the task.
4.2.22. rtems_interrupt_attributes#
This structure provides the attributes of an interrupt vector.
MEMBERS:
- is_maskable
This member is true, if the interrupt vector is maskable by rtems_interrupt_local_disable(), otherwise it is false. Interrupt vectors which are not maskable by rtems_interrupt_local_disable() should be used with care since they cannot use most operating system services.
- can_enable
This member is true, if the interrupt vector can be enabled by rtems_interrupt_vector_enable(), otherwise it is false. When an interrupt vector can be enabled, this means that the enabled state can always be changed from disabled to enabled. For an interrupt vector which can be enabled it follows that it may be enabled.
- maybe_enable
This member is true, if the interrupt vector may be enabled by rtems_interrupt_vector_enable(), otherwise it is false. When an interrupt vector may be enabled, this means that the enabled state may be changed from disabled to enabled. The requested enabled state change should be checked by rtems_interrupt_vector_is_enabled(). Some interrupt vectors may be optionally available and cannot be enabled on a particular target.
- can_disable
This member is true, if the interrupt vector can be disabled by rtems_interrupt_vector_disable(), otherwise it is false. When an interrupt vector can be disabled, this means that the enabled state can be changed from enabled to disabled. For an interrupt vector which can be disabled it follows that it may be disabled.
- maybe_disable
This member is true, if the interrupt vector may be disabled by rtems_interrupt_vector_disable(), otherwise it is false. When an interrupt vector may be disabled, this means that the enabled state may be changed from enabled to disabled. The requested enabled state change should be checked by rtems_interrupt_vector_is_enabled(). Some interrupt vectors may be always enabled and cannot be disabled on a particular target.
- can_raise
This member is true, if the interrupt vector can be raised by rtems_interrupt_raise(), otherwise it is false.
- can_raise_on
This member is true, if the interrupt vector can be raised on a processor by rtems_interrupt_raise_on(), otherwise it is false.
- can_clear
This member is true, if the interrupt vector can be cleared by rtems_interrupt_clear(), otherwise it is false.
- cleared_by_acknowledge
This member is true, if the pending status of the interrupt associated with the interrupt vector is cleared by an interrupt acknowledge from the processor, otherwise it is false.
- can_get_affinity
This member is true, if the affinity set of the interrupt vector can be obtained by rtems_interrupt_get_affinity(), otherwise it is false.
- can_set_affinity
This member is true, if the affinity set of the interrupt vector can be set by rtems_interrupt_set_affinity(), otherwise it is false.
- can_be_triggered_by_message
This member is true, if the interrupt associated with the interrupt vector can be triggered by a message. Interrupts may be also triggered by signals, rtems_interrupt_raise(), or rtems_interrupt_raise_on(). Examples for message triggered interrupts are the PCIe MSI/MSI-X and the ARM GICv3 Locality-specific Peripheral Interrupts (LPI).
- trigger_signal
This member describes the trigger signal of the interrupt associated with the interrupt vector. Interrupts are normally triggered by signals which indicate an interrupt request from a peripheral. Interrupts may be also triggered by messages, rtems_interrupt_raise(), or rtems_interrupt_raise_on().
- can_get_priority
This member is true, if the priority of the interrupt vector can be obtained by rtems_interrupt_get_priority(), otherwise it is false.
- can_set_priority
This member is true, if the priority of the interrupt vector can be set by rtems_interrupt_set_priority(), otherwise it is false.
- maximum_priority
This member represents the maximum priority value of the interrupt vector. By convention, the minimum priority value is zero. Lower priority values shall be associated with a higher importance. The higher the priority value, the less important is the service of the associated interrupt vector. Where nested interrupts are supported, interrupts with a lower priority value may preempt other interrupts having a higher priority value.
DESCRIPTION:
The rtems_interrupt_get_attributes() directive may be used to obtain the attributes of an interrupt vector.
4.2.23. rtems_interrupt_entry#
This structure represents an interrupt entry.
MEMBERS:
Members of the type shall not be accessed directly by the application.
NOTES:
This structure shall be treated as an opaque data type from the API point of view. Members shall not be accessed directly. An entry may be initialized by RTEMS_INTERRUPT_ENTRY_INITIALIZER() or rtems_interrupt_entry_initialize(). It may be installed for an interrupt vector with rtems_interrupt_entry_install() and removed from an interrupt vector by rtems_interrupt_entry_remove().
4.2.24. rtems_interrupt_handler#
Interrupt handler routines shall have this type.
4.2.25. rtems_interrupt_level#
This integer type represents interrupt levels.
4.2.26. rtems_interrupt_lock#
This structure represents an ISR lock.
NOTES:
Lock objects are only needed in some RTEMS build configurations, for example where the SMP support is enabled. The RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT
constant can be used to determine whether a lock object is needed or not. This may help to reduce the memory demands of an application. All lock operations do not use the lock object parameter if lock objects are not needed.
1#include <rtems.h>
2
3#if RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT
4rtems_interrupt_lock lock = RTEMS_INTERRUPT_LOCK_INITIALIZER( "name" );
5#endif
6
7struct s {
8#if RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT
9 rtems_interrupt_lock lock;
10#endif
11 int foobar;
12};
4.2.27. rtems_interrupt_lock_context#
This structure provides an ISR lock context for acquire and release pairs.
4.2.28. rtems_interrupt_per_handler_routine#
Visitor routines invoked by rtems_interrupt_handler_iterate() shall have this type.
4.2.29. rtems_interrupt_server_action#
This structure represents an interrupt server action.
MEMBERS:
Members of the type shall not be accessed directly by the application.
NOTES:
This structure shall be treated as an opaque data type from the API point of view. Members shall not be accessed directly.
4.2.30. rtems_interrupt_server_config#
This structure defines an interrupt server configuration.
MEMBERS:
Members of the type shall not be accessed directly by the application.
NOTES:
See also rtems_interrupt_server_create().
4.2.31. rtems_interrupt_server_control#
This structure represents an interrupt server.
MEMBERS:
Members of the type shall not be accessed directly by the application.
NOTES:
This structure shall be treated as an opaque data type from the API point of view. Members shall not be accessed directly. The structure is initialized by rtems_interrupt_server_create() and maintained by the interrupt server support.
4.2.32. rtems_interrupt_server_entry#
This structure represents an interrupt server entry.
MEMBERS:
Members of the type shall not be accessed directly by the application.
NOTES:
This structure shall be treated as an opaque data type from the API point of view. Members shall not be accessed directly. An entry is initialized by rtems_interrupt_server_entry_initialize() and destroyed by rtems_interrupt_server_entry_destroy(). Interrupt server actions can be prepended to the entry by rtems_interrupt_server_action_prepend(). The entry is submitted to be serviced by rtems_interrupt_server_entry_submit().
4.2.33. rtems_interrupt_server_request#
This structure represents an interrupt server request.
MEMBERS:
Members of the type shall not be accessed directly by the application.
NOTES:
This structure shall be treated as an opaque data type from the API point of view. Members shall not be accessed directly. A request is initialized by rtems_interrupt_server_request_initialize() and destroyed by rtems_interrupt_server_request_destroy(). The interrupt vector of the request can be set by rtems_interrupt_server_request_set_vector(). The request is submitted to be serviced by rtems_interrupt_server_request_submit().
4.2.34. rtems_interrupt_signal_variant#
This enumeration provides interrupt trigger signal variants.
ENUMERATORS:
- RTEMS_INTERRUPT_UNSPECIFIED_SIGNAL
This interrupt signal variant indicates that the interrupt trigger signal is unspecified.
- RTEMS_INTERRUPT_NO_SIGNAL
This interrupt signal variant indicates that the interrupt cannot be triggered by a signal.
- RTEMS_INTERRUPT_SIGNAL_LEVEL_LOW
This interrupt signal variant indicates that the interrupt is triggered by a low level signal.
- RTEMS_INTERRUPT_SIGNAL_LEVEL_HIGH
This interrupt signal variant indicates that the interrupt is triggered by a high level signal.
- RTEMS_INTERRUPT_SIGNAL_EDGE_FALLING
This interrupt signal variant indicates that the interrupt is triggered by a falling edge signal.
- RTEMS_INTERRUPT_SIGNAL_EDGE_RAISING
This interrupt signal variant indicates that the interrupt is triggered by a raising edge signal.
4.2.35. rtems_interval#
This type represents clock tick intervals.
4.2.36. rtems_isr#
This type defines the return type of interrupt service routines.
DESCRIPTION:
This type can be used to document interrupt service routines in the source code.
4.2.37. rtems_isr_entry#
Interrupt service routines installed by rtems_interrupt_catch() shall have this type.
4.2.38. rtems_message_queue_config#
This structure defines the configuration of a message queue constructed by rtems_message_queue_construct().
MEMBERS:
- name
This member defines the name of the message queue.
- maximum_pending_messages
This member defines the maximum number of pending messages supported by the message queue.
- maximum_message_size
This member defines the maximum message size supported by the message queue.
- storage_area
This member shall point to the message buffer storage area begin. The message buffer storage area for the message queue shall be an array of the type defined by RTEMS_MESSAGE_QUEUE_BUFFER() with a maximum message size equal to the maximum message size of this configuration.
- storage_size
This member defines size of the message buffer storage area in bytes.
- storage_free
This member defines the optional handler to free the message buffer storage area. It is called when the message queue is deleted. It is called from task context under protection of the object allocator lock. It is allowed to call
free()
in this handler. If handler is NULL, then no action will be performed.- attributes
This member defines the attributes of the message queue.
4.2.39. rtems_mode#
This type represents a Classic API task mode set.
4.2.40. rtems_mp_packet_classes#
This enumeration defines the MPCI packet classes.
4.2.41. rtems_mpci_entry#
MPCI handler routines shall have this return type.
4.2.42. rtems_mpci_get_packet_entry#
MPCI get packet routines shall have this type.
4.2.43. rtems_mpci_initialization_entry#
MPCI initialization routines shall have this type.
4.2.44. rtems_mpci_receive_packet_entry#
MPCI receive packet routines shall have this type.
4.2.45. rtems_mpci_return_packet_entry#
MPCI return packet routines shall have this type.
4.2.46. rtems_mpci_send_packet_entry#
MPCI send packet routines shall have this type.
4.2.47. rtems_mpci_table#
This type represents the user-provided MPCI control.
4.2.48. rtems_multiprocessing_table#
This type represents the user-provided MPCI configuration.
4.2.49. rtems_name#
This type represents Classic API object names.
DESCRIPTION:
It is an unsigned 32-bit integer which can be treated as a numeric value or initialized using rtems_build_name() to encode four ASCII characters. A value of zero may have a special meaning in some directives.
4.2.50. rtems_object_api_class_information#
This structure is used to return information to the application about the objects configured for a specific API/Class combination.
MEMBERS:
- minimum_id
This member contains the minimum valid object identifier for this class.
- maximum_id
This member contains the maximum valid object identifier for this class.
- maximum
This member contains the maximum number of active objects configured for this class.
- auto_extend
This member is true, if this class is configured for automatic object extension, otherwise it is false.
- unallocated
This member contains the number of currently inactive objects of this class.
4.2.51. rtems_option#
This type represents a Classic API directive option set.
4.2.52. rtems_packet_prefix#
This type represents the prefix found at the beginning of each MPCI packet sent between nodes.
4.2.53. rtems_rate_monotonic_period_states#
This enumeration defines the states in which a period may be.
ENUMERATORS:
- RATE_MONOTONIC_INACTIVE
This status indicates the period is off the watchdog chain, and has never been initialized.
- RATE_MONOTONIC_ACTIVE
This status indicates the period is on the watchdog chain, and running. The owner may be executing or blocked waiting on another object.
- RATE_MONOTONIC_EXPIRED
This status indicates the period is off the watchdog chain, and has expired. The owner may still execute and has taken too much time to complete this iteration of the period.
4.2.54. rtems_rate_monotonic_period_statistics#
This structure provides the statistics of a period.
MEMBERS:
- count
This member contains the number of periods executed.
- missed_count
This member contains the number of periods missed.
- min_cpu_time
This member contains the least amount of processor time used in a period.
- max_cpu_time
This member contains the highest amount of processor time used in a period.
- total_cpu_time
This member contains the total amount of processor time used in a period.
- min_wall_time
This member contains the least amount of CLOCK_MONOTONIC time used in a period.
- max_wall_time
This member contains the highest amount of CLOCK_MONOTONIC time used in a period.
- total_wall_time
This member contains the total amount of CLOCK_MONOTONIC time used in a period.
4.2.55. rtems_rate_monotonic_period_status#
This structure provides the detailed status of a period.
MEMBERS:
- owner
This member contains the identifier of the owner task of the period.
- state
This member contains the state of the period.
- since_last_period
This member contains the time elapsed since the last successful invocation rtems_rate_monotonic_period() using CLOCK_MONOTONIC. If the period is expired or has not been initiated, then this value has no meaning.
- executed_since_last_period
This member contains the processor time consumed by the owner task since the last successful invocation rtems_rate_monotonic_period(). If the period is expired or has not been initiated, then this value has no meaning.
- postponed_jobs_count
This member contains the count of jobs which are not released yet.
4.2.56. rtems_regulator_attributes#
This structure defines the configuration of a regulator created by rtems_regulator_create().
MEMBERS:
- deliverer
This member contains a pointer to an application function invoked by the Delivery thread to output a message to the destination.
- deliverer_context
This member contains a pointer to an application defined context which is passed to delivery function.
- maximum_message_size
This member contains the maximum size message to process.
- maximum_messages
This member contains the maximum number of messages to be able to buffer.
- output_thread_priority
This member contains the priority of output thread.
- output_thread_stack_size
This member contains the Stack size of output thread.
- output_thread_period
This member contains the period (in ticks) of output thread.
- maximum_to_dequeue_per_period
This member contains the maximum number of messages the output thread should dequeue and deliver per period.
NOTES:
This type is passed as an argument to rtems_regulator_create().
4.2.57. rtems_regulator_deliverer#
This type represents the function signature used to specify a delivery function for the RTEMS Regulator.
NOTES:
This type is used in the rtems_regulator_attributes structure which is passed as an argument to rtems_regulator_create().
4.2.58. rtems_regulator_statistics#
This structure defines the statistics maintained by each Regulator instance.
MEMBERS:
- obtained
This member contains the number of successfully obtained buffers.
- released
This member contains the number of successfully released buffers.
- delivered
This member contains the number of successfully delivered buffers.
- period_statistics
This member contains the Rate Monotonic Period statistics for the Delivery Thread. It is an instance of the rtems_rate_monotonic_period_statistics structure.
NOTES:
This type is passed as an argument to rtems_regulator_get_statistics().
4.2.59. rtems_signal_set#
This integer type represents a bit field which can hold exactly 32 individual signals.
4.2.60. rtems_stack_allocate_hook#
A thread stack allocator allocate handler shall have this type.
4.2.61. rtems_stack_allocate_init_hook#
A task stack allocator initialization handler shall have this type.
4.2.62. rtems_stack_free_hook#
A task stack allocator free handler shall have this type.
4.2.63. rtems_status_code#
This enumeration provides status codes for directives of the Classic API.
ENUMERATORS:
- RTEMS_SUCCESSFUL
This status code indicates successful completion of a requested operation.
- RTEMS_TASK_EXITTED
This status code indicates that a thread exitted.
- RTEMS_MP_NOT_CONFIGURED
This status code indicates that multiprocessing was not configured.
- RTEMS_INVALID_NAME
This status code indicates that an object name was invalid.
- RTEMS_INVALID_ID
This status code indicates that an object identifier was invalid.
- RTEMS_TOO_MANY
This status code indicates you have attempted to create too many instances of a particular object class.
- RTEMS_TIMEOUT
This status code indicates that a blocking directive timed out.
- RTEMS_OBJECT_WAS_DELETED
This status code indicates the object was deleted while the thread was blocked waiting.
- RTEMS_INVALID_SIZE
This status code indicates that a specified size was invalid.
- RTEMS_INVALID_ADDRESS
This status code indicates that a specified address was invalid.
- RTEMS_INVALID_NUMBER
This status code indicates that a specified number was invalid.
- RTEMS_NOT_DEFINED
This status code indicates that the item has not been initialized.
- RTEMS_RESOURCE_IN_USE
This status code indicates that the object still had resources in use.
- RTEMS_UNSATISFIED
This status code indicates that the request was not satisfied.
- RTEMS_INCORRECT_STATE
This status code indicates that an object was in wrong state for the requested operation.
- RTEMS_ALREADY_SUSPENDED
This status code indicates that the thread was already suspended.
- RTEMS_ILLEGAL_ON_SELF
This status code indicates that the operation was illegal on the calling thread.
- RTEMS_ILLEGAL_ON_REMOTE_OBJECT
This status code indicates that the operation was illegal on a remote object.
- RTEMS_CALLED_FROM_ISR
This status code indicates that the operation should not be called from this execution environment.
- RTEMS_INVALID_PRIORITY
This status code indicates that an invalid thread priority was provided.
- RTEMS_INVALID_CLOCK
This status code indicates that a specified date or time was invalid.
- RTEMS_INVALID_NODE
This status code indicates that a specified node identifier was invalid.
- RTEMS_NOT_CONFIGURED
This status code indicates that the directive was not configured.
- RTEMS_NOT_OWNER_OF_RESOURCE
This status code indicates that the caller was not the owner of the resource.
- RTEMS_NOT_IMPLEMENTED
This status code indicates 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_INTERNAL_ERROR
This status code indicates that an internal RTEMS inconsistency was detected.
- RTEMS_NO_MEMORY
This status code indicates that the directive attempted to allocate memory but was unable to do so.
- RTEMS_IO_ERROR
This status code indicates a device driver IO error.
- RTEMS_INTERRUPTED
This status code is used internally by the implementation to indicate a blocking device driver call has been interrupted and should be reflected to the caller as interrupted.
- RTEMS_PROXY_BLOCKING
This status code is used internally by the implementation 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.
4.2.64. rtems_task#
This type defines the return type of task entry points.
DESCRIPTION:
This type can be used to document task entry points in the source code.
4.2.65. rtems_task_argument#
This integer type represents task argument values.
NOTES:
The type is an architecture-specific unsigned integer type which is large enough to represent pointer values and 32-bit unsigned integers.
4.2.66. rtems_task_begin_extension#
Task begin extensions are invoked when a task begins execution.
PARAMETERS:
executing
This parameter is the TCB of the executing thread.
NOTES:
The task begin extensions are invoked in extension forward order.
Task begin extensions are invoked with thread dispatching enabled. This allows the use of dynamic memory allocation, creation of POSIX keys, and use of C++ thread-local storage. Blocking synchronization primitives are allowed also.
The task begin extensions are invoked before the global construction.
The task begin extensions may be called as a result of a task restart through rtems_task_restart().
4.2.67. rtems_task_config#
This structure defines the configuration of a task constructed by rtems_task_construct().
MEMBERS:
- name
This member defines the name of the task.
- initial_priority
This member defines the initial priority of the task.
- storage_area
This member shall point to the task storage area begin. The task storage area will contain the task stack, the thread-local storage, and the floating-point context on architectures with a separate floating-point context.
The task storage area begin address and size should be aligned by
RTEMS_TASK_STORAGE_ALIGNMENT
. To avoid memory waste, useRTEMS_ALIGNED()
andRTEMS_TASK_STORAGE_ALIGNMENT
to enforce the recommended alignment of a statically allocated task storage area.- storage_size
This member defines size of the task storage area in bytes. Use the RTEMS_TASK_STORAGE_SIZE() macro to determine the recommended task storage area size.
- maximum_thread_local_storage_size
This member defines the maximum thread-local storage size supported by the task storage area. Use
RTEMS_ALIGN_UP()
andRTEMS_TASK_STORAGE_ALIGNMENT
to adjust the size to meet the minimum alignment requirement of a thread-local storage area used to construct a task.If the value is less than the actual thread-local storage size, then the task construction by rtems_task_construct() fails.
If the is less than the task storage area size, then the task construction by rtems_task_construct() fails.
The actual thread-local storage size is determined when the application executable is linked. The
rtems-exeinfo
command line tool included in the RTEMS Tools can be used to obtain the thread-local storage size and alignment of an application executable.The application may configure the maximum thread-local storage size for all threads explicitly through the CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE configuration option.
- storage_free
This member defines the optional handler to free the task storage area. It is called on exactly two mutually exclusive occasions. Firstly, when the task construction aborts due to a failed task create extension, or secondly, when the task is deleted. It is called from task context under protection of the object allocator lock. It is allowed to call
free()
in this handler. If handler is NULL, then no action will be performed.- initial_modes
This member defines the initial modes of the task.
- attributes
This member defines the attributes of the task.
4.2.68. rtems_task_create_extension#
Task create extensions are invoked when a task is created.
PARAMETERS:
executing
This parameter is the TCB of the executing thread. When the idle thread is created, the executing thread is equal to NULL.
created
This parameter is the TCB of the created thread.
RETURN VALUES:
Returns true, if the task create extension was successful, otherwise false.
NOTES:
The task create extensions are invoked in extension forward order.
The task create extensions are invoked after a new task has been completely initialized, but before it is started.
While normal tasks are created, the executing thread is the owner of the object allocator mutex. The object allocator mutex allows nesting, so the normal memory allocation routines can be used allocate memory for the created thread.
If the task create extension returns false
, then the task create operation stops immediately and the entire task create operation will fail. In this case, all task delete extensions are invoked, see rtems_task_delete_extension.
4.2.69. rtems_task_delete_extension#
Task delete extensions are invoked when a task is deleted.
PARAMETERS:
executing
This parameter is the TCB of the executing thread. If the idle thread is created and one of the initial task create extension fails, then the executing thread is equal to NULL.
created
This parameter is the TCB of the deleted thread. The executing and deleted arguments are never equal.
NOTES:
The task delete extensions are invoked in extension reverse order.
The task delete extensions are invoked by task create directives before an attempt to allocate a TCB is made.
If a task create extension failed, then a task delete extension may be invoked without a previous invocation of the corresponding task create extension of the extension set.
4.2.70. rtems_task_entry#
This type defines the task entry point of an RTEMS task.
4.2.71. rtems_task_exitted_extension#
Task exitted extensions are invoked when a task entry returns.
PARAMETERS:
executing
This parameter is the TCB of the executing thread.
NOTES:
The task exitted extensions are invoked in extension forward order.
4.2.72. rtems_task_priority#
This integer type represents task priorities of the Classic API.
4.2.73. rtems_task_restart_extension#
Task restart extensions are invoked when a task restarts.
PARAMETERS:
executing
This parameter is the TCB of the executing thread.
restarted
This parameter is the TCB of the executing thread. Yes, the executing thread.
NOTES:
The task restart extensions are invoked in extension forward order.
The task restart extensions are invoked in the context of the restarted thread right before the execution context is reloaded. The thread stack reflects the previous execution context.
Thread restart and delete requests issued by restart extensions lead to recursion.
4.2.74. rtems_task_start_extension#
Task start extensions are invoked when a task was made ready for the first time.
PARAMETERS:
executing
This parameter is the TCB of the executing thread.
started
This parameter is the TCB of the started thread.
NOTES:
The task start extensions are invoked in extension forward order.
In SMP configurations, the thread may already run on another processor before the task start extensions are actually invoked. Task switch and task begin extensions may run before or in parallel with the thread start extension in SMP configurations, see rtems_task_switch_extension and rtems_task_begin_extension.
4.2.75. rtems_task_switch_extension#
Task switch extensions are invoked when a thread switch from an executing thread to a heir thread takes place.
PARAMETERS:
executing
This parameter is the TCB of the executing thread. In SMP configurations, this is the previously executing thread also known as the ancestor thread.
heir
This parameter is the TCB of the heir thread. In SMP configurations, this is the executing thread.
NOTES:
The task switch extensions are invoked in extension forward order.
The invocation conditions of the task switch extensions depend on whether RTEMS was built with SMP support enabled or disabled. A user must pay attention to the differences to correctly implement a task switch extension.
Where the system was built with SMP support disabled, the task switch extensions are invoked before the context switch from the currently executing thread to the heir thread. The executing
is a pointer to the TCB of the currently executing thread. The heir
is a pointer to the TCB of the heir thread. The context switch initiated through the multitasking start is not covered by the task switch extensions.
Where the system was built with SMP support enabled, the task switch extensions are invoked after the context switch to the heir thread. The executing
is a pointer to the TCB of the previously executing thread. Despite the name, this is not the currently executing thread. The heir
is a pointer to the TCB of the newly executing thread. This is the currently executing thread. The context switches initiated through the multitasking start are covered by the task switch extensions. The reason for the differences to uniprocessor configurations is that the context switch may update the heir thread of the processor. The task switch extensions are invoked with maskable interrupts disabled and with ownership of a processor-specific SMP lock. Task switch extensions may run in parallel on multiple processors. It is recommended to use thread-local or processor-specific data structures for task switch extensions. A global SMP lock should be avoided for performance reasons, see rtems_interrupt_lock_initialize().
4.2.76. rtems_task_terminate_extension#
Task terminate extensions are invoked when a task terminates.
PARAMETERS:
executing
This parameter is the TCB of the executing thread. This is the terminating thread.
NOTES:
The task terminate extensions are invoked in extension reverse order.
The task terminate extensions are invoked in the context of the terminating thread right before the thread dispatch to the heir thread should take place. The thread stack reflects the previous execution context. The POSIX cleanup and key destructors execute in this context.
Thread restart and delete requests issued by terminate extensions lead to recursion.
4.2.77. rtems_task_visitor#
Visitor routines invoked by rtems_task_iterate() shall have this type.
4.2.78. rtems_tcb#
This structure represents the TCB.
4.2.79. rtems_time_of_day#
This type represents Classic API calendar times.
MEMBERS:
- year
This member contains the year A.D.
- month
This member contains the month of the year with values from 1 to 12.
- day
This member contains the day of the month with values from 1 to 31.
- hour
This member contains the hour of the day with values from 0 to 23.
- minute
This member contains the minute of the hour with values from 0 to 59.
- second
This member contains the second of the minute with values from 0 to 59.
- ticks
This member contains the clock tick of the second with values from 0 to rtems_clock_get_ticks_per_second() minus one.
4.2.80. rtems_timer_information#
The structure contains information about a timer.
MEMBERS:
- the_class
The timer class member indicates how the timer was most recently fired.
- initial
This member indicates the initial requested interval.
- start_time
This member indicates the time the timer was initially scheduled. The time is in clock ticks since the clock driver initialization or the last clock tick counter overflow.
- stop_time
This member indicates the time the timer was scheduled to fire. The time is in clock ticks since the clock driver initialization or the last clock tick counter overflow.
4.2.81. rtems_timer_service_routine#
This type defines the return type of routines which can be fired by directives of the Timer Manager.
DESCRIPTION:
This type can be used to document timer service routines in the source code.
4.2.82. rtems_timer_service_routine_entry#
This type defines the prototype of routines which can be fired by directives of the Timer Manager.
4.2.83. rtems_vector_number#
This integer type represents interrupt vector numbers.
5. Scheduling Concepts#
5.1. Introduction#
The scheduling concepts relate to the allocation of processing time for tasks.
The concept of scheduling in real-time systems dictates the ability to provide an immediate response to specific external events, particularly the necessity of scheduling tasks to run within a specified time limit after the occurrence of an event. For example, software embedded in life-support systems used to monitor hospital patients must take instant action if a change in the patient’s status is detected.
The component of RTEMS responsible for providing this capability is appropriately called the scheduler. The scheduler’s sole purpose is to allocate the all important resource of processor time to the various tasks competing for attention. The directives provided by the Scheduler Manager are:
rtems_scheduler_ident() - Identifies a scheduler by the object name.
rtems_scheduler_ident_by_processor() - Identifies a scheduler by the processor index.
rtems_scheduler_ident_by_processor_set() - Identifies a scheduler by the processor set.
rtems_scheduler_get_maximum_priority() - Gets the maximum task priority of the scheduler.
rtems_scheduler_map_priority_to_posix() - Maps a Classic API task priority to the corresponding POSIX thread priority.
rtems_scheduler_map_priority_from_posix() - Maps a POSIX thread priority to the corresponding Classic API task priority.
rtems_scheduler_get_processor() - Returns the index of the current processor.
rtems_scheduler_get_processor_maximum() - Returns the processor maximum supported by the system.
rtems_scheduler_get_processor_set() - Gets the set of processors owned by the scheduler.
rtems_scheduler_add_processor() - Adds the processor to the set of processors owned by the scheduler.
rtems_scheduler_remove_processor() - Removes the processor from the set of processors owned by the scheduler.
5.2. Background#
5.2.1. Scheduling Algorithms#
RTEMS provides a plugin framework that allows it to support multiple scheduling algorithms. RTEMS includes multiple scheduling algorithms, and the user can select which of these they wish to use in their application at link-time. In addition, the user can implement their own scheduling algorithm and configure RTEMS to use it.
Supporting multiple scheduling algorithms gives the end user the option to select the algorithm which is most appropriate to their use case. Most real-time operating systems schedule tasks using a priority based algorithm, possibly with preemption control. The classic RTEMS scheduling algorithm which was the only algorithm available in RTEMS 4.10 and earlier, is a fixed-priority scheduling algorithm. This scheduling algorithm is suitable for uniprocessor (e.g., non-SMP) systems and is known as the Deterministic Priority Scheduler. Unless the user configures another scheduling algorithm, RTEMS will use this on uniprocessor systems.
5.2.2. Priority Scheduling#
When using priority based scheduling, RTEMS allocates the processor using a priority-based, preemptive algorithm augmented to provide round-robin characteristics within individual priority groups. The goal of this algorithm is to guarantee that the task which is executing on the processor at any point in time is the one with the highest priority among all tasks in the ready state.
When a task is added to the ready chain, it is placed behind all other tasks of the same priority. This rule provides a round-robin within a priority group scheduling characteristic. This means that in a group of equal priority tasks, tasks will execute in the order they become ready or FIFO order. Even though there are ways to manipulate and adjust task priorities, the most important rule to remember is:
Note
Priority based scheduling algorithms will always select the highest priority task that is ready to run when allocating the processor to a task.
Priority scheduling is the most commonly used scheduling algorithm. It should be used by applications in which multiple tasks contend for CPU time or other resources, and there is a need to ensure certain tasks are given priority over other tasks.
There are a few common methods of accomplishing the mechanics of this algorithm. These ways involve a list or chain of tasks in the ready state.
The least efficient method is to randomly place tasks in the ready chain forcing the scheduler to scan the entire chain to determine which task receives the processor.
A more efficient method is to schedule the task by placing it in the proper place on the ready chain based on the designated scheduling criteria at the time it enters the ready state. Thus, when the processor is free, the first task on the ready chain is allocated the processor.
Another mechanism is to maintain a list of FIFOs per priority. When a task is readied, it is placed on the rear of the FIFO for its priority. This method is often used with a bitmap to assist in locating which FIFOs have ready tasks on them. This data structure has \(O(1)\) insert, extract and find highest ready run-time complexities.
A red-black tree may be used for the ready queue with the priority as the key. This data structure has \(O(log(n))\) insert, extract and find highest ready run-time complexities while \(n\) is the count of tasks in the ready queue.
RTEMS currently includes multiple priority based scheduling algorithms as well as other algorithms that incorporate deadline. Each algorithm is discussed in the following sections.
5.2.3. Scheduling Modification Mechanisms#
RTEMS provides four mechanisms which allow the user to alter the task scheduling decisions:
user-selectable task priority level
task preemption control
task timeslicing control
manual round-robin selection
Each of these methods provides a powerful capability to customize sets of tasks to satisfy the unique and particular requirements encountered in custom real-time applications. Although each mechanism operates independently, there is a precedence relationship which governs the effects of scheduling modifications. The evaluation order for scheduling characteristics is always priority, preemption mode, and timeslicing. When reading the descriptions of timeslicing and manual round-robin it is important to keep in mind that preemption (if enabled) of a task by higher priority tasks will occur as required, overriding the other factors presented in the description.
5.2.3.1. Task Priority and Scheduling#
The most significant task scheduling modification mechanism is the ability for the user to assign a priority level to each individual task when it is created and to alter a task’s priority at run-time, see Task Priority.
5.2.3.2. Preemption#
Another way the user can alter the basic scheduling algorithm is by manipulating the preemption mode flag (RTEMS_PREEMPT_MASK
) of individual tasks. If preemption is disabled for a task (RTEMS_NO_PREEMPT
), then the task will not relinquish control of the processor until it terminates, blocks, or re-enables preemption. Even tasks which become ready to run and possess higher priority levels will not be allowed to execute. Note that the preemption setting has no effect on the manner in which a task is scheduled. It only applies once a task has control of the processor.
5.2.3.3. Timeslicing#
Timeslicing or round-robin scheduling is an additional method which can be used to alter the basic scheduling algorithm. Like preemption, timeslicing is specified on a task by task basis using the timeslicing mode flag (RTEMS_TIMESLICE_MASK
). If timeslicing is enabled for a task (RTEMS_TIMESLICE
), then RTEMS will limit the amount of time the task can execute before the processor is allocated to another task. Each tick of the real-time clock reduces the currently running task’s timeslice. When the execution time equals the timeslice, RTEMS will dispatch another task of the same priority to execute. If there are no other tasks of the same priority ready to execute, then the current task is allocated an additional timeslice and continues to run. Remember that a higher priority task will preempt the task (unless preemption is disabled) as soon as it is ready to run, even if the task has not used up its entire timeslice.
5.2.3.4. Manual Round-Robin#
The final mechanism for altering the RTEMS scheduling algorithm is called manual round-robin. Manual round-robin is invoked by using the rtems_task_wake_after
directive with a ticks
parameter of RTEMS_YIELD_PROCESSOR
. This allows a task to give up the processor and be immediately returned to the ready chain at the end of its priority group. If no other tasks of the same priority are ready to run, then the task does not lose control of the processor.
5.2.4. Dispatching Tasks#
The dispatcher is the RTEMS component responsible for allocating the processor to a ready task. In order to allocate the processor to one task, it must be deallocated or retrieved from the task currently using it. This involves a concept called a context switch. To perform a context switch, the dispatcher saves the context of the current task and restores the context of the task which has been allocated to the processor. Saving and restoring a task’s context is the storing/loading of all the essential information about a task to enable it to continue execution without any effects of the interruption. For example, the contents of a task’s register set must be the same when it is given the processor as they were when it was taken away. All of the information that must be saved or restored for a context switch is located either in the TCB or on the task’s stacks.
Tasks that utilize a numeric coprocessor and are created with the RTEMS_FLOATING_POINT
attribute require additional operations during a context switch. These additional operations are necessary to save and restore the floating point context of RTEMS_FLOATING_POINT
tasks. To avoid unnecessary save and restore operations, the state of the numeric coprocessor is only saved when a RTEMS_FLOATING_POINT
task is dispatched and that task was not the last task to utilize the coprocessor.
5.2.5. Task State Transitions#
Tasks in an RTEMS system must always be in one of the five allowable task states. These states are: executing, ready, blocked, dormant, and non-existent.
A task occupies the non-existent state before a rtems_task_create
has been issued on its behalf. A task enters the non-existent state from any other state in the system when it is deleted with the rtems_task_delete
directive. While a task occupies this state it does not have a TCB or a task ID assigned to it; therefore, no other tasks in the system may reference this task.
When a task is created via the rtems_task_create
directive, it enters the dormant state. This state is not entered through any other means. Although the task exists in the system, it cannot actively compete for system resources. It will remain in the dormant state until it is started via the rtems_task_start
directive, at which time it enters the ready state. The task is now permitted to be scheduled for the processor and to compete for other system resources.
A task occupies the blocked state whenever it is unable to be scheduled to run. A running task may block itself or be blocked by other tasks in the system. The running task blocks itself through voluntary operations that cause the task to wait. The only way a task can block a task other than itself is with the rtems_task_suspend
directive. A task enters the blocked state due to any of the following conditions:
A task issues a
rtems_task_suspend
directive which blocks either itself or another task in the system.The running task issues a
rtems_barrier_wait
directive.The running task issues a
rtems_message_queue_receive
directive with the wait option, and the message queue is empty.The running task issues a
rtems_event_receive
directive with the wait option, and the currently pending events do not satisfy the request.The running task issues a
rtems_semaphore_obtain
directive with the wait option and the requested semaphore is unavailable.The running task issues a
rtems_task_wake_after
directive which blocks the task for the given count of ticks. If the count of ticks specified is zero, the task yields the processor and remains in the ready state.The running task issues a
rtems_task_wake_when
directive which blocks the task until the requested date and time arrives.The running task issues a
rtems_rate_monotonic_period
directive and must wait for the specified rate monotonic period to conclude.The running task issues a
rtems_region_get_segment
directive with the wait option and there is not an available segment large enough to satisfy the task’s request.
A blocked task may also be suspended. Therefore, both the suspension and the blocking condition must be removed before the task becomes ready to run again.
A task occupies the ready state when it is able to be scheduled to run, but currently does not have control of the processor. Tasks of the same or higher priority will yield the processor by either becoming blocked, completing their timeslice, or being deleted. All tasks with the same priority will execute in FIFO order. A task enters the ready state due to any of the following conditions:
A running task issues a
rtems_task_resume
directive for a task that is suspended and the task is not blocked waiting on any resource.A running task issues a
rtems_message_queue_send
,rtems_message_queue_broadcast
, or artems_message_queue_urgent
directive which posts a message to the queue on which the blocked task is waiting.A running task issues an
rtems_event_send
directive which sends an event condition to a task that is blocked waiting on that event condition.A running task issues a
rtems_semaphore_release
directive which releases the semaphore on which the blocked task is waiting.The requested count of ticks has elapsed for a task which was blocked by a call to the
rtems_task_wake_after
directive.A timeout period expires for a task which blocked by a call to the
rtems_task_wake_when
directive.A running task issues a
rtems_region_return_segment
directive which releases a segment to the region on which the blocked task is waiting and a resulting segment is large enough to satisfy the task’s request.A rate monotonic period expires for a task which blocked by a call to the
rtems_rate_monotonic_period
directive.A timeout interval expires for a task which was blocked waiting on a message, event, semaphore, or segment with a timeout specified.
A running task issues a directive which deletes a message queue, a semaphore, or a region on which the blocked task is waiting.
A running task issues a
rtems_task_restart
directive for the blocked task.The running task, with its preemption mode enabled, may be made ready by issuing any of the directives that may unblock a task with a higher priority. This directive may be issued from the running task itself or from an ISR. A ready task occupies the executing state when it has control of the CPU. A task enters the executing state due to any of the following conditions:
The task is the highest priority ready task in the system.
The running task blocks and the task is next in the scheduling queue. The task may be of equal priority as in round-robin scheduling or the task may possess the highest priority of the remaining ready tasks.
The running task may reenable its preemption mode and a task exists in the ready queue that has a higher priority than the running task.
The running task lowers its own priority and another task is of higher priority as a result.
The running task raises the priority of a task above its own and the running task is in preemption mode.
5.3. Uniprocessor Schedulers#
All uniprocessor schedulers included in RTEMS are priority based. The processor is allocated to the highest priority task allowed to run.
5.3.1. Deterministic Priority Scheduler#
This is the scheduler implementation which has always been in RTEMS. After the 4.10 release series, it was factored into a pluggable scheduler selection. It schedules tasks using a priority based algorithm which takes into account preemption. It is implemented using an array of FIFOs with a FIFO per priority. It maintains a bitmap which is used to track which priorities have ready tasks.
This algorithm is deterministic (e.g., predictable and fixed) in execution time. This comes at the cost of using slightly over three (3) kilobytes of RAM on a system configured to support 256 priority levels.
This scheduler is only aware of a single core.
5.3.2. Simple Priority Scheduler#
This scheduler implementation has the same behaviour as the Deterministic Priority Scheduler but uses only one linked list to manage all ready tasks. When a task is readied, a linear search of that linked list is performed to determine where to insert the newly readied task.
This algorithm uses much less RAM than the Deterministic Priority Scheduler but is O(n) where n is the number of ready tasks. In a small system with a small number of tasks, this will not be a performance issue. Reducing RAM consumption is often critical in small systems that are incapable of supporting a large number of tasks.
This scheduler is only aware of a single core.
5.3.3. Earliest Deadline First Scheduler#
This is an alternative scheduler in RTEMS for single-core applications. The primary EDF advantage is high total CPU utilization (theoretically up to 100%). It assumes that tasks have priorities equal to deadlines.
This EDF is initially preemptive, however, individual tasks may be declared not-preemptive. Deadlines are declared using only Rate Monotonic manager whose goal is to handle periodic behavior. Period is always equal to the deadline. All ready tasks reside in a single ready queue implemented using a red-black tree.
This implementation of EDF schedules two different types of task priority types while each task may switch between the two types within its execution. If a task does have a deadline declared using the Rate Monotonic manager, the task is deadline-driven and its priority is equal to deadline. On the contrary, if a task does not have any deadline or the deadline is cancelled using the Rate Monotonic manager, the task is considered a background task with priority equal to that assigned upon initialization in the same manner as for priority scheduler. Each background task is of lower importance than each deadline-driven one and is scheduled when no deadline-driven task and no higher priority background task is ready to run.
Every deadline-driven scheduling algorithm requires means for tasks to claim a deadline. The Rate Monotonic Manager is responsible for handling periodic execution. In RTEMS periods are equal to deadlines, thus if a task announces a period, it has to be finished until the end of this period. The call of rtems_rate_monotonic_period
passes the scheduler the length of an oncoming deadline. Moreover, the rtems_rate_monotonic_cancel
and rtems_rate_monotonic_delete
calls clear the deadlines assigned to the task.
5.3.4. Constant Bandwidth Server Scheduling (CBS)#
This is an alternative scheduler in RTEMS for single-core applications. The CBS is a budget aware extension of EDF scheduler. The main goal of this scheduler is to ensure temporal isolation of tasks meaning that a task’s execution in terms of meeting deadlines must not be influenced by other tasks as if they were run on multiple independent processors.
Each task can be assigned a server (current implementation supports only one task per server). The server is characterized by period (deadline) and computation time (budget). The ratio budget/period yields bandwidth, which is the fraction of CPU to be reserved by the scheduler for each subsequent period.
The CBS is equipped with a set of rules applied to tasks attached to servers ensuring that deadline miss because of another task cannot occur. In case a task breaks one of the rules, its priority is pulled to background until the end of its period and then restored again. The rules are:
Task cannot exceed its registered budget,
Task cannot be unblocked when a ratio between remaining budget and remaining deadline is higher than declared bandwidth.
The CBS provides an extensive API. Unlike EDF, the rtems_rate_monotonic_period
does not declare a deadline because it is carried out using CBS API. This call only announces next period.
5.4. SMP Schedulers#
All SMP schedulers included in RTEMS are priority based. The processors managed by a scheduler instance are allocated to the highest priority tasks allowed to run.
5.4.1. Earliest Deadline First SMP Scheduler#
This is a job-level fixed-priority scheduler using the Earliest Deadline First (EDF) method. By convention, the maximum priority level is \(min(INT\_MAX, 2^{62} - 1)\) for background tasks. Tasks without an active deadline are background tasks. In case deadlines are not used, then the EDF scheduler behaves exactly like a fixed-priority scheduler. The tasks with an active deadline have a higher priority than the background tasks. This scheduler supports task processor affinities of one-to-one and one-to-all, e.g., a task can execute on exactly one processor or all processors managed by the scheduler instance. The processor affinity set of a task must contain all online processors to select the one-to-all affinity. This is to avoid pathological cases if processors are added/removed to/from the scheduler instance at run-time. In case the processor affinity set contains not all online processors, then a one-to-one affinity will be used selecting the processor with the largest index within the set of processors currently owned by the scheduler instance. This scheduler algorithm supports thread pinning. The ready queues use a red-black tree with the task priority as the key.
This scheduler algorithm is the default scheduler in SMP configurations if more than one processor is configured (CONFIGURE_MAXIMUM_PROCESSORS).
5.4.2. Deterministic Priority SMP Scheduler#
A fixed-priority scheduler which uses a table of chains with one chain per priority level for the ready tasks. The maximum priority level is configurable. By default, the maximum priority level is 255 (256 priority levels), see CONFIGURE_MAXIMUM_PRIORITY.
5.4.3. Simple Priority SMP Scheduler#
A fixed-priority scheduler which uses a sorted chain for the ready tasks. By convention, the maximum priority level is 255. The implementation limit is actually \(2^{63} - 1\).
5.4.4. Arbitrary Processor Affinity Priority SMP Scheduler#
A fixed-priority scheduler which uses a table of chains with one chain per priority level for the ready tasks. The maximum priority level is configurable. By default, the maximum priority level is 255 (256 priority levels), see CONFIGURE_MAXIMUM_PRIORITY. This scheduler supports arbitrary task processor affinities. The worst-case run-time complexity of some scheduler operations exceeds \(O(n)\) while \(n\) is the count of ready tasks.
5.5. Directives#
This section details the directives of the Scheduler Manager. A subsection is dedicated to each of this manager’s directives and lists the calling sequence, parameters, description, return values, and notes of the directive.
5.5.1. rtems_scheduler_ident()#
Identifies a scheduler by the object name.
CALLING SEQUENCE:
rtems_status_code rtems_scheduler_ident( rtems_name name, rtems_id *id );
PARAMETERS:
name
This parameter is the scheduler name to look up.
id
This parameter is the pointer to an rtems_id object. When the directive call is successful, the identifier of the scheduler will be stored in this object.
DESCRIPTION:
This directive obtains a scheduler identifier associated with the scheduler name specified in name
.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_NAME
There was no scheduler associated with the name.
RTEMS_INVALID_ADDRESS
The
id
parameter was NULL.
NOTES:
The scheduler name is determined by the scheduler configuration.
The scheduler identifier is used with other scheduler related directives to access the scheduler.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
5.5.2. rtems_scheduler_ident_by_processor()#
Identifies a scheduler by the processor index.
CALLING SEQUENCE:
rtems_status_code rtems_scheduler_ident_by_processor(
uint32_t cpu_index,
rtems_id *id
);
PARAMETERS:
cpu_index
This parameter is the processor index to identify the scheduler.
id
This parameter is the pointer to an rtems_id object. When the directive call is successful, the identifier of the scheduler will be stored in this object.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
id
parameter was NULL.RTEMS_INVALID_NAME
The processor index was invalid.
RTEMS_INCORRECT_STATE
The processor index was valid, however, the corresponding processor was not owned by a scheduler.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
5.5.3. rtems_scheduler_ident_by_processor_set()#
Identifies a scheduler by the processor set.
CALLING SEQUENCE:
rtems_status_code rtems_scheduler_ident_by_processor_set(
size_t cpusetsize,
const cpu_set_t *cpuset,
rtems_id *id
);
PARAMETERS:
cpusetsize
This parameter is the size of the processor set referenced by
cpuset
in bytes. The size shall be positive.cpuset
This parameter is the pointer to a
cpu_set_t
. The referenced processor set will be used to identify the scheduler.id
This parameter is the pointer to an rtems_id object. When the directive call is successful, the identifier of the scheduler will be stored in this object.
DESCRIPTION:
The scheduler is selected according to the highest numbered online processor in the specified processor set.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
id
parameter was NULL.RTEMS_INVALID_ADDRESS
The
cpuset
parameter was NULL.RTEMS_INVALID_SIZE
The processor set size was invalid.
RTEMS_INVALID_NAME
The processor set contained no online processor.
RTEMS_INCORRECT_STATE
The processor set was valid, however, the highest numbered online processor in the processor set was not owned by a scheduler.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
5.5.4. rtems_scheduler_get_maximum_priority()#
Gets the maximum task priority of the scheduler.
CALLING SEQUENCE:
rtems_status_code rtems_scheduler_get_maximum_priority(
rtems_id scheduler_id,
rtems_task_priority *priority
);
PARAMETERS:
scheduler_id
This parameter is the scheduler identifier.
priority
This parameter is the pointer to an rtems_task_priority object. When the directive the maximum priority of the scheduler will be stored in this object.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no scheduler associated with the identifier specified by
scheduler_id
.RTEMS_INVALID_ADDRESS
The
priority
parameter was NULL.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
5.5.5. rtems_scheduler_map_priority_to_posix()#
Maps a Classic API task priority to the corresponding POSIX thread priority.
CALLING SEQUENCE:
rtems_status_code rtems_scheduler_map_priority_to_posix(
rtems_id scheduler_id,
rtems_task_priority priority,
int *posix_priority
);
PARAMETERS:
scheduler_id
This parameter is the scheduler identifier.
priority
This parameter is the Classic API task priority to map.
posix_priority
This parameter is the pointer to an
int
object. When the directive call is successful, the POSIX thread priority value corresponding to the specified Classic API task priority value will be stored in this object.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
posix_priority
parameter was NULL.RTEMS_INVALID_ID
There was no scheduler associated with the identifier specified by
scheduler_id
.RTEMS_INVALID_PRIORITY
The Classic API task priority was invalid.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
5.5.6. rtems_scheduler_map_priority_from_posix()#
Maps a POSIX thread priority to the corresponding Classic API task priority.
CALLING SEQUENCE:
rtems_status_code rtems_scheduler_map_priority_from_posix(
rtems_id scheduler_id,
int posix_priority,
rtems_task_priority *priority
);
PARAMETERS:
scheduler_id
This parameter is the scheduler identifier.
posix_priority
This parameter is the POSIX thread priority to map.
priority
This parameter is the pointer to an rtems_task_priority object. When the directive call is successful, the Classic API task priority value corresponding to the specified POSIX thread priority value will be stored in this object.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
priority
parameter was NULL.RTEMS_INVALID_ID
There was no scheduler associated with the identifier specified by
scheduler_id
.RTEMS_INVALID_PRIORITY
The POSIX thread priority was invalid.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
5.5.7. rtems_scheduler_get_processor()#
Returns the index of the current processor.
CALLING SEQUENCE:
uint32_t rtems_scheduler_get_processor( void );
DESCRIPTION:
Where the system was built with SMP support disabled, this directive evaluates to a compile time constant of zero.
Where the system was built with SMP support enabled, this directive returns the index of the current processor. The set of processor indices is the range of integers starting with zero up to rtems_scheduler_get_processor_maximum() minus one.
RETURN VALUES:
Returns the index of the current processor.
NOTES:
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.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
5.5.8. rtems_scheduler_get_processor_maximum()#
Returns the processor maximum supported by the system.
CALLING SEQUENCE:
uint32_t rtems_scheduler_get_processor_maximum( void );
DESCRIPTION:
Where the system was built with SMP support disabled, this directive evaluates to a compile time constant of one.
Where the system was built with SMP support enabled, this directive returns the minimum of the processors (physically or virtually) available at the target and the configured processor maximum (see CONFIGURE_MAXIMUM_PROCESSORS). Not all processors in the range from processor index zero to the last processor index (which is the processor maximum minus one) may be configured to be used by a scheduler or may be online (online processors have a scheduler assigned).
RETURN VALUES:
Returns the processor maximum supported by the system.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
5.5.9. rtems_scheduler_get_processor_set()#
Gets the set of processors owned by the scheduler.
CALLING SEQUENCE:
rtems_status_code rtems_scheduler_get_processor_set(
rtems_id scheduler_id,
size_t cpusetsize,
cpu_set_t *cpuset
);
PARAMETERS:
scheduler_id
This parameter is the scheduler identifier.
cpusetsize
This parameter is the size of the processor set referenced by
cpuset
in bytes.cpuset
This parameter is the pointer to a
cpu_set_t
object. When the directive call is successful, the processor set of the scheduler will be stored in this object. A set bit in the processor set means that the corresponding processor is owned by the scheduler, otherwise the bit is cleared.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
cpuset
parameter was NULL.RTEMS_INVALID_ID
There was no scheduler associated with the identifier specified by
scheduler_id
.RTEMS_INVALID_SIZE
The provided processor set was too small for the set of processors owned by the scheduler.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
5.5.10. rtems_scheduler_add_processor()#
Adds the processor to the set of processors owned by the scheduler.
CALLING SEQUENCE:
rtems_status_code rtems_scheduler_add_processor(
rtems_id scheduler_id,
uint32_t cpu_index
);
PARAMETERS:
scheduler_id
This parameter is the scheduler identifier.
cpu_index
This parameter is the index of the processor to add.
DESCRIPTION:
This directive adds the processor specified by the cpu_index
to the scheduler specified by scheduler_id
.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no scheduler associated with the identifier specified by
scheduler_id
.RTEMS_NOT_CONFIGURED
The processor was not configured to be used by the application.
RTEMS_INCORRECT_STATE
The processor was configured to be used by the application, however, it was not online.
RTEMS_RESOURCE_IN_USE
The processor was already assigned to a scheduler.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
5.5.11. rtems_scheduler_remove_processor()#
Removes the processor from the set of processors owned by the scheduler.
CALLING SEQUENCE:
rtems_status_code rtems_scheduler_remove_processor(
rtems_id scheduler_id,
uint32_t cpu_index
);
PARAMETERS:
scheduler_id
This parameter is the scheduler identifier.
cpu_index
This parameter is the index of the processor to remove.
DESCRIPTION:
This directive removes the processor specified by the cpu_index
from the scheduler specified by scheduler_id
.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no scheduler associated with the identifier specified by
scheduler_id
.RTEMS_INVALID_NUMBER
The processor was not owned by the scheduler.
RTEMS_RESOURCE_IN_USE
The processor was required by at least one non-idle task that used the scheduler as its home scheduler.
RTEMS_RESOURCE_IN_USE
The processor was the last processor owned by the scheduler and there was at least one task that used the scheduler as a helping scheduler.
NOTES:
Removing a processor from a scheduler is a complex operation that involves all tasks of the system.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
6. Initialization Manager#
6.1. Introduction#
The Initialization Manager is responsible for initializing the system.
The system initialization includes the initialization of the Board Support Package, RTEMS, device drivers, the root filesystem, and the application. The Fatal Error Manager is responsible for the system shutdown. The directives provided by the Initialization Manager are:
rtems_initialize_executive() - Initializes the system and starts multitasking.
6.2. Background#
6.2.1. Initialization Tasks#
Initialization task(s) are the mechanism by which RTEMS transfers initial control to the user’s application. Initialization tasks differ from other application tasks in that they are defined in the User Initialization Tasks Table and automatically created and started by RTEMS as part of its initialization sequence. Since the initialization tasks are scheduled using the same algorithm as all other RTEMS tasks, they must be configured at a priority and mode which will ensure that they will complete execution before other application tasks execute. Although there is no upper limit on the number of initialization tasks, an application is required to define at least one.
A typical initialization task will create and start the static set of application tasks. It may also create any other objects used by the application. Initialization tasks which only perform initialization should delete themselves upon completion to free resources for other tasks. Initialization tasks may transform themselves into a “normal” application task. This transformation typically involves changing priority and execution mode. RTEMS does not automatically delete the initialization tasks.
6.2.2. The Idle Task#
The Idle Task is the lowest priority task in a system and executes only when no other task is ready to execute. The default implementation of this task consists of an infinite loop. RTEMS allows the Idle Task body to be replaced by a CPU specific implementation, a BSP specific implementation or an application specific implementation.
The Idle Task is preemptible and WILL be preempted when any other task is made ready to execute. This characteristic is critical to the overall behavior of any application.
6.2.3. Initialization Manager Failure#
System initialization errors are fatal. See Internal Error Codes.
6.3. Operations#
6.3.1. Initializing RTEMS#
The Initialization Manager rtems_initialize_executive()
directives is called by the boot_card()
routine which is invoked by the Board Support Package once a basic C run-time environment is set up. This consists of
a valid and accessible text section, read-only data, read-write data and zero-initialized data,
an initialization stack large enough to initialize the rest of the Board Support Package, RTEMS and the device drivers,
all registers and components mandated by Application Binary Interface, and
disabled interrupts.
The rtems_initialize_executive()
directive uses a system initialization linker set to initialize only those parts of the overall RTEMS feature set that is necessary for a particular application. Each RTEMS feature used the application may optionally register an initialization handler. The system initialization API is available via #included <rtems/sysinit.h>
.
A list of all initialization steps follows. Some steps are optional depending on the requested feature set of the application. The initialization steps are execute in the order presented here.
- RTEMS_SYSINIT_RECORD
Initialization of the event recording is the first initialization step. This allows to record the further system initialization. This step is optional and depends on the CONFIGURE_RECORD_PER_PROCESSOR_ITEMS configuration option.
- RTEMS_SYSINIT_BSP_EARLY
The Board Support Package may perform an early platform initialization in this step. This step is optional.
- RTEMS_SYSINIT_MEMORY
The Board Support Package should initialize everything so that calls to
_Memory_Get()
can be made after this step. This step is optional.- RTEMS_SYSINIT_DIRTY_MEMORY
The free memory is dirtied in this step. This step is optional and depends on the
BSP_DIRTY_MEMORY
BSP option.- RTEMS_SYSINIT_ISR_STACK
The stack checker initializes the ISR stacks in this step. This step is optional and depends on the CONFIGURE_STACK_CHECKER_ENABLED configuration option.
- RTEMS_SYSINIT_PER_CPU_DATA
The per-CPU data is initialized in this step. This step is mandatory.
- RTEMS_SYSINIT_SBRK
The Board Support Package may initialize the
sbrk()
support in this step. This step is optional.- RTEMS_SYSINIT_WORKSPACE
The workspace is initialized in this step. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_MALLOC
The C program heap is initialized in this step. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_BSP_START
The Board Support Package should perform a general platform initialization in this step (e.g. interrupt controller initialization). This step is mandatory.
- RTEMS_SYSINIT_CPU_COUNTER
Initialization of the CPU counter hardware and support functions. The CPU counter is initialized early to allow its use in the tracing and profiling of the system initialization sequence. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_INITIAL_EXTENSIONS
Registers the initial extensions. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_MP_EARLY
In MPCI configurations, an early MPCI initialization is performed in this step. This step is mandatory in MPCI configurations.
- RTEMS_SYSINIT_DATA_STRUCTURES
This directive is called when the Board Support Package has completed its basic initialization and allows RTEMS to initialize the application environment based upon the information in the Configuration Table, User Initialization Tasks Table, Device Driver Table, User Extension Table, Multiprocessor Configuration Table, and the Multiprocessor Communications Interface (MPCI) Table.
- RTEMS_SYSINIT_MP
In MPCI configurations, a general MPCI initialization is performed in this step. This step is mandatory in MPCI configurations.
- RTEMS_SYSINIT_USER_EXTENSIONS
Initialization of the User Extensions object class. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_CLASSIC_TASKS
Initialization of the Classic Tasks object class. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_CLASSIC_TASKS_MP
In MPCI configurations, the Classic Tasks MPCI support is initialized in this step. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_CLASSIC_TIMER
Initialization of the Classic Timer object class. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_CLASSIC_SIGNAL
Initialization of the Classic Signal support. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_CLASSIC_SIGNAL_MP
In MPCI configurations, the Classic Signal MPCI support is initialized in this step. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_CLASSIC_EVENT
Initialization of the Classic Event support. This step is optional and depends on the application configuration. This step is only used on MPCI configurations.
- RTEMS_SYSINIT_CLASSIC_EVENT_MP
In MPCI configurations, the Classic Event MPCI support is initialized in this step. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_CLASSIC_MESSAGE_QUEUE
Initialization of the Classic Message Queue object class. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_CLASSIC_SEMAPHORE
Initialization of the Classic Semaphore object class. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_CLASSIC_SEMAPHORE_MP
In MPCI configurations, the Classic Semaphore MPCI support is initialized in this step. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_CLASSIC_PARTITION
Initialization of the Classic Partition object class. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_CLASSIC_PARTITION_MP
In MPCI configurations, the Classic Partition MPCI support is initialized in this step. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_CLASSIC_REGION
Initialization of the Classic Region object class. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_CLASSIC_DUAL_PORTED_MEMORY
Initialization of the Classic Dual-Ported Memory object class. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_CLASSIC_RATE_MONOTONIC
Initialization of the Classic Rate-Monotonic object class. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_CLASSIC_BARRIER
Initialization of the Classic Barrier object class. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_POSIX_SIGNALS
Initialization of the POSIX Signals support. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_POSIX_THREADS
Initialization of the POSIX Threads object class. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_POSIX_MESSAGE_QUEUE
Initialization of the POSIX Message Queue object class. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_POSIX_SEMAPHORE
Initialization of the POSIX Semaphore object class. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_POSIX_TIMER
Initialization of the POSIX Timer object class. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_POSIX_SHM
Initialization of the POSIX Shared Memory object class. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_POSIX_KEYS
Initialization of the POSIX Keys object class. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_POSIX_CLEANUP
Initialization of the POSIX Cleanup support. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_IDLE_THREADS
Initialization of idle threads. This step is mandatory.
- RTEMS_SYSINIT_LIBIO
Initialization of IO library. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_ROOT_FILESYSTEM
Initialization of the root filesystem. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_DRVMGR
Driver manager initialization. This step is optional and depends on the application configuration. Only available if the driver manager is enabled.
- RTEMS_SYSINIT_MP_SERVER
In MPCI configurations, the MPCI server is initialized in this step. This step is mandatory in MPCI configurations.
- RTEMS_SYSINIT_BSP_PRE_DRIVERS
Initialization step performed right before device drivers are initialized. This step is mandatory.
- RTEMS_SYSINIT_DRVMGR_LEVEL_1
Driver manager level 1 initialization. This step is optional and depends on the application configuration. Only available if the driver manager is enabled.
- RTEMS_SYSINIT_DEVICE_DRIVERS
This step initializes all statically configured device drivers and performs all RTEMS initialization which requires device drivers to be initialized. This step is mandatory. In a multiprocessor configuration, this service will initialize the Multiprocessor Communications Interface (MPCI) and synchronize with the other nodes in the system.
- RTEMS_SYSINIT_DRVMGR_LEVEL_2
Driver manager level 2 initialization. This step is optional and depends on the application configuration. Only available if the driver manager is enabled.
- RTEMS_SYSINIT_DRVMGR_LEVEL_3
Driver manager level 3 initialization. This step is optional and depends on the application configuration. Only available if the driver manager is enabled.
- RTEMS_SYSINIT_DRVMGR_LEVEL_4
Driver manager level 4 initialization. This step is optional and depends on the application configuration. Only available if the driver manager is enabled.
- RTEMS_SYSINIT_MP_FINALIZE
Finalize MPCI initialization. This step is mandatory on MPCI configurations.
- RTEMS_SYSINIT_CLASSIC_USER_TASKS
Creates and starts the Classic initialization tasks. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_POSIX_USER_THREADS
Creates POSIX initialization threads. This step is optional and depends on the application configuration.
- RTEMS_SYSINIT_STD_FILE_DESCRIPTORS
Open the standard input, output and error file descriptors. This step is optional and depends on the application configuration.
The final action of the rtems_initialize_executive()
directive is to start multitasking and switch to the highest priority ready thread. RTEMS does not return to the initialization context and the initialization stack may be re-used for interrupt processing.
Many of RTEMS actions during initialization are based upon the contents of the Configuration Table. For more information regarding the format and contents of this table, please refer to the chapter Configuring a System.
6.3.2. Global Construction#
The global construction is carried out by the Classic API initialization task. If no Classic API initialization task exists, then it is carried out by the POSIX API initialization thread. If no initialization task or thread exists, then no global construction is performed. The Classic API task or POSIX API thread which carries out global construction is called the main thread. For configuration options related to initialization tasks, see CONFIGURE_RTEMS_INIT_TASKS_TABLE, CONFIGURE_POSIX_INIT_THREAD_TABLE, and CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION.
Global construction runs before the task entry of the main thread. The configuration of the main thread must take the global construction into account. In particular, the main thread stack size, priority, attributes and initial modes must be set accordingly. Thread-local objects and POSIX key values created during global construction are accessible by the main thread. If other initialization tasks are configured, and one of them has a higher priority than the main thread and the main thread is preemptible, this task executes before the global construction. In case the main thread blocks during global construction, then other tasks may run. In SMP configurations, other initialization tasks may run in parallel with global construction. Tasks created during global construction may preempt the main thread or run in parallel in SMP configurations. All RTEMS services allowed in task context are allowed during global construction.
Global constructors are C++ global object constructors or functions with the constructor attribute. For example, the following test program
#include <stdio.h>
#include <assert.h>
class A {
public:
A()
{
puts( "A:A()" );
}
};
static A a;
static thread_local int i;
static thread_local int j;
static __attribute__(( __constructor__ )) void b( void )
{
i = 1;
puts( "b()" );
}
static __attribute__(( __constructor__( 1000 ) )) void c( void )
{
puts( "c()" );
}
int main( void )
{
assert( i == 1 );
assert( j == 0 );
return 0;
}
should output:
c()
b()
A:A()
6.4. Directives#
This section details the directives of the Initialization Manager. A subsection is dedicated to each of this manager’s directives and lists the calling sequence, parameters, description, return values, and notes of the directive.
6.4.1. rtems_initialize_executive()#
Initializes the system and starts multitasking.
CALLING SEQUENCE:
void rtems_initialize_executive( void );
DESCRIPTION:
Iterates through the system initialization linker set and invokes the registered handlers. The final step is to start multitasking.
NOTES:
Errors in the initialization sequence are usually fatal and lead to a system termination.
CONSTRAINTS:
The following constraints apply to this directive:
The directive should be called by
boot_card()
only.The directive will not return to the caller.
7. Task Manager#
7.1. Introduction#
The Task Manager provides a comprehensive set of directives to create, delete, and administer tasks. The directives provided by the Task Manager are:
rtems_task_create() - Creates a task.
rtems_task_construct() - Constructs a task from the specified task configuration.
rtems_task_ident() - Identifies a task by the object name.
rtems_task_self() - Gets the task identifier of the calling task.
rtems_task_start() - Starts the task.
rtems_task_restart() - Restarts the task.
rtems_task_delete() - Deletes the task.
rtems_task_exit() - Deletes the calling task.
rtems_task_suspend() - Suspends the task.
rtems_task_resume() - Resumes the task.
rtems_task_is_suspended() - Checks if the task is suspended.
rtems_task_set_priority() - Sets the real priority or gets the current priority of the task.
rtems_task_get_priority() - Gets the current priority of the task with respect to the scheduler.
rtems_task_mode() - Gets and optionally sets the mode of the calling task.
rtems_task_wake_after() - Wakes up after a count of clock ticks have occurred or yields the processor.
rtems_task_wake_when() - Wakes up when specified.
rtems_task_get_scheduler() - Gets the home scheduler of the task.
rtems_task_set_scheduler() - Sets the home scheduler for the task.
rtems_task_get_affinity() - Gets the processor affinity of the task.
rtems_task_set_affinity() - Sets the processor affinity of the task.
rtems_task_iterate() - Iterates over all tasks and invokes the visitor routine for each task.
RTEMS_TASK_STORAGE_SIZE() - Gets the recommended task storage area size for the size and task attributes.
7.2. Background#
7.2.1. 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).
7.2.2. 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.
7.2.3. Task Memory#
The system uses two separate memory areas to manage a task. One memory area is the Task Control Block. The other memory area is allocated from the stack space or provided by the user and contains
the task stack,
the thread-local storage (TLS), and
an optional architecture-specific floating-point context.
The size of the thread-local storage is determined at link time. A user-provided task stack must take the size of the thread-local storage into account.
On architectures with a dedicated floating-point context, the application configuration assumes that every task is a floating-point task, but whether or not a task is actually floating-point is determined at runtime during task creation (see Floating Point Considerations). In highly memory constrained systems this potential overestimate of the task stack space can be mitigated through the CONFIGURE_MINIMUM_TASK_STACK_SIZE configuration option and aligned task stack sizes for the tasks. A user-provided task stack must take the potential floating-point context into account.
7.2.4. Task Name#
By default, the task name is defined by the task object name given to rtems_task_create(). The task name can be obtained with the pthread_getname_np() function. Optionally, a new task name may be set with the pthread_setname_np() function. The maximum size of a task name is defined by the application configuration option CONFIGURE_MAXIMUM_THREAD_NAME_SIZE.
7.2.5. 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.
7.2.6. Task Priority#
A task’s priority determines its importance in relation to the other tasks executing on the processor set owned by a scheduler. Normally, RTEMS supports 256 levels of priority ranging from 0 to 255. The priority level 0 represents a special priority reserved for the operating system. The data type rtems_task_priority
is used to store task priorities. The maximum priority level depends on the configured scheduler, see CONFIGURE_MAXIMUM_PRIORITY, Clustered Scheduler Configuration, and Scheduling Concepts.
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.
7.2.7. 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 (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 (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 (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 (RTEMS_NO_TIMESLICE
), then the task will be allowed to execute until a task of higher priority is made ready. If 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 (RTEMS_ASR
), then signals sent to the task will be processed the next time the task executes. If signal processing is disabled (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. RTEMS_INTERRUPT_LEVEL(n)
specifies that the task will execute at interrupt level n.
| enable preemption (default) |
| disable preemption |
| disable timeslicing (default) |
| enable timeslicing |
| enable ASR processing (default) |
| disable ASR processing |
| enable all interrupts (default) |
| execute at interrupt level n |
The set of default modes may be selected by specifying the RTEMS_DEFAULT_MODES
constant.
7.2.8. Task Life States#
Independent of the task state with respect to the scheduler, the task life is determined by several orthogonal states:
protected or unprotected
deferred life changes or no deferred life changes
restarting or not restarting
terminating or not terminating
detached or not detached
While the task life is protected, asynchronous task restart and termination requests are blocked. A task may still restart or terminate itself. All tasks are created with an unprotected task life. The task life protection is used by the system to prevent system resources being affected by asynchronous task restart and termination requests. The task life protection can be enabled (PTHREAD_CANCEL_DISABLE
) or disabled (PTHREAD_CANCEL_ENABLE
) for the calling task through the pthread_setcancelstate()
directive.
While deferred life changes are enabled, asynchronous task restart and termination requests are delayed until the task performs a life change itself or calls pthread_testcancel()
. Cancellation points are not implemented in RTEMS. Deferred task life changes can be enabled (PTHREAD_CANCEL_DEFERRED
) or disabled (PTHREAD_CANCEL_ASYNCHRONOUS
) for the calling task through the pthread_setcanceltype()
directive. Classic API tasks are created with deferred life changes disabled. POSIX threads are created with deferred life changes enabled.
A task is made restarting by issuing a task restart request through the rtems_task_restart() directive.
A task is made terminating by issuing a task termination request through the rtems_task_exit(), rtems_task_delete(), pthread_exit()
, and pthread_cancel()
directives.
When a detached task terminates, the termination procedure completes without the need for another task to join with the terminated task. Classic API tasks are created as not detached. The detached state of created POSIX threads is determined by the thread attributes. They are created as not detached by default. The calling task is made detached through the pthread_detach()
directive. The rtems_task_exit() directive and self deletion though rtems_task_delete() directive make the calling task detached. In contrast, the pthread_exit()
directive does not change the detached state of the calling task.
7.2.9. 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:
rtems_task user_task(
rtems_task_argument argument
);
Application tasks requiring more information may view this single argument as an index into an array of parameter blocks.
7.2.10. Floating Point Considerations#
Please consult the RTEMS CPU Architecture Supplement if this section is relevant on your architecture. On some architectures the floating-point context is contained in the normal task context and this section does not apply.
Creating a task with the RTEMS_FLOATING_POINT
attribute flag results in additional memory being allocated for the task to store the state of the numeric coprocessor during task switches. This additional memory is not allocated for RTEMS_NO_FLOATING_POINT
tasks. Saving and restoring the context of a RTEMS_FLOATING_POINT
task takes longer than that of a 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. In uniprocessor configurations, the state of the numeric coprocessor is only saved when a RTEMS_FLOATING_POINT
task is dispatched and that task was not the last task to utilize the coprocessor. In a uniprocessor system with only one RTEMS_FLOATING_POINT
task, the state of the numeric coprocessor will never be saved or restored.
Although the overhead imposed by RTEMS_FLOATING_POINT
tasks is minimal, some applications may wish to completely avoid the overhead associated with 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 RTEMS_NO_FLOATING_POINT
task can utilize the numeric coprocessor without incurring the overhead of a 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 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 RTEMS_NO_FLOATING_POINT
tasks. Some architectures with a dedicated floating-point context raise a processor exception if a task with RTEMS_NO_FLOATING_POINT
issues a floating-point instruction, so this approach may not work at all.
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 RTEMS_NO_FLOATING_POINT
whether created as RTEMS_FLOATING_POINT
or 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 RTEMS_FLOATING_POINT
attribute. The consequence of a RTEMS_NO_FLOATING_POINT
task attempting to access the floating point unit is CPU dependent but will generally result in an exception condition.
7.2.11. 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:
| does not use coprocessor (default) |
| uses numeric coprocessor |
| local task (default) |
| 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 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 RTEMS_FLOATING_POINT
or RTEMS_LOCAL | RTEMS_FLOATING_POINT
. The attribute_set parameter can be set to RTEMS_FLOATING_POINT
because 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 RTEMS_GLOBAL | RTEMS_FLOATING_POINT
.
7.2.12. 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:
| is masked by |
| is masked by |
| is masked by |
| is masked by |
| is masked by |
| is masked by |
| is masked by |
| is masked by |
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 RTEMS_DEFAULT_MODES
and the mask 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 RTEMS_INTERRUPT_LEVEL(3) | RTEMS_NO_PREEMPT
to indicate the desired preemption mode and interrupt level, while the mask parameter should be set to RTEMS_INTERRUPT_MASK | RTEMS_NO_PREEMPT_MASK
to indicate that the calling task’s interrupt level and preemption mode are being altered.
7.3. Operations#
7.3.1. Creating Tasks#
The rtems_task_create
directive creates a task by allocating a task control block, assigning the task a user-specified name, allocating it a stack and floating point context area, setting a user-specified initial priority, setting a user-specified initial mode, and assigning it a task ID. Newly created tasks are initially placed in the dormant state. All RTEMS tasks execute in the most privileged mode of the processor.
7.3.2. Obtaining Task IDs#
When a task is created, RTEMS generates a unique task ID and assigns it to the created task until it is deleted. The task ID may be obtained by either of two methods. First, as the result of an invocation of the rtems_task_create
directive, the task ID is stored in a user provided location. Second, the task ID may be obtained later using the rtems_task_ident
directive. The task ID is used by other directives to manipulate this task.
7.3.3. Starting and Restarting Tasks#
The rtems_task_start
directive is used to place a dormant task in the ready state. This enables the task to compete, based on its current priority, for the processor and other system resources. Any actions, such as suspension or change of priority, performed on a task prior to starting it are nullified when the task is started.
With the rtems_task_start
directive the user specifies the task’s starting address and argument. The argument is used to communicate some startup information to the task. As part of this directive, RTEMS initializes the task’s stack based upon the task’s initial execution mode and start address. The starting argument is passed to the task in accordance with the target processor’s calling convention.
The rtems_task_restart
directive restarts a task at its initial starting address with its original priority and execution mode, but with a possibly different argument. The new argument may be used to distinguish between the original invocation of the task and subsequent invocations. The task’s stack and control block are modified to reflect their original creation values. Although references to resources that have been requested are cleared, resources allocated by the task are NOT automatically returned to RTEMS. A task cannot be restarted unless it has previously been started (i.e. dormant tasks cannot be restarted). All restarted tasks are placed in the ready state.
7.3.4. Suspending and Resuming Tasks#
The rtems_task_suspend
directive is used to place either the caller or another task into a suspended state. The task remains suspended until a rtems_task_resume
directive is issued. This implies that a task may be suspended as well as blocked waiting either to acquire a resource or for the expiration of a timer.
The rtems_task_resume
directive is used to remove another task from the suspended state. If the task is not also blocked, resuming it will place it in the ready state, allowing it to once again compete for the processor and resources. If the task was blocked as well as suspended, this directive clears the suspension and leaves the task in the blocked state.
Suspending a task which is already suspended or resuming a task which is not suspended is considered an error. The rtems_task_is_suspended
can be used to determine if a task is currently suspended.
7.3.5. Delaying the Currently Executing Task#
The rtems_task_wake_after
directive creates a sleep timer which allows a task to go to sleep for a specified count of clock ticks. The task is blocked until the count of clock ticks has elapsed, at which time the task is unblocked. A task calling the rtems_task_wake_after
directive with a delay of RTEMS_YIELD_PROCESSOR
ticks will yield the processor to any other ready task of equal or greater priority and remain ready to execute.
The rtems_task_wake_when
directive creates a sleep timer which allows a task to go to sleep until a specified date and time. The calling task is blocked until the specified date and time has occurred, at which time the task is unblocked.
7.3.6. Changing Task Priority#
The rtems_task_set_priority
directive is used to obtain or change the current priority of either the calling task or another task. If the new priority requested is RTEMS_CURRENT_PRIORITY
or the task’s actual priority, then the current priority will be returned and the task’s priority will remain unchanged. If the task’s priority is altered, then the task will be scheduled according to its new priority.
The rtems_task_restart
directive resets the priority of a task to its original value.
7.3.7. Changing Task Mode#
The rtems_task_mode
directive is used to obtain or change the current execution mode of the calling task. A task’s execution mode is used to enable preemption, timeslicing, ASR processing, and to set the task’s interrupt level.
The rtems_task_restart
directive resets the mode of a task to its original value.
7.3.8. Task Deletion#
RTEMS provides the rtems_task_delete
directive to allow a task to delete itself or any other task. This directive removes all RTEMS references to the task, frees the task’s control block, removes it from resource wait queues, and deallocates its stack as well as the optional floating point context. The task’s name and ID become inactive at this time, and any subsequent references to either of them is invalid. In fact, RTEMS may reuse the task ID for another task which is created later in the application. A specialization of rtems_task_delete
is rtems_task_exit
which deletes the calling task.
Unexpired delay timers (i.e. those used by rtems_task_wake_after
and rtems_task_wake_when
) and timeout timers associated with the task are automatically deleted, however, other resources dynamically allocated by the task are NOT automatically returned to RTEMS. Therefore, before a task is deleted, all of its dynamically allocated resources should be deallocated by the user. This may be accomplished by instructing the task to delete itself rather than directly deleting the task. Other tasks may instruct a task to delete itself by sending a “delete self” message, event, or signal, or by restarting the task with special arguments which instruct the task to delete itself.
7.3.9. Setting Affinity to a Single Processor#
On some embedded applications targeting SMP systems, it may be beneficial to lock individual tasks to specific processors. In this way, one can designate a processor for I/O tasks, another for computation, etc.. The following illustrates the code sequence necessary to assign a task an affinity for processor with index processor_index
.
#include <rtems.h>
#include <assert.h>
void pin_to_processor(rtems_id task_id, int processor_index)
{
rtems_status_code sc;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(processor_index, &cpuset);
sc = rtems_task_set_affinity(task_id, sizeof(cpuset), &cpuset);
assert(sc == RTEMS_SUCCESSFUL);
}
It is important to note that the cpuset
is not validated until the rtems_task_set_affinity
call is made. At that point, it is validated against the current system configuration.
7.3.10. Transition Advice for Removed Notepads#
Task notepads and the associated directives TASK_GET_NOTE - Get task notepad entry and TASK_SET_NOTE - Set task notepad entry were removed in RTEMS 5.1. These were never thread-safe to access and subject to conflicting use of the notepad index by libraries which were designed independently.
It is recommended that applications be modified to use services which are thread safe and not subject to issues with multiple applications conflicting over the key (e.g. notepad index) selection. For most applications, POSIX Keys should be used. These are available in all RTEMS build configurations. It is also possible that thread-local storage (TLS) is an option for some use cases.
7.3.11. Transition Advice for Removed Task Variables#
Task notepads and the associated directives TASK_VARIABLE_ADD - Associate per task variable, TASK_VARIABLE_GET - Obtain value of a per task variable and TASK_VARIABLE_DELETE - Remove per task variable were removed in RTEMS 5.1. Task variables must be replaced by POSIX Keys or thread-local storage (TLS). POSIX Keys are available in all configurations and support value destructors. For the TLS support consult the RTEMS CPU Architecture Supplement.
7.4. Directives#
This section details the directives of the Task Manager. A subsection is dedicated to each of this manager’s directives and lists the calling sequence, parameters, description, return values, and notes of the directive.
7.4.1. rtems_task_create()#
Creates a task.
CALLING SEQUENCE:
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
);
PARAMETERS:
name
This parameter is the object name of the task.
initial_priority
This parameter is the initial task priority.
stack_size
This parameter is the task stack size in bytes.
initial_modes
This parameter is the initial mode set of the task.
attribute_set
This parameter is the attribute set of the task.
id
This parameter is the pointer to an rtems_id object. When the directive call is successful, the identifier of the created task will be stored in this object.
DESCRIPTION:
This directive creates a task which resides on the local node. The task has the user-defined object name specified in name
. The assigned object identifier is returned in id
. This identifier is used to access the task with other task related directives.
The initial priority of the task is specified in initial_priority
. The home scheduler of the created task is the home scheduler of the calling task at some time point during the task creation. The initial task priority specified in initial_priority
shall be valid for this scheduler.
The stack size of the task is specified in stack_size
. If the requested stack size is less than the configured minimum stack size, then RTEMS will use the configured minimum as the stack size for this task. The configured minimum stack size is defined by the CONFIGURE_MINIMUM_TASK_STACK_SIZE application configuration option. In addition to being able to specify the task stack size as a integer, there are two constants which may be specified:
The
RTEMS_MINIMUM_STACK_SIZE
constant can be specified to use the recommended minimum stack size for the target processor. This value is selected by the RTEMS maintainers conservatively to minimize the risk of blown stacks for most user applications. Using this constant when specifying the task stack size, indicates that the stack size will be at leastRTEMS_MINIMUM_STACK_SIZE
bytes in size. If the user configured minimum stack size is larger than the recommended minimum, then it will be used.The
RTEMS_CONFIGURED_MINIMUM_STACK_SIZE
constant can be specified to use the minimum stack size that was configured by the application. If not explicitly configured by the application, the default configured minimum stack size is the target processor dependent valueRTEMS_MINIMUM_STACK_SIZE
. Since this uses the configured minimum stack size value, you may get a stack size that is smaller or larger than the recommended minimum. This can be used to provide large stacks for all tasks on complex applications or small stacks on applications that are trying to conserve memory.
The initial mode set specified in initial_modes
is built through a bitwise or of the mode constants described below. Not all combinations of modes are allowed. Some modes are mutually exclusive. If mutually exclusive modes are combined, the behaviour is undefined. Default task modes can be selected by using the RTEMS_DEFAULT_MODES
constant. The task mode set defines
the preemption mode of the task:
RTEMS_PREEMPT
(default) orRTEMS_NO_PREEMPT
,the timeslicing mode of the task:
RTEMS_TIMESLICE
orRTEMS_NO_TIMESLICE
(default),the ASR processing mode of the task:
RTEMS_ASR
(default) orRTEMS_NO_ASR
,the interrupt level of the task:
RTEMS_INTERRUPT_LEVEL()
with a default ofRTEMS_INTERRUPT_LEVEL( 0 )
which is associated with enabled interrupts.
The initial preemption mode of the task is enabled or disabled.
An enabled preemption is the default and can be emphasized through the use of the
RTEMS_PREEMPT
mode constant.A disabled preemption is set by the
RTEMS_NO_PREEMPT
mode constant.
The initial timeslicing mode of the task is enabled or disabled.
A disabled timeslicing is the default and can be emphasized through the use of the
RTEMS_NO_TIMESLICE
mode constant.An enabled timeslicing is set by the
RTEMS_TIMESLICE
mode constant.
The initial ASR processing mode of the task is enabled or disabled.
An enabled ASR processing is the default and can be emphasized through the use of the
RTEMS_ASR
mode constant.A disabled ASR processing is set by the
RTEMS_NO_ASR
mode constant.
The initial interrupt level mode of the task is defined by RTEMS_INTERRUPT_LEVEL()
.
Task execution with interrupts enabled the default and can be emphasized through the use of the
RTEMS_INTERRUPT_LEVEL()
mode macro with a value of zero (0) for the parameter. An interrupt level of zero is associated with enabled interrupts on all target processors.Task execution at a non-zero interrupt level can be specified by the
RTEMS_INTERRUPT_LEVEL()
mode macro with a non-zero value for the parameter. The interrupt level portion of the task mode supports a maximum of 256 interrupt levels. These levels are mapped onto the interrupt levels actually supported by the target processor in a processor dependent fashion.
The attribute set specified in attribute_set
is built through a bitwise or of the attribute constants described below. Not all combinations of attributes are allowed. Some attributes are mutually exclusive. If mutually exclusive attributes are combined, the behaviour is undefined. Attributes not mentioned below are not evaluated by this directive and have no effect. Default attributes can be selected by using the RTEMS_DEFAULT_ATTRIBUTES
constant. The attribute set defines
the scope of the task:
RTEMS_LOCAL
(default) orRTEMS_GLOBAL
andthe floating-point unit use of the task:
RTEMS_FLOATING_POINT
orRTEMS_NO_FLOATING_POINT
(default).
The task has a local or global scope in a multiprocessing network (this attribute does not refer to SMP systems). The scope is selected by the mutually exclusive RTEMS_LOCAL
and RTEMS_GLOBAL
attributes.
A local scope is the default and can be emphasized through the use of the
RTEMS_LOCAL
attribute. A local task can be only used by the node which created it.A global scope is established if the
RTEMS_GLOBAL
attribute is set. Setting the global attribute in a single node system has no effect.the
The use of the floating-point unit is selected by the mutually exclusive RTEMS_FLOATING_POINT
and RTEMS_NO_FLOATING_POINT
attributes. On some target processors, the use of the floating-point unit can be enabled or disabled for each task. Other target processors may have no hardware floating-point unit or enable the use of the floating-point unit for all tasks. Consult the RTEMS CPU Architecture Supplement for the details.
A disabled floating-point unit is the default and can be emphasized through use of the
RTEMS_NO_FLOATING_POINT
attribute. For performance reasons, it is recommended that tasks not using the floating-point unit should specify this attribute.An enabled floating-point unit is selected by the
RTEMS_FLOATING_POINT
attribute.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_NAME
The
name
parameter was invalid.RTEMS_INVALID_ADDRESS
The
id
parameter was NULL.RTEMS_INVALID_PRIORITY
The
initial_priority
was invalid.RTEMS_TOO_MANY
There was no inactive object available to create a task. The number of tasks available to the application is configured through the CONFIGURE_MAXIMUM_TASKS application configuration option.
RTEMS_TOO_MANY
In multiprocessing configurations, there was no inactive global object available to create a global task. The number of global objects available to the application is configured through the CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS application configuration option.
RTEMS_UNSATISFIED
There was not enough memory to allocate the task storage area. The task storage area contains the task stack, the thread-local storage, and the floating point context.
RTEMS_UNSATISFIED
One of the task create extensions failed to create the task.
RTEMS_UNSATISFIED
In SMP configurations, the non-preemption mode was not supported.
RTEMS_UNSATISFIED
In SMP configurations, the interrupt level mode was not supported.
NOTES:
The task processor affinity is initialized to the set of online processors.
When created, a task is placed in the dormant state and can only be made ready to execute using the directive rtems_task_start().
Application developers should consider the stack usage of the device drivers when calculating the stack size required for tasks which utilize the driver. The task stack size shall account for an target processor dependent interrupt stack frame which may be placed on the stack of the interrupted task while servicing an interrupt. The stack checker may be used to monitor the stack usage, see CONFIGURE_STACK_CHECKER_ENABLED.
For control and maintenance of the task, RTEMS allocates a TCB from the local TCB free pool and initializes it.
The TCB for a global task is allocated on the local node. Task should not be made global unless remote tasks must interact with the task. This is to avoid the system overhead incurred by the creation of a global task. When a global task is created, the task’s name and identifier must be transmitted to every node in the system for insertion in the local copy of the global object table.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
When the directive operates on a global object, the directive sends a message to remote nodes. This may preempt the calling task.
The number of tasks available to the application is configured through the CONFIGURE_MAXIMUM_TASKS application configuration option.
Where the object class corresponding to the directive is configured to use unlimited objects, the directive may allocate memory from the RTEMS Workspace.
The number of global objects available to the application is configured through the CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS application configuration option.
7.4.2. rtems_task_construct()#
Constructs a task from the specified task configuration.
CALLING SEQUENCE:
rtems_status_code rtems_task_construct(
const rtems_task_config *config,
rtems_id *id
);
PARAMETERS:
config
This parameter is the pointer to an rtems_task_config object. It configures the task.
id
This parameter is the pointer to an rtems_id object. When the directive call is successful, the identifier of the constructed task will be stored in this object.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
config
parameter was NULL.RTEMS_INVALID_NAME
The task name was invalid.
RTEMS_INVALID_ADDRESS
The
id
parameter was NULL.RTEMS_INVALID_PRIORITY
The initial task priority was invalid.
RTEMS_INVALID_SIZE
The thread-local storage size is greater than the maximum thread-local storage size specified in the task configuration. The thread-local storage size is determined by the thread-local variables used by the application and CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE.
RTEMS_INVALID_SIZE
The task storage area was too small to provide a task stack of the configured minimum size, see CONFIGURE_MINIMUM_TASK_STACK_SIZE. The task storage area contains the task stack, the thread-local storage, and the floating-point context on architectures with a separate floating-point context.
RTEMS_TOO_MANY
There was no inactive task object available to construct a task.
RTEMS_TOO_MANY
In multiprocessing configurations, there was no inactive global object available to construct a global task.
RTEMS_UNSATISFIED
One of the task create extensions failed during the task construction.
RTEMS_UNSATISFIED
In SMP configurations, the non-preemption mode was not supported.
RTEMS_UNSATISFIED
In SMP configurations, the interrupt level mode was not supported.
NOTES:
In contrast to tasks created by rtems_task_create(), the tasks constructed by this directive use a user-provided task storage area. The task storage area contains the task stack, the thread-local storage, and the floating-point context on architectures with a separate floating-point context.
This directive is intended for applications which do not want to use the RTEMS Workspace and instead statically allocate all operating system resources. It is not recommended to use rtems_task_create() and rtems_task_construct() together in an application. It is also not recommended to use rtems_task_construct() for drivers or general purpose libraries. The reason for these recommendations is that the task configuration needs settings which can be only given with a through knowledge of the application resources.
An application based solely on static allocation can avoid any runtime memory allocators. This can simplify the application architecture as well as any analysis that may be required.
The stack space estimate done by <rtems/confdefs.h>
assumes that all tasks are created by rtems_task_create(). The estimate can be adjusted to take user-provided task storage areas into account through the CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE application configuration option.
The CONFIGURE_MAXIMUM_TASKS should include tasks constructed by rtems_task_construct().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
When the directive operates on a global object, the directive sends a message to remote nodes. This may preempt the calling task.
The number of tasks available to the application is configured through the CONFIGURE_MAXIMUM_TASKS application configuration option.
Where the object class corresponding to the directive is configured to use unlimited objects, the directive may allocate memory from the RTEMS Workspace.
The number of global objects available to the application is configured through the CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS application configuration option.
7.4.3. rtems_task_ident()#
Identifies a task by the object name.
CALLING SEQUENCE:
rtems_status_code rtems_task_ident(
rtems_name name,
uint32_t node,
rtems_id *id
);
PARAMETERS:
name
This parameter is the object name to look up.
node
This parameter is the node or node set to search for a matching object.
id
This parameter is the pointer to an rtems_id object. When the directive call is successful, the object identifier of an object with the specified name will be stored in this object.
DESCRIPTION:
This directive obtains a task identifier associated with the task name specified in name
.
A task may obtain its own identifier by specifying RTEMS_WHO_AM_I
for the name.
The node to search is specified in node
. It shall be
a valid node number,
the constant
RTEMS_SEARCH_ALL_NODES
to search in all nodes,the constant
RTEMS_SEARCH_LOCAL_NODE
to search in the local node only, orthe constant
RTEMS_SEARCH_OTHER_NODES
to search in all nodes except the local node.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
id
parameter was NULL.RTEMS_INVALID_NAME
There was no object with the specified name on the specified nodes.
RTEMS_INVALID_NODE
In multiprocessing configurations, the specified node was invalid.
NOTES:
If the task name is not unique, then the task identifier will match the first task with that name in the search order. However, this task identifier is not guaranteed to correspond to the desired task.
The objects are searched from lowest to the highest index. If node
is RTEMS_SEARCH_ALL_NODES
, all nodes are searched with the local node being searched first. All other nodes are searched from lowest to the highest node number.
If node is a valid node number which does not represent the local node, then only the tasks exported by the designated node are searched.
This directive does not generate activity on remote nodes. It accesses only the local copy of the global object table.
The task identifier is used with other task related directives to access the task.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
7.4.4. rtems_task_self()#
Gets the task identifier of the calling task.
CALLING SEQUENCE:
rtems_id rtems_task_self( void );
DESCRIPTION:
This directive returns the task identifier of the calling task.
RETURN VALUES:
Returns the task identifier of the calling task.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
7.4.5. rtems_task_start()#
Starts the task.
CALLING SEQUENCE:
rtems_status_code rtems_task_start(
rtems_id id,
rtems_task_entry entry_point,
rtems_task_argument argument
);
PARAMETERS:
id
This parameter is the task identifier. The constant
RTEMS_SELF
may be used to specify the calling task.entry_point
This parameter is the task entry point.
argument
This parameter is the task entry point argument.
DESCRIPTION:
This directive readies the task, specified by id
, for execution based on the priority and execution mode specified when the task was created. The task entry point of the task is given in entry_point
. The task’s entry point argument is contained in argument
.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
entry_point
parameter was NULL.RTEMS_INVALID_ID
There was no task associated with the identifier specified by
id
.RTEMS_INCORRECT_STATE
The task was not in the dormant state.
RTEMS_ILLEGAL_ON_REMOTE_OBJECT
The task resided on a remote node.
NOTES:
The type of the entry point argument is an unsigned integer type. However, the integer type has the property that any valid pointer to void
can be converted to this type and then converted back to a pointer to void
. The result will compare equal to the original pointer. The type can represent at least 32 bits. Some applications use the entry point argument as an index into a parameter table to get task-specific parameters.
Any actions performed on a dormant task such as suspension or change of priority are nullified when the task is initiated via the rtems_task_start() directive.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may unblock a task. This may cause the calling task to be preempted.
7.4.6. rtems_task_restart()#
Restarts the task.
CALLING SEQUENCE:
rtems_status_code rtems_task_restart(
rtems_id id,
rtems_task_argument argument
);
PARAMETERS:
id
This parameter is the task identifier. The constant
RTEMS_SELF
may be used to specify the calling task.argument
This parameter is the task entry point argument.
DESCRIPTION:
This directive resets the task specified by id
to begin execution at its original entry point. The task’s priority and execution mode are set to the original creation values. If the task is currently blocked, RTEMS automatically makes the task ready. A task can be restarted from any state, except the dormant state. The task’s entry point argument is contained in argument
.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no task associated with the identifier specified by
id
.RTEMS_INCORRECT_STATE
The task never started.
RTEMS_ILLEGAL_ON_REMOTE_OBJECT
The task resided on a remote node.
NOTES:
The type of the entry point argument is an unsigned integer type. However, the integer type has the property that any valid pointer to void
can be converted to this type and then converted back to a pointer to void
. The result will compare equal to the original pointer. The type can represent at least 32 bits. Some applications use the entry point argument as an index into a parameter table to get task-specific parameters.
A new entry point argument may be used to distinguish between the initial rtems_task_start() of the task and any ensuing calls to rtems_task_restart() of the task. This can be beneficial in deleting a task. Instead of deleting a task using the rtems_task_delete() directive, a task can delete another task by restarting that task, and allowing that task to release resources back to RTEMS and then delete itself.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may change the priority of a task. This may cause the calling task to be preempted.
The directive may unblock a task. This may cause the calling task to be preempted.
7.4.7. rtems_task_delete()#
Deletes the task.
CALLING SEQUENCE:
rtems_status_code rtems_task_delete( rtems_id id );
PARAMETERS:
id
This parameter is the task identifier. The constant
RTEMS_SELF
may be used to specify the calling task.
DESCRIPTION:
This directive deletes the task, either the calling task or another task, as specified by id
.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no task associated with the identifier specified by
id
.RTEMS_CALLED_FROM_ISR
The directive was called from within interrupt context.
RTEMS_INCORRECT_STATE
The task termination procedure was started, however, waiting for the terminating task would have resulted in a deadlock.
RTEMS_ILLEGAL_ON_REMOTE_OBJECT
The task resided on a remote node.
NOTES:
The task deletion is done in several steps. Firstly, the task is marked as terminating. While the task life of the terminating task is protected, it executes normally until it disables the task life protection or it deletes itself. A terminating task will eventually stop its normal execution and start its termination procedure. The procedure executes in the context of the terminating task. The task termination procedure involves the destruction of POSIX key values and running the task termination user extensions. Once complete the execution of the task is stopped and task-specific resources are reclaimed by the system, such as the stack memory, any allocated delay or timeout timers, the TCB, and, if the task is RTEMS_FLOATING_POINT
, its floating point context area. RTEMS explicitly does not reclaim the following resources: region segments, partition buffers, semaphores, timers, or rate monotonic periods.
A task is responsible for releasing its resources back to RTEMS before deletion. To insure proper deallocation of resources, a task should not be deleted unless it is unable to execute or does not hold any RTEMS resources. If a task holds RTEMS resources, the task should be allowed to deallocate its resources before deletion. A task can be directed to release its resources and delete itself by restarting it with a special argument or by sending it a message, an event, or a signal.
Deletion of the calling task (RTEMS_SELF
) will force RTEMS to select another task to execute.
When a task deletes another task, the calling task waits until the task termination procedure of the task being deleted has completed. The terminating task inherits the eligible priorities of the calling task.
When a global task is deleted, the task identifier must be transmitted to every node in the system for deletion from the local copy of the global object table.
The task must reside on the local node, even if the task was created with the RTEMS_GLOBAL
attribute.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
When the directive operates on a global object, the directive sends a message to remote nodes. This may preempt the calling task.
The calling task does not have to be the task that created the object. Any local task that knows the object identifier can delete the object.
Where the object class corresponding to the directive is configured to use unlimited objects, the directive may free memory to the RTEMS Workspace.
7.4.8. rtems_task_exit()#
Deletes the calling task.
CALLING SEQUENCE:
void rtems_task_exit( void );
DESCRIPTION:
This directive deletes the calling task.
NOTES:
The directive is an optimized variant of the following code sequences, see also rtems_task_delete():
#include <pthread.h>
#include <rtems.h>
void classic_delete_self( void )
{
(void) rtems_task_delete( RTEMS_SELF );
}
void posix_delete_self( void )
{
(void) pthread_detach( pthread_self() );
(void) pthread_exit( NULL);
}
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within task context.
The directive will not return to the caller.
While thread dispatching is disabled, if the directive performs a thread dispatch, then the fatal error with the fatal source INTERNAL_ERROR_CORE and the fatal code INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL will occur.
7.4.9. rtems_task_suspend()#
Suspends the task.
CALLING SEQUENCE:
rtems_status_code rtems_task_suspend( rtems_id id );
PARAMETERS:
id
This parameter is the task identifier. The constant
RTEMS_SELF
may be used to specify the calling task.
DESCRIPTION:
This directive suspends the task specified by id
from further execution by placing it in the suspended state. This state is additive to any other blocked state that the task may already be in. The task will not execute again until another task issues the rtems_task_resume() directive for this task and any blocked state has been removed. The rtems_task_restart() directive will also remove the suspended state.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no task associated with the identifier specified by
id
.RTEMS_ALREADY_SUSPENDED
The task was already suspended.
RTEMS_ILLEGAL_ON_REMOTE_OBJECT
The task resided on a remote node.
NOTES:
The requesting task can suspend itself for example by specifying RTEMS_SELF
as id
. In this case, the task will be suspended and a successful return code will be returned when the task is resumed.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
When the directive operates on a remote object, the directive sends a message to the remote node and waits for a reply. This will preempt the calling task.
7.4.10. rtems_task_resume()#
Resumes the task.
CALLING SEQUENCE:
rtems_status_code rtems_task_resume( rtems_id id );
PARAMETERS:
id
This parameter is the task identifier.
DESCRIPTION:
This directive removes the task specified by id
from the suspended state. If the task is in the ready state after the suspension is removed, then it will be scheduled to run. If the task is still in a blocked state after the suspension is removed, then it will remain in that blocked state.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no task associated with the identifier specified by
id
.RTEMS_INCORRECT_STATE
The task was not suspended.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may unblock a task. This may cause the calling task to be preempted.
When the directive operates on a remote object, the directive sends a message to the remote node and waits for a reply. This will preempt the calling task.
7.4.11. rtems_task_is_suspended()#
Checks if the task is suspended.
CALLING SEQUENCE:
rtems_status_code rtems_task_is_suspended( rtems_id id );
PARAMETERS:
id
This parameter is the task identifier. The constant
RTEMS_SELF
may be used to specify the calling task.
DESCRIPTION:
This directive returns a status code indicating whether or not the task specified by id
is currently suspended.
RETURN VALUES:
RTEMS_SUCCESSFUL
The task was not suspended.
RTEMS_INVALID_ID
There was no task associated with the identifier specified by
id
.RTEMS_ALREADY_SUSPENDED
The task was suspended.
RTEMS_ILLEGAL_ON_REMOTE_OBJECT
The task resided on a remote node.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
7.4.12. rtems_task_set_priority()#
Sets the real priority or gets the current priority of the task.
CALLING SEQUENCE:
rtems_status_code rtems_task_set_priority(
rtems_id id,
rtems_task_priority new_priority,
rtems_task_priority *old_priority
);
PARAMETERS:
id
This parameter is the task identifier. The constant
RTEMS_SELF
may be used to specify the calling task.new_priority
This parameter is the new real priority or
RTEMS_CURRENT_PRIORITY
to get the current priority.old_priority
This parameter is the pointer to an rtems_task_priority object. When the directive call is successful, the current or previous priority of the task with respect to its home scheduler will be stored in this object.
DESCRIPTION:
This directive manipulates the priority of the task specified by id
. When new_priority
is not equal to RTEMS_CURRENT_PRIORITY
, the specified task’s previous priority is returned in old_priority
. When new_priority
is RTEMS_CURRENT_PRIORITY
, the specified task’s current priority is returned in old_priority
.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
old_priority
parameter was NULL.RTEMS_INVALID_ID
There was no task associated with the identifier specified by
id
.RTEMS_INVALID_PRIORITY
The task priority specified in
new_priority
was invalid with respect to the home scheduler of the task.
NOTES:
Valid priorities range from one to a maximum value which depends on the configured scheduler. The lower the priority value the higher is the importance of the task.
If the task is currently holding any binary semaphores which use a locking protocol, then the task’s priority cannot be lowered immediately. If the task’s priority were lowered immediately, then this could violate properties of the locking protocol and may result in priority inversion. The requested lowering of the task’s priority will occur when the task has released all binary semaphores which make the task more important. The task’s priority can be increased regardless of the task’s use of binary semaphores with locking protocols.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may change the priority of a task. This may cause the calling task to be preempted.
When the directive operates on a remote object, the directive sends a message to the remote node and waits for a reply. This will preempt the calling task.
7.4.13. rtems_task_get_priority()#
Gets the current priority of the task with respect to the scheduler.
CALLING SEQUENCE:
rtems_status_code rtems_task_get_priority(
rtems_id task_id,
rtems_id scheduler_id,
rtems_task_priority *priority
);
PARAMETERS:
task_id
This parameter is the task identifier. The constant
RTEMS_SELF
may be used to specify the calling task.scheduler_id
This parameter is the scheduler identifier.
priority
This parameter is the pointer to an rtems_task_priority object. When the directive call is successful, the current priority of the task with respect to the specified scheduler will be stored in this object.
DESCRIPTION:
This directive returns the current priority in priority
of the task specified by task_id
with respect to the scheduler specified by scheduler_id
.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
priority
parameter was NULL.RTEMS_INVALID_ID
There was no task associated with the identifier specified by
task_id
.RTEMS_INVALID_ID
There was no scheduler associated with the identifier specified by
scheduler_id
.RTEMS_NOT_DEFINED
The task had no priority with respect to the scheduler.
RTEMS_ILLEGAL_ON_REMOTE_OBJECT
The task resided on a remote node.
NOTES:
The current priority reflects temporary priority adjustments due to locking protocols, the rate-monotonic period objects on some schedulers such as EDF, and the POSIX sporadic server.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
7.4.14. rtems_task_mode()#
Gets and optionally sets the mode of the calling task.
CALLING SEQUENCE:
rtems_status_code rtems_task_mode(
rtems_mode mode_set,
rtems_mode mask,
rtems_mode *previous_mode_set
);
PARAMETERS:
mode_set
This parameter is the mode set to apply to the calling task. When
mask
is set toRTEMS_CURRENT_MODE
, the value of this parameter is ignored. Only modes requested bymask
are applied to the calling task.mask
This parameter is the mode mask which specifies which modes in
mode_set
are applied to the calling task. When the value isRTEMS_CURRENT_MODE
, the mode of the calling task is not changed.previous_mode_set
This parameter is the pointer to an
rtems_mode
object. When the directive call is successful, the mode of the task before any mode changes done by the directive call will be stored in this object.
DESCRIPTION:
This directive queries and optionally manipulates the execution mode of the calling task. A task’s execution mode enables and disables preemption, timeslicing, asynchronous signal processing, as well as specifying the interrupt level. To modify an execution mode, the mode class(es) to be changed must be specified in the mask
parameter and the desired mode(s) must be specified in the mode_set
parameter.
A task can obtain its current execution mode, without modifying it, by calling this directive with a mask
value of RTEMS_CURRENT_MODE
.
The mode set specified in mode_set
is built through a bitwise or of the mode constants described below. Not all combinations of modes are allowed. Some modes are mutually exclusive. If mutually exclusive modes are combined, the behaviour is undefined. Default task modes can be selected by using the RTEMS_DEFAULT_MODES
constant. The task mode set defines
the preemption mode of the task:
RTEMS_PREEMPT
(default) orRTEMS_NO_PREEMPT
,the timeslicing mode of the task:
RTEMS_TIMESLICE
orRTEMS_NO_TIMESLICE
(default),the ASR processing mode of the task:
RTEMS_ASR
(default) orRTEMS_NO_ASR
,the interrupt level of the task:
RTEMS_INTERRUPT_LEVEL()
with a default ofRTEMS_INTERRUPT_LEVEL( 0 )
which is associated with enabled interrupts.
The mode mask specified in mask
is built through a bitwise or of the mode mask constants described below.
When the RTEMS_PREEMPT_MASK
is set in mask
, the preemption mode of the calling task is
enabled by using the
RTEMS_PREEMPT
mode constant inmode_set
anddisabled by using the
RTEMS_NO_PREEMPT
mode constant inmode_set
.
When the RTEMS_TIMESLICE_MASK
is set in mask
, the timeslicing mode of the calling task is
enabled by using the
RTEMS_TIMESLICE
mode constant inmode_set
anddisabled by using the
RTEMS_NO_TIMESLICE
mode constant inmode_set
.
Enabling timeslicing has no effect if preemption is disabled. For a task to be timesliced, that task must have both preemption and timeslicing enabled.
When the RTEMS_ASR_MASK
is set in mask
, the ASR processing mode of the calling task is
enabled by using the
RTEMS_ASR
mode constant inmode_set
anddisabled by using the
RTEMS_NO_ASR
mode constant inmode_set
.
When the RTEMS_INTERRUPT_MASK
is set in mask
, interrupts of the calling task are
enabled by using the
RTEMS_INTERRUPT_LEVEL()
mode macro with a value of zero (0) inmode_set
anddisabled up to the specified level by using the
RTEMS_INTERRUPT_LEVEL()
mode macro with a positive value inmode_set
.
An interrupt level of zero is associated with enabled interrupts on all target processors. The interrupt level portion of the task mode supports a maximum of 256 interrupt levels. These levels are mapped onto the interrupt levels actually supported by the target processor in a processor dependent fashion.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_NOT_IMPLEMENTED
The
RTEMS_NO_PREEMPT
was set inmode_set
and setting the preemption mode was requested byRTEMS_PREEMPT_MASK
inmask
and the system configuration had no implementation for this mode.RTEMS_NOT_IMPLEMENTED
The
RTEMS_INTERRUPT_LEVEL()
was set to a positive level inmode_set
and setting the interrupt level was requested byRTEMS_INTERRUPT_MASK
inmask
and the system configuration had no implementation for this mode.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within task context.
When the directive enables preemption for the calling task, another task may preempt the calling task.
While thread dispatching is disabled, if the directive performs a thread dispatch, then the fatal error with the fatal source INTERNAL_ERROR_CORE and the fatal code INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL will occur.
7.4.15. rtems_task_wake_after()#
Wakes up after a count of clock ticks have occurred or yields the processor.
CALLING SEQUENCE:
rtems_status_code rtems_task_wake_after( rtems_interval ticks );
PARAMETERS:
ticks
This parameter is the count of clock ticks to delay the task or
RTEMS_YIELD_PROCESSOR
to yield the processor.
DESCRIPTION:
This directive blocks the calling task for the specified ticks
count of clock ticks if the value is not equal to RTEMS_YIELD_PROCESSOR
. When the requested count of ticks have occurred, the task is made ready. The clock tick directives automatically update the delay period. The calling task may give up the processor and remain in the ready state by specifying a value of RTEMS_YIELD_PROCESSOR
in ticks
.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
NOTES:
Setting the system date and time with the rtems_clock_set() directive and similar directives which set CLOCK_REALTIME have no effect on a rtems_task_wake_after() blocked task. The delay until first clock tick will never be a whole clock tick interval since this directive will never execute exactly on a clock tick. Applications requiring use of a clock (CLOCK_REALTIME or CLOCK_MONOTONIC) instead of clock ticks should make use of clock_nanosleep().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within task context.
The directive requires a Clock Driver.
While thread dispatching is disabled, if the directive performs a thread dispatch, then the fatal error with the fatal source INTERNAL_ERROR_CORE and the fatal code INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL will occur.
7.4.16. rtems_task_wake_when()#
Wakes up when specified.
CALLING SEQUENCE:
rtems_status_code rtems_task_wake_when( const rtems_time_of_day *time_buffer );
PARAMETERS:
time_buffer
This parameter is the date and time to wake up.
DESCRIPTION:
This directive blocks a task until the date and time specified in time_buffer
. At the requested date and time, the calling task will be unblocked and made ready to execute.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_NOT_DEFINED
The system date and time was not set.
RTEMS_INVALID_ADDRESS
The
time_buffer
parameter was NULL.RTEMS_INVALID_CLOCK
The time of day was invalid.
NOTES:
The ticks portion of time_buffer
structure is ignored. The timing granularity of this directive is a second.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within task context.
The directive requires a Clock Driver.
While thread dispatching is disabled, if the directive performs a thread dispatch, then the fatal error with the fatal source INTERNAL_ERROR_CORE and the fatal code INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL will occur.
7.4.17. rtems_task_get_scheduler()#
Gets the home scheduler of the task.
CALLING SEQUENCE:
rtems_status_code rtems_task_get_scheduler(
rtems_id task_id,
rtems_id *scheduler_id
);
PARAMETERS:
task_id
This parameter is the task identifier. The constant
RTEMS_SELF
may be used to specify the calling task.scheduler_id
This parameter is the pointer to an rtems_id object. When the directive call is successful, the identifier of the home scheduler of the task will be stored in this object.
DESCRIPTION:
This directive returns the identifier of the home scheduler of the task specified by task_id
in scheduler_id
.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
scheduler_id
parameter was NULL.RTEMS_INVALID_ID
There was no task associated with the identifier specified by
task_id
.RTEMS_ILLEGAL_ON_REMOTE_OBJECT
The task resided on a remote node.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
7.4.18. rtems_task_set_scheduler()#
Sets the home scheduler for the task.
CALLING SEQUENCE:
rtems_status_code rtems_task_set_scheduler(
rtems_id task_id,
rtems_id scheduler_id,
rtems_task_priority priority
);
PARAMETERS:
task_id
This parameter is the task identifier. The constant
RTEMS_SELF
may be used to specify the calling task.scheduler_id
This parameter is the scheduler identifier of the new home scheduler for the task specified by
task_id
.priority
This parameter is the new real priority for the task with respect to the scheduler specified by
scheduler_id
.
DESCRIPTION:
This directive sets the home scheduler to the scheduler specified by scheduler_id
for the task specified by task_id
.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no scheduler associated with the identifier specified by
scheduler_id
.RTEMS_INVALID_PRIORITY
The task priority specified by
priority
was invalid with respect to the scheduler specified byscheduler_id
.RTEMS_INVALID_ID
There was no task associated with the identifier specified by
task_id
.RTEMS_RESOURCE_IN_USE
The task specified by
task_id
was enqueued on a wait queue.RTEMS_RESOURCE_IN_USE
The task specified by
task_id
had a current priority which consisted of more than the real priority.RTEMS_RESOURCE_IN_USE
The task specified by
task_id
had a helping scheduler.RTEMS_RESOURCE_IN_USE
The task specified by
task_id
was pinned.RTEMS_UNSATISFIED
The scheduler specified by
scheduler_id
owned no processor.RTEMS_UNSATISFIED
The scheduler specified by
scheduler_id
did not support the affinity set of the task specified bytask_id
.RTEMS_ILLEGAL_ON_REMOTE_OBJECT
The task resided on a remote node.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may change the priority of a task. This may cause the calling task to be preempted.
7.4.19. rtems_task_get_affinity()#
Gets the processor affinity of the task.
CALLING SEQUENCE:
rtems_status_code rtems_task_get_affinity(
rtems_id id,
size_t cpusetsize,
cpu_set_t *cpuset
);
PARAMETERS:
id
This parameter is the task identifier. The constant
RTEMS_SELF
may be used to specify the calling task.cpusetsize
This parameter is the size of the processor set referenced by
cpuset
in bytes.cpuset
This parameter is the pointer to a
cpu_set_t
object. When the directive call is successful, the processor affinity set of the task will be stored in this object. A set bit in the processor set means that the corresponding processor is in the processor affinity set of the task, otherwise the bit is cleared.
DESCRIPTION:
This directive returns the processor affinity of the task in cpuset
of the task specified by id
.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
cpuset
parameter was NULL.RTEMS_INVALID_ID
There was no task associated with the identifier specified by
id
.RTEMS_INVALID_SIZE
The size specified by
cpusetsize
of the processor set was too small for the processor affinity set of the task.RTEMS_ILLEGAL_ON_REMOTE_OBJECT
The task resided on a remote node.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
7.4.20. rtems_task_set_affinity()#
Sets the processor affinity of the task.
CALLING SEQUENCE:
rtems_status_code rtems_task_set_affinity(
rtems_id id,
size_t cpusetsize,
const cpu_set_t *cpuset
);
PARAMETERS:
id
This parameter is the task identifier. The constant
RTEMS_SELF
may be used to specify the calling task.cpusetsize
This parameter is the size of the processor set referenced by
cpuset
in bytes.cpuset
This parameter is the pointer to a
cpu_set_t
object. The processor set defines the new processor affinity set of the task. A set bit in the processor set means that the corresponding processor shall be in the processor affinity set of the task, otherwise the bit shall be cleared.
DESCRIPTION:
This directive sets the processor affinity of the task specified by id
.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
cpuset
parameter was NULL.RTEMS_INVALID_ID
There was no task associated with the identifier specified by
id
.RTEMS_INVALID_NUMBER
The referenced processor set was not a valid new processor affinity set for the task.
RTEMS_ILLEGAL_ON_REMOTE_OBJECT
The task resided on a remote node.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may change the processor affinity of a task. This may cause the calling task to be preempted.
7.4.21. rtems_task_iterate()#
Iterates over all tasks and invokes the visitor routine for each task.
CALLING SEQUENCE:
void rtems_task_iterate( rtems_task_visitor visitor, void *arg );
PARAMETERS:
visitor
This parameter is the visitor routine invoked for each task.
arg
This parameter is the argument passed to each visitor routine invocation during the iteration.
DESCRIPTION:
This directive iterates over all tasks in the system. This operation covers all tasks of all APIs. The user should be careful in accessing the contents of the TCB. The visitor argument arg
is passed to all invocations of visitor
in addition to the TCB. The iteration stops immediately in case the visitor routine returns true.
NOTES:
The visitor routine is invoked while owning the objects allocator lock. It is allowed to perform blocking operations in the visitor routine, however, care must be taken so that no deadlocks via the object allocator lock can occur.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
7.4.22. RTEMS_TASK_STORAGE_SIZE()#
Gets the recommended task storage area size for the size and task attributes.
CALLING SEQUENCE:
size_t RTEMS_TASK_STORAGE_SIZE( size_t size, rtems_attribute attributes );
PARAMETERS:
size
This parameter is the size dedicated to the task stack and thread-local storage in bytes.
attributes
This parameter is the attribute set of the task using the storage area.
RETURN VALUES:
Returns the recommended task storage area size calculated from the input parameters.
7.5. Deprecated Directives#
7.5.1. ITERATE_OVER_ALL_THREADS - Iterate Over Tasks#
Warning
This directive is deprecated. Its use is unsafe. Use rtems_task_iterate instead.
- CALLING SEQUENCE:
typedef void (*rtems_per_thread_routine)(Thread_Control *the_thread); void rtems_iterate_over_all_threads( rtems_per_thread_routine routine );
- DIRECTIVE STATUS CODES:
NONE
- DESCRIPTION:
This directive iterates over all of the existant threads in the system and invokes
routine
on each of them. The user should be careful in accessing the contents ofthe_thread
.This routine is intended for use in diagnostic utilities and is not intented for routine use in an operational system.
- NOTES:
There is no protection while this routine is called. The thread control block may be in an inconsistent state or may change due to interrupts or activity on other processors.
7.6. Removed Directives#
7.6.1. TASK_GET_NOTE - Get task notepad entry#
Warning
This directive was removed in RTEMS 5.1.
- CALLING SEQUENCE:
rtems_status_code rtems_task_get_note( rtems_id id, uint32_t notepad, uint32_t *note );
- DIRECTIVE STATUS CODES:
RTEMS_SUCCESSFUL
note value obtained successfully
RTEMS_INVALID_ADDRESS
note
parameter is NULLRTEMS_INVALID_ID
invalid task id
RTEMS_INVALID_NUMBER
invalid notepad location
- DESCRIPTION:
This directive returns the note contained in the notepad location of the task specified by id.
- NOTES:
This directive will not cause the running task to be preempted.
If id is set to
RTEMS_SELF
, the calling task accesses its own notepad.The sixteen notepad locations can be accessed using the constants
RTEMS_NOTEPAD_0
throughRTEMS_NOTEPAD_15
.Getting a note of a global task which does not reside on the local node will generate a request to the remote node to obtain the notepad entry of the specified task.
7.6.2. TASK_SET_NOTE - Set task notepad entry#
Warning
This directive was removed in RTEMS 5.1.
- CALLING SEQUENCE:
rtems_status_code rtems_task_set_note( rtems_id id, uint32_t notepad, uint32_t note );
- DIRECTIVE STATUS CODES:
RTEMS_SUCCESSFUL
note set successfully
RTEMS_INVALID_ID
invalid task id
RTEMS_INVALID_NUMBER
invalid notepad location
- DESCRIPTION:
This directive sets the notepad entry for the task specified by id to the value note.
- NOTES:
If
id
is set toRTEMS_SELF
, the calling task accesses its own notepad.This directive will not cause the running task to be preempted.
The sixteen notepad locations can be accessed using the constants
RTEMS_NOTEPAD_0
throughRTEMS_NOTEPAD_15
.Setting a note of a global task which does not reside on the local node will generate a request to the remote node to set the notepad entry of the specified task.
7.6.3. TASK_VARIABLE_ADD - Associate per task variable#
Warning
This directive was removed in RTEMS 5.1.
- CALLING SEQUENCE:
rtems_status_code rtems_task_variable_add( rtems_id tid, void **task_variable, void (*dtor)(void *) );
- DIRECTIVE STATUS CODES:
RTEMS_SUCCESSFUL
per task variable added successfully
RTEMS_INVALID_ADDRESS
task_variable
is NULLRTEMS_INVALID_ID
invalid task id
RTEMS_NO_MEMORY
invalid task id
RTEMS_ILLEGAL_ON_REMOTE_OBJECT
not supported on remote tasks
- DESCRIPTION:
This directive adds the memory location specified by the ptr argument to the context of the given task. The variable will then be private to the task. The task can access and modify the variable, but the modifications will not appear to other tasks, and other tasks’ modifications to that variable will not affect the value seen by the task. This is accomplished by saving and restoring the variable’s value each time a task switch occurs to or from the calling task. If the dtor argument is non-NULL it specifies the address of a ‘destructor’ function which will be called when the task is deleted. The argument passed to the destructor function is the task’s value of the variable.
- NOTES:
Task variables increase the context switch time to and from the tasks that own them so it is desirable to minimize the number of task variables. One efficient method is to have a single task variable that is a pointer to a dynamically allocated structure containing the task’s private ‘global’ data. In this case the destructor function could be ‘free’.
Per-task variables are disabled in SMP configurations and this service is not available.
7.6.4. TASK_VARIABLE_GET - Obtain value of a per task variable#
Warning
This directive was removed in RTEMS 5.1.
- CALLING SEQUENCE:
rtems_status_code rtems_task_variable_get( rtems_id tid, void **task_variable, void **task_variable_value );
- DIRECTIVE STATUS CODES:
RTEMS_SUCCESSFUL
per task variable obtained successfully
RTEMS_INVALID_ADDRESS
task_variable
is NULLRTEMS_INVALID_ADDRESS
task_variable_value
is NULLRTEMS_INVALID_ADDRESS
task_variable
is not foundRTEMS_NO_MEMORY
invalid task id
RTEMS_ILLEGAL_ON_REMOTE_OBJECT
not supported on remote tasks
- DESCRIPTION:
This directive looks up the private value of a task variable for a specified task and stores that value in the location pointed to by the result argument. The specified task is usually not the calling task, which can get its private value by directly accessing the variable.
- NOTES:
If you change memory which
task_variable_value
points to, remember to declare that memory as volatile, so that the compiler will optimize it correctly. In this case both the pointertask_variable_value
and data referenced bytask_variable_value
should be considered volatile.Per-task variables are disabled in SMP configurations and this service is not available.
7.6.5. TASK_VARIABLE_DELETE - Remove per task variable#
Warning
This directive was removed in RTEMS 5.1.
- CALLING SEQUENCE:
rtems_status_code rtems_task_variable_delete( rtems_id id, void **task_variable );
- DIRECTIVE STATUS CODES:
RTEMS_SUCCESSFUL
per task variable deleted successfully
RTEMS_INVALID_ID
invalid task id
RTEMS_NO_MEMORY
invalid task id
RTEMS_INVALID_ADDRESS
task_variable
is NULLRTEMS_ILLEGAL_ON_REMOTE_OBJECT
not supported on remote tasks
- DESCRIPTION:
This directive removes the given location from a task’s context.
- NOTES:
Per-task variables are disabled in SMP configurations and this service is not available.
8. Interrupt Manager#
8.1. Introduction#
Any real-time executive must provide a mechanism for quick response to externally generated interrupts to satisfy the critical time constraints of the application. The Interrupt Manager provides this mechanism for RTEMS. This manager permits quick interrupt response times by providing the critical ability to alter task execution which allows a task to be preempted upon exit from an ISR. The directives provided by the Interrupt Manager are:
rtems_interrupt_catch() - Establishes an interrupt service routine.
rtems_interrupt_disable() - Disables the maskable interrupts on the current processor.
rtems_interrupt_enable() - Restores the previous interrupt level on the current processor.
rtems_interrupt_flash() - Flashes interrupts on the current processor.
rtems_interrupt_local_disable() - Disables the maskable interrupts on the current processor.
rtems_interrupt_local_enable() - Restores the previous interrupt level on the current processor.
rtems_interrupt_is_in_progress() - Checks if an ISR is in progress on the current processor.
rtems_interrupt_lock_initialize() - Initializes the ISR lock.
rtems_interrupt_lock_destroy() - Destroys the ISR lock.
rtems_interrupt_lock_acquire() - Acquires the ISR lock.
rtems_interrupt_lock_release() - Releases the ISR lock.
rtems_interrupt_lock_acquire_isr() - Acquires the ISR lock from within an ISR.
rtems_interrupt_lock_release_isr() - Releases the ISR lock from within an ISR.
rtems_interrupt_lock_interrupt_disable() - Disables maskable interrupts on the current processor.
RTEMS_INTERRUPT_LOCK_DECLARE() - Declares an ISR lock object.
RTEMS_INTERRUPT_LOCK_DEFINE() - Defines an ISR lock object.
RTEMS_INTERRUPT_LOCK_INITIALIZER() - Statically initializes an ISR lock object.
RTEMS_INTERRUPT_LOCK_MEMBER() - Defines an ISR lock member.
RTEMS_INTERRUPT_LOCK_REFERENCE() - Defines an ISR lock object reference.
RTEMS_INTERRUPT_ENTRY_INITIALIZER() - Statically initializes an interrupt entry object.
rtems_interrupt_entry_initialize() - Initializes the interrupt entry.
rtems_interrupt_entry_install() - Installs the interrupt entry at the interrupt vector.
rtems_interrupt_entry_remove() - Removes the interrupt entry from the interrupt vector.
rtems_interrupt_handler_install() - Installs the interrupt handler routine and argument at the interrupt vector.
rtems_interrupt_handler_remove() - Removes the interrupt handler routine and argument from the interrupt vector.
rtems_interrupt_vector_is_enabled() - Checks if the interrupt vector is enabled.
rtems_interrupt_vector_enable() - Enables the interrupt vector.
rtems_interrupt_vector_disable() - Disables the interrupt vector.
rtems_interrupt_is_pending() - Checks if the interrupt is pending.
rtems_interrupt_raise() - Raises the interrupt vector.
rtems_interrupt_raise_on() - Raises the interrupt vector on the processor.
rtems_interrupt_clear() - Clears the interrupt vector.
rtems_interrupt_get_priority() - Gets the priority of the interrupt vector.
rtems_interrupt_set_priority() - Sets the priority of the interrupt vector.
rtems_interrupt_get_affinity() - Gets the processor affinity set of the interrupt vector.
rtems_interrupt_set_affinity() - Sets the processor affinity set of the interrupt vector.
rtems_interrupt_get_attributes() - Gets the attributes of the interrupt vector.
rtems_interrupt_handler_iterate() - Iterates over all interrupt handler installed at the interrupt vector.
rtems_interrupt_server_initialize() - Initializes the interrupt server tasks.
rtems_interrupt_server_create() - Creates an interrupt server.
rtems_interrupt_server_handler_install() - Installs the interrupt handler routine and argument at the interrupt vector on the interrupt server.
rtems_interrupt_server_handler_remove() - Removes the interrupt handler routine and argument from the interrupt vector and the interrupt server.
rtems_interrupt_server_set_affinity() - Sets the processor affinity of the interrupt server.
rtems_interrupt_server_delete() - Deletes the interrupt server.
rtems_interrupt_server_suspend() - Suspends the interrupt server.
rtems_interrupt_server_resume() - Resumes the interrupt server.
rtems_interrupt_server_move() - Moves the interrupt handlers installed at the interrupt vector and the source interrupt server to the destination interrupt server.
rtems_interrupt_server_handler_iterate() - Iterates over all interrupt handler installed at the interrupt vector and interrupt server.
rtems_interrupt_server_entry_initialize() - Initializes the interrupt server entry.
rtems_interrupt_server_action_prepend() - Prepends the interrupt server action to the list of actions of the interrupt server entry.
rtems_interrupt_server_entry_destroy() - Destroys the interrupt server entry.
rtems_interrupt_server_entry_submit() - Submits the interrupt server entry to be serviced by the interrupt server.
rtems_interrupt_server_entry_move() - Moves the interrupt server entry to the interrupt server.
rtems_interrupt_server_request_initialize() - Initializes the interrupt server request.
rtems_interrupt_server_request_set_vector() - Sets the interrupt vector in the interrupt server request.
rtems_interrupt_server_request_destroy() - Destroys the interrupt server request.
rtems_interrupt_server_request_submit() - Submits the interrupt server request to be serviced by the interrupt server.
8.2. Background#
8.2.1. Processing an Interrupt#
The interrupt manager allows the application to connect a function to a hardware interrupt vector. When an interrupt occurs, the processor will automatically vector to RTEMS. RTEMS saves and restores all registers which are not preserved by the normal C calling convention for the target processor and invokes the user’s ISR. The user’s ISR is responsible for processing the interrupt, clearing the interrupt if necessary, and device specific manipulation.
The rtems_interrupt_catch
directive connects a procedure to an interrupt vector. The vector number is managed using the rtems_vector_number
data type.
The interrupt service routine is assumed to abide by these conventions and have a prototype similar to the following:
rtems_isr user_isr(
rtems_vector_number vector
);
The vector number argument is provided by RTEMS to allow the application to identify the interrupt source. This could be used to allow a single routine to service interrupts from multiple instances of the same device. For example, a single routine could service interrupts from multiple serial ports and use the vector number to identify which port requires servicing.
To minimize the masking of lower or equal priority level interrupts, the ISR should perform the minimum actions required to service the interrupt. Other non-essential actions should be handled by application tasks. Once the user’s ISR has completed, it returns control to the RTEMS interrupt manager which will perform task dispatching and restore the registers saved before the ISR was invoked.
The RTEMS interrupt manager guarantees that proper task scheduling and dispatching are performed at the conclusion of an ISR. A system call made by the ISR may have readied a task of higher priority than the interrupted task. Therefore, when the ISR completes, the postponed dispatch processing must be performed. No dispatch processing is performed as part of directives which have been invoked by an ISR.
Applications must adhere to the following rule if proper task scheduling and dispatching is to be performed:
Note
The interrupt manager must be used for all ISRs which may be interrupted by the highest priority ISR which invokes an RTEMS directive.
Consider a processor which allows a numerically low interrupt level to interrupt a numerically greater interrupt level. In this example, if an RTEMS directive is used in a level 4 ISR, then all ISRs which execute at levels 0 through 4 must use the interrupt manager.
Interrupts are nested whenever an interrupt occurs during the execution of another ISR. RTEMS supports efficient interrupt nesting by allowing the nested ISRs to terminate without performing any dispatch processing. Only when the outermost ISR terminates will the postponed dispatching occur.
8.2.2. RTEMS Interrupt Levels#
Many processors support multiple interrupt levels or priorities. The exact number of interrupt levels is processor dependent. RTEMS internally supports 256 interrupt levels which are mapped to the processor’s interrupt levels. For specific information on the mapping between RTEMS and the target processor’s interrupt levels, refer to the Interrupt Processing chapter of the Applications Supplement document for a specific target processor.
8.2.3. Disabling of Interrupts by RTEMS#
During the execution of directive calls, critical sections of code may be executed. When these sections are encountered, RTEMS disables all maskable interrupts before the execution of the section and restores them to the previous level upon completion of the section. RTEMS has been optimized to ensure that interrupts are disabled for a minimum length of time. The maximum length of time interrupts are disabled by RTEMS is processor dependent and is detailed in the Timing Specification chapter of the Applications Supplement document for a specific target processor.
Non-maskable interrupts (NMI) cannot be disabled, and ISRs which execute at this level MUST NEVER issue RTEMS system calls. If a directive is invoked, unpredictable results may occur due to the inability of RTEMS to protect its critical sections. However, ISRs that make no system calls may safely execute as non-maskable interrupts.
8.3. Operations#
8.3.1. Establishing an ISR#
The rtems_interrupt_catch
directive establishes an ISR for the system. The address of the ISR and its associated CPU vector number are specified to this directive. This directive installs the RTEMS interrupt wrapper in the processor’s Interrupt Vector Table and the address of the user’s ISR in the RTEMS’ Vector Table. This directive returns the previous contents of the specified vector in the RTEMS’ Vector Table.
8.3.2. Directives Allowed from an ISR#
Using the interrupt manager ensures that RTEMS knows when a directive is being called from an ISR. The ISR may then use system calls to synchronize itself with an application task. The synchronization may involve messages, events or signals being passed by the ISR to the desired task. Directives invoked by an ISR must operate only on objects which reside on the local node. The following is a list of RTEMS system calls that may be made from an ISR:
Task Management Although it is acceptable to operate on the RTEMS_SELF task (e.g. the currently executing task), while in an ISR, this will refer to the interrupted task. Most of the time, it is an application implementation error to use RTEMS_SELF from an ISR.
rtems_task_suspend
rtems_task_resume
Interrupt Management
rtems_interrupt_enable
rtems_interrupt_disable
rtems_interrupt_flash
rtems_interrupt_lock_acquire
rtems_interrupt_lock_release
rtems_interrupt_lock_acquire_isr
rtems_interrupt_lock_release_isr
rtems_interrupt_is_in_progress
rtems_interrupt_catch
Clock Management
rtems_clock_set
rtems_clock_get_tod
rtems_clock_get_tod_timeval
rtems_clock_get_seconds_since_epoch
rtems_clock_get_ticks_per_second
rtems_clock_get_ticks_since_boot
rtems_clock_get_uptime
Timer Management
rtems_timer_cancel
rtems_timer_reset
rtems_timer_fire_after
rtems_timer_fire_when
rtems_timer_server_fire_after
rtems_timer_server_fire_when
Event Management
rtems_event_send
rtems_event_system_send
rtems_event_transient_send
Semaphore Management
rtems_semaphore_release
Message Management
rtems_message_queue_broadcast
rtems_message_queue_send
rtems_message_queue_urgent
Signal Management
rtems_signal_send
Dual-Ported Memory Management
rtems_port_external_to_internal
rtems_port_internal_to_external
IO Management The following services are safe to call from an ISR if and only if the device driver service invoked is also safe. The IO Manager itself is safe but the invoked driver entry point may or may not be.
rtems_io_initialize
rtems_io_open
rtems_io_close
rtems_io_read
rtems_io_write
rtems_io_control
Fatal Error Management
rtems_fatal
rtems_fatal_error_occurred
Multiprocessing
rtems_multiprocessing_announce
8.4. Directives#
This section details the directives of the Interrupt Manager. A subsection is dedicated to each of this manager’s directives and lists the calling sequence, parameters, description, return values, and notes of the directive.
8.4.1. rtems_interrupt_catch()#
Establishes an interrupt service routine.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_catch(
rtems_isr_entry new_isr_handler,
rtems_vector_number vector,
rtems_isr_entry *old_isr_handler
);
PARAMETERS:
new_isr_handler
This parameter is the new interrupt service routine.
vector
This parameter is the interrupt vector number.
old_isr_handler
This parameter is the pointer to an rtems_isr_entry object. When the directive call is successful, the previous interrupt service routine established for this interrupt vector will be stored in this object.
DESCRIPTION:
This directive establishes an interrupt service routine (ISR) for the interrupt specified by the vector
number. The new_isr_handler
parameter specifies the entry point of the ISR. The entry point of the previous ISR for the specified vector is returned in old_isr_handler
.
To release an interrupt vector, pass the old handler’s address obtained when the vector was first capture.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_NUMBER
The interrupt vector number was illegal.
RTEMS_INVALID_ADDRESS
The
new_isr_handler
parameter was NULL.RTEMS_INVALID_ADDRESS
The
old_isr_handler
parameter was NULL.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
The directive is only available where the target architecture support enabled simple vectored interrupts.
8.4.2. rtems_interrupt_disable()#
Disables the maskable interrupts on the current processor.
CALLING SEQUENCE:
void rtems_interrupt_disable( rtems_interrupt_level isr_cookie );
PARAMETERS:
isr_cookie
This parameter is a variable of type rtems_interrupt_level which will be used to save the previous interrupt level.
DESCRIPTION:
This directive disables all maskable interrupts on the current processor and returns the previous interrupt level in isr_cookie
.
NOTES:
A later invocation of the rtems_interrupt_enable() directive should be used to restore the previous interrupt level.
This directive is implemented as a macro which sets the isr_cookie
parameter.
1#include <rtems.h>
2
3void local_critical_section( void )
4{
5 rtems_interrupt_level level;
6
7 // Please note that the rtems_interrupt_disable() is a macro. The
8 // previous interrupt level (before the maskable interrupts are
9 // disabled) is returned here in the level macro parameter. This
10 // would be wrong:
11 //
12 // rtems_interrupt_disable( &level );
13 rtems_interrupt_disable( level );
14
15 // Here is the critical section: maskable interrupts are disabled
16
17 {
18 rtems_interrupt_level nested_level;
19
20 rtems_interrupt_disable( nested_level );
21
22 // Here is a nested critical section
23
24 rtems_interrupt_enable( nested_level );
25 }
26
27 // Maskable interrupts are still disabled
28
29 rtems_interrupt_enable( level );
30}
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
Where the system was built with SMP support enabled, the directive is not available. Its use will result in compiler warnings and linker errors. The rtems_interrupt_local_disable() and rtems_interrupt_local_enable() directives are available in all build configurations.
8.4.3. rtems_interrupt_enable()#
Restores the previous interrupt level on the current processor.
CALLING SEQUENCE:
void rtems_interrupt_enable( rtems_interrupt_level isr_cookie );
PARAMETERS:
isr_cookie
This parameter is the previous interrupt level to restore. The value must be obtained by a previous call to rtems_interrupt_disable() or rtems_interrupt_flash().
DESCRIPTION:
This directive restores the interrupt level specified by isr_cookie
on the current processor.
NOTES:
The isr_cookie
parameter value must be obtained by a previous call to rtems_interrupt_disable() or rtems_interrupt_flash(). Using an otherwise obtained value is undefined behaviour.
This directive is unsuitable to enable particular interrupt sources, for example in an interrupt controller.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
While at least one maskable interrupt is pending, when the directive enables maskable interrupts, the pending interrupts are immediately serviced. The interrupt service routines may unblock higher priority tasks which may preempt the calling task.
Where the system was built with SMP support enabled, the directive is not available. Its use will result in compiler warnings and linker errors. The rtems_interrupt_local_disable() and rtems_interrupt_local_enable() directives are available in all build configurations.
8.4.4. rtems_interrupt_flash()#
Flashes interrupts on the current processor.
CALLING SEQUENCE:
void rtems_interrupt_flash( rtems_interrupt_level isr_cookie );
PARAMETERS:
isr_cookie
This parameter is the previous interrupt level.
DESCRIPTION:
This directive is functionally equivalent to a calling rtems_interrupt_enable() immediately followed by a rtems_interrupt_disable(). On some architectures it is possible to provide an optimized implementation for this sequence.
NOTES:
The isr_cookie
parameter value must be obtained by a previous call to rtems_interrupt_disable() or rtems_interrupt_flash(). Using an otherwise obtained value is undefined behaviour.
Historically, the interrupt flash directive was heavily used in the operating system implementation. However, this is no longer the case. The interrupt flash directive is provided for backward compatibility reasons.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
Where the system was built with SMP support enabled, the directive is not available. Its use will result in compiler warnings and linker errors. The rtems_interrupt_local_disable() and rtems_interrupt_local_enable() directives are available in all build configurations.
8.4.5. rtems_interrupt_local_disable()#
Disables the maskable interrupts on the current processor.
CALLING SEQUENCE:
void rtems_interrupt_local_disable( rtems_interrupt_level isr_cookie );
PARAMETERS:
isr_cookie
This parameter is a variable of type rtems_interrupt_level which will be used to save the previous interrupt level.
DESCRIPTION:
This directive disables all maskable interrupts on the current processor and returns the previous interrupt level in isr_cookie
.
NOTES:
A later invocation of the rtems_interrupt_local_enable() directive should be used to restore the previous interrupt level.
This directive is implemented as a macro which sets the isr_cookie
parameter.
Where the system was built with SMP support enabled, this will not ensure system wide mutual exclusion. Use interrupt locks instead, see rtems_interrupt_lock_acquire(). Interrupt disabled critical sections may be used to access processor-specific data structures or disable thread dispatching.
1#include <rtems.h>
2
3void local_critical_section( void )
4{
5 rtems_interrupt_level level;
6
7 // Please note that the rtems_interrupt_local_disable() is a macro.
8 // The previous interrupt level (before the maskable interrupts are
9 // disabled) is returned here in the level macro parameter. This would
10 // be wrong:
11 //
12 // rtems_interrupt_local_disable( &level );
13 rtems_interrupt_local_disable( level );
14
15 // Here is the critical section: maskable interrupts are disabled
16
17 {
18 rtems_interrupt_level nested_level;
19
20 rtems_interrupt_local_disable( nested_level );
21
22 // Here is a nested critical section
23
24 rtems_interrupt_local_enable( nested_level );
25 }
26
27 // Maskable interrupts are still disabled
28
29 rtems_interrupt_local_enable( level );
30}
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
8.4.6. rtems_interrupt_local_enable()#
Restores the previous interrupt level on the current processor.
CALLING SEQUENCE:
void rtems_interrupt_local_enable( rtems_interrupt_level isr_cookie );
PARAMETERS:
isr_cookie
This parameter is the previous interrupt level to restore. The value must be obtained by a previous call to rtems_interrupt_local_disable().
DESCRIPTION:
This directive restores the interrupt level specified by isr_cookie
on the current processor.
NOTES:
The isr_cookie
parameter value must be obtained by a previous call to rtems_interrupt_local_disable(). Using an otherwise obtained value is undefined behaviour.
This directive is unsuitable to enable particular interrupt sources, for example in an interrupt controller.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
While at least one maskable interrupt is pending, when the directive enables maskable interrupts, the pending interrupts are immediately serviced. The interrupt service routines may unblock higher priority tasks which may preempt the calling task.
8.4.7. rtems_interrupt_is_in_progress()#
Checks if an ISR is in progress on the current processor.
CALLING SEQUENCE:
bool rtems_interrupt_is_in_progress( void );
DESCRIPTION:
This directive returns true
, if the current processor is currently servicing an interrupt, and false
otherwise. A return value of true
indicates that the caller is an interrupt service routine, not a task. The directives available to an interrupt service routine are restricted.
RETURN VALUES:
Returns true, if the current processor is currently servicing an interrupt, otherwise false.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
8.4.8. rtems_interrupt_lock_initialize()#
Initializes the ISR lock.
CALLING SEQUENCE:
void rtems_interrupt_lock_initialize(
rtems_interrupt_lock *lock,
const char *name
);
PARAMETERS:
lock
This parameter is the ISR lock to initialize.
name
This parameter is the ISR lock name. It shall be a string. The name is only used where the system was built with profiling support enabled.
NOTES:
ISR locks may also be statically defined by RTEMS_INTERRUPT_LOCK_DEFINE() or statically initialized by RTEMS_INTERRUPT_LOCK_INITIALIZER().
8.4.9. rtems_interrupt_lock_destroy()#
Destroys the ISR lock.
CALLING SEQUENCE:
void rtems_interrupt_lock_destroy( rtems_interrupt_lock *lock );
PARAMETERS:
lock
This parameter is the ISR lock to destroy.
NOTES:
The lock must have been dynamically initialized by rtems_interrupt_lock_initialize(), statically defined by RTEMS_INTERRUPT_LOCK_DEFINE(), or statically initialized by RTEMS_INTERRUPT_LOCK_INITIALIZER().
Concurrent lock use during the destruction or concurrent destruction leads to unpredictable results.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
8.4.10. rtems_interrupt_lock_acquire()#
Acquires the ISR lock.
CALLING SEQUENCE:
void rtems_interrupt_lock_acquire(
rtems_interrupt_lock *lock,
rtems_interrupt_lock_context *lock_context
);
PARAMETERS:
lock
This parameter is the ISR lock to acquire.
lock_context
This parameter is the ISR lock context. This lock context shall be used to release the lock by calling rtems_interrupt_lock_release().
DESCRIPTION:
This directive acquires the ISR lock specified by lock
using the lock context provided by lock_context
. Maskable interrupts will be disabled on the current processor.
NOTES:
A caller-specific lock context shall be provided for each acquire/release pair, for example an automatic variable.
Where the system was built with SMP support enabled, this directive acquires an SMP lock. An attempt to recursively acquire the lock may result in an infinite loop with maskable interrupts disabled.
This directive establishes a non-preemptive critical section with system wide mutual exclusion on the local node in all RTEMS build configurations.
1#include <rtems.h>
2
3void critical_section( rtems_interrupt_lock *lock )
4{
5 rtems_interrupt_lock_context lock_context;
6
7 rtems_interrupt_lock_acquire( lock, &lock_context );
8
9 // Here is the critical section. Maskable interrupts are disabled.
10 // Where the system was built with SMP support enabled, this section
11 // is protected by an SMP lock.
12
13 rtems_interrupt_lock_release( lock, &lock_context );
14}
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
8.4.11. rtems_interrupt_lock_release()#
Releases the ISR lock.
CALLING SEQUENCE:
void rtems_interrupt_lock_release( rtems_interrupt_lock_context *lock );
PARAMETERS:
lock
This parameter is the ISR lock to release.
lock_context
This parameter is the ISR lock context. This lock context shall have been used to acquire the lock by calling rtems_interrupt_lock_acquire().
DESCRIPTION:
This directive releases the ISR lock specified by lock
using the lock context provided by lock_context
. The previous interrupt level will be restored on the current processor.
NOTES:
The lock context shall be the one used to acquire the lock, otherwise the result is unpredictable.
Where the system was built with SMP support enabled, this directive releases an SMP lock.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
While at least one maskable interrupt is pending, when the directive enables maskable interrupts, the pending interrupts are immediately serviced. The interrupt service routines may unblock higher priority tasks which may preempt the calling task.
8.4.12. rtems_interrupt_lock_acquire_isr()#
Acquires the ISR lock from within an ISR.
CALLING SEQUENCE:
void rtems_interrupt_lock_acquire_isr(
rtems_interrupt_lock *lock,
rtems_interrupt_lock_context *lock_context
);
PARAMETERS:
lock
This parameter is the ISR lock to acquire within an ISR.
lock_context
This parameter is the ISR lock context. This lock context shall be used to release the lock by calling rtems_interrupt_lock_release_isr().
DESCRIPTION:
This directive acquires the ISR lock specified by lock
using the lock context provided by lock_context
. The interrupt level will remain unchanged.
NOTES:
A caller-specific lock context shall be provided for each acquire/release pair, for example an automatic variable.
Where the system was built with SMP support enabled, this directive acquires an SMP lock. An attempt to recursively acquire the lock may result in an infinite loop.
This directive is intended for device drivers and should be called from the corresponding interrupt service routine.
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. This directive may be used under specific circumstances as an optimization. In doubt, use rtems_interrupt_lock_acquire() and rtems_interrupt_lock_release().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
8.4.13. rtems_interrupt_lock_release_isr()#
Releases the ISR lock from within an ISR.
CALLING SEQUENCE:
void rtems_interrupt_lock_release_isr(
rtems_interrupt_lock *lock,
rtems_interrupt_lock_context *lock_context
);
PARAMETERS:
lock
This parameter is the ISR lock to release within an ISR.
lock_context
This parameter is the ISR lock context. This lock context shall have been used to acquire the lock by calling rtems_interrupt_lock_acquire_isr().
DESCRIPTION:
This directive releases the ISR lock specified by lock
using the lock context provided by lock_context
. The interrupt level will remain unchanged.
NOTES:
The lock context shall be the one used to acquire the lock, otherwise the result is unpredictable.
Where the system was built with SMP support enabled, this directive releases an SMP lock.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
8.4.14. rtems_interrupt_lock_interrupt_disable()#
Disables maskable interrupts on the current processor.
CALLING SEQUENCE:
void rtems_interrupt_lock_interrupt_disable(
rtems_interrupt_lock_context *lock_context
);
PARAMETERS:
lock_context
This parameter is the ISR lock context for an acquire and release pair.
DESCRIPTION:
This directive disables maskable interrupts on the current processor and stores the previous interrupt level in lock_context
.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
8.4.15. RTEMS_INTERRUPT_LOCK_DECLARE()#
Declares an ISR lock object.
CALLING SEQUENCE:
RTEMS_INTERRUPT_LOCK_DECLARE( specifier, designator );
PARAMETERS:
specifier
This parameter is the storage-class specifier for the ISR lock to declare, for example
extern
orstatic
.designator
This parameter is the ISR lock object designator.
NOTES:
Do not add a “;” after this macro.
8.4.16. RTEMS_INTERRUPT_LOCK_DEFINE()#
Defines an ISR lock object.
CALLING SEQUENCE:
RTEMS_INTERRUPT_LOCK_DEFINE( specifier, designator, const char *name );
PARAMETERS:
specifier
This parameter is the storage-class specifier for the ISR lock to declare, for example
extern
orstatic
.designator
This parameter is the ISR lock object designator.
name
This parameter is the ISR lock name. It shall be a string. The name is only used where the system was built with profiling support enabled.
NOTES:
Do not add a “;” after this macro.
ISR locks may also be dynamically initialized by rtems_interrupt_lock_initialize() or statically by RTEMS_INTERRUPT_LOCK_INITIALIZER().
8.4.17. RTEMS_INTERRUPT_LOCK_INITIALIZER()#
Statically initializes an ISR lock object.
CALLING SEQUENCE:
RTEMS_INTERRUPT_LOCK_INITIALIZER( const char *name );
PARAMETERS:
name
This parameter is the ISR lock name. It shall be a string. The name is only used where the system was built with profiling support enabled.
NOTES:
ISR locks may also be dynamically initialized by rtems_interrupt_lock_initialize() or statically defined by RTEMS_INTERRUPT_LOCK_DEFINE().
8.4.18. RTEMS_INTERRUPT_LOCK_MEMBER()#
Defines an ISR lock member.
CALLING SEQUENCE:
RTEMS_INTERRUPT_LOCK_MEMBER( designator );
PARAMETERS:
designator
This parameter is the ISR lock member designator.
NOTES:
Do not add a “;” after this macro.
8.4.19. RTEMS_INTERRUPT_LOCK_REFERENCE()#
Defines an ISR lock object reference.
CALLING SEQUENCE:
RTEMS_INTERRUPT_LOCK_REFERENCE( designator, rtems_interrupt_lock *target );
PARAMETERS:
designator
This parameter is the ISR lock reference designator.
target
This parameter is the target object to reference.
NOTES:
Do not add a “;” after this macro.
8.4.20. RTEMS_INTERRUPT_ENTRY_INITIALIZER()#
Statically initializes an interrupt entry object.
CALLING SEQUENCE:
RTEMS_INTERRUPT_ENTRY_INITIALIZER(
rtems_interrupt_handler routine,
void *arg,
const char *info
);
PARAMETERS:
routine
This parameter is the interrupt handler routine for the entry.
arg
This parameter is the interrupt handler argument for the entry.
info
This parameter is the descriptive information for the entry.
NOTES:
Alternatively, rtems_interrupt_entry_initialize() may be used to dynamically initialize an interrupt entry.
8.4.21. rtems_interrupt_entry_initialize()#
Initializes the interrupt entry.
CALLING SEQUENCE:
void rtems_interrupt_entry_initialize(
rtems_interrupt_entry *entry,
rtems_interrupt_handler routine,
void *arg,
const char *info
);
PARAMETERS:
entry
This parameter is the interrupt entry to initialize.
routine
This parameter is the interrupt handler routine for the entry.
arg
This parameter is the interrupt handler argument for the entry.
info
This parameter is the descriptive information for the entry.
NOTES:
Alternatively, RTEMS_INTERRUPT_ENTRY_INITIALIZER() may be used to statically initialize an interrupt entry.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
8.4.22. rtems_interrupt_entry_install()#
Installs the interrupt entry at the interrupt vector.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_entry_install(
rtems_vector_number vector,
rtems_option options,
rtems_interrupt_entry *entry
);
PARAMETERS:
vector
This parameter is the interrupt vector number.
options
This parameter is the interrupt entry install option set.
entry
This parameter is the interrupt entry to install.
DESCRIPTION:
One of the following mutually exclusive options
RTEMS_INTERRUPT_UNIQUE
, andRTEMS_INTERRUPT_SHARED
shall be set in the options
parameter.
The handler routine of the entry specified by entry
will be called with the handler argument of the entry when dispatched. The order in which shared interrupt handlers are dispatched for one vector is defined by the installation order. The first installed handler is dispatched first.
If the option RTEMS_INTERRUPT_UNIQUE
is set, then it will be ensured that the handler will be the only one for the interrupt vector.
If the option RTEMS_INTERRUPT_SHARED
is set, then multiple handlers may be installed for the interrupt vector.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
entry
parameter was NULL.RTEMS_INCORRECT_STATE
The service was not initialized.
RTEMS_INVALID_ADDRESS
The handler routine of the entry was NULL.
RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_CALLED_FROM_ISR
The directive was called from within interrupt context.
RTEMS_INVALID_NUMBER
An option specified by
options
was not applicable.RTEMS_RESOURCE_IN_USE
The
RTEMS_INTERRUPT_UNIQUE
option was set inentry
and the interrupt vector was already occupied by a handler.RTEMS_RESOURCE_IN_USE
The
RTEMS_INTERRUPT_SHARED
option was set inentry
and the interrupt vector was already occupied by a unique handler.RTEMS_TOO_MANY
The handler routine of the entry specified by
entry
was already installed for the interrupt vector specified byvector
with an argument equal to the handler argument of the entry.
NOTES:
When the directive call was successful, the ownership of the interrupt entry has been transferred from the caller to the interrupt service. An installed interrupt entry may be removed from the interrupt service by calling rtems_interrupt_entry_remove().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
The interrupt entry shall have been initialized by rtems_interrupt_entry_initialize() or RTEMS_INTERRUPT_ENTRY_INITIALIZER().
8.4.23. rtems_interrupt_entry_remove()#
Removes the interrupt entry from the interrupt vector.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_entry_remove(
rtems_vector_number vector,
rtems_interrupt_entry *entry
);
PARAMETERS:
vector
This parameter is the interrupt vector number.
entry
This parameter is the interrupt entry to remove.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INCORRECT_STATE
The service was not initialized.
RTEMS_INVALID_ADDRESS
The
entry
parameter was NULL.RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_CALLED_FROM_ISR
The directive was called from within interrupt context.
RTEMS_UNSATISFIED
The entry specified by
entry
was not installed at the interrupt vector specified byvector
.
NOTES:
When the directive call was successful, the ownership of the interrupt entry has been transferred from the interrupt service to the caller.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
The interrupt entry shall have been installed by rtems_interrupt_entry_install().
8.4.24. rtems_interrupt_handler_install()#
Installs the interrupt handler routine and argument at the interrupt vector.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_handler_install(
rtems_vector_number vector,
const char *info,
rtems_option options,
rtems_interrupt_handler routine,
void *arg
);
PARAMETERS:
vector
This parameter is the interrupt vector number.
info
This parameter is the descriptive information of the interrupt handler to install.
options
This parameter is the interrupt handler install option set.
routine
This parameter is the interrupt handler routine to install.
arg
This parameter is the interrupt handler argument to install.
DESCRIPTION:
One of the following mutually exclusive options
RTEMS_INTERRUPT_UNIQUE
,RTEMS_INTERRUPT_SHARED
, andRTEMS_INTERRUPT_REPLACE
shall be set in the options
parameter.
The handler routine will be called with the argument specified by arg
when dispatched. The order in which shared interrupt handlers are dispatched for one vector is defined by the installation order. The first installed handler is dispatched first.
If the option RTEMS_INTERRUPT_UNIQUE
is set, then it will be ensured that the handler will be the only one for the interrupt vector.
If the option RTEMS_INTERRUPT_SHARED
is set, then multiple handler may be installed for the interrupt vector.
If the option RTEMS_INTERRUPT_REPLACE
is set, then the handler specified by routine
will replace the first handler with the same argument for the interrupt vector if it exists, otherwise an error status will be returned. A second handler with the same argument for the interrupt vector will remain unchanged. The new handler will inherit the unique or shared options from the replaced handler.
An informative description may be provided in info
. It may be used for system debugging and diagnostic tools. The referenced string has to be persistent as long as the handler is installed.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INCORRECT_STATE
The service was not initialized.
RTEMS_INVALID_ADDRESS
The
routine
parameter was NULL.RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_CALLED_FROM_ISR
The directive was called from within interrupt context.
RTEMS_NO_MEMORY
There was not enough memory available to allocate data structures to install the handler.
RTEMS_RESOURCE_IN_USE
The
RTEMS_INTERRUPT_UNIQUE
option was set inoptions
and the interrupt vector was already occupied by a handler.RTEMS_RESOURCE_IN_USE
The
RTEMS_INTERRUPT_SHARED
option was set inoptions
and the interrupt vector was already occupied by a unique handler.RTEMS_TOO_MANY
The handler specified by
routine
was already installed for the interrupt vector specified byvector
with an argument equal to the argument specified byarg
.RTEMS_UNSATISFIED
The
RTEMS_INTERRUPT_REPLACE
option was set inoptions
and no handler to replace was installed.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
8.4.25. rtems_interrupt_handler_remove()#
Removes the interrupt handler routine and argument from the interrupt vector.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_handler_remove(
rtems_vector_number vector,
rtems_interrupt_handler routine,
void *arg
);
PARAMETERS:
vector
This parameter is the interrupt vector number.
routine
This parameter is the interrupt handler routine to remove.
arg
This parameter is the interrupt handler argument to remove.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INCORRECT_STATE
The service was not initialized.
RTEMS_INVALID_ADDRESS
The
routine
parameter was NULL.RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_CALLED_FROM_ISR
The directive was called from within interrupt context.
RTEMS_UNSATISFIED
There was no handler routine and argument pair installed specified by
routine
andarg
.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
8.4.26. rtems_interrupt_vector_is_enabled()#
Checks if the interrupt vector is enabled.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_vector_is_enabled(
rtems_vector_number vector,
bool *enabled
);
PARAMETERS:
vector
This parameter is the interrupt vector number.
enabled
This parameter is the pointer to a
bool
object. When the directive call is successful, the enabled status of the interrupt associated with the interrupt vector specified byvector
will be stored in this object. When the interrupt was enabled for the processor executing the directive call at some time point during the call, the object value will be set totrue
, otherwise tofalse
.
DESCRIPTION:
The directive checks if the interrupt associated with the interrupt vector specified by vector
was enabled for the processor executing the directive call at some time point during the call.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
enabled
parameter was NULL.RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.
NOTES:
Interrupt vectors may be enabled by rtems_interrupt_vector_enable() and disabled by rtems_interrupt_vector_disable().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
8.4.27. rtems_interrupt_vector_enable()#
Enables the interrupt vector.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_vector_enable( rtems_vector_number vector );
PARAMETERS:
vector
This parameter is the number of the interrupt vector to enable.
DESCRIPTION:
The directive enables the interrupt vector specified by vector
. This allows that interrupt service requests are issued to the target processors of the interrupt vector. Interrupt service requests for an interrupt vector may be raised by rtems_interrupt_raise(), rtems_interrupt_raise_on(), external signals, or messages.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_UNSATISFIED
The request to enable the interrupt vector has not been satisfied.
NOTES:
The rtems_interrupt_get_attributes() directive may be used to check if an interrupt vector can be enabled. Interrupt vectors may be disabled by rtems_interrupt_vector_disable().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
8.4.28. rtems_interrupt_vector_disable()#
Disables the interrupt vector.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_vector_disable( rtems_vector_number vector );
PARAMETERS:
vector
This parameter is the number of the interrupt vector to disable.
DESCRIPTION:
The directive disables the interrupt vector specified by vector
. This prevents that an interrupt service request is issued to the target processors of the interrupt vector.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_UNSATISFIED
The request to disable the interrupt vector has not been satisfied.
NOTES:
The rtems_interrupt_get_attributes() directive may be used to check if an interrupt vector can be disabled. Interrupt vectors may be enabled by rtems_interrupt_vector_enable(). There may be targets on which some interrupt vectors cannot be disabled, for example a hardware watchdog interrupt or software generated interrupts.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
8.4.29. rtems_interrupt_is_pending()#
Checks if the interrupt is pending.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_is_pending(
rtems_vector_number vector,
bool *pending
);
PARAMETERS:
vector
This parameter is the interrupt vector number.
pending
This parameter is the pointer to a
bool
object. When the directive call is successful, the pending status of the interrupt associated with the interrupt vector specified byvector
will be stored in this object. When the interrupt was pending for the processor executing the directive call at some time point during the call, the object value will be set totrue
, otherwise tofalse
.
DESCRIPTION:
The directive checks if the interrupt associated with the interrupt vector specified by vector
was pending for the processor executing the directive call at some time point during the call.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
pending
parameter was NULL.RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_UNSATISFIED
The request to get the pending status has not been satisfied.
NOTES:
Interrupts may be made pending by calling the rtems_interrupt_raise() or rtems_interrupt_raise_on() directives or due to external signals or messages. The pending state may be cleared by rtems_interrupt_clear().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
8.4.30. rtems_interrupt_raise()#
Raises the interrupt vector.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_raise( rtems_vector_number vector );
PARAMETERS:
vector
This parameter is the number of the interrupt vector to raise.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_UNSATISFIED
The request to raise the interrupt vector has not been satisfied.
NOTES:
The rtems_interrupt_get_attributes() directive may be used to check if an interrupt vector can be raised.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
8.4.31. rtems_interrupt_raise_on()#
Raises the interrupt vector on the processor.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_raise_on(
rtems_vector_number vector,
uint32_t cpu_index
);
PARAMETERS:
vector
This parameter is the number of the interrupt vector to raise.
cpu_index
This parameter is the index of the target processor of the interrupt vector to raise.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_NOT_CONFIGURED
The processor specified by
cpu_index
was not configured to be used by the application.RTEMS_INCORRECT_STATE
The processor specified by
cpu_index
was configured to be used by the application, however, it was not online.RTEMS_UNSATISFIED
The request to raise the interrupt vector has not been satisfied.
NOTES:
The rtems_interrupt_get_attributes() directive may be used to check if an interrupt vector can be raised on a processor.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
8.4.32. rtems_interrupt_clear()#
Clears the interrupt vector.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_clear( rtems_vector_number vector );
PARAMETERS:
vector
This parameter is the number of the interrupt vector to clear.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_UNSATISFIED
The request to raise the interrupt vector has not been satisfied.
NOTES:
The rtems_interrupt_get_attributes() directive may be used to check if an interrupt vector can be cleared.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
8.4.33. rtems_interrupt_get_priority()#
Gets the priority of the interrupt vector.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_get_priority(
rtems_vector_number vector,
uint32_t *priority
);
PARAMETERS:
vector
This parameter is the interrupt vector number.
priority
This parameter is the pointer to an uint32_t object. When the directive call is successful, the priority of the interrupt vector will be stored in this object.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
priority
parameter was NULL.RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_UNSATISFIED
There is no priority associated with the interrupt vector.
NOTES:
The rtems_interrupt_set_priority() directive may be used to set the priority associated with an interrupt vector.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
8.4.34. rtems_interrupt_set_priority()#
Sets the priority of the interrupt vector.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_set_priority(
rtems_vector_number vector,
uint32_t priority
);
PARAMETERS:
vector
This parameter is the interrupt vector number.
priority
This parameter is the new priority for the interrupt vector.
DESCRIPTION:
This directive sets the priority of the interrupt specified by vector
to the priority specified by priority
.
For processor-specific interrupts, the priority of the interrupt specific to a processor executing the directive call will be set.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_INVALID_PRIORITY
The priority specified by
priority
was not a valid new priority for the interrupt vector.RTEMS_UNSATISFIED
The request to set the priority of the interrupt vector has not been satisfied.
NOTES:
The rtems_interrupt_get_priority() directive may be used to get the priority associated with an interrupt vector.
The interrupt prioritization support depends on the interrupt controller of the target. It is strongly recommended to read the relevant hardware documentation. What happens when the priority of a pending or active interrupt is changed, depends on the interrupt controller. In general, you should set the interrupt priority of an interrupt vector before a handler is installed. On some interrupt controllers, setting the priority to the maximum value (lowest importance) effectively disables the interrupt.
On some architectures, a range of interrupt priority values may be not disabled by the interrupt disable directives such as rtems_interrupt_disable() and rtems_interrupt_local_disable(). These interrupts are called non-maskable interrupts. Handlers of non-maskable interrupts shall not use operating system services. In addition, non-maskable interrupts may be not installable through rtems_interrupt_entry_install() or rtems_interrupt_handler_install(), and may require architecture-specific prologue and epilogue code.
The interrupt priority settings affect the maximum nesting depth while servicing interrupts. The interrupt stack size calculation needs to take this into account, see also CONFIGURE_INTERRUPT_STACK_SIZE.
For the ARM Generic Interrupt Controller (GIC), an 8-bit priority value is supported. The granularity of the priority levels depends on the interrupt controller configuration. Some low-order bits of a priority value may be read-as-zero (RAZ) and writes are ignored (WI). Where group 0 (FIQ) and group 1 (IRQ) interrupts are used, it is recommended to use the lower half of the supported priority value range for the group 0 interrupts and the upper half for group 1 interrupts. This ensures that group 1 interrupts cannot preempt group 0 interrupts.
For the Armv7-M Nested Vector Interrupt Controller (NVIC), an 8-bit priority value is supported. The granularity of the priority levels depends on the interrupt controller configuration. Some lower bits of a priority value may be read-as-zero (RAZ) and writes are ignored (WI). Interrupts with a priority value less than 128 are not disabled by the RTEMS interrupt disable directives. Handlers of such interrupts shall not use operating system services.
For the RISC-V Platform-Level Interrupt Controller (PLIC), all priority values from 0 up to and including the 0xffffffff are supported since the priority for the PLIC is defined by a write-any-read-legal (WARL) register. Please note that for this directive in contrast to the PLIC, a higher priority value is associated with a lower importance. The maximum priority value (mapped to the value 0 for the PLIC) is reserved to mean “never interrupt” and effectively disables the interrupt.
For the QorIQ Multicore Programmable Interrupt Controller (MPIC), a 4-bit priority value is supported. Please note that for this directive in contrast to the MPIC, a higher priority value is associated with a lower importance. The maximum priority value of 15 (mapped to the value 0 for the MPIC) inhibits signalling of this interrupt.
Consult the RTEMS CPU Architecture Supplement and the BSP documentation in the RTEMS User Manual for further information.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
8.4.35. rtems_interrupt_get_affinity()#
Gets the processor affinity set of the interrupt vector.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_get_affinity(
rtems_vector_number vector,
size_t affinity_size,
cpu_set_t *affinity
);
PARAMETERS:
vector
This parameter is the interrupt vector number.
affinity_size
This parameter is the size of the processor set referenced by
affinity
in bytes.affinity
This parameter is the pointer to a
cpu_set_t
object. When the directive call is successful, the processor affinity set of the interrupt vector will be stored in this object. A set bit in the processor set means that the corresponding processor is in the processor affinity set of the interrupt vector, otherwise the bit is cleared.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
affinity
parameter was NULL.RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_INVALID_SIZE
The size specified by
affinity_size
of the processor set was too small for the processor affinity set of the interrupt vector.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
8.4.36. rtems_interrupt_set_affinity()#
Sets the processor affinity set of the interrupt vector.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_set_affinity(
rtems_vector_number vector,
size_t affinity_size,
const cpu_set_t *affinity
);
PARAMETERS:
vector
This parameter is the interrupt vector number.
affinity_size
This parameter is the size of the processor set referenced by
affinity
in bytes.affinity
This parameter is the pointer to a
cpu_set_t
object. The processor set defines the new processor affinity set of the interrupt vector. A set bit in the processor set means that the corresponding processor shall be in the processor affinity set of the interrupt vector, otherwise the bit shall be cleared.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
affinity
parameter was NULL.RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_INVALID_NUMBER
The referenced processor set was not a valid new processor affinity set for the interrupt vector.
RTEMS_UNSATISFIED
The request to set the processor affinity of the interrupt vector has not been satisfied.
NOTES:
The rtems_interrupt_get_attributes() directive may be used to check if the processor affinity of an interrupt vector can be set.
Only online processors of the affinity set specified by affinity_size
and affinity
are considered by the directive. Other processors of the set are ignored. If the set contains no online processor, then the set is invalid and an error status is returned.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
8.4.37. rtems_interrupt_get_attributes()#
Gets the attributes of the interrupt vector.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_get_attributes(
rtems_vector_number vector,
rtems_interrupt_attributes *attributes
);
PARAMETERS:
vector
This parameter is the interrupt vector number.
attributes
This parameter is the pointer to an rtems_interrupt_attributes object. When the directive call is successful, the attributes of the interrupt vector will be stored in this object.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
attributes
parameter was NULL.RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
8.4.38. rtems_interrupt_handler_iterate()#
Iterates over all interrupt handler installed at the interrupt vector.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_handler_iterate(
rtems_vector_number vector,
rtems_interrupt_per_handler_routine routine,
void *arg
);
PARAMETERS:
vector
This parameter is the interrupt vector number.
routine
This parameter is the visitor routine.
arg
This parameter is the visitor argument.
DESCRIPTION:
For each installed handler at the interrupt vector the visitor function specified by routine
will be called with the argument specified by arg
and the handler information, options, routine and argument.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INCORRECT_STATE
The service was not initialized.
RTEMS_INVALID_ADDRESS
The
routine
parameter was NULL.RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_CALLED_FROM_ISR
The directive was called from within interrupt context.
NOTES:
The directive is intended for system information and diagnostics.
Never install or remove an interrupt handler within the visitor function. This may result in a deadlock.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
8.4.39. rtems_interrupt_server_initialize()#
Initializes the interrupt server tasks.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_server_initialize(
rtems_task_priority priority,
size_t stack_size,
rtems_mode modes,
rtems_attribute attributes,
uint32_t *server_count
);
PARAMETERS:
priority
This parameter is the initial task priority of the created interrupt servers.
stack_size
This parameter is the task stack size of the created interrupt servers.
modes
This parameter is the initial mode set of the created interrupt servers.
attributes
This parameter is the attribute set of the created interrupt servers.
server_count
This parameter is the pointer to an uint32_t object or NULL. When the pointer is not equal to NULL, the count of successfully created interrupt servers is stored in this object regardless of the return status.
DESCRIPTION:
The directive tries to create an interrupt server task for each online processor in the system. The tasks will have the initial priority specified by priority
, the stack size specified by stack_size
, the initial mode set specified by modes
, and the attribute set specified by attributes
. The count of successfully created server tasks will be returned in server_count
if the pointer is not equal to NULL.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INCORRECT_STATE
The interrupt servers were already initialized.
The directive uses rtems_task_create(). If this directive fails, then its error status will be returned.
NOTES:
Interrupt handlers may be installed on an interrupt server with rtems_interrupt_server_handler_install() and removed with rtems_interrupt_server_handler_remove() using a server index. In case of an interrupt, the request will be forwarded to the interrupt server. The handlers are executed within the interrupt server context. If one handler blocks on something this may delay the processing of other handlers.
Interrupt servers may be deleted by rtems_interrupt_server_delete().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
8.4.40. rtems_interrupt_server_create()#
Creates an interrupt server.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_server_create(
rtems_interrupt_server_control *control,
const rtems_interrupt_server_config *config,
uint32_t *server_index
);
PARAMETERS:
control
This parameter is the pointer to an rtems_interrupt_server_control object. When the directive call was successful, the ownership of the object was transferred from the caller of the directive to the interrupt server management.
config
This parameter is the interrupt server configuration.
server_index
This parameter is the pointer to an uint32_t object. When the directive call was successful, the index of the created interrupt server will be stored in this object.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
The directive uses rtems_task_create(). If this directive fails, then its error status will be returned.
NOTES:
See also rtems_interrupt_server_initialize() and rtems_interrupt_server_delete().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
8.4.41. rtems_interrupt_server_handler_install()#
Installs the interrupt handler routine and argument at the interrupt vector on the interrupt server.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_server_handler_install(
uint32_t server_index,
rtems_vector_number vector,
const char *info,
rtems_option options,
rtems_interrupt_handler routine,
void *arg
);
PARAMETERS:
server_index
This parameter is the interrupt server index. The constant
RTEMS_INTERRUPT_SERVER_DEFAULT
may be used to specify the default interrupt server.vector
This parameter is the interrupt vector number.
info
This parameter is the descriptive information of the interrupt handler to install.
options
This parameter is the interrupt handler install option set.
routine
This parameter is the interrupt handler routine to install.
arg
This parameter is the interrupt handler argument to install.
DESCRIPTION:
The handler routine specified by routine
will be executed within the context of the interrupt server task specified by server_index
.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt server associated with the index specified by
server_index
.RTEMS_CALLED_FROM_ISR
The directive was called from within interrupt context.
RTEMS_INVALID_ADDRESS
The
routine
parameter was NULL.RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_INVALID_NUMBER
An option specified by
info
was not applicable.RTEMS_RESOURCE_IN_USE
The
RTEMS_INTERRUPT_UNIQUE
option was set ininfo
and the interrupt vector was already occupied by a handler.RTEMS_RESOURCE_IN_USE
The
RTEMS_INTERRUPT_SHARED
option was set ininfo
and the interrupt vector was already occupied by a unique handler.RTEMS_TOO_MANY
The handler specified by
routine
was already installed for the interrupt vector specified byvector
with an argument equal to the argument specified byarg
.RTEMS_UNSATISFIED
The
RTEMS_INTERRUPT_REPLACE
option was set ininfo
and no handler to replace was installed.
NOTES:
See also rtems_interrupt_handler_install().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
8.4.42. rtems_interrupt_server_handler_remove()#
Removes the interrupt handler routine and argument from the interrupt vector and the interrupt server.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_server_handler_remove(
uint32_t server_index,
rtems_vector_number vector,
rtems_interrupt_handler routine,
void *arg
);
PARAMETERS:
server_index
This parameter is the interrupt server index. The constant
RTEMS_INTERRUPT_SERVER_DEFAULT
may be used to specify the default interrupt server.vector
This parameter is the interrupt vector number.
routine
This parameter is the interrupt handler routine to remove.
arg
This parameter is the interrupt handler argument to remove.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt server associated with the index specified by
server_index
.RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.RTEMS_UNSATISFIED
There was no handler routine and argument pair installed specified by
routine
andarg
.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
The directive sends a request to another task and waits for a response. This may cause the calling task to be blocked and unblocked.
The directive shall not be called from within the context of an interrupt server. Calling the directive from within the context of an interrupt server is undefined behaviour.
8.4.43. rtems_interrupt_server_set_affinity()#
Sets the processor affinity of the interrupt server.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_server_set_affinity(
uint32_t server_index,
size_t affinity_size,
const cpu_set_t *affinity,
rtems_task_priority priority
);
PARAMETERS:
server_index
This parameter is the interrupt server index. The constant
RTEMS_INTERRUPT_SERVER_DEFAULT
may be used to specify the default interrupt server.affinity_size
This parameter is the size of the processor set referenced by
affinity
in bytes.affinity
This parameter is the pointer to a
cpu_set_t
object. The processor set defines the new processor affinity set of the interrupt server. A set bit in the processor set means that the corresponding processor shall be in the processor affinity set of the task, otherwise the bit shall be cleared.priority
This parameter is the new real priority for the interrupt server.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt server associated with the index specified by
server_index
.
The directive uses rtems_scheduler_ident_by_processor_set(), rtems_task_set_scheduler(), and rtems_task_set_affinity(). If one of these directive fails, then its error status will be returned.
NOTES:
The scheduler is set determined by the highest numbered processor in the affinity set specified by affinity
.
This operation is only reliable in case the interrupt server was suspended via rtems_interrupt_server_suspend().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may change the processor affinity of a task. This may cause the calling task to be preempted.
The directive may change the priority of a task. This may cause the calling task to be preempted.
8.4.44. rtems_interrupt_server_delete()#
Deletes the interrupt server.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_server_delete( uint32_t server_index );
PARAMETERS:
server_index
This parameter is the index of the interrupt server to delete.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt server associated with the server index specified by
server_index
.
NOTES:
The interrupt server deletes itself, so after the return of the directive the interrupt server may be still in the termination process depending on the task priorities of the system.
See also rtems_interrupt_server_create().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within task context.
The directive shall not be called from within the context of an interrupt server. Calling the directive from within the context of an interrupt server is undefined behaviour.
The directive sends a request to another task and waits for a response. This may cause the calling task to be blocked and unblocked.
8.4.45. rtems_interrupt_server_suspend()#
Suspends the interrupt server.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_server_suspend( uint32_t server_index );
PARAMETERS:
server_index
This parameter is the index of the interrupt server to suspend. The constant
RTEMS_INTERRUPT_SERVER_DEFAULT
may be used to specify the default interrupt server.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt server associated with the index specified by
server_index
.
NOTES:
Interrupt server may be resumed by rtems_interrupt_server_resume().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within task context.
The directive shall not be called from within the context of an interrupt server. Calling the directive from within the context of an interrupt server is undefined behaviour.
The directive sends a request to another task and waits for a response. This may cause the calling task to be blocked and unblocked.
8.4.46. rtems_interrupt_server_resume()#
Resumes the interrupt server.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_server_resume( uint32_t server_index );
PARAMETERS:
server_index
This parameter is the index of the interrupt server to resume. The constant
RTEMS_INTERRUPT_SERVER_DEFAULT
may be used to specify the default interrupt server.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt server associated with the index specified by
server_index
.
NOTES:
Interrupt server may be suspended by rtems_interrupt_server_suspend().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within task context.
The directive shall not be called from within the context of an interrupt server. Calling the directive from within the context of an interrupt server is undefined behaviour.
The directive sends a request to another task and waits for a response. This may cause the calling task to be blocked and unblocked.
8.4.47. rtems_interrupt_server_move()#
Moves the interrupt handlers installed at the interrupt vector and the source interrupt server to the destination interrupt server.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_server_move(
uint32_t source_server_index,
rtems_vector_number vector,
uint32_t destination_server_index
);
PARAMETERS:
source_server_index
This parameter is the index of the source interrupt server. The constant
RTEMS_INTERRUPT_SERVER_DEFAULT
may be used to specify the default interrupt server.vector
This parameter is the interrupt vector number.
destination_server_index
This parameter is the index of the destination interrupt server. The constant
RTEMS_INTERRUPT_SERVER_DEFAULT
may be used to specify the default interrupt server.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt server associated with the index specified by
source_server_index
.RTEMS_INVALID_ID
There was no interrupt server associated with the index specified by
destination_server_index
.RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within task context.
The directive shall not be called from within the context of an interrupt server. Calling the directive from within the context of an interrupt server is undefined behaviour.
The directive sends a request to another task and waits for a response. This may cause the calling task to be blocked and unblocked.
8.4.48. rtems_interrupt_server_handler_iterate()#
Iterates over all interrupt handler installed at the interrupt vector and interrupt server.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_server_handler_iterate(
uint32_t server_index,
rtems_vector_number vector,
rtems_interrupt_per_handler_routine routine,
void *arg
);
PARAMETERS:
server_index
This parameter is the index of the interrupt server.
vector
This parameter is the interrupt vector number.
routine
This parameter is the visitor routine.
arg
This parameter is the visitor argument.
DESCRIPTION:
For each installed handler at the interrupt vector and interrupt server the visitor function specified by vector
will be called with the argument specified by routine
and the handler information, options, routine and argument.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt server associated with the index specified by
server_index
.RTEMS_INVALID_ID
There was no interrupt vector associated with the number specified by
vector
.
NOTES:
The directive is intended for system information and diagnostics.
Never install or remove an interrupt handler within the visitor function. This may result in a deadlock.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
8.4.49. rtems_interrupt_server_entry_initialize()#
Initializes the interrupt server entry.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_server_entry_initialize(
uint32_t server_index,
rtems_interrupt_server_entry *entry
);
PARAMETERS:
server_index
This parameter is the interrupt server index. The constant
RTEMS_INTERRUPT_SERVER_DEFAULT
may be used to specify the default interrupt server.entry
This parameter is the interrupt server entry to initialize.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt server associated with the index specified by
server_index
.
NOTES:
After initialization, the list of actions of the interrupt server entry is empty. Actions may be prepended by rtems_interrupt_server_action_prepend(). Interrupt server entries may be moved to another interrupt vector with rtems_interrupt_server_entry_move(). Server entries may be submitted to get serviced by the interrupt server with rtems_interrupt_server_entry_submit(). Server entries may be destroyed by rtems_interrupt_server_entry_destroy().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
8.4.50. rtems_interrupt_server_action_prepend()#
Prepends the interrupt server action to the list of actions of the interrupt server entry.
CALLING SEQUENCE:
void rtems_interrupt_server_action_prepend(
rtems_interrupt_server_entry *entry,
rtems_interrupt_server_action *action,
rtems_interrupt_handler routine,
void *arg
);
PARAMETERS:
entry
This parameter is the interrupt server entry to prepend the interrupt server action. It shall have been initialized via rtems_interrupt_server_entry_initialize().
action
This parameter is the interrupt server action to initialize and prepend to the list of actions of the entry.
routine
This parameter is the interrupt handler routine to set in the action.
arg
This parameter is the interrupt handler argument to set in the action.
NOTES:
No error checking is performed by the directive.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
The interrupt server entry shall have been initialized by rtems_interrupt_server_entry_initialize() and further optional calls to rtems_interrupt_server_action_prepend().
The directive shall not be called concurrently with rtems_interrupt_server_action_prepend() with the same interrupt server entry. Calling the directive under this condition is undefined behaviour.
The directive shall not be called concurrently with rtems_interrupt_server_entry_move() with the same interrupt server entry. Calling the directive under this condition is undefined behaviour.
The directive shall not be called concurrently with rtems_interrupt_server_entry_submit() with the same interrupt server entry. Calling the directive under this condition is undefined behaviour.
The directive shall not be called while the interrupt server entry is pending on or serviced by its current interrupt server. Calling the directive under these conditions is undefined behaviour.
8.4.51. rtems_interrupt_server_entry_destroy()#
Destroys the interrupt server entry.
CALLING SEQUENCE:
void rtems_interrupt_server_entry_destroy(
rtems_interrupt_server_entry *entry
);
PARAMETERS:
entry
This parameter is the interrupt server entry to destroy.
NOTES:
No error checking is performed by the directive.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within task context.
The directive shall not be called from within the context of an interrupt server. Calling the directive from within the context of an interrupt server is undefined behaviour.
The directive sends a request to another task and waits for a response. This may cause the calling task to be blocked and unblocked.
The interrupt server entry shall have been initialized by rtems_interrupt_server_entry_initialize() and further optional calls to rtems_interrupt_server_action_prepend().
8.4.52. rtems_interrupt_server_entry_submit()#
Submits the interrupt server entry to be serviced by the interrupt server.
CALLING SEQUENCE:
void rtems_interrupt_server_entry_submit(
rtems_interrupt_server_entry *entry
);
PARAMETERS:
entry
This parameter is the interrupt server entry to submit.
DESCRIPTION:
The directive appends the entry to the pending entries of the interrupt server. The interrupt server is notified that a new entry is pending. Once the interrupt server is scheduled it services the actions of all pending entries.
NOTES:
This directive may be used to do a two-step interrupt processing. The first step is done from within interrupt context by a call to this directive. The second step is then done from within the context of the interrupt server.
No error checking is performed by the directive.
A submitted entry may be destroyed by rtems_interrupt_server_entry_destroy().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may unblock a task. This may cause the calling task to be preempted.
The interrupt server entry shall have been initialized by rtems_interrupt_server_entry_initialize() and further optional calls to rtems_interrupt_server_action_prepend().
The directive shall not be called concurrently with rtems_interrupt_server_action_prepend() with the same interrupt server entry. Calling the directive under this condition is undefined behaviour.
The directive shall not be called concurrently with rtems_interrupt_server_entry_move() with the same interrupt server entry. Calling the directive under this condition is undefined behaviour.
8.4.53. rtems_interrupt_server_entry_move()#
Moves the interrupt server entry to the interrupt server.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_server_entry_move(
rtems_interrupt_server_entry *entry,
uint32_t server_index
);
PARAMETERS:
entry
This parameter is the interrupt server entry to move.
server_index
This parameter is the index of the destination interrupt server. The constant
RTEMS_INTERRUPT_SERVER_DEFAULT
may be used to specify the default interrupt server.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt server associated with the index specified by
server_index
.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
The interrupt server entry shall have been initialized by rtems_interrupt_server_entry_initialize() and further optional calls to rtems_interrupt_server_action_prepend().
The directive shall not be called concurrently with rtems_interrupt_server_action_prepend() with the same interrupt server entry. Calling the directive under this condition is undefined behaviour.
The directive shall not be called concurrently with rtems_interrupt_server_entry_move() with the same interrupt server entry. Calling the directive under this condition is undefined behaviour.
The directive shall not be called concurrently with rtems_interrupt_server_entry_submit() with the same interrupt server entry. Calling the directive under this condition is undefined behaviour.
The directive shall not be called while the interrupt server entry is pending on or serviced by its current interrupt server. Calling the directive under these conditions is undefined behaviour.
8.4.54. rtems_interrupt_server_request_initialize()#
Initializes the interrupt server request.
CALLING SEQUENCE:
rtems_status_code rtems_interrupt_server_request_initialize(
uint32_t server_index,
rtems_interrupt_server_request *request,
rtems_interrupt_handler routine,
void *arg
);
PARAMETERS:
server_index
This parameter is the interrupt server index. The constant
RTEMS_INTERRUPT_SERVER_DEFAULT
may be used to specify the default interrupt server.request
This parameter is the interrupt server request to initialize.
routine
This parameter is the interrupt handler routine for the request action.
arg
This parameter is the interrupt handler argument for the request action.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no interrupt server associated with the index specified by
server_index
.
NOTES:
An interrupt server requests consists of an interrupt server entry and exactly one interrupt server action. The interrupt vector of the request may be changed with rtems_interrupt_server_request_set_vector(). Interrupt server requests may be submitted to get serviced by the interrupt server with rtems_interrupt_server_request_submit(). Requests may be destroyed by rtems_interrupt_server_request_destroy().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
8.4.55. rtems_interrupt_server_request_set_vector()#
Sets the interrupt vector in the interrupt server request.
CALLING SEQUENCE:
void rtems_interrupt_server_request_set_vector(
rtems_interrupt_server_request *request,
rtems_vector_number vector
);
PARAMETERS:
request
This parameter is the interrupt server request to change.
vector
This parameter is the interrupt vector number to be used by the request.
NOTES:
By default, the interrupt vector of an interrupt server request is set to a special value which is outside the range of vectors supported by the interrupt controller hardware.
Calls to rtems_interrupt_server_request_submit() will disable the interrupt vector of the request. After processing of the request by the interrupt server the interrupt vector will be enabled again.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
The interrupt server request shall have been initialized by rtems_interrupt_server_request_initialize().
The directive shall not be called concurrently with rtems_interrupt_server_request_set_vector() with the same interrupt server request. Calling the directive under this condition is undefined behaviour.
The directive shall not be called concurrently with rtems_interrupt_server_request_submit() with the same interrupt server request. Calling the directive under this condition is undefined behaviour.
The directive shall not be called while the interrupt server entry is pending on or serviced by its current interrupt server. Calling the directive under these conditions is undefined behaviour.
8.4.56. rtems_interrupt_server_request_destroy()#
Destroys the interrupt server request.
CALLING SEQUENCE:
void rtems_interrupt_server_request_destroy(
rtems_interrupt_server_request *request
);
PARAMETERS:
request
This parameter is the interrupt server request to destroy.
NOTES:
No error checking is performed by the directive.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within task context.
The directive shall not be called from within the context of an interrupt server. Calling the directive from within the context of an interrupt server is undefined behaviour.
The directive sends a request to another task and waits for a response. This may cause the calling task to be blocked and unblocked.
The interrupt server request shall have been initialized by rtems_interrupt_server_request_initialize().
8.4.57. rtems_interrupt_server_request_submit()#
Submits the interrupt server request to be serviced by the interrupt server.
CALLING SEQUENCE:
void rtems_interrupt_server_request_submit(
rtems_interrupt_server_request *request
);
PARAMETERS:
request
This parameter is the interrupt server request to submit.
DESCRIPTION:
The directive appends the interrupt server entry of the request to the pending entries of the interrupt server. The interrupt server is notified that a new entry is pending. Once the interrupt server is scheduled it services the actions of all pending entries.
NOTES:
This directive may be used to do a two-step interrupt processing. The first step is done from within interrupt context by a call to this directive. The second step is then done from within the context of the interrupt server.
No error checking is performed by the directive.
A submitted request may be destroyed by rtems_interrupt_server_request_destroy().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may unblock a task. This may cause the calling task to be preempted.
The interrupt server request shall have been initialized by rtems_interrupt_server_request_initialize().
The directive shall not be called concurrently with rtems_interrupt_server_request_set_vector() with the same interrupt server request. Calling the directive under this condition is undefined behaviour.
9. Clock Manager#
9.1. Introduction#
The Clock Manager provides support for time of day and other time related capabilities. The directives provided by the Clock Manager are:
rtems_clock_set() - Sets the CLOCK_REALTIME to the time of day.
rtems_clock_get_tod() - Gets the time of day associated with the current CLOCK_REALTIME.
rtems_clock_get_tod_timeval() - Gets the seconds and microseconds elapsed since the Unix epoch and the current CLOCK_REALTIME.
rtems_clock_get_realtime() - Gets the time elapsed since the Unix epoch measured using CLOCK_REALTIME in seconds and nanoseconds format.
rtems_clock_get_realtime_bintime() - Gets the time elapsed since the Unix epoch measured using CLOCK_REALTIME in binary time format.
rtems_clock_get_realtime_timeval() - Gets the time elapsed since the Unix epoch measured using CLOCK_REALTIME in seconds and microseconds format.
rtems_clock_get_realtime_coarse() - Gets the time elapsed since the Unix epoch measured using CLOCK_REALTIME in coarse resolution in seconds and nanoseconds format.
rtems_clock_get_realtime_coarse_bintime() - Gets the time elapsed since the Unix epoch measured using CLOCK_REALTIME in coarse resolution in binary time format.
rtems_clock_get_realtime_coarse_timeval() - Gets the time elapsed since the Unix epoch measured using CLOCK_REALTIME in coarse resolution in seconds and microseconds format.
rtems_clock_get_monotonic() - Gets the time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC in seconds and nanoseconds format.
rtems_clock_get_monotonic_bintime() - Gets the time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC in binary time format.
rtems_clock_get_monotonic_sbintime() - Gets the time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC in signed binary time format.
rtems_clock_get_monotonic_timeval() - Gets the time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC in seconds and microseconds format.
rtems_clock_get_monotonic_coarse() - Gets the time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC in coarse resolution in seconds and nanoseconds format.
rtems_clock_get_monotonic_coarse_bintime() - Gets the time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC in coarse resolution in binary time format.
rtems_clock_get_monotonic_coarse_timeval() - Gets the time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC in coarse resolution in seconds and microseconds format.
rtems_clock_get_boot_time() - Gets the time elapsed since the Unix epoch at some time point during system initialization in seconds and nanoseconds format.
rtems_clock_get_boot_time_bintime() - Gets the time elapsed since the Unix epoch at some time point during system initialization in binary time format.
rtems_clock_get_boot_time_timeval() - Gets the time elapsed since the Unix epoch at some time point during system initialization in seconds and microseconds format.
rtems_clock_get_seconds_since_epoch() - Gets the seconds elapsed since the RTEMS epoch and the current CLOCK_REALTIME.
rtems_clock_get_ticks_per_second() - Gets the number of clock ticks per second configured for the application.
rtems_clock_get_ticks_since_boot() - Gets the number of clock ticks since some time point during the system initialization or the last overflow of the clock tick counter.
rtems_clock_get_uptime() - Gets the seconds and nanoseconds elapsed since some time point during the system initialization using CLOCK_MONOTONIC.
rtems_clock_get_uptime_timeval() - Gets the seconds and microseconds elapsed since some time point during the system initialization using CLOCK_MONOTONIC.
rtems_clock_get_uptime_seconds() - Gets the seconds elapsed since some time point during the system initialization using CLOCK_MONOTONIC.
rtems_clock_get_uptime_nanoseconds() - Gets the nanoseconds elapsed since some time point during the system initialization using CLOCK_MONOTONIC.
rtems_clock_tick_later() - Gets a clock tick value which is at least delta clock ticks in the future.
rtems_clock_tick_later_usec() - Gets a clock tick value which is at least delta microseconds in the future.
rtems_clock_tick_before() - Indicates if the current clock tick counter is before the ticks.
9.2. Background#
9.2.1. Required Support#
For the features provided by the Clock Manager to be utilized, a Clock Driver is required. The Clock Driver usually provides a clock interrupt which is serviced on each configured processor at each clock tick. In addition, the Clock Driver provides three clock sources:
clock tick
The time of these clock sources advances at each clock tick. This yields the time of the clock sources in a coarse resolution. To get the time of the CLOCK_REALTIME
or CLOCK_MONOTONIC
clock sources in a higher resolution, the Clock Driver may use a clock device to get the time between clock ticks.
9.2.2. Time and Date Data Structures#
The clock facilities of the Clock Manager operate upon calendar time. These directives utilize the following date and time structure for the native time and date format:
typedef struct {
uint32_t year; /* greater than 1987 */
uint32_t month; /* 1 - 12 */
uint32_t day; /* 1 - 31 */
uint32_t hour; /* 0 - 23 */
uint32_t minute; /* 0 - 59 */
uint32_t second; /* 0 - 59 */
uint32_t ticks; /* elapsed between seconds */
} rtems_time_of_day;
The native date and time format is the only format supported when setting the system date and time using the rtems_clock_set() directive. Some applications expect to operate on a UNIX-style date and time data structure. For example, the rtems_clock_get_tod_timeval() returns the date and time in struct timeval
format.
Some directives use data structures defined by POSIX. The struct timeval
data structure has two members: tv_sec
and tv_usec
which are seconds and microseconds, respectively. The struct timespec
data structure has two members: tv_sec
and tv_nsec
which are seconds and nanoseconds, respectively. For CLOCK_REALTIME time points, the tv_sec
member in these data structures is the number of seconds since the Unix epoch but will never be prior to the RTEMS epoch.
The struct bintime
and sbintime_t
time formats used by some directives originate in FreeBSD. The struct bintime
data structure which represents time in a binary time format has two members: sec
and frac
which are seconds and fractions of a second in units of \(1 / 2^{64}\) seconds, respectively. The sbintime_t
type is a signed 64-bit integer type used to represent time in units of \(1 / 2^{32}\) seconds.
9.2.3. Clock Tick and Timeslicing#
Timeslicing is a task scheduling discipline in which tasks of equal priority are executed for a specific period of time before control of the CPU is passed to another task. It is also sometimes referred to as the automatic round-robin scheduling algorithm. The length of time allocated to each task is known as the quantum or timeslice.
The system’s timeslice is defined as an integral number of ticks, and is specified by the CONFIGURE_TICKS_PER_TIMESLICE application configuration option. The timeslice is defined for the entire system of tasks, but timeslicing is enabled and disabled on a per task basis.
The clock tick directives implement timeslicing by decrementing the running task’s time-remaining counter when both timeslicing and preemption are enabled. If the task’s timeslice has expired, then that task will be preempted if there exists a ready task of equal priority.
9.2.4. Delays#
A sleep timer allows a task to delay for a given interval or up until a given time, and then wake and continue execution. This type of timer is created automatically by the rtems_task_wake_after() and rtems_task_wake_when() directives and, as a result, does not have an object identifier. Once activated, a sleep timer cannot be explicitly deleted. Each task may activate one and only one sleep timer at a time.
9.2.5. Timeouts#
Timeouts are a special type of timer automatically created when the timeout option is used on the rtems_barrier_wait(), rtems_event_receive(), rtems_message_queue_receive(), rtems_region_get_segment(), and rtems_semaphore_obtain() directives. Each task may have one and only one timeout active at a time. When a timeout expires, it unblocks the task with a timeout status code.
9.3. Operations#
9.3.1. Announcing a Tick#
RTEMS provides the several clock tick directives which are called from the user’s real-time clock ISR to inform RTEMS that a tick has elapsed. Depending on the timer hardware capabilities the clock driver must choose the most appropriate clock tick directive. The tick frequency value, defined in microseconds, is a configuration parameter found in the Configuration Table. RTEMS divides one million microseconds (one second) by the number of microseconds per tick to determine the number of calls to the clock tick directive per second. The frequency of clock tick calls determines the resolution (granularity) for all time dependent RTEMS actions. For example, calling the clock tick directive ten times per second yields a higher resolution than calling the clock tick two times per second. The clock tick directives are responsible for maintaining both calendar time and the dynamic set of timers.
9.3.2. Setting the Time#
The rtems_clock_set
directive allows a task or an ISR to set the date and time maintained by RTEMS. If setting the date and time causes any outstanding timers to pass their deadline, then the expired timers will be fired during the invocation of the rtems_clock_set
directive.
9.3.3. Obtaining the Time#
RTEMS provides multiple directives which can be used by an application to obtain the current date and time or date and time related information. These directives allow a task or an ISR to obtain the current date and time or date and time related information. The current date and time can be returned in either native or UNIX-style format. Additionally, the application can obtain date and time related information such as the number of seconds since the RTEMS epoch, the number of ticks since the executive was initialized, and the number of ticks per second. The following directives are available:
rtems_clock_get_tod
obtain native style date and time
rtems_clock_get_time_value
obtain UNIX-style date and time
rtems_clock_get_ticks_since_boot
obtain number of ticks since RTEMS was initialized
rtems_clock_get_seconds_since_epoch
obtain number of seconds since RTEMS epoch
rtems_clock_get_ticks_per_second
obtain number of clock ticks per second
Calendar time operations will return an error code if invoked before the date and time have been set.
9.3.4. Transition Advice for the Removed rtems_clock_get()#
The directive CLOCK_GET - Get date and time information took an untyped pointer with an options argument to indicate the time information desired. This has been replaced with a set of typed directives:
rtems_clock_get_seconds_since_epoch
rtems_clock_get_ticks_per_second
rtems_clock_get_ticks_since_boot
rtems_clock_get_tod
rtems_clock_get_tod_timeval
These directives directly correspond to what were previously referred to as clock options. These strongly typed directives were available for multiple releases in parallel with rtems_clock_get()
until that directive was removed.
9.4. Directives#
This section details the directives of the Clock Manager. A subsection is dedicated to each of this manager’s directives and lists the calling sequence, parameters, description, return values, and notes of the directive.
9.4.1. rtems_clock_set()#
Sets the CLOCK_REALTIME to the time of day.
CALLING SEQUENCE:
rtems_status_code rtems_clock_set( const rtems_time_of_day *time_of_day );
PARAMETERS:
time_of_day
This parameter is the time of day to set the clock.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
time_of_day
parameter was NULL.RTEMS_INVALID_CLOCK
The time of day specified by
time_of_day
was invalid.
NOTES:
The date, time, and ticks specified by time_of_day
are all range-checked, and an error is returned if any one is out of its valid range.
RTEMS can represent time points of the CLOCK_REALTIME clock in nanoseconds ranging from 1988-01-01T00:00:00.000000000Z to 2514-05-31T01:53:03.999999999Z. The future uptime of the system shall be in this range, otherwise the system behaviour is undefined. Due to implementation constraints, the time of day set by the directive shall be before 2100-01-01:00:00.000000000Z. The latest valid time of day accepted by the POSIX clock_settime() is 2400-01-01T00:00:00.999999999Z.
The specified time is based on the configured clock tick rate, see the CONFIGURE_MICROSECONDS_PER_TICK application configuration option.
Setting the time forward will fire all CLOCK_REALTIME timers which are scheduled at a time point before or at the time set by the directive. This may unblock tasks, which may preempt the calling task. User-provided timer routines will execute in the context of the caller.
It is allowed to call this directive from within interrupt context, however, this is not recommended since an arbitrary number of timers may fire.
The directive shall be called at least once to enable the service of CLOCK_REALTIME related directives. If the clock is not set at least once, they may return an error status.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive may change the priority of a task. This may cause the calling task to be preempted.
The directive may unblock a task. This may cause the calling task to be preempted.
The time of day set by the directive shall be 1988-01-01T00:00:00.000000000Z or later.
The time of day set by the directive shall be before 2100-01-01T00:00:00.000000000Z.
9.4.2. rtems_clock_get_tod()#
Gets the time of day associated with the current CLOCK_REALTIME.
CALLING SEQUENCE:
rtems_status_code rtems_clock_get_tod( rtems_time_of_day *time_of_day );
PARAMETERS:
time_of_day
This parameter is the pointer to an rtems_time_of_day object. When the directive call is successful, the time of day associated with the CLOCK_REALTIME at some point during the directive call will be stored in this object.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
time_of_day
parameter was NULL.RTEMS_NOT_DEFINED
The CLOCK_REALTIME was not set. It can be set with rtems_clock_set().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.3. rtems_clock_get_tod_timeval()#
Gets the seconds and microseconds elapsed since the Unix epoch and the current CLOCK_REALTIME.
CALLING SEQUENCE:
rtems_status_code rtems_clock_get_tod_timeval( struct timeval *time_of_day );
PARAMETERS:
time_of_day
This parameter is the pointer to a struct timeval object. When the directive call is successful, the seconds and microseconds elapsed since the Unix epoch and the CLOCK_REALTIME at some point during the directive call will be stored in this object.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
time_of_day
parameter was NULL.RTEMS_NOT_DEFINED
The CLOCK_REALTIME was not set. It can be set with rtems_clock_set().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.4. rtems_clock_get_realtime()#
Gets the time elapsed since the Unix epoch measured using CLOCK_REALTIME in seconds and nanoseconds format.
CALLING SEQUENCE:
void rtems_clock_get_realtime( struct timespec *time_snapshot );
PARAMETERS:
time_snapshot
This parameter is the pointer to a struct timespec object. The time elapsed since the Unix epoch measured using the CLOCK_REALTIME at some time point during the directive call will be stored in this object. Calling the directive with a pointer equal to NULL is undefined behaviour.
NOTES:
The directive accesses a device provided by the Clock Driver to get the time in the highest resolution available to the system. Alternatively, the rtems_clock_get_realtime_coarse() directive may be used to get the time in a lower resolution and with less runtime overhead.
See rtems_clock_get_realtime_bintime() and rtems_clock_get_realtime_timeval() to get the time in alternative formats.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.5. rtems_clock_get_realtime_bintime()#
Gets the time elapsed since the Unix epoch measured using CLOCK_REALTIME in binary time format.
CALLING SEQUENCE:
void rtems_clock_get_realtime_bintime( struct bintime *time_snapshot );
PARAMETERS:
time_snapshot
This parameter is the pointer to a
struct bintime
object. The time elapsed since the Unix epoch measured using the CLOCK_REALTIME at some time point during the directive call will be stored in this object. Calling the directive with a pointer equal to NULL is undefined behaviour.
NOTES:
The directive accesses a device provided by the Clock Driver to get the time in the highest resolution available to the system. Alternatively, the rtems_clock_get_realtime_coarse_bintime() directive may be used to get the time in a lower resolution and with less runtime overhead.
See rtems_clock_get_realtime() and rtems_clock_get_realtime_timeval() to get the time in alternative formats.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.6. rtems_clock_get_realtime_timeval()#
Gets the time elapsed since the Unix epoch measured using CLOCK_REALTIME in seconds and microseconds format.
CALLING SEQUENCE:
void rtems_clock_get_realtime_timeval( struct timeval *time_snapshot );
PARAMETERS:
time_snapshot
This parameter is the pointer to a struct timeval object. The time elapsed since the Unix epoch measured using the CLOCK_REALTIME at some time point during the directive call will be stored in this object. Calling the directive with a pointer equal to NULL is undefined behaviour.
NOTES:
The directive accesses a device provided by the Clock Driver to get the time in the highest resolution available to the system. Alternatively, the rtems_clock_get_realtime_coarse_timeval() directive may be used to get the time in a lower resolution and with less runtime overhead.
See rtems_clock_get_realtime() and rtems_clock_get_realtime_bintime() to get the time in alternative formats.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.7. rtems_clock_get_realtime_coarse()#
Gets the time elapsed since the Unix epoch measured using CLOCK_REALTIME in coarse resolution in seconds and nanoseconds format.
CALLING SEQUENCE:
void rtems_clock_get_realtime_coarse( struct timespec *time_snapshot );
PARAMETERS:
time_snapshot
This parameter is the pointer to a struct timespec object. The time elapsed since the Unix epoch measured using the CLOCK_REALTIME at some time point close to the directive call will be stored in this object. Calling the directive with a pointer equal to NULL is undefined behaviour.
NOTES:
The directive does not access a device to get the time. It uses a recent snapshot provided by the Clock Driver. Alternatively, the rtems_clock_get_realtime() directive may be used to get the time in a higher resolution and with a higher runtime overhead.
See rtems_clock_get_realtime_coarse_bintime() and rtems_clock_get_realtime_coarse_timeval() to get the time in alternative formats.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.8. rtems_clock_get_realtime_coarse_bintime()#
Gets the time elapsed since the Unix epoch measured using CLOCK_REALTIME in coarse resolution in binary time format.
CALLING SEQUENCE:
void rtems_clock_get_realtime_coarse_bintime( struct bintime *time_snapshot );
PARAMETERS:
time_snapshot
This parameter is the pointer to a
struct bintime
object. The time elapsed since the Unix epoch measured using the CLOCK_REALTIME at some time point close to the directive call will be stored in this object. Calling the directive with a pointer equal to NULL is undefined behaviour.
NOTES:
The directive does not access a device to get the time. It uses a recent snapshot provided by the Clock Driver. Alternatively, the rtems_clock_get_realtime_bintime() directive may be used to get the time in a higher resolution and with a higher runtime overhead.
See rtems_clock_get_realtime_coarse() and rtems_clock_get_realtime_coarse_timeval() to get the time in alternative formats.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.9. rtems_clock_get_realtime_coarse_timeval()#
Gets the time elapsed since the Unix epoch measured using CLOCK_REALTIME in coarse resolution in seconds and microseconds format.
CALLING SEQUENCE:
void rtems_clock_get_realtime_coarse_timeval( struct timeval *time_snapshot );
PARAMETERS:
time_snapshot
This parameter is the pointer to a struct timeval object. The time elapsed since the Unix epoch measured using the CLOCK_REALTIME at some time point close to the directive call will be stored in this object. Calling the directive with a pointer equal to NULL is undefined behaviour.
NOTES:
The directive does not access a device to get the time. It uses a recent snapshot provided by the Clock Driver. Alternatively, the rtems_clock_get_realtime_timeval() directive may be used to get the time in a higher resolution and with a higher runtime overhead.
See rtems_clock_get_realtime_coarse() and rtems_clock_get_realtime_coarse_timeval() to get the time in alternative formats.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.10. rtems_clock_get_monotonic()#
Gets the time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC in seconds and nanoseconds format.
CALLING SEQUENCE:
void rtems_clock_get_monotonic( struct timespec *time_snapshot );
PARAMETERS:
time_snapshot
This parameter is the pointer to a struct timespec object. The time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC at some time point during the directive call will be stored in this object. Calling the directive with a pointer equal to NULL is undefined behaviour.
NOTES:
The directive accesses a device provided by the Clock Driver to get the time in the highest resolution available to the system. Alternatively, the rtems_clock_get_monotonic_coarse() directive may be used to get the time with in a lower resolution and with less runtime overhead.
See rtems_clock_get_monotonic_bintime(), rtems_clock_get_monotonic_sbintime(), and rtems_clock_get_monotonic_timeval() to get the time in alternative formats.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.11. rtems_clock_get_monotonic_bintime()#
Gets the time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC in binary time format.
CALLING SEQUENCE:
void rtems_clock_get_monotonic_bintime( struct bintime *time_snapshot );
PARAMETERS:
time_snapshot
This parameter is the pointer to a
struct bintime
object. The time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC at some time point during the directive call will be stored in this object. Calling the directive with a pointer equal to NULL is undefined behaviour.
NOTES:
The directive accesses a device provided by the Clock Driver to get the time in the highest resolution available to the system. Alternatively, the rtems_clock_get_monotonic_coarse_bintime() directive may be used to get the time in a lower resolution and with less runtime overhead.
See rtems_clock_get_monotonic(), rtems_clock_get_monotonic_sbintime(), and rtems_clock_get_monotonic_timeval() to get the time in alternative formats.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.12. rtems_clock_get_monotonic_sbintime()#
Gets the time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC in signed binary time format.
CALLING SEQUENCE:
int64_t rtems_clock_get_monotonic_sbintime( void );
RETURN VALUES:
Returns the time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC at some time point during the directive call.
NOTES:
The directive accesses a device provided by the Clock Driver to get the time in the highest resolution available to the system.
See rtems_clock_get_monotonic(), rtems_clock_get_monotonic_bintime(), and rtems_clock_get_monotonic_timeval() to get the time in alternative formats.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.13. rtems_clock_get_monotonic_timeval()#
Gets the time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC in seconds and microseconds format.
CALLING SEQUENCE:
void rtems_clock_get_monotonic_timeval( struct timeval *time_snapshot );
PARAMETERS:
time_snapshot
This parameter is the pointer to a struct timeval object. The time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC at some time point during the directive call will be stored in this object. Calling the directive with a pointer equal to NULL is undefined behaviour.
NOTES:
The directive accesses a device provided by the Clock Driver to get the time in the highest resolution available to the system. Alternatively, the rtems_clock_get_monotonic_coarse_timeval() directive may be used to get the time in a lower resolution and with less runtime overhead.
See rtems_clock_get_monotonic(), rtems_clock_get_monotonic_bintime(), and rtems_clock_get_monotonic_sbintime() to get the time in alternative formats.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.14. rtems_clock_get_monotonic_coarse()#
Gets the time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC in coarse resolution in seconds and nanoseconds format.
CALLING SEQUENCE:
void rtems_clock_get_monotonic_coarse( struct timespec *time_snapshot );
PARAMETERS:
time_snapshot
This parameter is the pointer to a struct timespec object. The time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC at some time point close to the directive call will be stored in this object. Calling the directive with a pointer equal to NULL is undefined behaviour.
NOTES:
The directive does not access a device to get the time. It uses a recent snapshot provided by the Clock Driver. Alternatively, the rtems_clock_get_monotonic() directive may be used to get the time in a higher resolution and with a higher runtime overhead.
See rtems_clock_get_monotonic_coarse_bintime() and rtems_clock_get_monotonic_coarse_timeval() to get the time in alternative formats.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.15. rtems_clock_get_monotonic_coarse_bintime()#
Gets the time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC in coarse resolution in binary time format.
CALLING SEQUENCE:
void rtems_clock_get_monotonic_coarse_bintime( struct bintime *time_snapshot );
PARAMETERS:
time_snapshot
This parameter is the pointer to a
struct bintime
object. The time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC at some time point close to the directive call will be stored in this object. Calling the directive with a pointer equal to NULL is undefined behaviour.
NOTES:
The directive does not access a device to get the time. It uses a recent snapshot provided by the Clock Driver. Alternatively, the rtems_clock_get_monotonic_bintime() directive may be used to get the time in a higher resolution and with a higher runtime overhead.
See rtems_clock_get_monotonic_coarse() and rtems_clock_get_monotonic_coarse_timeval() to get the time in alternative formats.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.16. rtems_clock_get_monotonic_coarse_timeval()#
Gets the time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC in coarse resolution in seconds and microseconds format.
CALLING SEQUENCE:
void rtems_clock_get_monotonic_coarse_timeval( struct timeval *time_snapshot );
PARAMETERS:
time_snapshot
This parameter is the pointer to a struct timeval object. The time elapsed since some fixed time point in the past measured using the CLOCK_MONOTONIC at some time point close to the directive call will be stored in this object. Calling the directive with a pointer equal to NULL is undefined behaviour.
NOTES:
The directive does not access a device to get the time. It uses a recent snapshot provided by the Clock Driver. Alternatively, the rtems_clock_get_monotonic_timeval() directive may be used to get the time in a higher resolution and with a higher runtime overhead.
See rtems_clock_get_monotonic_coarse() and rtems_clock_get_monotonic_coarse_bintime() to get the time in alternative formats.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.17. rtems_clock_get_boot_time()#
Gets the time elapsed since the Unix epoch at some time point during system initialization in seconds and nanoseconds format.
CALLING SEQUENCE:
void rtems_clock_get_boot_time( struct timespec *boot_time );
PARAMETERS:
boot_time
This parameter is the pointer to a struct timespec object. The time elapsed since the Unix epoch at some time point during system initialization call will be stored in this object. Calling the directive with a pointer equal to NULL is undefined behaviour.
NOTES:
See rtems_clock_get_boot_time_bintime() and rtems_clock_get_boot_time_timeval() to get the boot time in alternative formats. Setting the CLOCK_REALTIME will also set the boot time.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.18. rtems_clock_get_boot_time_bintime()#
Gets the time elapsed since the Unix epoch at some time point during system initialization in binary time format.
CALLING SEQUENCE:
void rtems_clock_get_boot_time_bintime( struct bintime *boot_time );
PARAMETERS:
boot_time
This parameter is the pointer to a
struct bintime
object. The time elapsed since the Unix epoch at some time point during system initialization call will be stored in this object. Calling the directive with a pointer equal to NULL is undefined behaviour.
NOTES:
See rtems_clock_get_boot_time() and rtems_clock_get_boot_time_timeval() to get the boot time in alternative formats. Setting the CLOCK_REALTIME will also set the boot time.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.19. rtems_clock_get_boot_time_timeval()#
Gets the time elapsed since the Unix epoch at some time point during system initialization in seconds and microseconds format.
CALLING SEQUENCE:
void rtems_clock_get_boot_time_timeval( struct timeval *boot_time );
PARAMETERS:
boot_time
This parameter is the pointer to a struct timeval object. The time elapsed since the Unix epoch at some time point during system initialization call will be stored in this object. Calling the directive with a pointer equal to NULL is undefined behaviour.
NOTES:
See rtems_clock_get_boot_time() and rtems_clock_get_boot_time_bintime() to get the boot time in alternative formats. Setting the CLOCK_REALTIME will also set the boot time.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.20. rtems_clock_get_seconds_since_epoch()#
Gets the seconds elapsed since the RTEMS epoch and the current CLOCK_REALTIME.
CALLING SEQUENCE:
rtems_status_code rtems_clock_get_seconds_since_epoch(
rtems_interval *seconds_since_rtems_epoch
);
PARAMETERS:
seconds_since_rtems_epoch
This parameter is the pointer to an rtems_interval object. When the directive call is successful, the seconds elapsed since the RTEMS epoch and the CLOCK_REALTIME at some point during the directive call will be stored in this object.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
seconds_since_rtems_epoch
parameter was NULL.RTEMS_NOT_DEFINED
The CLOCK_REALTIME was not set. It can be set with rtems_clock_set().
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.21. rtems_clock_get_ticks_per_second()#
Gets the number of clock ticks per second configured for the application.
CALLING SEQUENCE:
rtems_interval rtems_clock_get_ticks_per_second( void );
RETURN VALUES:
Returns the number of clock ticks per second configured for this application.
NOTES:
The number of clock ticks per second is defined indirectly by the CONFIGURE_MICROSECONDS_PER_TICK configuration option.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
9.4.22. rtems_clock_get_ticks_since_boot()#
Gets the number of clock ticks since some time point during the system initialization or the last overflow of the clock tick counter.
CALLING SEQUENCE:
rtems_interval rtems_clock_get_ticks_since_boot( void );
RETURN VALUES:
Returns the number of clock ticks since some time point during the system initialization or the last overflow of the clock tick counter.
NOTES:
With a 1ms clock tick, this counter overflows after 50 days since boot. This is the historical measure of uptime in an RTEMS system. The newer service rtems_clock_get_uptime() is another and potentially more accurate way of obtaining similar information.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
9.4.23. rtems_clock_get_uptime()#
Gets the seconds and nanoseconds elapsed since some time point during the system initialization using CLOCK_MONOTONIC.
CALLING SEQUENCE:
rtems_status_code rtems_clock_get_uptime( struct timespec *uptime );
PARAMETERS:
uptime
This parameter is the pointer to a struct timespec object. When the directive call is successful, the seconds and nanoseconds elapsed since some time point during the system initialization and some point during the directive call using CLOCK_MONOTONIC will be stored in this object.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
uptime
parameter was NULL.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.24. rtems_clock_get_uptime_timeval()#
Gets the seconds and microseconds elapsed since some time point during the system initialization using CLOCK_MONOTONIC.
CALLING SEQUENCE:
void rtems_clock_get_uptime_timeval( struct timeval *uptime );
PARAMETERS:
uptime
This parameter is the pointer to a struct timeval object. The seconds and microseconds elapsed since some time point during the system initialization and some point during the directive call using CLOCK_MONOTONIC will be stored in this object. The pointer shall be valid, otherwise the behaviour is undefined.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.25. rtems_clock_get_uptime_seconds()#
Gets the seconds elapsed since some time point during the system initialization using CLOCK_MONOTONIC.
CALLING SEQUENCE:
time_t rtems_clock_get_uptime_seconds( void );
RETURN VALUES:
Returns the seconds elapsed since some time point during the system initialization and some point during the directive call using CLOCK_MONOTONIC.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.26. rtems_clock_get_uptime_nanoseconds()#
Gets the nanoseconds elapsed since some time point during the system initialization using CLOCK_MONOTONIC.
CALLING SEQUENCE:
uint64_t rtems_clock_get_uptime_nanoseconds( void );
RETURN VALUES:
Returns the nanoseconds elapsed since some time point during the system initialization and some point during the directive call using CLOCK_MONOTONIC.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.27. rtems_clock_tick_later()#
Gets a clock tick value which is at least delta clock ticks in the future.
CALLING SEQUENCE:
rtems_interval rtems_clock_tick_later( rtems_interval delta );
PARAMETERS:
delta
This parameter is the delta value in clock ticks.
RETURN VALUES:
Returns a clock tick counter value which is at least delta
clock ticks in the future.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.28. rtems_clock_tick_later_usec()#
Gets a clock tick value which is at least delta microseconds in the future.
CALLING SEQUENCE:
rtems_interval rtems_clock_tick_later_usec( rtems_interval delta_in_usec );
PARAMETERS:
delta_in_usec
This parameter is the delta value in microseconds.
RETURN VALUES:
Returns a clock tick counter value which is at least delta_in_usec
microseconds in the future.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.4.29. rtems_clock_tick_before()#
Indicates if the current clock tick counter is before the ticks.
CALLING SEQUENCE:
bool rtems_clock_tick_before( rtems_interval ticks );
PARAMETERS:
ticks
This parameter is the ticks value to check.
RETURN VALUES:
Returns true, if current clock tick counter indicates a time before the time in ticks, otherwise returns false.
NOTES:
This directive can be used to write busy loops with a timeout.
1status busy( void )
2{
3 rtems_interval timeout;
4
5 timeout = rtems_clock_tick_later_usec( 10000 );
6
7 do {
8 if ( ok() ) {
9 return success;
10 }
11 } while ( rtems_clock_tick_before( timeout ) );
12
13 return timeout;
14}
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
The directive requires a Clock Driver.
9.5. Removed Directives#
9.5.1. CLOCK_GET - Get date and time information#
Warning
This directive was removed in RTEMS 5.1. See also Transition Advice for the Removed rtems_clock_get().
- CALLING SEQUENCE:
rtems_status_code rtems_clock_get( rtems_clock_get_options option, void *time_buffer );
- DIRECTIVE STATUS CODES:
RTEMS_SUCCESSFUL
current time obtained successfully
RTEMS_NOT_DEFINED
system date and time is not set
RTEMS_INVALID_ADDRESS
time_buffer
is NULL- DESCRIPTION:
This directive obtains the system date and time. If the caller is attempting to obtain the date and time (i.e. option is set to either
RTEMS_CLOCK_GET_SECONDS_SINCE_EPOCH
,RTEMS_CLOCK_GET_TOD
, orRTEMS_CLOCK_GET_TIME_VALUE
) and the date and time has not been set with a previous call tortems_clock_set
, then theRTEMS_NOT_DEFINED
status code is returned. The caller can always obtain the number of ticks per second (option isRTEMS_CLOCK_GET_TICKS_PER_SECOND
) and the number of ticks since the executive was initialized option isRTEMS_CLOCK_GET_TICKS_SINCE_BOOT
).The
option
argument may taken on any value of the enumerated typertems_clock_get_options
. The data type expected fortime_buffer
is based on the value ofoption
as indicated below:Option
Return type
RTEMS_CLOCK_GET_TOD
(rtems_time_of_day *)
RTEMS_CLOCK_GET_SECONDS_SINCE_EPOCH
(rtems_interval *)
RTEMS_CLOCK_GET_TICKS_SINCE_BOOT
(rtems_interval *)
RTEMS_CLOCK_GET_TICKS_PER_SECOND
(rtems_interval *)
RTEMS_CLOCK_GET_TIME_VALUE
(struct timeval *)
- NOTES:
This directive is callable from an ISR.
This directive will not cause the running task to be preempted. Re-initializing RTEMS causes the system date and time to be reset to an uninitialized state. Another call to
rtems_clock_set
is required to re-initialize the system date and time to application specific specifications.
10. Timer Manager#
10.1. Introduction#
The Timer Manager provides support for timer facilities. The directives provided by the Timer Manager are:
rtems_timer_create() - Creates a timer.
rtems_timer_ident() - Identifies a timer by the object name.
rtems_timer_cancel() - Cancels the timer.
rtems_timer_delete() - Deletes the timer.
rtems_timer_fire_after() - Fires the timer after the interval.
rtems_timer_fire_when() - Fires the timer at the time of day.
rtems_timer_initiate_server() - Initiates the Timer Server.
rtems_timer_server_fire_after() - Fires the timer after the interval using the Timer Server.
rtems_timer_server_fire_when() - Fires the timer at the time of day using the Timer Server.
rtems_timer_reset() - Resets the timer.
rtems_timer_get_information() - Gets information about the timer.
10.2. Background#
10.2.1. Required Support#
A clock tick is required to support the functionality provided by this manager.
10.2.2. Timers#
A timer is an RTEMS object which allows the application to schedule operations to occur at specific times in the future. User supplied timer service routines are invoked by either a clock tick directive or a special Timer Server task when the timer fires. Timer service routines may perform any operations or directives which normally would be performed by the application code which invoked a clock tick directive.
The timer can be used to implement watchdog routines which only fire to denote that an application error has occurred. The timer is reset at specific points in the application to ensure that the watchdog does not fire. Thus, if the application does not reset the watchdog timer, then the timer service routine will fire to indicate that the application has failed to reach a reset point. This use of a timer is sometimes referred to as a “keep alive” or a “deadman” timer.
10.2.3. Timer Server#
The Timer Server task is responsible for executing the timer service routines associated with all task-based timers. This task executes at a priority specified by rtems_timer_initiate_server() and it may have a priority of zero (the highest priority). In uniprocessor configurations, it is created non-preemptible.
By providing a mechanism where timer service routines execute in task rather than interrupt space, the application is allowed a bit more flexibility in what operations a timer service routine can perform. For example, the Timer Server can be configured to have a floating point context in which case it would be safe to perform floating point operations from a task-based timer. Most of the time, executing floating point instructions from an interrupt service routine is not considered safe. The timer service routines invoked by the Timer Server may block, however, since this blocks the Timer Server itself, other timer service routines that are already pending do not run until the blocked timer service routine finished its work.
The Timer Server is designed to remain blocked until a task-based timer fires. This reduces the execution overhead of the Timer Server.
10.2.4. Timer Service Routines#
The timer service routine should adhere to C calling conventions and have a prototype similar to the following:
rtems_timer_service_routine user_routine(
rtems_id timer_id,
void *user_data
);
Where the timer_id parameter is the RTEMS object ID of the timer which is being fired and user_data is a pointer to user-defined information which may be utilized by the timer service routine. The argument user_data may be NULL.
10.3. Operations#
10.3.1. Creating a Timer#
The rtems_timer_create
directive creates a timer by allocating a Timer Control Block (TMCB), assigning the timer a user-specified name, and assigning it a timer ID. Newly created timers do not have a timer service routine associated with them and are not active.
10.3.2. Obtaining Timer IDs#
When a timer is created, RTEMS generates a unique timer ID and assigns it to the created timer until it is deleted. The timer ID may be obtained by either of two methods. First, as the result of an invocation of the rtems_timer_create
directive, the timer ID is stored in a user provided location. Second, the timer ID may be obtained later using the rtems_timer_ident
directive. The timer ID is used by other directives to manipulate this timer.
10.3.3. Initiating an Interval Timer#
The rtems_timer_fire_after
and rtems_timer_server_fire_after
directives initiate a timer to fire a user provided timer service routine after the specified number of clock ticks have elapsed. When the interval has elapsed, the timer service routine will be invoked from a clock tick directive if it was initiated by the rtems_timer_fire_after
directive and from the Timer Server task if initiated by the rtems_timer_server_fire_after
directive.
10.3.4. Initiating a Time of Day Timer#
The rtems_timer_fire_when
and rtems_timer_server_fire_when
directive initiate a timer to fire a user provided timer service routine when the specified time of day has been reached. When the interval has elapsed, the timer service routine will be invoked from a clock tick directive by the rtems_timer_fire_when
directive and from the Timer Server task if initiated by the rtems_timer_server_fire_when
directive.
10.3.5. Canceling a Timer#
The rtems_timer_cancel
directive is used to halt the specified timer. Once canceled, the timer service routine will not fire unless the timer is reinitiated. The timer can be reinitiated using the rtems_timer_reset
, rtems_timer_fire_after
, and rtems_timer_fire_when
directives.
10.3.6. Resetting a Timer#
The rtems_timer_reset
directive is used to restore an interval timer initiated by a previous invocation of rtems_timer_fire_after
or rtems_timer_server_fire_after
to its original interval length. If the timer has not been used or the last usage of this timer was by the rtems_timer_fire_when
or rtems_timer_server_fire_when
directive, then an error is returned. The timer service routine is not changed or fired by this directive.
10.3.7. Initiating the Timer Server#
The rtems_timer_initiate_server
directive is used to allocate and start the execution of the Timer Server task. The application can specify both the stack size and attributes of the Timer Server. The Timer Server executes at a priority higher than any application task and thus the user can expect to be preempted as the result of executing the rtems_timer_initiate_server
directive.
10.3.8. Deleting a Timer#
The rtems_timer_delete
directive is used to delete a timer. If the timer is running and has not expired, the timer is automatically canceled. The timer’s control block is returned to the TMCB free list when it is deleted. A timer can be deleted by a task other than the task which created the timer. Any subsequent references to the timer’s name and ID are invalid.
10.4. Directives#
This section details the directives of the Timer Manager. A subsection is dedicated to each of this manager’s directives and lists the calling sequence, parameters, description, return values, and notes of the directive.
10.4.1. rtems_timer_create()#
Creates a timer.
CALLING SEQUENCE:
rtems_status_code rtems_timer_create( rtems_name name, rtems_id *id );
PARAMETERS:
name
This parameter is the object name of the timer.
id
This parameter is the pointer to an rtems_id object. When the directive call is successful, the identifier of the created timer will be stored in this object.
DESCRIPTION:
This directive creates a timer which resides on the local node. The timer has the user-defined object name specified in name
. The assigned object identifier is returned in id
. This identifier is used to access the timer with other timer related directives.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_NAME
The
name
parameter was invalid.RTEMS_INVALID_ADDRESS
The
id
parameter was NULL.RTEMS_TOO_MANY
There was no inactive object available to create a timer. The number of timers available to the application is configured through the CONFIGURE_MAXIMUM_TIMERS application configuration option.
NOTES:
The processor used to maintain the timer is the processor of the calling task at some point during the timer creation.
For control and maintenance of the timer, RTEMS allocates a TMCB from the local TMCB free pool and initializes it.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
The number of timers available to the application is configured through the CONFIGURE_MAXIMUM_TIMERS application configuration option.
Where the object class corresponding to the directive is configured to use unlimited objects, the directive may allocate memory from the RTEMS Workspace.
10.4.2. rtems_timer_ident()#
Identifies a timer by the object name.
CALLING SEQUENCE:
rtems_status_code rtems_timer_ident( rtems_name name, rtems_id *id );
PARAMETERS:
name
This parameter is the object name to look up.
id
This parameter is the pointer to an rtems_id object. When the directive call is successful, the object identifier of an object with the specified name will be stored in this object.
DESCRIPTION:
This directive obtains a timer identifier associated with the timer name specified in name
.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
id
parameter was NULL.RTEMS_INVALID_NAME
The
name
parameter was 0.RTEMS_INVALID_NAME
There was no object with the specified name on the local node.
NOTES:
If the timer name is not unique, then the timer identifier will match the first timer with that name in the search order. However, this timer identifier is not guaranteed to correspond to the desired timer.
The objects are searched from lowest to the highest index. Only the local node is searched.
The timer identifier is used with other timer related directives to access the timer.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within any runtime context.
The directive will not cause the calling task to be preempted.
10.4.3. rtems_timer_cancel()#
Cancels the timer.
CALLING SEQUENCE:
rtems_status_code rtems_timer_cancel( rtems_id id );
PARAMETERS:
id
This parameter is the timer identifier.
DESCRIPTION:
This directive cancels the timer specified by id
. This timer will be reinitiated by the next invocation of rtems_timer_reset(), rtems_timer_fire_after(), rtems_timer_fire_when(), rtems_timer_server_fire_after(), or rtems_timer_server_fire_when() with the same timer identifier.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no timer associated with the identifier specified by
id
.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
10.4.4. rtems_timer_delete()#
Deletes the timer.
CALLING SEQUENCE:
rtems_status_code rtems_timer_delete( rtems_id id );
PARAMETERS:
id
This parameter is the timer identifier.
DESCRIPTION:
This directive deletes the timer specified by id
. If the timer is running, it is automatically canceled.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no timer associated with the identifier specified by
id
.
NOTES:
The TMCB for the deleted timer is reclaimed by RTEMS.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
The calling task does not have to be the task that created the object. Any local task that knows the object identifier can delete the object.
Where the object class corresponding to the directive is configured to use unlimited objects, the directive may free memory to the RTEMS Workspace.
10.4.5. rtems_timer_fire_after()#
Fires the timer after the interval.
CALLING SEQUENCE:
rtems_status_code rtems_timer_fire_after(
rtems_id id,
rtems_interval ticks,
rtems_timer_service_routine_entry routine,
void *user_data
);
PARAMETERS:
id
This parameter is the timer identifier.
ticks
This parameter is the interval until the routine is fired in clock ticks.
routine
This parameter is the routine to schedule.
user_data
This parameter is the argument passed to the routine when it is fired.
DESCRIPTION:
This directive initiates the timer specified by id
. If the timer is running, it is automatically canceled before being initiated. The timer is scheduled to fire after an interval of clock ticks has passed specified by ticks
. When the timer fires, the timer service routine routine
will be invoked with the argument user_data
in the context of the clock tick ISR.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_NUMBER
The
ticks
parameter was 0.RTEMS_INVALID_ADDRESS
The
routine
parameter was NULL.RTEMS_INVALID_ID
There was no timer associated with the identifier specified by
id
.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
10.4.6. rtems_timer_fire_when()#
Fires the timer at the time of day.
CALLING SEQUENCE:
rtems_status_code rtems_timer_fire_when(
rtems_id id,
const rtems_time_of_day *wall_time,
rtems_timer_service_routine_entry routine,
void *user_data
);
PARAMETERS:
id
This parameter is the timer identifier.
wall_time
This parameter is the time of day when the routine is fired.
routine
This parameter is the routine to schedule.
user_data
This parameter is the argument passed to the routine when it is fired.
DESCRIPTION:
This directive initiates the timer specified by id
. If the timer is running, it is automatically canceled before being initiated. The timer is scheduled to fire at the time of day specified by wall_time
. When the timer fires, the timer service routine routine
will be invoked with the argument user_data
in the context of the clock tick ISR.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_NOT_DEFINED
The system date and time was not set.
RTEMS_INVALID_ADDRESS
The
routine
parameter was NULL.RTEMS_INVALID_ADDRESS
The
wall_time
parameter was NULL.RTEMS_INVALID_CLOCK
The time of day was invalid.
RTEMS_INVALID_ID
There was no timer associated with the identifier specified by
id
.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
10.4.7. rtems_timer_initiate_server()#
Initiates the Timer Server.
CALLING SEQUENCE:
rtems_status_code rtems_timer_initiate_server(
rtems_task_priority priority,
size_t stack_size,
rtems_attribute attribute_set
);
PARAMETERS:
priority
This parameter is the task priority.
stack_size
This parameter is the task stack size in bytes.
attribute_set
This parameter is the task attribute set.
DESCRIPTION:
This directive initiates the Timer Server task. This task is responsible for executing all timers initiated via the rtems_timer_server_fire_after() or rtems_timer_server_fire_when() directives.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INCORRECT_STATE
The Timer Server was already initiated.
RTEMS_INVALID_PRIORITY
The task priority was invalid.
RTEMS_TOO_MANY
There was no inactive task object available to create the Timer Server task.
RTEMS_UNSATISFIED
There was not enough memory to allocate the task storage area. The task storage area contains the task stack, the thread-local storage, and the floating point context.
RTEMS_UNSATISFIED
One of the task create extensions failed to create the Timer Server task.
NOTES:
The Timer Server task is created using the rtems_task_create() directive and must be accounted for when configuring the system.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may obtain and release the object allocator mutex. This may cause the calling task to be preempted.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The number of timers available to the application is configured through the CONFIGURE_MAXIMUM_TIMERS application configuration option.
Where the object class corresponding to the directive is configured to use unlimited objects, the directive may allocate memory from the RTEMS Workspace.
10.4.8. rtems_timer_server_fire_after()#
Fires the timer after the interval using the Timer Server.
CALLING SEQUENCE:
rtems_status_code rtems_timer_server_fire_after(
rtems_id id,
rtems_interval ticks,
rtems_timer_service_routine_entry routine,
void *user_data
);
PARAMETERS:
id
This parameter is the timer identifier.
ticks
This parameter is the interval until the routine is fired in clock ticks.
routine
This parameter is the routine to schedule.
user_data
This parameter is the argument passed to the routine when it is fired.
DESCRIPTION:
This directive initiates the timer specified by id
. If the timer is running, it is automatically canceled before being initiated. The timer is scheduled to fire after an interval of clock ticks has passed specified by ticks
. When the timer fires, the timer service routine routine
will be invoked with the argument user_data
in the context of the Timer Server task.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INCORRECT_STATE
The Timer Server was not initiated.
RTEMS_INVALID_NUMBER
The
ticks
parameter was 0.RTEMS_INVALID_ADDRESS
The
routine
parameter was NULL.RTEMS_INVALID_ID
There was no timer associated with the identifier specified by
id
.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
10.4.9. rtems_timer_server_fire_when()#
Fires the timer at the time of day using the Timer Server.
CALLING SEQUENCE:
rtems_status_code rtems_timer_server_fire_when(
rtems_id id,
const rtems_time_of_day *wall_time,
rtems_timer_service_routine_entry routine,
void *user_data
);
PARAMETERS:
id
This parameter is the timer identifier.
wall_time
This parameter is the time of day when the routine is fired.
routine
This parameter is the routine to schedule.
user_data
This parameter is the argument passed to the routine when it is fired.
DESCRIPTION:
This directive initiates the timer specified by id
. If the timer is running, it is automatically canceled before being initiated. The timer is scheduled to fire at the time of day specified by wall_time
. When the timer fires, the timer service routine routine
will be invoked with the argument user_data
in the context of the Timer Server task.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INCORRECT_STATE
The Timer Server was not initiated.
RTEMS_NOT_DEFINED
The system date and time was not set.
RTEMS_INVALID_ADDRESS
The
routine
parameter was NULL.RTEMS_INVALID_ADDRESS
The
wall_time
parameter was NULL.RTEMS_INVALID_CLOCK
The time of day was invalid.
RTEMS_INVALID_ID
There was no timer associated with the identifier specified by
id
.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
10.4.10. rtems_timer_reset()#
Resets the timer.
CALLING SEQUENCE:
rtems_status_code rtems_timer_reset( rtems_id id );
PARAMETERS:
id
This parameter is the timer identifier.
DESCRIPTION:
This directive resets the timer specified by id
. This timer must have been previously initiated with either the rtems_timer_fire_after() or rtems_timer_server_fire_after() directive. If active the timer is canceled, after which the timer is reinitiated using the same interval and timer service routine which the original rtems_timer_fire_after() or rtems_timer_server_fire_after() directive used.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ID
There was no timer associated with the identifier specified by
id
.RTEMS_NOT_DEFINED
The timer was not of the interval class.
NOTES:
If the timer has not been used or the last usage of this timer was by a rtems_timer_fire_when() or rtems_timer_server_fire_when() directive, then the RTEMS_NOT_DEFINED
error is returned.
Restarting a cancelled after timer results in the timer being reinitiated with its previous timer service routine and interval.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
10.4.11. rtems_timer_get_information()#
Gets information about the timer.
CALLING SEQUENCE:
rtems_status_code rtems_timer_get_information(
rtems_id id,
rtems_timer_information *the_info
);
PARAMETERS:
id
This parameter is the timer identifier.
the_info
This parameter is the pointer to an rtems_timer_information object. When the directive call is successful, the information about the timer will be stored in this object.
DESCRIPTION:
This directive returns information about the timer.
RETURN VALUES:
RTEMS_SUCCESSFUL
The requested operation was successful.
RTEMS_INVALID_ADDRESS
The
the_info
parameter was NULL.RTEMS_INVALID_ID
There was no timer associated with the identifier specified by
id
.
CONSTRAINTS:
The following constraints apply to this directive:
The directive may be called from within interrupt context.
The directive may be called from within device driver initialization context.
The directive may be called from within task context.
The directive will not cause the calling task to be preempted.
11. Rate Monotonic Manager#
11.1. Introduction#
The Rate-Monotonic Manager provides facilities to implement tasks which execute in a periodic fashion. Critically, it also gathers information about the execution of those periods and can provide important statistics to the user which can be used to analyze and tune the application. The directives provided by the Rate-Monotonic Manager are:
rtems_rate_monotonic_create() - Creates a period.
rtems_rate_monotonic_ident() - Identifies a period by the object name.
rtems_rate_monotonic_cancel() - Cancels the period.
rtems_rate_monotonic_delete() - Deletes the period.
rtems_rate_monotonic_period() - Concludes the current period and start the next period, or gets the period status.
rtems_rate_monotonic_get_status() - Gets the detailed status of the period.
rtems_rate_monotonic_get_statistics() - Gets the statistics of the period.
rtems_rate_monotonic_reset_statistics() - Resets the statistics of the period.
rtems_rate_monotonic_reset_all_statistics() - Resets the statistics of all periods.
rtems_rate_monotonic_report_statistics() - Reports the period statistics using the printk() printer.
rtems_rate_monotonic_report_statistics_with_plugin() - Reports the period statistics using the printer plugin.
11.2. Background#
The rate monotonic manager provides facilities to manage the execution of periodic tasks. This manager was designed to support application designers who utilize the Rate Monotonic Scheduling Algorithm (RMS) to ensure that their periodic tasks will meet their deadlines, even under transient overload conditions. Although designed for hard real-time systems, the services provided by the rate monotonic manager may be used by any application which requires periodic tasks.
11.2.1. Rate Monotonic Manager Required Support#
A clock tick is required to support the functionality provided by this manager.
11.2.2. Period Statistics#
This manager maintains a set of statistics on each period object. These statistics are reset implictly at period creation time and may be reset or obtained at any time by the application. The following is a list of the information kept:
owner
is the id of the thread that owns this period.
count
is the total number of periods executed.
missed_count
is the number of periods that were missed.
min_cpu_time
is the minimum amount of CPU execution time consumed on any execution of the periodic loop.
max_cpu_time
is the maximum amount of CPU execution time consumed on any execution of the periodic loop.
total_cpu_time
is the total amount of CPU execution time consumed by executions of the periodic loop.
min_wall_time
is the minimum amount of wall time that passed on any execution of the periodic loop.
max_wall_time
is the maximum amount of wall time that passed on any execution of the periodic loop.
total_wall_time
is the total amount of wall time that passed during executions of the periodic loop.
Each period is divided into two consecutive phases. The period starts with the active phase of the task and is followed by the inactive phase of the task. In the inactive phase the task is blocked and waits for the start of the next period. The inactive phase is skipped in case of a period miss. The wall time includes the time during the active phase of the task on which the task is not executing on a processor. The task is either blocked (for example it waits for a resource) or a higher priority tasks executes, thus preventing it from executing. In case the wall time exceeds the period time, then this is a period miss. The gap between the wall time and the period time is the margin between a period miss or success.
The period statistics information is inexpensive to maintain and can provide very useful insights into the execution characteristics of a periodic task loop. But it is just information. The period statistics reported must be analyzed by the user in terms of what the applications is. For example, in an application where priorities are assigned by the Rate Monotonic Algorithm, it would be very undesirable for high priority (i.e. frequency) tasks to miss their period. Similarly, in nearly any application, if a task were supposed to execute its periodic loop every 10 milliseconds and it averaged 11 milliseconds, then application requirements are not being met.
The information reported can be used to determine the “hot spots” in the application. Given a period’s id, the user can determine the length of that period. From that information and the CPU usage, the user can calculate the percentage of CPU time consumed by that periodic task. For example, a task executing for 20 milliseconds every 200 milliseconds is consuming 10 percent of the processor’s execution time. This is usually enough to make it a good candidate for optimization.
However, execution time alone is not enough to gauge the value of optimizing a particular task. It is more important to optimize a task executing 2 millisecond every 10 milliseconds (20 percent of the CPU) than one executing 10 milliseconds every 100 (10 percent of the CPU). As a general rule of thumb, the higher frequency at which a task executes, the more important it is to optimize that task.
11.2.3. Periodicity Definitions#
A periodic task is one which must be executed at a regular interval. The interval between successive iterations of the task is referred to as its period. Periodic tasks can be characterized by the length of their period and execution time. The period and execution time of a task can be used to determine the processor utilization for that task. Processor utilization is the percentage of processor time used and can be calculated on a per-task or system-wide basis. Typically, the task’s worst-case execution time will be less than its period. For example, a periodic task’s requirements may state that it should execute for 10 milliseconds every 100 milliseconds. Although the execution time may be the average, worst, or best case, the worst-case execution time is more appropriate for use when analyzing system behavior under transient overload conditions.
In contrast, an aperiodic task executes at irregular intervals and has only a soft deadline. In other words, the deadlines for aperiodic tasks are not rigid, but adequate response times are desirable. For example, an aperiodic task may process user input from a terminal.
Finally, a sporadic task is an aperiodic task with a hard deadline and minimum interarrival time. The minimum interarrival time is the minimum period of time which exists between successive iterations of the task. For example, a sporadic task could be used to process the pressing of a fire button on a joystick. The mechanical action of the fire button ensures a minimum time period between successive activations, but the missile must be launched by a hard deadline.
11.2.4. Rate Monotonic Scheduling Algorithm#
The Rate Monotonic Scheduling Algorithm (RMS) is important to real-time systems designers because it allows one to sufficiently guarantee that a set of tasks is schedulable (see [LL73], [LSD89], [SG90], [Bur91]).
A set of tasks is said to be schedulable if all of the tasks can meet their deadlines. RMS provides a set of rules which can be used to perform a guaranteed schedulability analysis for a task set. This analysis determines whether a task set is schedulable under worst-case conditions and emphasizes the predictability of the system’s behavior. It has been proven that:
RMS is optimal in the sense that if a set of tasks can be scheduled by any fixed-priority algorithm, then RMS will be able to schedule that task set. RMS bases it schedulability analysis on the processor utilization level below which all deadlines can be met.
RMS calls for the static assignment of task priorities based upon their period. The shorter a task’s period, the higher its priority. For example, a task with a 1 millisecond period has higher priority than a task with a 100 millisecond period. If two tasks have the same period, then RMS does not distinguish between the tasks. However, RTEMS specifies that when given tasks of equal priority, the task which has been ready longest will execute first. RMS’s priority assignment scheme does not provide one with exact numeric values for task priorities. For example, consider the following task set and priority assignments:
Task | Period (in milliseconds) | Priority |
---|---|---|
1 | 100 | Low |
2 | 50 | Medium |
3 | 50 | Medium |
4 | 25 | High |
RMS only calls for task 1 to have the lowest priority, task 4 to have the highest priority, and tasks 2 and 3 to have an equal priority between that of tasks 1 and 4. The actual RTEMS priorities assigned to the tasks must only adhere to those guidelines.
Many applications have tasks with both hard and soft deadlines. The tasks with hard deadlines are typically referred to as the critical task set, with the soft deadline tasks being the non-critical task set. The critical task set can be scheduled using RMS, with the non-critical tasks not executing under transient overload, by simply assigning priorities such that the lowest priority critical task (i.e. longest period) has a higher priority than the highest priority non-critical task. Although RMS may be used to assign priorities to the non-critical tasks, it is not necessary. In this instance, schedulability is only guaranteed for the critical task set.
11.2.5. Schedulability Analysis#
RMS allows application designers to ensure that tasks can meet all deadlines under fixed-priority assignment, even under transient overload, without knowing exactly when any given task will execute by applying proven schedulability analysis rules.
11.2.5.1. Assumptions#
The schedulability analysis rules for RMS were developed based on the following assumptions:
The requests for all tasks for which hard deadlines exist are periodic, with a constant interval between requests.
Each task must complete before the next request for it occurs.
The tasks are independent in that a task does not depend on the initiation or completion of requests for other tasks.
The execution time for each task without preemption or interruption is constant and does not vary.
Any non-periodic tasks in the system are special. These tasks should not displace periodic tasks while executing and do not have hard, critical deadlines.
Once the basic schedulability analysis is understood, some of the above assumptions can be relaxed and the side-effects accounted for.
11.2.5.2. Processor Utilization Rule#
The Processor Utilization Rule requires that processor utilization be calculated based upon the period and execution time of each task. The fraction of processor time spent executing task index is Time(i) / Period(i)
. The processor utilization can be calculated as follows where n is the number of tasks in the set being analyzed:
To ensure schedulability even under transient overload, the processor utilization must adhere to the following rule:
As the number of tasks increases, the above formula approaches ln(2) for a worst-case utilization factor of approximately 0.693. Many tasks sets can be scheduled with a greater utilization factor. In fact, the average processor utilization threshold for a randomly generated task set is approximately 0.88. See more detail in [LL73].
11.2.5.3. Processor Utilization Rule Example#
This example illustrates the application of the Processor Utilization Rule to an application with three critical periodic tasks. The following table details the RMS priority, period, execution time, and processor utilization for each task:
Task | RMS Priority | Period | Execution Time | Processor Utilization |
---|---|---|---|---|
1 | High | 100 | 15 | 0.15 |
2 | Medium | 200 | 50 | 0.25 |
3 | Low | 300 | 100 | 0.33 |
The total processor utilization for this task set is 0.73 which is below the upper bound of 3 * (2**(1/3) - 1), or 0.779, imposed by the Processor Utilization Rule. Therefore, this task set is guaranteed to be schedulable using RMS.
11.2.5.4. First Deadline Rule#
If a given set of tasks do exceed the processor utilization upper limit imposed by the Processor Utilization Rule, they can still be guaranteed to meet all their deadlines by application of the First Deadline Rule. This rule can be stated as follows:
For a given set of independent periodic tasks, if each task meets its first deadline when all tasks are started at the same time, then the deadlines will always be met for any combination of start times.
A key point with this rule is that ALL periodic tasks are assumed to start at the exact same instant in time. Although this assumption may seem to be invalid, RTEMS makes it quite easy to ensure. By having a non-preemptible user initialization task, all application tasks, regardless of priority, can be created and started before the initialization deletes itself. This technique ensures that all tasks begin to compete for execution time at the same instant - when the user initialization task deletes itself. See more detail in [LSD89].
11.2.5.5. First Deadline Rule Example#
The First Deadline Rule can ensure schedulability even when the Processor Utilization Rule fails. The example below is a modification of the Processor Utilization Rule example where task execution time has been increased from 15 to 25 units. The following table details the RMS priority, period, execution time, and processor utilization for each task:
Task | RMS Priority | Period | Execution Time | Processor Utilization |
---|---|---|---|---|
1 | High | 100 | 25 | 0.25 |
2 | Medium | 200 | 50 | 0.25 |
3 | Low | 300 | 100 | 0.33 |
The total processor utilization for the modified task set is 0.83 which is above the upper bound of 3 * (2**(1/3) - 1), or 0.779, imposed by the Processor Utilization Rule. Therefore, this task set is not guaranteed to be schedulable using RMS. However, the First Deadline Rule can guarantee the schedulability of this task set. This rule calls for one to examine each occurrence of deadline until either all tasks have met their deadline or one task failed to meet its first deadline. The following table details the time of each deadline occurrence, the maximum number of times each task may have run, the total execution time, and whether all the deadlines have been met:
Deadline Time | Task 1 | Task 2 | Task 3 | Total Execution Time | All Deadlines Met? |
---|---|---|---|---|---|
100 | 1 | 1 | 1 | 25 + 50 + 100 = 175 | NO |
200 | 2 | 1 | 1 | 50 + 50 + 100 = 200 | YES |
The key to this analysis is to recognize when each task will execute. For example at time 100, task 1 must have met its first deadline, but tasks 2 and 3 may also have begun execution. In this example, at time 100 tasks 1 and 2 have completed execution and thus have met their first deadline. Tasks 1 and 2 have used (25 + 50) = 75 time units, leaving (100 - 75) = 25 time units for task 3 to begin. Because task 3 takes 100 ticks to execute, it will not have completed execution at time 100. Thus at time 100, all of the tasks except task 3 have met their first deadline.
At time 200, task 1 must have met its second deadline and task 2 its first deadline. As a result, of the first 200 time units, task 1 uses (2 * 25) = 50 and task 2 uses 50, leaving (200 - 100) time units for task 3. Task 3 requires 100 time units to execute, thus it will have completed execution at time 200. Thus, all of the tasks have met their first deadlines at time 200, and the task set is schedulable using the First Deadline Rule.
11.2.5.6. Relaxation of Assumptions#
The assumptions used to develop the RMS schedulability rules are uncommon in most real-time systems. For example, it was assumed that tasks have constant unvarying execution time. It is possible to relax this assumption, simply by using the worst-case execution time of each task.
Another assumption is that the tasks are independent. This means that the tasks do not wait for one another or contend for resources. This assumption can be relaxed by accounting for the amount of time a task spends waiting to acquire resources. Similarly, each task’s execution time must account for any I/O performed and any RTEMS directive calls.
In addition, the assumptions did not account for the time spent executing interrupt service routines. This can be accounted for by including all the processor utilization by interrupt service routines in the utilization calculation. Similarly, one should also account for the impact of delays in accessing local memory caused by direct memory access and other processors accessing local dual-ported memory.
The assumption that nonperiodic tasks are used only for initialization or failure-recovery can be relaxed by placing all periodic tasks in the critical task set. This task set can be scheduled and analyzed using RMS. All nonperiodic tasks are placed in the non-critical task set. Although the critical task set can be guaranteed to execute even under transient overload, the non-critical task set is not guaranteed to execute.
In conclusion, the application designer must be fully cognizant of the system and its run-time behavior when performing schedulability analysis for a system using RMS. Every hardware and software factor which impacts the execution time of each task must be accounted for in the schedulability analysis.
11.3. Operations#
11.3.1. Creating a Rate Monotonic Period#
The rtems_rate_monotonic_create
directive creates a rate monotonic period which is to be used by the calling task to delineate a period. RTEMS allocates a Period Control Block (PCB) from the PCB free list. This data structure is used by RTEMS to manage the newly created rate monotonic period. RTEMS returns a unique period ID to the application which is used by other rate monotonic manager directives to access this rate monotonic period.
11.3.2. Manipulating a Period#
The rtems_rate_monotonic_period
directive is used to establish and maintain periodic execution utilizing a previously created rate monotonic period. Once initiated by the rtems_rate_monotonic_period
directive, the period is said to run until it either expires or is reinitiated. The state of the rate monotonic period results in one of the following scenarios:
If the rate monotonic period is running, the calling task will be blocked for the remainder of the outstanding period and, upon completion of that period, the period will be reinitiated with the specified period.
If the rate monotonic period is not currently running and has not expired, it is initiated with a length of period ticks and the calling task returns immediately.
If the rate monotonic period has expired before the task invokes the
rtems_rate_monotonic_period
directive, the postponed job will be released until there is no more postponed jobs. The calling task returns immediately with a timeout error status. In the watchdog routine, the period will still be updated periodically and track the count of the postponed jobs [CvdBruggenC16]. Please note, the count of the postponed jobs is only saturated until 0xffffffff.
11.3.3. Obtaining the Status of a Period#
If the rtems_rate_monotonic_period
directive is invoked with a period of RTEMS_PERIOD_STATUS
ticks, the current state of the specified rate monotonic period will be returned. The following table details the relationship between the period’s status and the directive status code returned by the rtems_rate_monotonic_period
directive:
| period is running |
| period has expired |
| period has never been initiated |
Obtaining the status of a rate monotonic period does not alter the state or length of that period.
11.3.4. Canceling a Period#
The rtems_rate_monotonic_cancel
directive is used to stop the period maintained by the specified rate monotonic period. The period is stopped and the rate monotonic period can be reinitiated using the rtems_rate_monotonic_period
directive.
11.3.5. Deleting a Rate Monotonic Period#
The rtems_rate_monotonic_delete
directive is used to delete a rate monotonic period. If the period is running and has not expired, the period is automatically canceled. The rate monotonic period’s control block is returned to the PCB free list when it is deleted. A rate monotonic period can be deleted by a task other than the task which created the period.
11.3.6. Examples#
The following sections illustrate common uses of rate monotonic periods to construct periodic tasks.
11.3.7. Simple Periodic Task#
This example consists of a single periodic task which, after initialization, executes every 100 clock ticks.
1rtems_task Periodic_task(rtems_task_argument arg)
2{
3 rtems_name name;
4 rtems_id period;
5 rtems_status_code status;
6 name = rtems_build_name( 'P', 'E', 'R', 'D' );
7 status = rtems_rate_monotonic_create( name, &period );
8 if ( status != RTEMS_SUCCESSFUL ) {
9 printf( "rtems_monotonic_create failed with status of %d.\n", status );
10 exit( 1 );
11 }
12 while ( 1 ) {
13 if ( rtems_rate_monotonic_period( period, 100 ) == RTEMS_TIMEOUT )
14 break;
15 /* Perform some periodic actions */
16 }
17 /* missed period so delete period and SELF */
18 status = rtems_rate_monotonic_delete( period );
19 if ( status != RTEMS_SUCCESSFUL ) {
20 printf( "rtems_rate_monotonic_delete failed with status of %d.\n", status );
21 exit( 1 );
22 }
23 status = rtems_task_delete( RTEMS_SELF ); /* should not return */
24 printf( "rtems_task_delete returned with status of %d.\n", status );
25 exit( 1 );
26}
The above task creates a rate monotonic period as part of its initialization. The first time the loop is executed, the rtems_rate_monotonic_period
directive will initiate the period for 100 ticks and return immediately. Subsequent invocations of the rtems_rate_monotonic_period
directive will result in the task blocking for the remainder of the 100 tick period. If, for any reason, the body of the loop takes more than 100 ticks to execute, the rtems_rate_monotonic_period
directive will return the RTEMS_TIMEOUT
status. If the above task misses its deadline, it will delete the rate monotonic period and itself.
11.3.8. Task with Multiple Periods#
This example consists of a single periodic task which, after initialization, performs two sets of actions every 100 clock ticks. The first set of actions is performed in the first forty clock ticks of every 100 clock ticks, while the second set of actions is performed between the fortieth and seventieth clock ticks. The last thirty clock ticks are not used by this task.
1rtems_task Periodic_task(rtems_task_argument arg)
2{
3 rtems_name name_1, name_2;
4 rtems_id period_1, period_2;
5 name_1 = rtems_build_name( 'P', 'E', 'R', '1' );
6 name_2 = rtems_build_name( 'P', 'E', 'R', '2' );
7 (void ) rtems_rate_monotonic_create( name_1, &period_1 );
8 (void ) rtems_rate_monotonic_create( name_2, &period_2 );
9 while ( 1 ) {
10 if ( rtems_rate_monotonic_period( period_1, 100 ) == RTEMS_TIMEOUT )
11 break;
12 if ( rtems_rate_monotonic_period( period_2, 40 ) == RTEMS_TIMEOUT )
13 break;
14 /*
15 * Perform first set of actions between clock
16 * ticks 0 and 39 of every 100 ticks.
17 */
18 if ( rtems_rate_monotonic_period( period_2, 30 ) == RTEMS_TIMEOUT )
19 break;
20 /*
21 * Perform second set of actions between clock 40 and 69
22 * of every 100 ticks. THEN ...
23 *
24 * Check to make sure we didn't miss the period_2 period.
25 */
26 if ( rtems_rate_monotonic_period( period_2, RTEMS_PERIOD_STATUS ) == RTEMS_TIMEOUT )
27 break;
28