AVR: Absolute Jumps mit rjmp

Hallo Gruppe,

und gerade ist mir beim Herumspielen noch etwas aufgefallen: Wenn ich aus einer C-Datei, die ich mit avr-gcc übersetze auf einem AVR einen absoluten Jump einfügen will, ohne das jmp-Kommando zu verwenden (das unterstützen einige Einheiten ja nicht), muss ich auf rjmp ausweichen. Damit das automatisch die aktuelle Adresse verwendet:

__asm__ __volatile__("JumpLbl: rjmp .+0x100 - JumpLbl");

führt im Code dazu:

274: 73 cf rjmp .-282 ; 0x15c

d.h. immer 0x5c Bytes zu weit. Wenn ich diese 0x5c immer abziehe

__asm__ __volatile__("JumpLbl: rjmp .+0x100 - JumpLbl - 0x5c");

dann klappt es - aber eine "saubere" Lösung ist das nicht. Insbesondere denke ich mal, dass diese 0x5c davon abhängen für welches Device ich übersetze (Anzahl der Interruptvektoren u.ä.). Ich nehme an, dass diese Differenz damit zusammenhängt, dass das "JumpLbl" Label aufgelöst wird, bevor der Code reloziert ist (also vor dem Linkerskript). Wie bekomme ich das Deviceunanhängig hin?

Viele Grüße, Johannes

--
"PS: Ein Realname wäre nett. Ich selbst nutze nur keinen, weil mich die
meisten hier bereits mit Namen kennen." -- Markus Gronotte aka Makus /
Kosst Amojan / maqqusz / Mr. G / Ferdinand Simpson / Quartillia
Rosenberg in dse
Reply to
Johannes Bauer
Loading thread data ...

Johannes Bauer schrieb:

Was soll das denn für einen Sinn haben?

Wenn du Assembler schreiben willst, dann schreib Assembler, aber irgendwie wild aus einer C-Datei rumspringen hat keinen Sinn.

--
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Reply to
Joerg Wunsch

Joerg Wunsch schrieb:

Ich will zwei Codeteile zusammenpappen, einen, den ich in Assembler geschrieben habe und explizit an eine bestimmte Stelle linke (ganz ans Ende, "Bootloader"). Dazu dann das "eigentliche" Programm, das ganz gewöhnlich compiliert wird. Zusammengepappt werden die Codeschnipsel mit etwas avr-objcopy und dd. An irgendeiner Stelle im Programm will ich nun den unteren Teil anspringen, wenn z.B. eine bestimmte Magic-Sequenz kommt. Dazu brauche ich das.

Alternativ: Den Bootloadercode in eine eigene Object-Datei compilieren, die in eine eigene Section linken und die Position dieser Section explizit definieren - geht das? Dann kann ich auch schön mit den bekannten Symbolen arbeiten.

Viele Grüße, Johannes

--
"PS: Ein Realname wäre nett. Ich selbst nutze nur keinen, weil mich die
meisten hier bereits mit Namen kennen." -- Markus Gronotte aka Makus /
Kosst Amojan / maqqusz / Mr. G / Ferdinand Simpson / Quartillia
Rosenberg in dse
Reply to
Johannes Bauer

C kennt das Schl=C3=BCsselwort "goto". Versuch's mal damit. =C3=9Cber Funktionsgrenzen hinweg zu springen ist eh nicht sinnvoll (Stichwort Stackrahmen).

Wolfgang Draxinger

--=20 E-Mail address works, Jabber: snipped-for-privacy@jabber.org, ICQ: 134682867

Reply to
Wolfgang Draxinger

Johannes Bauer schrieb: ...

Mächtig kompliziert und fehlerträchtig.

Ich mache es gerade so. Im assembler-programm wird beim Booten der UART initialisiert. Kommt binnen X Sekunden kein bestimmtes Zeichen, wird nach "0000" gesprungen. Das kann man so machen, daß man zweimal 0 auf den Stack pusht und dann "ret" ausführt.

Assembler code, "flash.S":

------------------------- #include

.section .bootld .org 0x0 ;Set 9600 Bd ldi r31,((F_CPU)/(9600*16)-1)&0xff

... arbeiten ... ;RESET ins Programm exitloops: ldi r31,0 ldi r30,0 ijmp

