Forum: Compiler & IDEs Wie AVR-Progamm simulieren?


von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Hi,

ich würd gerne mit der GNU AVR-Toolchain erzeugte Programme simulieren, 
bzw. Teile davon.

Die Programme werden automatisch generiert, so daß der 
Simulator/Debugger geskriptet werden können muss.

Als Beispiel folgendes kleines C-Programm, für das die Ausführungszeit 
zwischen Zeile 7 und 9 (den beiden asm) ermittelt werden soll:
1
#include <avr/io.h>
2
3
void __attribute__((noinline)) foo(void);
4
5
int main(void)
6
{
7
    asm volatile ("" ::: "memory");
8
    foo();
9
    asm volatile ("" ::: "memory");
10
    return 0;
11
}
12
13
void foo (void)
14
{
15
    // mach was
16
}

Mit avr-gdb + simulavr kann man das Programm zwar starten, etwa mit 
einen gdb-Skritp wie
1
target remote 127.0.0.1:1212
2
load
3
b main.c:7
4
b main.c:9
5
c

jedoch kommt man nicht an die Ticks ran, die zwischen den beiden 
Brechpunkten vergeht. simulavr unterstützt kaum SFRs, und über avr-gdb 
kommt man auch nicht an die Info ran.

AVR-Studio scheidet aus. Ich hab bisher keine Info darüber gefunden, daß 
es in irgendeiner Weise skriptbar ist. Und für zig generierte Programme 
von Hand rumzuclicken bis die Maus qualmt tut sich niemand ernsthaft an.

Hat jemand schon mal sowas gemacht oder ein paar Ideen dazu?

Grüß, Johann

Nachtrag: foo enthält nur reinen C-Code und keine Zugriffe auf (interne) 
Peripherie wie Timer, Ports, etc.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Hmm.  Ich würde wohl simulavr schnell so modifizieren, dass er beim
Erreichen eines BREAK nicht abbricht sondern nur die Statistik
ausgibt:
1
--- src/decoder.c.orig  2008-01-07 14:04:54.000000000 +0100
2
+++ src/decoder.c  2009-01-06 14:31:27.000000000 +0100
3
@@ -740,8 +740,8 @@
4
        break replaced here or let the caller handle that? For now we defer
5
        that to the caller. */
6
 
7
-/*     return opcode_BREAK; */
8
-    return BREAK_POINT;
9
+    avr_core_PC_incr (core, 1);
10
+    return opcode_BREAK;
11
 }
12
 
13
 static int

Dann kannst du um dein foo() herum zwei
1
asm volatile("break");

platzieren.  Allerdings musst du den Simulator dann von außen
abschießen, da er natürlich (wie ein richtiger AVR) kein
,,natürliches'' Ende finden kann.  Oder aber du modifizierst
zusätzlich irgendeinen anderen Befehl, den du sonst nicht brauchst,
so, dass dieser ein «return BREAK_POINT;» ausführt und damit dann den
Simulator stoppt.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Daran simulavr zu ändern hatte ich auch schon gedacht, aber eher
-- Die Ticks von gdb aus abfragbar machen, etwa $clock oder $ticks
-- Die Ticks von gdb aus setzen können
-- simulavr von gdb aus beenden

Oder müsste dazu auch avr-gdb angepasst werden? Das wäre dann zu 
schmerzhaft...

Ist simulavr überhaupt noch in der Entwicklung? Die letzten Neuigkeiten 
auf der HP sind von 2005...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Johann L. wrote:
> Daran simulavr zu ändern hatte ich auch schon gedacht, aber eher
> -- Die Ticks von gdb aus abfragbar machen, etwa $clock oder $ticks

Ich glaube, dafür müsstest du den GDB anfassen.  Keine Ahnung, ob
es eine Möglichkeit gibt, über so eine Art "Escape" den GDB einen
Wert im remote target abfragen zu lassen, über den er vorab keinerlei
Informationen besitzt.

> Ist simulavr überhaupt noch in der Entwicklung?

