mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR Simulator in Java als Übungsprojekt


Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Allerseits,

da ich mich zur Zeit in Java einarbeite, habe ich mir gedacht, einen 
Simulator für AVR-Prozessoren zu schreiben wäre eine gute Sache, um die 
Objektorientierung zu üben.
Ausserdem gibt wohl auch einige Leute, die an einer 
Plattformunabhängigkeit interessiert wären: 
Beitrag "AVR-Ass-Compiler in Java?"
Ein Prozessor läst sich meiner Meinung nach gut in Objekte zergliedern: 
Register, Speicher, Alu usw.
Deshalb ist ein Simulator meiner Meinung nach gut für eine 
objektorientierte Programmiersprache geeignet.
Wenn man einen Simulator selbst schreibt, lernt man natürlich auch einen 
Prozessor im Detail kennen.

Wer würde sich für so ein Projekt interssieren?

Gruß,
chris

Autor: Dennis B. (higret)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

ich hab selbst schon mit so einem Projekt angefangen, allerdings in C++.

Hatte bis jetzt nur noch nicht die Zeit und den Antrieb da 
weiterzumachen


lg

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja da hast Dir ganz schoen viel vorgenommen. Eine GUI zur 
Visualisierung wirst Du auch noch brauchen...

Ich wuerde da nen bissel kleiner einsteigen als mit so nem 
Monsterprojekt.

Michael

Autor: Squawk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt schon einen Open-Source AVR-Simulator, der in Java implementiert 
ist. Siehe http://compilers.cs.ucla.edu/avrora/ Du kannst ihn vielleicht 
als Vorlage nehmen...

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>ich hab selbst schon mit so einem Projekt angefangen, allerdings in C++.

Wie weit bist Du denn gekommen? Kannst Du schon disassemblieren, 
simulieren?
Vielleicht könnte man die Befehlsdefinitionen kompatibel machen.

>Naja da hast Dir ganz schoen viel vorgenommen. Eine GUI zur
>Visualisierung wirst Du auch noch brauchen...

Nun, man kann ja auch klein anfangen, ohne GUI. Ich nehme mal an, dass 
es genügend Leute gibt, die Erfahrung im GUI Bau haben.
Man kann auch klein beim Kern des Simulators anfangen. Als erstes würde 
ich einen Disassembler bauen, der nur einen kleinen Teil der Befehle 
kennt. Wenn die Struktur steht, finden sich vielleicht auch ein paar 
Leute, die Lust haben, auch ein paar Befehle beizutragen. Man muss sie 
ja dann nur noch aus dem Datenblatt abschreiben. Wenn man selber dazu 
etwas beiträgt, kann man viel über den Aufbau der AVR-Instructionen 
lernen. Wenn nur jeder 10 Befehler macht, kann man mit 13 Leuten den 
Instructionssatz der AVR-Serie umsetzen.

>Es gibt schon einen Open-Source AVR-Simulator, der in Java implementiert
>ist.

Hab's mir grad mal angeschaut, aber ich konnte die Source-Files nicht 
finden. Es gibt fertig kompilierte Jar's mit ziemlich vielen Klassen. 
Die haben jeden Befehl zu einer eigenen Klasse gemacht. Ohnen zuviel mit 
Java gearbeitet zu haben, denke ich, diese Umsetzung ist 
unübersichtlich.

Autor: ... ... (docean) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1. Link auf
http://compilers.cs.ucla.edu/avrora/release.html
(Beta 1.6.0 [5.89mb] source release (July 23, 2005).)

und ja es kann Sinn machen soviele Klassen zu machen...

Wenn du vorweg richtig gut die Vererbungstruktur planst, kommst du 
schnell auf ähnliche Strukturren...

Das ist aber nicht trivial geschweige denn einfach ;)

Autor: Gastt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Entwurf mit vielen Klassen ist hier durchaus sinnvoll...
Das Ganze kennt man unter den Entwurfsmustern sogar als Command-Pattern, 
wenn ich mich recht erinnere!
Google hilft hier sicher weiter...
Dadurch wird die Erweiterbarkeit ungemein erhöht.

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>1. Link auf
>http://compilers.cs.ucla.edu/avrora/release.html
Wenn ich es richtig sehe, ist der Code von Avora zwar Open Source, aber 
nicht unter einer GPL.
Ausserdem ist die letzte Source von 2005, obwohl es eine neu Jar-Version 
von 2008 gibt.

