HotSpot JVM on RIOT-OS?

Has anyone here ever heard of someone trying to run a JVM (HotSpot/OpenJDK) on a RIOT-OS embedded device? I'm interested in trying to get such a project off the ground, and was wondering if anyone could give me some steering/advice.

Motivation? It would be most-neat if I could port some of my Java apps over to an RTOS. With some manual offline byte buffer management, or once the "Shenandoah"/G1 pauseless GC arrives with Java 9 or 10, we'd practically have the ability to run "real-time Java" on an embedded device...

Hey,

Has anyone here ever heard of someone trying to run a JVM (HotSpot/OpenJDK) on a RIOT-OS embedded device?

RIOT targets devices that don't have enough RAM to run Linux. The official Java embedded VMs are way too fat for those devices, as they're just stripped-down versions of the original POSIX-based codebase.

There are some specialized VMs for constrained devices which are probably portable to RIOT. Maybe take a look how the Lego guys did it [1].

Kaspar

[1] http://www.lejos.org/

Thanks for that Lejos link, Kaspar, I will definitely dig into it later today.

You mentioned that RIOT *targets* devices that require a small footprint, but you didn't state that RIOT only supports devices with small RAM.

What's the max size/RAM that RIOT can support, or that RIOT is addressable for? What would be entailed with refactoring it to handle larger apps?

I ask this because to me, and for many others I'm sure, the main value in an RTOS (as opposed to Linux) is its deadline guarantees. When I run Java on Linux, the whole JVM process might come to a hault for a few seconds while Linux flushes some stream. Or perhaps some system-level utility runs for a few minutes and bogs down everything on the server (including my Java app). So to me, the real appeal of RIOT is:

1. Its a legitimate real-time OS when hard deadlines, task execution guarantees, etc.; and 2. It's an OS where I can just deploy my app and I know that *nothing else* besides the OS is running

So to me, if RIOT-OS can technically handle JVM apps (2GB - 4GB in size), then why not try to get a JVM like HotSpot to run on it? And if for some reason it can't handle apps that size (e.g. perhaps the largest integer it can handle is only 65,536, etc.), then I'm wondering what level of refactoring would be required to enable it to handle beefier/server-like apps.

Traditionally, the counter-argument here is: "Well then just write your apps in C." However, in 2015, all hobbyists, commercial and open source organizations have an enormous amount of time & effort ($$$) invested in existing software systems, which may be Java-based, Python-based, Ruby-based, Node-based, etc.

I can't speak for anyone else, but I would argue that the ability to run a JVM app on a real-time OS is going to be of *enormous* utility, especially in this modern "Internet of Things" era we're careening towards. It might also spawn up a whole subculture of getting other systems (again, Python, Ruby, etc.) running in an embedded context. I'm just sayin'...!

Thoughts? Criticisms? Hate mail?

Hi,

There are some specialized VMs for constrained devices which are probably portable to RIOT. Maybe take a look how the Lego guys did it [1].

Darjeeling VM [1] might also be a good starting point. I've looked also some time ago into VMKit [2] from LLVM - the results where quite impressive, but the project is no longer maintained.

Best, Michael

[1] http://darjeeling.sourceforge.net/ [2] http://vmkit.llvm.org/

See my response inline below.

Thanks for that Lejos link, Kaspar, I will definitely dig into it later today.

You mentioned that RIOT *targets* devices that require a small footprint, but you didn't state that RIOT only supports devices with small RAM.

What's the max size/RAM that RIOT can support, or that RIOT is addressable for? What would be entailed with refactoring it to handle larger apps?

So far, RIOT does not support 64 bit systems (native included, it is compiled as a 32 bit binary even on amd64 afaik), and it will take some effort to add that support, because there may be hidden assumptions in the code that some data type is 32 bit long.

The biggest problem, however, with porting to a larger system than a microcontroller is that these larger systems have MMU (memory management unit)-hardware which performs address space translations between virtual addresses and physical addresses, and ensures that each process has its own address space to run inside. This MMU must be configured when booting in order to access all of the memory. My area of expertise is constrained systems, such as the current RIOT platforms, so I may have some factual errors in the above explanation, please correct me if I am wrong about anything above.

I ask this because to me, and for many others I'm sure, the main value in an RTOS (as opposed to Linux) is its deadline guarantees. When I run Java on Linux, the whole JVM process might come to a hault for a few seconds while Linux flushes some stream. Or perhaps some system-level utility runs for a few minutes and bogs down everything on the server (including my Java app). So to me, the real appeal of RIOT is:

1. Its a legitimate real-time OS when hard deadlines, task execution guarantees, etc.; and

