As expected, my article on “Embedded C Bashing” generated some discussion. So, I thought I better call in some experts to provide advice when it comes to safety and performance.
The performance of compilers for languages like Java and C# has improved to where code generated for adding a pair of integers winds up being a single instruction. Features such as ahead-of-time (AOT) versus just-in-time (JIT) compilation allow Java to be used to address real-time applications.
JSR-001, Real Time Java Specification (RTSJ), is a large and cumbersome standard that addresses just about any real-time configuration imaginable. It includes various types of scheduling for the restricted use of memory that allows the elimination of the garbage collector for time-critical, hard real-time applications with NoHeapRealtimeThreads. So, memory allocation is either static or on the stack. In return, a number of traditional Java run-time checks can be omitted, increasing performance.
TAKING OUT THE GARBAGE
Garbage collection support can address many hard real-time applications. The key is predictability. Products like Aonix’s Perc Ultra and DDC-I’s Scorpion implement incremental garbage collection with fixed, distributed overhead that can be tuned. This enables the dynamic memory management issue to be controlled even better than with a C/C++ environment.
Garbage collection is split up the same way as interrupt and time slice support for threads, allowing it to stay ahead of the system’s dynamic memory requirements versus the typical stop-and-collect scenario that isn’t appreciated in real-time applications.
Ole Oest, CTO at DDC-I, notes that Scorpion’s patented real-time garbage collector performs its work time-bound and within the application threads. There is no separate garbage collection thread. The incremental amount of garbage collection work done in each step has an upper bound that can be calculated by the application’s designer. The allocating thread “pays” for the memory by performing a small number of garbage collection steps. The number of steps required can be analyzed to determine the worst-case number of steps required.
Scorpion allows application threads, RealtimeThreads, and NoHeapRealtimeThreads to share memory, giving the latter access to dynamically allocated memory. JSR-302 is a Java 2 MicroEdition (J2ME) system that’s a stripped-down version of RTSJ suitable for safety-critical systems like DO-178B.
“The safety-critical Java subset also has a ‘severely’ restricted library. The advantage is that safety/hard real-time Java is much smaller and simpler than traditional Java. The disadvantage is that the safety/hard real-time Java does not have immediate access to the wealth of capabilities already present in traditional Java,” says Kelvin Nilsen, CTO of Aonix.
“Mechanisms have been developed to allow traditional Java and hard-real-time Java applications to be bolted together to get the best of both worlds. Lowlevel code can be written using the hard real-time technology. High-level application logic, database access, GUIs, and distributed computing can be written in traditional Java, with the option of running this traditional Java code on a real-time virtual machine that has real-time garbage collection,” Nilsen adds.
“Real-time garbage collection addresses the needs of the soft real-time community who might have timing constraints measured in the range of 1 ms to a few hundred ms. Hard real-time Java is suited to timing requirements measured in microseconds,” he notes.
These days, it isn’t enough to just write fast code quickly. The code needs to be safe and secure, meaning it’s as bug-free as possible.