Nein, im Prinzip wurde es mal durch simulavrxx abgelöst, aber erstens
hat dessen Autor auch relativ wenig Motivation, derzeit da irgendwelche
Arbeit reinzustecken (,,das tut, wofür ich es brauche'') und zweitens
haben die beiden (Autor + Admin) offenbar auch keine Motivation, einen
Release-Prozess irgendwie zu organisieren.  Daher gibt es für simulavrxx
also praktisch nur ein uraltes alpha-Release und ein CVS.

Da simulavr selbst (ohne xx) noch in der Testsuite der avr-libc
benutzt wird und mich ein paar der uralten Bugs so genervt haben, dass
ich sie mal reparieren wollte, habe ich mir dann mal Zugriffsrechte
für das CVS geben lassen und so wenigstens noch zwei, drei Bugfix-
Releases davon selbst gezimmert.  Im Gegensatz zu simulavrxx hat es
wenigstens eine autoconf-Infrastruktur, sodass ein Release recht
einfach zu bauen ist und auch auf meinem FreeBSD läuft (simulavrxx
habe ich da noch nicht einmal geschlossen bauen können).  Wirklich
pflegen mag ich aber simulavr auch nicht so recht, habe so schon
genug an der Backe.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Ok, werd mich vielleicht mal dranmachen wenn ich viel Zeit und Lust hab.

BTW dachte ich, daß die Testsuite auf realer Hardware getestet wird?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Johann L. wrote:

> BTW dachte ich, daß die Testsuite auf realer Hardware getestet wird?

Die avr-libc selbst wird auch auf realer Hardware getestet
(insbesondere sind alle ,,offiziellen'' Codebeispiele getestet),
aber die Testsuite läuft gegen den Simulator und nutzt das Feature
von simulavr aus, dass man nach der Simulation einen ``core dump''
bekommt mit dem Speicher- und Registerabbild am Ende der Simulation,
welches man automatisiert auswerten kann.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

hmmm, und wie geht das?

Mit "-C" macht er mir ne "core_avr_dump.core" wo alle SFRs + RAM = 0x00 
sind und das komplette Flash = 0xff.

Irgendwie ist der simulavr ziemlich nutzlos hab ich den Eindruck. Kann 
man den überhaupt von avr-gdb aus beenden? Intern wird ein kill 
unterstützt irgendwi in gdbserver.c, aber keine Ahnung wie man das 
triggert...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Johann L. wrote:

> Mit "-C" macht er mir ne "core_avr_dump.core" wo alle SFRs + RAM = 0x00
> sind und das komplette Flash = 0xff.

Wenn man ihn ohne GDB startet, dann hinterlässt er am Ende (also
beim Erreichen eines BREAK) ein corefile, das weiter nichts als ein
reines Textfile ist.

> Irgendwie ist der simulavr ziemlich nutzlos hab ich den Eindruck.

Naja, die CPU-Core-Simulation ist meines Wissens (vom fehlenden Xmega
natürlich abgesehen) recht vollständig.  Wo's ihm wirklich fehlt ist
am IO-Support.  Da soll simulavrxx besser sein, aber mittlerweile
wohl auch Jahre hinterher (d. h. auf dem Niveau eines ATmega128
stehen geblieben).

> Kann
> man den überhaupt von avr-gdb aus beenden? Intern wird ein kill
> unterstützt irgendwi in gdbserver.c, aber keine Ahnung wie man das
> triggert...

«signal 9» würde ich aus dem Bauch raus sagen.  Ich benutze mehr
AVaRICE als die Simulation, da braucht man ganz häufig «signal 1»,
da dies im JTAG ICE einen Reset auslöst.  Ich glaube, man kann
auch SIGKILL und SIGHUP symbolisch schreiben.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

SIGHUP et al. senden das Signal doch an das zu debuggende Programm, 
nicht an simulavr, oder?

momentan bin ich mit windoofs geschlagen, da ist das eh ein Krampf
1
debug:
2
  $(CPATH)avr-gdb --nw --nx -x gdb.init main.elf
3
  $(CWD)/simeval.sh $(TICKS) `grep 'decoder.*clock' out.txt | gawk '{print $$10;}'`