Ich finde es ganz interessant, mal ein wenig selbst zu versuchen, so ein 
Programm zu entwickeln.
Hier mal ein Auszug aus meiner AVR-Kommando-Defintion.
Ein AVR-Kommando besteht aus
1. Kommando Name
2. Befehlscode ( in der Parameterliste fälschlicherweise opcode genannt 
)
3. Maske, für Bits die im Opcode fest sind und die Parameter 
wegmaskieren
4. Anzahl der Flash-Worte
5. Anzahl Taktzyklen, die ein Befehl braucht

Habe ich was vergessen?

Ein kleines Problem bleibt aber, und da könnten die oben erwähnten 
vielen Klassen für AVR-Befehle ins Spiel kommen:
Füf den Simulator wird natürlich auch der Code zur 
Instrucktionsausführung benötigt. Da wäre es natürlich praktisch, wenn 
man den Code einfach als Objekt zur Befehlsbeschreibung hinzufügt.
Was mich daran stört ist, dass die AVR-Prozessoren 113 Befehle haben ( 
o.ä. ), d.h. wären 113 Klassen notwendig, oder?
  // commands without parameter
  //public AvrCommand(String name, Parameter parameter1,int opcode,int opcodeMask,int opcodeLength,int cycles)
  commands.add(new AvrCommand("NOP",0x0000,0xFFFF,1,1));
  commands.lastSetDescription("no operation");

  // commands with one parameter
  Parameter k=new Parameter("k","",0x0FFF);
  commands.add(new AvrCommand("RJMP",k,0xC000,0xF000,1,2));
  commands.lastSetDescription("relative jump");

Autor: Dennis B. (higret)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ chris

ne so weit bin ich noch nicht, aber werde wohl auch direkt den ASM 
Quellcode parsen (dafür hab ich schon nen Programm), dann sieht der User 
auch seine selbst gewählten Definitionen (.equ und so)

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>...habe ich mir gedacht, einen Simulator für AVR-Prozessoren zu schreiben >wäre 
eine gute Sache...

Ich sitze gerade auch an meinem Disassembler (Delphi). Gerade noch einen 
Bug entdeckt.
Ein Simulator ist ist aber eine ganz andere Liga. Die ALU zu simulieren 
wäre noch das einfachste. Da könnte man eine ganze Reihe Befehle direkt 
in ASM simulieren. Da würden schon einiges entfallen, da z.B. die 
Flagbearbeitung ähnlich ist. Der Knackpunkt ist aber die Perepherie. Das 
hat selbst ATMEL noch nicht 100%-tig hinbekommen.

MfG Spess

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ein Simulator ist ist aber eine ganz andere Liga. Die ALU zu simulieren
>wäre noch das einfachste. Da könnte man eine ganze Reihe Befehle direkt
>in ASM simulieren.

Jaja, schon klar, dass ein Simualtor eine andere Liga ist. Man könnte ja 
mit einem sehr kleinen Prozessor anfangen, z.B. dem Attiny 11 ( btw. den 
gibt's scheinbar gar nicht mehr, man kann in auf atmel.com nicht mehr 
finden ).

Mein Java Programm kann auch schon ein wenig disassemblieren: es sind 5 
Befehler implementiert. Die Klassen sind aber so gemacht, dass man 
relativ einfach neue Befehle hinzufügen kann ( siehe oben ).

Wenn jemand Lust hat, sich meinen Versuch anzusehen:
http://www.hobby-roboter.de/forum/download/file.php?id=17
(Die akutelle Main-Klasse heist instructions.java )

Ich freue mich über Kommentare, wie man es besser machen könnte.

Gruß,
chris

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Die Klassen sind aber so gemacht, dass man
>relativ einfach neue Befehle hinzufügen kann ( siehe oben ).

Warum willst du für jeden Befehl eine Klasse machen? Entscheidender ist, 
wie die Argumente des Befehls verarbeitet werden.

Beispielsweise sind alle 'br..'- Befehle fast identisch: Bit15..10 
bedingter Sprung, Bit 9..3 Sprungweite, Bit 2..0 Bedingung.

