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
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
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
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...
>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.
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 ;)
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.
>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?
1 | // commands without parameter
|
2 | //public AvrCommand(String name, Parameter parameter1,int opcode,int opcodeMask,int opcodeLength,int cycles)
|
3 | commands.add(new AvrCommand("NOP",0x0000,0xFFFF,1,1)); |
4 | commands.lastSetDescription("no operation"); |
5 | |
6 | // commands with one parameter
|
7 | Parameter k=new Parameter("k","",0x0FFF); |
8 | commands.add(new AvrCommand("RJMP",k,0xC000,0xF000,1,2)); |
9 | commands.lastSetDescription("relative jump"); |
@ 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)
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
>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
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
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.
> 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.
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
>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.
> 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!!!!!!!
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:
1 | public class Instr_INC extends Instruction |
2 | {
|
3 | public Instr_INC() |
4 | {
|
5 | Parameter Rd=new Parameter("Rd",0x01F0); |
6 | command=new AvrCommand("INC",Rd,0x9403,0xFE0F,1,1); |
7 | command.setDescription("increment register"); |
8 | }
|
9 | public void execute(CPU cpu) |
10 | {
|
11 | int sreg=cpu.getRegisterSet().readSreg(); |
12 | |
13 | int b=cpu.readGpRegister(parameterValue1); |
14 | if(b==0x7F) sreg=sreg|0x08; // set overflow flag |
15 | |
16 | b++; |
17 | cpu.writeGpRegister(b,parameterValue1); |
18 | |
19 | if(b&0x80) sreg=sreg|0x04; // set negativ flag |
20 | if(b==0) sreg=sreg|02; // set zero flag |
21 | cpu.getRegisterSet().writeSreg(sreg); |
22 | |
23 | cpu.updateProgrammCounter(command.length()); |
24 | }
|
25 | }
|
Das S-Flag steht noch aus, da fällt mir keine effektive Implementierung ein.
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
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.