SJC: Unterschied zwischen den Versionen

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche
Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
 
(10 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
''von [[Benutzer:Stefan Frenz]]''
''von [[Benutzer:Stefan Frenz]]''
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 ==
== Übersicht über SJC ==
Es existiert ein experimenteller Java-Compiler namens SJC (siehe Link unten), direkt nativen Code für diverse Plattformen 1.4 erzeugt, wobei die Syntax in etwa Java 1.4 entspricht und keine Bibliotheken oder virtuelle Maschinen vorausgesetzt werden. Neben ia32 und x86_64 kann auch nativer (i.e. ausführbarer, nicht zu interpretierenden) Code für die ATmega-Reihe erzeugt werden.


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.
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 Implementierung mit avrgcc etwa mit Faktor 1.8 Flashbedarf gerechnet werden muss. Der Autor freut sich über Mithilfe. ;-)
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 ==
== Systemprogrammierung mit SJC ==
Zeile 16: Zeile 16:


* MAGIC: Codeerzeugender Zugriff auf die Hardware, zum Beispiel Zugriff auf das RAM mittels MAGIC.rMem8(addr) oder MAGIC.wMem32(addr, value).
* MAGIC: Codeerzeugender Zugriff auf die Hardware, zum Beispiel Zugriff auf das RAM mittels MAGIC.rMem8(addr) oder MAGIC.wMem32(addr, value).
* MARKER: 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 MARKER.interrupt().
* STRUCT: Elternklasse für eigene Klassen, die den Zugriff auf strukturierte RAM-Bereiche ohne Objekte ermöglichen.
* 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'''
'''Laufzeitumgebung'''


Die Laufzeitumgebung wird immer mitübersetzt, es kann also gezielt auf Bestandteile verzichtet werden, die nicht benötigt werden. Beispielumgebungen sind unter untenstehendem Link auf SJC vorhanden, das Handbuch beschreibt die erforderlichen und optionalen Klassen und Methoden.
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'''
'''Kurzanleitung'''


1. Benötigte Dateien
1. Benötigte Dateien und angenommene Verzeichnisstruktur
 
* Linux: compile (~500kb)
* Windows: compile.exe (~500kb)
* alle: bootconf.txt (~130b), batmel32.bin (98b)
* Beispielprojekt: atbase.zip (~10kb)
Alle Dateien sind unter untenstehender Quelle verfügbar.


2. 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"


* im aktuellen Verzeichnis: obige Dateien
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.
* im Verzeichnis atbase unterhalb des aktuellen: entpacktes Beispielprojekt


3. Testaufruf
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 atbase
* 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 atbase
* 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 "atbase" 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
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


4. Erläuterung der Optionen
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 "atbase"). Er erzeugt standardmäßig Code für die ia32-Architektur mit einer maximalen Image-Größe von 128k und diversen Java-konformen Einstellungen. Für die Verwendung mit dem ATmega sind "ein paar" andere Einstellungen sinnvoll:
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.
* -t atmega: Code für den ATmega statt für ia32 erzeugen.
* -L: Möglichst abgespeckte Objekte ohne Heap-Informationen verwenden.
* -L: Möglichst abgespeckte Objekte ohne Heap-Informationen verwenden.
Zeile 55: Zeile 60:
* -P batmel32.bin: Speziellen Header (bei ATmega für Startcode und Interrupt-Tabelle) verwenden.
* -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.
* -e 0x60 -E -a 0: Compiler in den "embedded mode" schalten, RAM bei Adresse 0x60 und Flash bei Adresse 0 beginnen lassen.
* -o boot -O "bootconf.lin#atmel": Ausgabemodul "boot" des Compilers aktivieren, die dafür erforderliche Konfiguration steht in der Datei "bootconf.lin" im Abschnitt "atmel" (standardmäßig wird die Datei "bootconf.txt" und der Abschnitt "default" verwendet).
* -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'''
'''Geplante Erweiterungen'''
Zeile 61: Zeile 66:
Für den Compiler sind eine Reihe von Erweiterungen geplant, die derzeit mangels Zeit noch nicht umgesetzt sind:
Für den Compiler sind eine Reihe von Erweiterungen geplant, die derzeit mangels Zeit noch nicht umgesetzt sind:


* Konstante Platzierung von STRUCTs zum einfacheren Zugriff auf die benannten Register des ATmega.
* Markierung von Klassen als "keep in flash", um zum Beispiel Strings direkt aus dem Flash zugreifen zu können.
* Code-Optimierung - sei es abhängig oder unabhängig von der Zielarchitektur.
* Code-Optimierung - sei es abhängig oder unabhängig von der Zielarchitektur.


'''Umgesetzte Projekte'''
== 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.
Hier soll eine kleine Liste der Projekte entstehen, die mit SJC umgesetzt wurden, zur leichteren Einordnung optimalerweise mit Autor und Datum des ersten Eintrags.
Zeile 74: Zeile 77:
== Software ==
== Software ==


* Offizielle Versionen: http://www.fam-frenz.de/stefan/compiler.html
* SJC-Homepage: http://www.fam-frenz.de/stefan/compiler.html
* Nightly Snapshot: http://www-vs.informatik.uni-ulm.de/dept/staff/frenz/private/snapshot/
* Beispielprojekte: http://www.fam-frenz.de/stefan/atproj.html
* Beispielprojekte: http://www.fam-frenz.de/stefan/atproj.html


Zeile 84: Zeile 86:
* [[Java]], [[NanoVM]]
* [[Java]], [[NanoVM]]


[[Kategorie:AVR]]
[[Kategorie:AVR-Projekte]]
[[Kategorie:AVR-Projekte]]
[[Kategorie:Java]]
[[Kategorie:Java]]
[[Kategorie:Projekte]]

Aktuelle Version vom 9. Dezember 2010, 20:04 Uhr

von Benutzer:Stefan Frenz

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

Siehe auch