mir der gdb.init
1
shell sh -c "d:/avr/test/sim.sh"
2
target remote 127.0.0.1:1212
3
load
4
b main.c:9
5
b main.c:11
6
cont
7
cont
8
#sig SIGTERM
9
detach
10
shell sh -c "d:/avr/test/kill.sh"
11
quit

Die sim.sh startet den simulator und schreibt ein Skript um ihn zu 
beenden:
1
#!/bin/sh
2
3
KILLSH=d:/avr/test/kill.sh
4
OUT=d:/avr/test/out.txt
5
rm -f ${OUT}
6
7
e:/WinAVR-20081205/bin/simulavr -d atmega8 -g -D > ${OUT} &
8
9
PID=$!
10
11
echo "#!/bin/sh" > ${KILLSH}
12
echo "kill $PID" >> ${KILLSH}

Immerhin taugt die momentane Lösung zum automatischen Auswerten der 
Ticks, aber nur weil simulavr so gnädig ist, die Ticks auf stdout zu 
schreiben.

Aber wie ich es auch anstelle, mit -C erhalte ich ein triviales 
coredump...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Johann L. wrote:
> SIGHUP et al. senden das Signal doch an das zu debuggende Programm,
> nicht an simulavr, oder?

Ja, sieht leider so aus, als könnte man simulavr nur durch einen
externen Interrupt abbrechen.

von Mario Schwarz (Gast)


Lesenswert?

@Jörg,

mmh - das simulavr nicht auf dem neusten Stand ist hab ich nun auch 
gemerkt. Aber vielleicht kannst du mir als Experte das nochmal 
bestätigen - ich simuliere einen Atmega 16 und möchte den 16bit Timer 
initialisieren. Aber in den entsprechenden Registern TCCR1B, TCCR1A und 
OCR1A passiert laut dem simulavr-disp nix, obwohl ich sie im Programm 
belege...

Kannst du bestätigen, dass es nicht implementiert ist? Beim Startup 
meldet der simulavr ja auch sowas:

devsupp.c:338: MESSAGE: TODO: attach IO Reg 'OCR1AL' at 0x004a
devsupp.c:338: MESSAGE: TODO: attach IO Reg 'OCR1AH' at 0x004b
...
devsupp.c:338: MESSAGE: TODO: attach IO Reg 'TCCR1B' at 0x004e
devsupp.c:338: MESSAGE: TODO: attach IO Reg 'TCCR1A' at 0x004f

MMH muss ich mir doch nen JTAG adapter kaufen und auf der Zielhardware 
debuggen :-(

Gruss
  Mario

von Oliver (Gast)


Lesenswert?

>MMH muss ich mir doch nen JTAG adapter kaufen und auf der Zielhardware
>debuggen :-(

Zum einfachen Debuggen gibts ja immer noch AVRStudio oder VMLAB. Timer 
simulieren können die beide wunderbar. Ist halt für Windows, wer Linux 
nutzt, muß halt leiden :-) (oder WINE probieren)

Oliver

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Mittlerweile kann auch simulavrxx einen Blick wert sein.  Ist in den
letzten Wochen einiges getan worden daran, insbesondere gibt es jetzt
eine funktionierende autoconf-Infrastruktur, sodass man es auf gängigen
Unixen erstmal out of the box compiliert bekommt.  Auch das Projekt
ist nicht wirklich vollständig, aber in vielen Details doch ein ganzes
Stück weiter.  16-bit-Timer an sich sind dort dabei.  Es gibt zwar
keinen ATmega16, aber mit ein paar #ifdefs bekommst du deinen Code
sicher auch für einen ATmega128 compiliert.

Mittels JTAG direkt am Zielsystem zu debuggen, ist natürlich ein
völlig anderes Ding, mit eigenen Vor- und Nachteilen.  Insbesondere
läuft man mit einem Simulator über kurz oder lang eigentlich immer
in das Problem rein, dass man die Komplexität der notwendigen
Stimuli zur Simulation der Umgebung des Controllers nicht mehr
gebacken bekommt.

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
Noch kein Account? Hier anmelden.