Can you really get any real-time guarantees on a Java VM? There are background processes happening inside the Java VM which may cause delays, for example memory garbage collection (this applies to Python too and probably others, but I don't know any other interpreted languages well enough to comment on them)

2. It's an OS where I can just deploy my app and I know that *nothing else* besides the OS is running

So to me, if RIOT-OS can technically handle JVM apps (2GB - 4GB in size), then why not try to get a JVM like HotSpot to run on it? And if for some reason it can't handle apps that size (e.g. perhaps the largest integer it can handle is only 65,536, etc.), then I'm wondering what level of refactoring would be required to enable it to handle beefier/server-like apps.

Traditionally, the counter-argument here is: "Well then just write your apps in C." However, in 2015, all hobbyists, commercial and open source organizations have an enormous amount of time & effort ($$$) invested in existing software systems, which may be Java-based, Python-based, Ruby-based, Node-based, etc.

I can't speak for anyone else, but I would argue that the ability to run a JVM app on a real-time OS is going to be of *enormous* utility, especially in this modern "Internet of Things" era we're careening towards. It might also spawn up a whole subculture of getting other systems (again, Python, Ruby, etc.) running in an embedded context. I'm just sayin'...!

Thoughts? Criticisms? Hate mail?

By all means, go for it! Even if it may not give the same real-time guarantees as running a process hand-coded in C on the bare metal platform it is still a useful experiment and concept.

For anyone attempting this: I don't believe this is an easy task. You will probably have to implement quite a large part of POSIX ioctl, some improvements to the supervisor call handler (at leas if running on ARM, to handle more than just task scheduling). You may also need to write an adaptation layer between gnrc (the network stack) and whatever network API is expected by the JVM. Filesystem storage may not be strictly necessary, but probably mandatory for almost any apps you want to run on this system.

Best regards, Joakim

Hi,

Darjeeling VM [1] might also be a good starting point.

in an effort to prevent duplicate work: if anyone wants to start playing around with Darjeeling on ARM cortex, please have a look at the port I did for my Bachelors Thesis first [0].

While the examples[1] do not use RIOT, but xpcc for platform abstraction, the vm itself is independent of any hardware abstraction. I have fixed a lot of alignment issues on cortex-m0 and at least one logic bug in the implementation on sourceforge, so it might be worthwhile to have a look at my code before starting your own port to cortex-m.

Kevin Laeufer

[0]: GitHub - RWTH-OS/ostfriesentee: a darjeeling fork for cortex-m microprocessors [1]: GitHub - RWTH-OS/ostfriesentee-examples

Hey!

[0]: GitHub - RWTH-OS/ostfriesentee: a darjeeling fork for cortex-m microprocessors

Nice name!

Cheers, Oleg

Kevin,

Thanks for getting back to me and yes, I would agree that this Darjeeling fork makes for a nice starting point for such a project. I will have a good look at it tonight after I get home, but will likely have a lot of questions.

Are you OK with me reaching out to you via email or GitHub, or would you prefer that I keep these questions on the mailing list; or would you prefer that I just figure things out for myself :slight_smile: ? I'm only a hesitant to use these mailing lists because I will likely have a lot of initial questions and feel this is a pretty niche topic that not many other RIOTers will care about.

Thanks again! Zac

Thanks Michael,

I appreciate the Darjeeling/LVVM links - I’m looking into a Darjeeling fork - Ostfriesentee - but will also look at LVVM as well!

Best, Zac

I think the few others who _are_ interested in this kind of project may find your progress interesting. I personally wouldn't mind if you ask questions on the mailing list as long as you try to stick to one thread and don't post a large number of messages without letting the list users a little time to answer your posts first.

Best regards, Joakim

Zac,

[I'm CCing the mailing list, as this might be relevant for people wanting to play with JVMs on devices supported by RIOT]

Are you OK with me reaching out to you via email or GitHub, or would you prefer that I keep these questions on the mailing list; or would you prefer that I just figure things out for myself :slight_smile: ? I'm only a hesitant to use these mailing lists because I will likely have a lot of initial questions and feel this is a pretty niche topic that not many other RIOTers will care about.

You can send me an email or open issues on github. The RIOT mailinglist isn't really the place to talk about Ostfriesentee, since it does not have a lot to with RIOT. However, if you want to talk about porting Ostfriesentee to RIOT or writing RIOT specific libraries, that would be something to talk about on the RIOT mailinglist.

Before you start, you have to be aware of the limitations that Darjeeling/Ostfriesentee have. 1.) They are intended for smallish Java programs, have a look at the example apps 2.) They only support a minimal subset of the Java runtime libraries, have a look at the `lib` folder in the Ostfriesentee repo 3.) They are both research projects/proofs of concept, that never had the remaining bugs ironed out, so it is not unlikely for your microcontroller to crash on execution