-------------------------- Im Makefile steht u.a.: ASFLAGS = -Wa,-adhlns=$(

Reply to
Falk Willberg

Also eigentlich macht man das ja so, dass man mit einem Pragma die Startadresse f=C3=BCr die nachfolgenden Funktionen im C Quelltext festlegt und in dieser Funktion dann, wenn's denn sein muss, inline Assembler verwendet.

Wolfgang Draxinger

--=20 E-Mail address works, Jabber: snipped-for-privacy@jabber.org, ICQ: 134682867

Reply to
Wolfgang Draxinger

Wolfgang Draxinger schrieb:

Welches Pragma ist das denn beim avr-gcc?

Viele Grüße, Johannes

--
"PS: Ein Realname wäre nett. Ich selbst nutze nur keinen, weil mich die
meisten hier bereits mit Namen kennen." -- Markus Gronotte aka Makus /
Kosst Amojan / maqqusz / Mr. G / Ferdinand Simpson / Quartillia
Rosenberg in dse
Reply to
Johannes Bauer

Falk Willberg schrieb:

Hmm, du definierst dir die bootld-Section, die aber den Origin bei 0x0 hat - wie relozierst du die dann beim Linken, im Makefile hab ich dazu nichts gefunden. Also sagen wir, du willst die komplette bootld-Section nach 0x700 relozieren - was wären die Linkerbefehle?

Viele Grüße, Johannes

--
"PS: Ein Realname wäre nett. Ich selbst nutze nur keinen, weil mich die
meisten hier bereits mit Namen kennen." -- Markus Gronotte aka Makus /
Kosst Amojan / maqqusz / Mr. G / Ferdinand Simpson / Quartillia
Rosenberg in dse
Reply to
Johannes Bauer

Wolfgang Draxinger schrieb:

Für ein goto brauche ich aber ein bekanntes Symbol - das habe ich nicht. Dass ich mit dem Stackframe böse(tm) Sachen mache ist mir klar ;-) Aber das ist in dem Fall kein Problem, weil ich nachher auch einen Reset ausführe.

Viele Grüße, Johannes

--
"PS: Ein Realname wäre nett. Ich selbst nutze nur keinen, weil mich die
meisten hier bereits mit Namen kennen." -- Markus Gronotte aka Makus /
Kosst Amojan / maqqusz / Mr. G / Ferdinand Simpson / Quartillia
Rosenberg in dse
Reply to
Johannes Bauer

Johannes Bauer schrieb:

Da steht: ALL_CFLAGS = -mmcu=$(MCU) -Wl,--section-start=.bootld=0x1800 Für atmega8. Das Flag BOOTRST ist programmiert, so daß direkt in den Assembler-Teil gesprungen wird.

--section-start=.bootld=0x0700

Aber Vorsicht, die Adressen im Handbuch sind Wort-Adressen. Die 0x1800 bei mir passen zu den 0x0c00 im Handbuch.

Falk

Reply to
Falk Willberg

Johannes Bauer schrieb:

"usart_getc" soll in der section ".bootld" liegen:

uint8_t usart_getc (void) __attribute__ ((section (".bootld")));

Falk

Reply to
Falk Willberg

Falk Willberg schrieb:

Kann sein, dass das in deinem Makefile steht, aber in deinem Beispiel hast du's weggelassen. Danke dafür!

Ciao, Johannes

--
"PS: Ein Realname wäre nett. Ich selbst nutze nur keinen, weil mich die
meisten hier bereits mit Namen kennen." -- Markus Gronotte aka Makus /
Kosst Amojan / maqqusz / Mr. G / Ferdinand Simpson / Quartillia
Rosenberg in dse
Reply to
Johannes Bauer

Johannes Bauer schrieb:

void (*startprog)(void) = (void (*)(void))0;

... startprog();

Hmm, Mist, geht hier nicht ganz so, da der ATtiny2313 keine BOOTRST-Fuse hat. :-( Dann musst du dir wohl oder übel die tatsächliche Startadresse deiner Applikation da oben eintragen lassen.

Dass der Aufruf von startprog() eine Adresse auf den Stack pusht, braucht dich nicht zu stören, da die Applikation den Stack sowieso reinitialisiert.

--
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Reply to
Joerg Wunsch

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.