Forum: Compiler & IDEs ATmega 8515 und "jmp 0x000"


von Jürgen S. (jsachs)


Lesenswert?

Hallo,

auf die Gefahr hin das ich mich nun blamiere:
der ATmega8515 kennt wohl keinen "jmp" Befehl. Zumidest meckert der gcc 
bei der Zeile :
asm("jmp 0");
mit :
/tmp/ccu3fldo.s:112: Error: illegal opcode jmp for mcu atmega8515

Ein Blick ins Datenblatt bestätigt meine Vermutung.
Ich nehme an die Lösung ist "rjmp"
Aber wie springe ich da geziehlt an 0x0000 (von meinem Bootloader aus). 
Ich weis ja von meinem C-Code aus nicht an welcher Stelle des Programms 
ich nun stehe.

Danke für Eure Hilfe
Juergen

von Joe D. (kosmonaut_pirx)


Lesenswert?

hallo,
probier doch nen IJMP.
bye kosmo

von johnny.m (Gast)


Lesenswert?

Alle AVRs mit bis zu 8 KB Flash besitzen keinen jmp-Befehl, sondern nur 
den rjmp. jmp gibts nur für die AVRs mit 16 KB Flash und mehr. In jedem 
AVR-Datenblatt steht übrigens hinten eine Tabelle aller Befehle, die für 
den Controller relevant sind.

ijmp macht einen indirekten Sprung und ist etwas ganz anderes.

von Jürgen S. (jsachs)


Lesenswert?

Wie ich schon schrieb, viel mir das im Datenblatt ja auch auf.
Nur wie mache ich es dann.
Kann mir einer hier ein Beispiel geben, also nur die Zeilen die für den 
Sprung Notwendig sind ?

Danke
Juergen

von Joe D. (kosmonaut_pirx)


Lesenswert?

so mache ich es, so funktionierts auch:
1
uint16_t __bl_start = (uint16_t) GET_BL_SECTION_START();
2
 // jump to address
3
  __asm__ __volatile__                           \
4
    (                                            \
5
     "movw r30,%0\n\t"                           \
6
     "ijmp \n\t"                                 \
7
     :                                           \
8
     : "r" ((uint16_t) __bl_start)               \
9
     :
10
    );

warum das was ganz anderes sein soll, bitte verratet es mir.
bye kosmo

von Jürgen S. (jsachs)


Lesenswert?

Danke Joe,

hab dein Beispiel etwas gekürzt:
  asm("movw R30,0x0000");
  asm("ijmp");
Funktioniert tadellos.

Gruss
Juergen Sachs

von Michael U. (Gast)


Lesenswert?

Hallo,

als unlesbare Version (oder als Denkaufgabe ;)

clr r0
push r0
push r0
ret

Gruß aus Berlin
Michael


von johnny.m (Gast)


Lesenswert?

Tja, wenn ich die anderen Postings richtig gelesen hätte, dann hätte 
ich vll. auch mitgekriegt, worum es eigentlich ging... 
schämundineckeverkriech Sorry, kosmo hatte natürlich recht. Michaels 
Variante ist allerdings auch nett...

von Jürgen S. (jsachs)


Lesenswert?

Doch, da muß ich zustimmen.
Michaels Varinte ist echt nett. Den Compiler auch so zu verschaukeln :-)
Aber es funktioniert.

Andere Frage, wieso geht folgendes nicht ?:

void (*restart)(void) = (void (*)(void))0x0000; // Dummyfunktion an 
Adresse 0x0000
restart();

Das wäre eine schöne(?!) C-Only Variante gewesen. Aber durch das 
Verschieben von ".text" in den Bootloader Bereich wandert auch das 
0x0000 dorthin, d.h. der Compiler hat den Wert angepasst.
Wieso macht er das nicht bei den obigen Lösungen in Asembler ?
Oder kann man ihm das für die eine Codezeile verbieten ?

Gruss
Juergen

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.