Thus if you are looking into this for the fun of it, or if you want to find out, what kinds of JAVA programs you can possibly run on a cortex-m core (that has less processing power than the core that powers the SUN Sport devices) have a go at it. Just be aware, that you will not be able to run excessively large JAVA programs, are certain to run into bugs and that you will have to implement a lot of library functionality yourself.

Finally I can recommend the following papers, if you want to learn more about some efforts in the research community to run JAVA on deeply embedded devices, I can recommend the following papers:

Brouwers, Niels, Koen Langendoen, and Peter Corke. “Darjeeling, a Feature-Rich VM for the Resource Poor.” In Proceedings of the 7th ACM Conference on Embedded Networked Sensor Systems, 169–82. SenSys ’09. New York, NY, USA: ACM, 2009. doi:10.1145/1644038.1644056.

Aslam, Faisal, Luminous Fennell, Christian Schindelhauer, Peter Thiemann, Gidon Ernst, Elmar Haussmann, Stefan Rührup, and Zastash A. Uzmi. “Optimized Java Binary and Virtual Machine for Tiny Motes.” In Distributed Computing in Sensor Systems, edited by Rajmohan Rajaraman, Thomas Moscibroda, Adam Dunkels, and Anna Scaglione, 15–30. Lecture Notes in Computer Science 6131. Springer Berlin Heidelberg, 2010. Optimized Java Binary and Virtual Machine for Tiny Motes | SpringerLink.

Maye, Oliver, and Michael Maaser. “Comparing Java Virtual Machines for Sensor Nodes.” In Grid and Pervasive Computing, edited by James J. (Jong Hyuk) Park, Hamid R. Arabnia, Cheonshik Kim, Weisong Shi, and Joon-Min Gil, 181–88. Lecture Notes in Computer Science 7861. Springer Berlin Heidelberg, 2013. Comparing Java Virtual Machines for Sensor Nodes | SpringerLink.

Kevin Laeufer

Thanks for the thorough response Joakim.

I actually think 32-bit is perfectly fine, at least for my needs. Specifically I'm looking to target the ARM SAM3X8E family (Cortex M3) which is 32-bit (most Java apps can - and arguably should run inside of 4GB).

Your point about Java not being able to *truly* deliver real-time guarantees is spot-on. However, there are all sorts of tricks you can do so that major collections run very infrequently. And the Shenandoah/G1 "pauseless" GC coming in Java 9 or 10 promises to reduce actual pausetime down to <1ms. That's probably not impressive for you hardcore RTOS peoples, but in Java-land that is like...the best thing...of all time...ever.

A lot of IoT-type devices do not need *hard* real-time guarantees, but could greatly benefit from running existing platforms, libraries and frameworks running in JVM/Python/Ruby/etc. lanaguages. How cool would it be to run Akka on a smart device? This is likely how Skynet will come to be self-aware and enslave us all. I guess my motivation would be to accept the current real-time shortcomings of the JVM, use those tricks to minimize GC, and hold out for a few years until improvements to the core JVM (such as Shenandoah) are released into the wild.

I also think such an endeavor would spark a large community of non-C devs to get heavily interested in RIOT-OS, which from what I can tell, is best-in-show in the modern RTOS landscape.

Thanks again for the solid input here - stay tuned!

A quick mid-day follow up here: From everything I’ve collected so far, the RIOT-OS has no problem handling 32-bit (ARM-based) architectures, and so there’d be nothing stopping me from getting it to run on, say, the ARM SAM3X8E Cortex M3 MCU, yes? (Please correct me if I’m wrong!)

