KESO: A Java VM an MCU developer could love? Maybe.
At the recent ESC DESIGN West, in the context of conversations about microcontroller usage and architecture evolution, several embedded system developers I met were excited about a new open source Java virtual machine (VM) implementation called KESO (which is OSEK backwards, the OS environment within which it was originally designed to function). This enthusiasm for a JVM surprised me because the conventional wisdom among embedded developers is that Java and its VMs have no place in small footprint, highly deterministic, and real time apps in automotive, industrial, and machine control designs.
While Java was developed to make code development cleaner and more bug free, this comes at the cost of unpredictable timing due to the garbage collection algorithms it uses to deal with extraneous code and to the memory space its VMs require. Java virtual machines, even the just-in-time and ahead-of-time compiled versions, are still too big and too slow for use on most microcontrollers.
Not so with the KESO virtual machine. In general, it avoids many of the problems with traditional JVMs through the use of a design that is carefully architected (by researchers at the Embedded Systems Institute in the the School of Engineering, Friedrich-Alexander University, Erlangen-Nuremberg, Germany) with the limited resources and response times of microcontroller applications in mind - not just for 32-bit MCUs, but on 8- and 16-bit microcontrollers such as the Atmel AVRs and Microchip’s 8-bit PICs as well.
Unlike traditional JVMs, KESO is designed to operate in tandem with an RTOS, leaving to the RTOS many functions traditional JVMs might take on. For example, it does not implement thread scheduling and thread synchronization, but uses an existing RTOS to do these tasks. As with most Java implementations, it makes selective use of garbage collection, but when it does, it uses a bare-bone, primitive form that assumes operation in a priority-based scheduling environment, another function it lets devolve to the RTOS. Also, rather than depend on the traditional Java VM compiler to generate executable Java code, KESO is provided with a companion compiler called “jino” that generates native C code in an ahead-of-time fashion, making possible a very slim run time environment and fast execution times.
Rather than just any C code, KESO generates ISO-C90 code, which has a number of advantages. First, because it makes use of a standard C compiler available for most embedded microcontrollers, there is no need for a compiler backend for each target microcontroller. Second, the C source code is easier to read than native code, making it easier to debug. Third, it allows the use of existing C language tools for static analysis and testing. Fourth, the jino compiler is designed to work in cooperation with standard C compilers, concentrating on high-level optimizations. Low-level optimizations are left to the traditional C compilers..
Because KESO is initially targeted for automotive applications, it is designed as a multi-JVM, in which the basic structural building block is the “protection domain.” This allows different applications to coexist on a microcontroller in their own memory space, with communications between them limited to a set of well-defined and safe communications channels, again mediated by an RTOS.
As I mentioned earlier, KESO incorporates a minimalist and flexible form of garbage collection and assumes operation in a purely static memory environment, typical of many auto applications which use an AUTOSAR operating system. It’s multi-JVM structure requires logical separation of executable code into different memory domain heap areas rather than allocating from a common heap. Not only does such static partitioning allow the VM to give the various allocated heap spaces guarantees on performance and response time but also provides protection on a per domain basis.
To operate effectively in such a multi-JVM environment, KESO uses a relatively simple heap strategy which often does not require the use of garbage collection at all. The advantage of this is that memory objects can be deployed with short, constant, and easily predictable time constraints. In addition, if a developer feels the need to use garbage collection, KESO makes use of two precise tracing non-moving mark-and-sweep garbage collection techniques: through-put optimized GC and an incremental GC that is at least latency aware.
Various implementations of KESO on MCUs run the gamut from high end 32-bit MCUs such as the ARM Cortex-M and Infineon’s Tricore to Atmel’s 8-bit AVR MCUs and equivalent Microchip PICs. In the 8-bit domain, a typical memory configuration is about 8 kilobytes of flash and about 500 to 600 bytes or so of internal SRAM.
The current compiler backend for KESO requires an OSEK/VDK or an AUTOSAR-compatible OS, the most common platforms used in automotive designs. In that environment, KESO takes advantage of the fact that OSEK/VDX is at its core little more than a scheduler based on static priorities. As a result, it supports determinism and takes advantage of code generators sent out with the OS that allow a developer to generate a KESO/RTOS variant tailored to the specific hardware platform and application at hand.
Despite its initial OSEK/AUTOSAR implementations, though, KESO makes few assumptions about the underlying scheduling model, other than requiring priority-based scheduling. This implies that it can be used in combination with any RTOS if the developer is willing to do the work to adapt it. If not, there is a whole range of OSEK/VDX compatible configurations, including emulations for most commodity and open source RTOSes.
Similar to several other Java platforms optimized for embedded systems, KESO doesn’t offer support for the full spectrum of features provided by the Java 2 Standard platform (J2SE), for obvious performance and memory space considerations. Despite that, it seems to incorporate a range of features that MCU developers should find useful. Its native interface (KNI) is lightweight and flexible enough to interact with any number of native APIs. Safe abstractions have been built atop the KNI for accessing OS services such as memory-mapped hardware registers. As a multi-domain JVM, it incorporates a high level remote procedure call (RPC) mechanism that allows communications between protection domains and allows tasks to perform in those different protection contexts without losing their original priority scheduling.
What I am describing here is tantalizing more for the details that are left out than for what I have been able to describe based on what developers have told me. That is one of the most exciting – and most frustrating – things about directly talking to developers at conferences such as ESC. I am currently scouring the web and querying my developer contacts for further details and hope to have more to report later.
How KESO can be used in embedded applications is a topic worth further exploration, and I would like to hear from you about your experiences with it. Just as valuable is the input from developers who have looked at KESO and did not find it attractive.
A final note: The fact that KESO was developed for use on microcontrollers and seems able to meet fairly strict deterministic response time constraints even on 8-bit MCUs convinces me that despite the constant refrains from high-end MCU vendors that 32 bit MCUs will soon displace 8-bitters, this under-appreciated segment of the embedded systems market is still one of the most creatively active areas of development.
Embedded.com Site Editor Bernard Cole is also editor of the twice-a-week Embedded.com newsletters as well as a partner in the TechRite Associates editorial services consultancy. He welcomes your feedback. Send an email to firstname.lastname@example.org, or call 928-525-9087.