SJC
Es existiert ein experimenteller Java-Compiler namens SJC (siehe Link unten), der direkt nativen Code für diverse Plattformen erzeugt, wobei die Syntax abgesehen von Enums und Generics der von Java 1.5 entspricht und keine Bibliotheken oder virtuelle Maschinen vorausgesetzt werden. Neben nativem ia32 und x86_64 kann auch Code für die ATmega-Reihe und ARM7-Controller wie z.B. LPC2103 erzeugt werden.
Übersicht über SJC
Der Compiler wird für Forschung und Lehre sowie diverse private Projekte eingesetzt, ist vollständig in Java geschrieben und steht unter GPL. Da er sich selbst übersetzen kann und entsprechende Konfigurationen für Linux- und Windows-Ausgaben existieren, können statt der Java-Class-Files auch einzeln ausführbare Versionen verwendet werden, für die keine SunJava-Umgebung und keine Bibliotheken erforderlich sind.
Derzeit ist der Optimierer noch sehr rudimentär, so dass derzeit gegenüber einer vergleichbaren Implementierung in C und voll optimierendem avrgcc mit etwa mit Faktor 2 Flashbedarf gerechnet werden muss. Der Autor freut sich über Mithilfe beim Optimierer... ;-)
Systemprogrammierung mit SJC
Hardwarezugriff
Um den Zugriff auf die Hardware auch in Java zu ermöglichen, existieren drei Spezial-Klassen:
- MAGIC: Codeerzeugender Zugriff auf die Hardware, zum Beispiel Zugriff auf das RAM mittels MAGIC.rMem8(addr) oder MAGIC.wMem32(addr, value).
- STRUCT: Elternklasse für eigene Klassen, die den Zugriff auf strukturierte RAM-Bereiche ohne Objekte ermöglichen.
- FLASH: Instanzen im Flash halten (ie.: nicht ins RAM kopieren).
- @SJC: Hinweise für den Compiler, eine besondere Behandlung der aktuellen Methode oder des nachfolgenden Codes vorzunehmen, zum Beispiel Markierung der aktuellen Methode als Interrupt-Handler mittels @SJC.Interrupt oder Markierung von static final Arrays als unveränderlich und somit im Flash zu halten mittels @SJC.Flash.
Laufzeitumgebung
Die Laufzeitumgebung wird immer mitübersetzt, es kann also gezielt auf Bestandteile verzichtet werden, die nicht benötigt werden, es muss aber auch alles vorhanden sein, was verwendet wird. Wird zum Beispiel "new" verwendet, muss die Methode rte.DynamicRuntime.newInstance(.) implementiert werden, bei einem Cast zwischen Objekten isInstance(.) etc.
Beispielumgebungen sind unter untenstehendem Link auf SJC vorhanden, das Handbuch beschreibt die erforderlichen und optionalen Klassen und Methoden.
Kurzanleitung
1. Benötigte Dateien und angenommene Verzeichnisstruktur
- im aktuellen Verzeichnis: Compiler und Konfiguration
- Compiler: unter Linux "compile", unter Windows "compile.exe" (~500kb)
- Ausgabekonfiguration: Textdatei "bootconf.txt" (~130b)
- Header für Zielplattform
- ATmega32: batmel32.bin (98b)
- ARM7: barm7.bin (92b)
- im Verzeichnis "src" unterhalb des aktuellen: Testprojekt
- Java-Dateien für Java-Kompatibilität: Verzeichnis "java"
- Java-Dateien des eigentlichen Projekts: Verzeichnis "kernel"
- Java-Dateien der Laufzeitumgebung: Verzeichnis "rte"
Der Compiler kann entweder aus den jeweils aktuellen "executables" der offiziellen Version von http://www.fam-frenz.de/stefan/compiler.html oder aus dem nächtlichen Build von http://www.fam-frenz.de/stefan/compsnpe.zip bezogen werden. Die beiden anderen Dateien im Hauptverzeichnis zur Konfiguration sowie ein kleines Testprojekt für den Verzeichnisbaum "src" sind unter http://www.fam-frenz.de/stefan/atbasenw.zip für ein ATmega-Projekt verfügbar, die entsprechenden Dateien für ein ARM-Projekt folgen.
2. Testaufruf für ATmega-Projekte
- Linux: ./compile -t atmega -L -P batmel32.bin -y -e 0x60 -E -a 0 -o boot -B -C -k src
- Windows: compile.exe -t atmega -L -P batmel32.bin -y -e 0x60 -E -a 0 -o boot -B -C -k src
Erzeugt werden sollten aus allen (!) Quelltexten im Verzeichnis "src" eine Datei syminfo.txt mit textuellen Informationen zum erzeugten Image sowie eine Datei BOOT_ATM.HEX, die das erzeugte Image enthält und von avrdude weiterverwendet werden können sollte, je nach lokalen Gegebenheiten zum Beispiel mittels: avrdude -P /dev/ttyUSB1 -p m32 -c stk500v2 -U flash:w:BOOT_ATM.HEX
3. Erläuterung der Optionen
Der Compiler übersetzt im Gegensatz zum Java-Compiler von Sun nicht eine Datei nach der anderen und sucht sich die jeweils referenzierten Dateien selbst, sondern übersetzt genau die angegebenen Dateien oder rekursiv alle auffindbaren Java-Dateien in einem Verzeichnis (in obigem Beispiel "src"). Er erzeugt standardmäßig Code für die ia32-Architektur mit einfachem Speicher-Dump und diversen Java-konformen Einstellungen. Für die Verwendung mit dem ATmega sind "ein paar" andere Einstellungen sinnvoll:
- -t atmega: Code für den ATmega statt für ia32 erzeugen.
- -L: Möglichst abgespeckte Objekte ohne Heap-Informationen verwenden.
- -y: Strings mit byte- statt char-Werten verwenden.
- -B: Keine Bound-Checks für Arrays (Vorsicht: ein ungültiger Index wird nicht mehr erkannt!).
- -C: Keine Array-Store-Checks für Arrays (Vorsicht: die Ablage eines Objekts in einem Objekt-Array wird zur Laufzeit nicht mehr überprüft, bei ATmega-Projekten wohl kein Problem).
- -k: Keine Code-Erzeugung für ausschließlich inline erzeugte Methoden.
- -P batmel32.bin: Speziellen Header (bei ATmega für Startcode und Interrupt-Tabelle) verwenden.
- -e 0x60 -E -a 0: Compiler in den "embedded mode" schalten, RAM bei Adresse 0x60 und Flash bei Adresse 0 beginnen lassen.
- -o boot: Ausgabemodul "boot" des Compilers aktivieren, die dafür erforderliche Konfiguration steht in der Datei "bootconf.txt" im Abschnitt "default" (soll eine andere Datei oder ein anderer Abschnitt verwendet werden, hilft der Parameter "-O DATEI#ABSCHNITT").
Geplante Erweiterungen
Für den Compiler sind eine Reihe von Erweiterungen geplant, die derzeit mangels Zeit noch nicht umgesetzt sind:
- Code-Optimierung - sei es abhängig oder unabhängig von der Zielarchitektur.
Umgesetzte Projekte
Hier soll eine kleine Liste der Projekte entstehen, die mit SJC umgesetzt wurden, zur leichteren Einordnung optimalerweise mit Autor und Datum des ersten Eintrags.
- smf, 2010-01-13: GPS-Logger mit Anzeige auf LCD und Aufzeichnung auf SD-Karte.
- smf, 2010-01-13: Zeitmessung und Rundenzähler für Rennbahnen.
Software
- SJC-Homepage: http://www.fam-frenz.de/stefan/compiler.html
- Beispielprojekte: http://www.fam-frenz.de/stefan/atproj.html
Siehe auch
- SunJava: http://java.sun.com
- NanoVM: http://www.harbaum.org/till/nanovm/index.shtml
- Java, NanoVM