MfG Spess

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na, ich will ja nicht für alle Befehle eine eigene Klasse machen. Soweit 
ich gesehen habe, ist das in avora so.
Im Moment schwebt mir da eine Realisierung etwa in der Art vor:

String s;
if(s=="ADD Rd,Rr") { ...}
if(s=="JMP K") ...
usw.

das unschöne dabei ist, dass die Befehle nicht mehr richtig gekapselt 
sind.
Im aktuellen Programm habe ich eine Klasse, die sich "Command.java" 
nennt. Dort sollte eigentlich alles, was zu den Befehlen gehört, 
gespeichert sein also eigentlich auch der Code für den Simualtor.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> String s;
> if(s=="ADD Rd,Rr") { ...}
> if(s=="JMP K") ...
> usw.
also dann wirst du aber das ganze bloss in Zeitlupe Simulieren können - 
jedes mal ein Stringvergleich - muss denn das wirklich sein? Und dann 
etwa noch das Parsen der Parameter wieder als String operration. Es gibt 
ein grund warum Emulatoren noch in ASM geschrieben werden - für eine µC 
recht bestimmt auch sinnvoll optimierter code aus - aber bestimmt nicht 
code der auf String basis arbeitet.

Autor: spess53 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Bist du jetzt beim Disassemblieren oder Simulieren. Bei Ersteren gehe 
ich vom Hex-File aus. Und auch beim Simulieren würde ich eine Art 
Zwischencode erzeugen, mit dem die eigendliche Simulation läuft.
Habe mal ein Screenshoot von meinem Disassembler angehängt.

MfG Spess

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Habe mal ein Screenshoot von meinem Disassembler angehängt.
Sieht doch schon mal ganz nett aus, weiter so :-)

>also dann wirst du aber das ganze bloss in Zeitlupe Simulieren können
Sag doch so was nicht, wo doch die heutigen PC-Prozessoren so rasend 
schnell sind. Ausserdem soll die Java-Engine ja mittlerweile auch recht 
flott laufen.

Wie gesagt, bei dem Projekt geht es mir eher darum, mit java eine 
saubere objektorientierte Struktur zu schaffen, da ja immer behauptet 
wird, Programmierer, die das objektorientierte Programmieren erst späht 
lernen, können gar nicht mehr objektorientiert denken.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Sag doch so was nicht, wo doch die heutigen PC-Prozessoren so rasend
> schnell sind. Ausserdem soll die Java-Engine ja mittlerweile auch recht
> flott laufen.
Ja der Optimierer von Java wird immer besser, kann aber nicht aus 
schlechten Programiere gute machen und denken kann er auch nicht.
Aber bevor man "saubere objektorientierte" Programmiert sollte man sich 
auch ein wenig gedanken über die Performance machen - und 
stringoperationen ist das schlimmste was man an der stelle machen kann 
und es sehr schlechte Angewohnheit. Macht nicht java intern noch UTF8? 
wenn ja wirst du wohl schon die ersten 50Takte(geschätzt) nur für den 
vergleich brauchen welcher befehl jetzt an der reihe ist, da hast du 
noch nicht einmal etwas sinnvolles gemacht.
Warum fängst du nicht an alle Module eines Atmels (Timer, PWM, UART, ADC 
usw) also Klasse abzubilden, das macht ja noch sinn - aber doch nicht 
jeden Befehl.

Nachtrag:
ist ja sogar noch schlimmer wenn du immer
if ( ... )
if ( ... )
if ( ... )
if ( ... )
und das mit 132 Befehlen und der letzte wird gebraucht hast du 131 
Stringvergleiche umsonst gemacht!!!!!!!

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Simulator "avora" ist jeder Befehl als eigene Klasse aufgeführt.

Mir scheint es mittlerweile auch am besten, wenn man jeden Befehl als 
eigene Klasse implementiert. Das ergibt insgesammt auch eine wesentlich 
bessere Klasse.
Mein Simulator läuft quasi schon, nämlich mit den Befehlen NOP,INC und 
RJMP.

Man lernt ziemlich viel, wenn man versucht, die Befehle nachzubauen, da 
man sie wirklich im Detail verstehen muss.
Im Moment hänge ich ein bischen an den Status Flags. Was ist der 
Unterschied Zeischem dem Vorzeichenflag "V" und dem Signed Flag "S" ?