There is a 32-bit (i386) version of OpenJDK 7 available on lots of Linux repos (check them out here: http://openjdk.java.net/install/). So, I can’t imagine it would be too difficult to get a 32-bit, Open JDK 7 compiled and running on an ARM chip where RIOT-OS is its underlying OS. Again, *please* correct me if I’m wrong, or if I’m overlooking some obvious hurdles here!

Best, Zac

Hey,

A quick mid-day follow up here: From everything I’ve collected so far, the RIOT-OS has no problem handling 32-bit (ARM-based) architectures, and so there’d be nothing stopping me from getting it to run on, say, the ARM SAM3X8E Cortex M3 MCU, yes? (Please correct me if I’m wrong!)

Yes, the SAM3X8E is already supported in RIOT [1]. It is used by the udoo and arduino-due boards.

There is a 32-bit (i386) version of OpenJDK 7 available on lots of Linux repos (check them out here: OpenJDK: Download and install). So, I can’t imagine it would be too difficult to get a 32-bit, Open JDK 7 compiled and running on an ARM chip where RIOT-OS is its underlying OS. Again, *please* correct me if I’m wrong, or if I’m overlooking some obvious hurdles here!

The OpenJDK would probably require many megabytes of both ROM and RAM, this means it will not run on the sam3x8e, even if you add all the support functions that are required by the program to get it to run inside RIOT. A more realistic approach would be to take a serious look at the embedded JVMs that were suggested earlier in this thread (Darjeeling, and the LLVM based one).

BR, Joakim

[1]: RIOT/cpu/sam3 at master · RIOT-OS/RIOT · GitHub

Thanks Kaspar and Joakim,

I'm not trying to be difficult here (I promise!) I'm just trying to see the forest through the trees.

When you say that "The OpenJDK would probably require many megabytes of both ROM and RAM, this means it will not run on the sam3x8e...", why? Is it because it would require "many megabytes", or because it requires ROM, which I'm guessing isn't supported by RIOT-OS?

And yes, I will definitely dive into Darjeeling/LLVM, but am trying to see if I can't brute force an easier solution first. :slight_smile:

Thanks again!

Thanks Kaspar and Joakim,

I'm not trying to be difficult here (I promise!) I'm just trying to see the forest through the trees.

When you say that "The OpenJDK would probably require many megabytes of both ROM and RAM, this means it will not run on the sam3x8e...", why? Is it because it would require "many megabytes", or because it requires ROM, which I'm guessing isn't supported by RIOT-OS?

ROM is the flash memory inside your MCU, that is where you store the actual program code. RAM is volatile and is used for storing runtime variables and buffers. Both kinds of memory are used by all RIOT applications (OT: it is possible to run an application without touching the ROM by loading the binary to RAM via the debugger. It is not very useful in a real world application, though.)

The SAM3X8E has 512 kB of ROM and 96 kB of RAM. It will not run OpenJDK because the binary will not fit, and if you manage to load it (for example via external flash memory) it will definitely run out of RAM before even finishing its initialization procedure.

And yes, I will definitely dive into Darjeeling/LLVM, but am trying to see if I can't brute force an easier solution first. :slight_smile:

Darjeeling is probably the easy solution here :slight_smile:

Thanks again!

BR, Joakim

Hi Zac,

Have you looked at the sam3x8e datasheet? Right on the front page it says it has 512KB of flash (AKA ROM or nonvolatile program and data storage). The chip has 96KB of RAM. Looking into task manager on Windows 7 I see a javaw.exe that is occupying 133MB of RAM and my JRE takes up 153MB of disk. Admittedly this is not a perfect comparison, but surely these numbers mean something to you.

RIOT is meant for *small* systems. Not SMALL or S M A L L but small systems. Some of these systems are so small that they can't do "Hello World" because the "printf" code takes up too much space.

Thoughts? Criticisms? Hate mail?

In other words, you're nuts!

  ;-)

Given that, here's a true Java bytecode chip that I worked with a few years back:

   http://www.ajile.com/index.php?option=com_content&view=article&id=2&Itemid=6

Here's an FPGA core:

   http://www.jopdesign.com/

And an ARM product:

   Jazelle - Wikipedia

In other words, you are not the first to think of this, and in some cases it's not a bad idea. On the other hand, I think you can safely forget Akka on RIOT.

You also mentioned Python; have a look here:

    http://micropython.org/

Enjoy!

Marc Sissom Krypton Solutions

Thanks Marc, I appreciate the candid input. I have a few final (I promise) followups here that are more for my edification/learning than anything else.

You say that RIOT is meant for *small* systems, and I think I'm beginning to understand what that means. But regardless of what RIOT is *typically* used for, are there any inherent limitations in RIOT that would prevent me from deploying/flashing it to a sophisticated MCU that *could* run Java? In other words, say I have an MCU that has a crazy amount of ROM/RAM on it that has the stats to handle a full bore JVM app...does RIOT itself have any limitation/constraints that would prevent me from choosing it (nevermind *why* I would choose it in the first place!)?

Also, I get that MCU ROM is the memory where the executable is flashed to. And I understand that because of this, in order for a non-running executable to "fit" on an MCU, it must have a file size that is smaller than the amount of ROM (obviously). But I'm still not understanding why the RAM (that is, the memory allocated to the running executable) can't be scalable by somehow attaching additional storage (flash/whatever) to the MCU. In other words, if the sam3x8e has 512KB ROM and only 96KB RAM, if my entire JVM executable (which includes *everything*) is somehow magically less than 512KB, it will fit on the MCU. So why can't I then "get around" the 96KB RAM limitation by (somehow) integrating that onboard 96KB RAM with, say, an 8GB solid state drive, or something thereabouts. I just feel like there *must* be a way to scale the RAM and perhaps even the ROM. Ideas?

Thanks again, if I can get answers to these I should be all set!

Best, Zac

Hey,