AVR: Absolute Jumps mit rjmp

Feb 03, 2008 12 Replies

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

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. ;-)

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

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

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=$(

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

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

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

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

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

Johannes Bauer schrieb:

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

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

Falk

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

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. ;-)

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required