Hier mal meine Realisierung der INC Befehlsklasse:
public class Instr_INC extends Instruction
{
    public Instr_INC()
    {
  Parameter Rd=new Parameter("Rd",0x01F0);
  command=new AvrCommand("INC",Rd,0x9403,0xFE0F,1,1);
  command.setDescription("increment register");
    }
    public void execute(CPU cpu)
    {
  int sreg=cpu.getRegisterSet().readSreg();

  int b=cpu.readGpRegister(parameterValue1);
  if(b==0x7F) sreg=sreg|0x08; // set overflow flag

  b++;
  cpu.writeGpRegister(b,parameterValue1);
  
  if(b&0x80) sreg=sreg|0x04; // set negativ flag
  if(b==0) sreg=sreg|02; // set zero flag
  cpu.getRegisterSet().writeSreg(sreg);
    
  cpu.updateProgrammCounter(command.length());
    }
}

Das S-Flag steht noch aus, da fällt mir keine effektive Implementierung 
ein.

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt ist der Simulator noch um ein paar Befehle erweitert.
Durch die Kapselung der Befehle ist es relativ einfach, einen 
Disassembler zu programmieren und an den Simulator anhängen. Ein Vorteil 
ist auch, dass man den Befehlen gleich eine Beschreibung mitgeben kann. 
Allerdings habe ich mittlerweile auch schon eine ganze Menge Zeit 
verbraten und ich bin mir nicht sicher, ob man "objekorientiert" 
wirklich schneller programmieren kann als ohne.

Hier eine kleiner Test-Dump, wenn ich das Programm starte.
Erst wird der Code disaasembliert und dargestellt ( inclusive 
Befehlsbeschreibung ), dann wird die Simulation gestartet:

MC Simulator V0.003

test code
0000: 0000  NOP              no operation
0001: 9403  INC R0              increment register
0002: 3003  CPI R0,$3              compare with immediate value
0003: F7E9  BRNE -3              branch if not equal
0004: CFFE  RJMP -2              relative jump
0005: F7F1  BRNE -2              branch if not equal
0006: 3402  CPI R0,$66              compare with immediate value
0007: F409  BRNE 1              branch if not equal
0008: C002  RJMP 2              relative jump
0009: 0F01  ADD R16,R17              add without carry
000A: 9503  INC R16              increment register
000B: 0000  NOP              no operation

simulator run
0 :NOP      00 00 00 00 00 00 00 00 I:0 T:0 H:0 S:0 V:0 N:0 Z:0 C:0
1 :INC R0      01 00 00 00 00 00 00 00 I:0 T:0 H:0 S:0 V:0 N:0 Z:0 C:0
2 :CPI R0,$3      01 00 00 00 00 00 00 00 I:0 T:0 H:1 S:0 V:1 N:1 Z:0 
C:1
3 :BRNE -3      01 00 00 00 00 00 00 00 I:0 T:0 H:1 S:0 V:1 N:1 Z:0 C:1
1 :INC R0      02 00 00 00 00 00 00 00 I:0 T:0 H:1 S:0 V:0 N:0 Z:0 C:1
2 :CPI R0,$3      02 00 00 00 00 00 00 00 I:0 T:0 H:1 S:0 V:1 N:1 Z:0 
C:1
3 :BRNE -3      02 00 00 00 00 00 00 00 I:0 T:0 H:1 S:0 V:1 N:1 Z:0 C:1
1 :INC R0      03 00 00 00 00 00 00 00 I:0 T:0 H:1 S:0 V:0 N:0 Z:0 C:1
2 :CPI R0,$3      03 00 00 00 00 00 00 00 I:0 T:0 H:0 S:0 V:0 N:0 Z:1 
C:0
3 :BRNE -3      03 00 00 00 00 00 00 00 I:0 T:0 H:0 S:0 V:0 N:0 Z:1 C:0
4 :RJMP -2      03 00 00 00 00 00 00 00 I:0 T:0 H:0 S:0 V:0 N:0 Z:1 C:0
3 :BRNE -3      03 00 00 00 00 00 00 00 I:0 T:0 H:0 S:0 V:0 N:0 Z:1 C:0

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wer sich für den Code interessiert, kann die neueste Version jetzt hier:

http://www.hobby-roboter.de/forum/download/file.php?id=19

herunterladen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.