Exponential improvements in hardware capacity made possible by Moore’s Law have substantially expanded the size and complexity of embedded-system software. For many embedded software products, the amount of software deployed in each new revision of the product doubles every 18 to 36 months. The challenges of managing this rapid expansion of software size require innovative approaches and improved software engineering disciplines.
One key to tackling the growing size and complexity of modern embedded-system software is to divide these large systems into many smaller components, each isolated from its neighbors by abstract encapsulation and isolation barriers. These barriers assure each component’s developers that other components won't interfere with correct operation.
The general strategy of using divide-and-conquer to managing software complexity is a fundamental tenet of software engineering. However, its relevance to embedded and real-time software has, until recently, not been fully appreciated. There are two reasons for this circumstance:
- Most embedded systems are much smaller than their desktop and “mainframe” counterparts.
- Many early attempts to adopt object-oriented encapsulation and isolation disciplines from the mainstream (non-embedded) software engineering community overlooked the reality that embedded real-time software engineering has special needs that aren't adequately served by mainstream abstractions.
In particular, developers of non-embedded software are almost always told to ignore resource constraint issues in order to focus on functional correctness, generality, and ease of software maintenance. However, developers of embedded real-time software can't ignore these issues. They are precisely what make development and maintenance of embedded real-time software so much more challenging.
For this reason, it's essential that the encapsulation and isolation mechanisms in effective embedded real-time software engineering assist developers with isolating and encapsulating resource constraint issues at the level of abstraction required by each component developer. This article describes some of the mechanisms available to assist developers of embedded real-time Java software with these challenges.
In typical embedded real-time software systems, each critical software component represents different requirements and tradeoffs. For developers who use Java in their real-time embedded system design, it's necessary to carefully balance hard real-time versus soft real-time performance with the tradeoffs to achieve specific goals.
Hard real-time constraints are those for which an action performed at the wrong time will have zero or possibly negative value. The connotation of “hard real-time” is that compliance with all timing constraints is proven using theoretical static analysis techniques prior to deployment. Soft real-time constraints are those for which an action performed at the wrong time (either too early or too late) has some positive value even though it would have had greater value if performed at the proper time. The expectation is that soft real-time systems use empirical (statistical) measurements and heuristic enforcement of resource budgets to improve the likelihood that software complies with timing constraints.
Note that the difference between hard real-time and soft real-time doesn't depend on the time ranges specified for deadlines or periodic tasks. A soft real-time system might have a deadline of 100 µs, while a hard real-time system's deadline may be 3 seconds.
Satisfying real-time constraints in high-assurance Java applications is possible. Here, the developer must recognize the strengths and weaknesses of particular Java methodologies, such as automatic garbage collection, and carefully select the most appropriate mechanisms to address each particular system requirement. For those pursuing use of the Java language to improve developer productivity and decrease the costs of software maintenance, a collection of recommendations can be found in “Draft Guidelines for Scalable Java Development of Real-Time Systems,” authored by Kelvin Nilsen (http://research.aonix.com/jsc/rtjava.guidelines.5-6-05.pdf).
Practically speaking, guidelines for soft real-time Java development are usually preferred, unless there's a specific constraint that precludes them. This is because soft real-time Java offers the best developer and software maintenance productivity. Guidelines for soft real-time Java involve the use of traditional JSE-style Java APIs with virtual machines that are specially implemented to support real-time behavior. These virtual machines support preemptible and incremental real-time garbage collection, fixed priority scheduling, and priority inheritance in the implementation of all synchronization locks.
In contrast, hard real-time Java technologies don't employ automatic garbage collection. Instead, dynamic memory is allocated and deallocated under more explicit programmer control. The hard real-time Java guidelines enable deployments that run up to three times faster in less than a tenth the memory required by traditional Java implementations. Furthermore, deterministic response latencies are over a thousand times better. For safety-critical development, Java programmers use a restricted subset of the hard real-time technologies.