goto im avr gcc

Gast #238912
Lesenswert?

Wie schon in der Überschrift drinsteht will ich ein "goto" in mein
Programm einbauen. Hier mal die Beschreibung:



RESTART:

.
.
.

goto RESTART


aber irgendetwas mach ich falsch, da der Compiler mein Projekt so nicht
mag.



Eine andere Frage würde sich darauf beziehen, wie ich an Adresse 0
springen kann, denn nichts anderes will ich hier bewirken (also einen
Software Reset)
Gast #238916
Lesenswert?

Also mehr code ist kein Problem, wobei obrige Lösung mir schon sehr
gefällt, mal noch testen...

...

SIGNAL(SIG_COMPARATOR)
// signal handler for analog comperator
{
     goto RESTART;    // Zeile : 127
}

...

int main(void)
{
RESTART:             // Zeile 140
...


-----------------------------------------------------

Fehlermeldung:
prog.c: In function `__vector_18':
prog.c:127: error: parse error before numeric constant
prog.c: In function `main':
prog.c:140: warning: label `RESTART' defined but not used
make: *** [prog.o] Error 1
Gast #238917
Lesenswert?

So weit ich weiß, kann man in C mit goto ("das ist böse, BÖSE!") nicht
zwischen zwei Funktionen hin- und herspringen. Das wird so also nix. An
die Adresse für den Resetvektor (normalerweise 0) kämst Du außerdem je
nach AVR auch mit
1
  asm volatile ("jmp __vectors"::);

oder (bei kleineren Modelle)
1
  asm volatile ("rjmp __vectors"::);
#238921
Lesenswert?

Salve,

Sprung zur Adresse 0 ist - wie hier ja schon öfters angemerkt wurde -
noch lange kein Software-Reset. Ziel eines Resets ist ja die Rückkehr
in einen definierten Zustand - meist dann, wenn ein Ausnahmezustand
eingetreten ist, der nicht behandelt werden kann. Ein Sprung an Adresse
0 hilft Dir dann überhaupt nicht, wenn sämtliche Interrupts weiterlaufen
und I/Os geschaltet bleiben. Also: Mach es sauber über den Watchdog. Du
sparst Dir ne Menge Zeit und Ärger. Sind ja auch nur zwei Zeilen.

@Volkmar:
Bist Du sicher, daß die Register initialisiert werden? Imho bleiben die
bestehen (solange die Spannung nicht getrennt wird), nur I/O-Ports
werden auf 0x00 gelöscht.

Mark
Moderator Persönliche Seite #238923
Lesenswert?

Ich kann's nur immer wiederholen.  Atmels Appnote AVR109
macht es völlig portabel vor:
1
    void (*funcptr)( void ) = 0x0000; // Set up function pointer to
2
RESET vector
3
...
4
                funcptr(); // Jump to Reset vector 0x0000 in
5
Application Section

Mit Optimierung generiert das Ganze exakt einen CALL (oder RCALL,
je nach Prozessor) nach 0, ohne weiteren Speicherverbrauch o.ä.
Gast #238935
Lesenswert?

Hmm, also mein avr-g++ macht aus dem Aufruf:
1
        lds r30,funcptr
2
        lds r31,(funcptr)+1
3
        icall

Das ist genau das, was ich erwartet hätte.
Daß er den Zugriff auf funcptr nicht wegoptimieren kann, ist logisch,
da es weder eine lokale Variable, noch konstant ist. Damit kann der
Compiler nicht darauf vertrauen, daß der Wert immer 0 ist und muß den
Lesezugriff auf die Variable tatsächlich durchführen.
Moderator Persönliche Seite #238936
Lesenswert?

Ich bekomme dafür (allerdings mit GCC 3.4.6, ebenfalls -Os) diesen
Code generiert:

/* #APP */
        cli
/* #NOAPP */
        rcall 0
        rjmp .L536

Allerdings löst der Assembler den rcall 0 irgendwie ,,schräg'' auf,
offenbar versucht er die 0 relativ auf irgendwas zu beziehen.  Es
entsteht daraus ein Call auf die Adresse 0x7a (init_main).  Das halte
ich für einen Bug im Assembler.

Für einen Prozessor > 8 KB macht er dann einen call 0 draus, was
korrekt ist.

GCC 4.1.0 macht daraus:

/* #APP */
        cli
/* #NOAPP */
        ldi r30,lo8(0)
        ldi r31,hi8(0)
        icall
        rjmp .L189

Das sollte unstrittig richtig sein.
Moderator Persönliche Seite #238939
Lesenswert?

> Sollte der übergebene Wert
> nicht relativ zur aktuellen Adresse sein?

Zumindest trägt er dann keine 0 ein in den Opcode. ;-)

Normalerweise steht da ja eine externe Referenz, die der
Linker dann auflöst.  Wenn man einen Label auf Adresse 0
setzen würde, könnte der Compiler stattdessen den RCALL
auf diesen Label beziehen.  Im Prinzip gibt's den Label
sogar, der heißt __vectors.  Der Compiler könnte also
ein "rcall __vectors" ausgeben, dann wäre alles in Butter...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren