Forum: Compiler & IDEs avr-gcc: .vectors verschieben


von Mark .. (mork)


Lesenswert?

Hallo,

wie kann man dem avr-gcc bzw. dem Linker beibringen, .vectors, also die 
Tabelle mit den ISR-Adressen, an einen anderen Ort im Flash zu 
verschieben? Habs mit --section-start=.vectors=0x7800 versucht, aber die 
Tabelle wird immer am Anfang von .text angelegt.

MfG Mark

von mthomas (Gast)


Lesenswert?

Wüsste (zumindest noch) nicht, dass dies mit einem der 
Standard-Linker-Skripte funktionieren kann, wie sie bei 
avr-gcc/avr-libc/WinAVR mitgeliefert werden. vectors-section ist in 
diesen "fest" eingetragen. Es gibt mglw. eine Option für den Linker, mit 
der man das umbiegen kann, kenne aber im Moment keine. Falls niemand 
eine bessere Idee zeigt: vorhandenes Linker-Skipt als Vorlage nehmen und 
modifizieren, dieses dann per "-T" verwenden.

von Oliver (Gast)


Lesenswert?

Was genau ist denn der Zweck der Übung?

Oliver

von haube (Gast)


Lesenswert?

hab sowas in zukunft auch vor ..

aber naja die vectot-tab. zu verschieben wird nix bringen ... denk mal 
das die Tab. dort am anfang des flash liegen muss - da die IRQs feste 
adressen anspringen.   oder ist das nicht so ?


wenn dann müsste man die interruptVectorTab.  irgendwie  mappen / 
jmp-Ptr umleiten .     aber wie man das am besten macht .. da bin ich 
auch überfragt

von Marcus M. (marcus67)


Lesenswert?

Hmm - sollte eigentlich nichts bringen: Der Prozessor erwartet die IRQ 
Sprungtabelle immer an der gleichen Stelle. Lediglich für den Bootloader 
läßt sie sich verschieben - an den Anfang des Bootloaders natürlich.

Gruß, Marcus

von Mark .. (mork)


Lesenswert?

Hallo,

@M. Thomas
Ok, ich werds mal mit dem Linker-Script versuchen. Welches von den 
Scripts in WinAVR ist denn das Standart-Script? Die mit der .x Endung?

@all
Wie Marcus gesagt hat, an kann auswählen, ob die Sprungtabelle am Anfang 
des ganzen Flashes oder am Anfang der Bootloaders sein soll. Tatsächlich 
soll das Ganze eine Art Bootloader werden, der gleichzeitig aber auch 
ein Multithreading-Betriebsystem ist und viele Funktionen für die 
Anwendung bereitstellen soll. Deshalb passt es auch bei weitem(>16KB 
groß) nicht in den Bootloader-Bereich und muss schon bei 0x3000 
beginnen. Die Sprungtabelle muss aber trotzem bei 0x7800 anfangen. Zweck 
der übung ist es, dass ich keine Lust habe, immer eine halbe Minute zu 
warten, bis das Programm endlich auf dem Chip ist und den 
gleichbleibenden Teil nicht immer wieder neu draufmachen will.

MfG Mark

von Tobi (Gast)


Lesenswert?

Hi!

Also ich glaube, das wird so nicht funktionieren! Wie schon erwähnt, der 
Prozessor erwartet die Interrupt-Funktionsadressen an bestimmten Stellen 
--> Die Interruptvektortabelle. Wenn du nun diese Adressen woanders 
hinmappst, funktionieren deine Interrupts nicht mehr, da der Prozessor 
an undefinierte Stellen springt.
Aber vielleicht irre ich mich ja...

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


Lesenswert?

Tobi wrote:

> Aber vielleicht irre ich mich ja...

Ja, du irrst.  Man kann die Tabelle per IVSEL-Bit verschieben.

Nein, die derzeitige Organisation des gcrt1.S gestattet keine
Behandlung der Vektortabelle separat vom Rest von .text.  Was du
aber tun kannst ist, dass du .text und alles, was in den
Bootloader-Bereich passt zusammen mit diesem per
--change-section-address auf die Bootloaderadresse schiebst, aber
die restlichen Funktionen per __attribute__((section("yourname")))
in eine andere section packst, die du dann auf deine 0x3000 (oder
so) ebenfalls per Linkeroption platzierst.  Die genaue Aufteilung
zwischen den beiden großen Codeblöcken (vor und nach der Vektortabelle
resp. dem Anfang des Bootloader-Bereichs) musst du ohnehin manuell
vornehmen, der Linker kann kein ,,Umfließen'' einer einzelnen
input section um einen fest platzierten Bereich in der Ausgabe herum
automatisch organisieren.

von Mark .. (mork)


Lesenswert?

>Wie schon erwähnt, der Prozessor erwartet die Interrupt-Funktionsadressen  an > 
bestimmten Stellen --> Die Interruptvektortabelle.

Ja genau deshalb muss ich die Tabelle ja auch nach 0x7800 (Anfang der 
Bootloader-Section) verschieben. Nur geht es mit 
--section-start=.vectors=0x7800 nicht, weil der Linker die Tabelle immer 
an den Anfang von .text macht, der bei mir aber schon bei 0x3000 
startet.

von Tobi (Gast)


Lesenswert?

Hi!

Ok, das Problem hatte ich auch mal. Ich habe dazu die komplette .text 
Section in den Bootloader-Bereich verschoben. Dann geht's. Aber das geht 
nur, wenn der Code auch in den Bootloader reinpasst!

von Tobi (Gast)


Lesenswert?

Ansosnten Jörgs Methode anwenden!

Sections definieren und da deinen Code reinlegen!
Mir würde nur einfallen eine "naked" Funktion zu deklarieren, die alle 
Interruptvertoren enthält und diese dann auf 0x7800 legen:

--section-start=.mysection=0x7800
1
__attribute__((naked)) __attribute__((section(".mysection"))) Vectortable(void)
2
  {
3
  //Vektoren...
4
  }

von Mark .. (mork)


Lesenswert?

Die Methode von Jörg würde sicher funktionieren, nur gibts de ca. 160 
Funktionen, die ich mit dem Attribut ausstatten müsste, worauf ich keine 
Lust habe. Die Tabelle manuell erstellen möchte ich auch nicht, da jede 
neue hinzukommende ISR dort auch manuell vermerkt werden müsste. Hab 
jetzt das Standard-Ld-Script genommen und .vectors daraus entfernt, 
sodass man mittels --section-start auch .vectors beliebig verschieben 
kann.

Danke euch allen.

MfG mark

von Dirk B. (sharandac)


Lesenswert?

Hallo Mark,

könntest du das nochmal genau erklären, ich arbeite auch gerade mit 
Bootloadern und will auf den ATmega2561 eigentlich mehr als 8Kbyte für 
den Bootloader haben um mehr dort rein zu bekommen. Ziel ist es einen 
vernünftigen Bootloader über Ethernet zu bekommen.

CA Dirk

von Mark .. (mork)


Lesenswert?

Also, im /avr/lib/ldscripts/ Ordner von WinAVR gibt es verschiedene 
Dateien, die je mit avrN anfangen und auf x, xbn, xn etc enden. Dies 
sind alles Dateien, die dem Linker sagen, wie der Speicher des AVRs 
aufgebaut ist und wo welche sections wie .bss, .data ... hinkommen. Die 
Standard-Scripts enden auf .x, beim ATmega2561 heißt sie avr6.x. Um zu 
verhindern, dass .vectors immer automatische an den Anfang von .text(dem 
Flash) gelegt wird, ganz egal was man mittels --section-start angegeben 
hat, muss man .vectors aus .text herausnehmen. Wenn man das Script etwas 
herunterscrollt, steht da
1
"/* Internal text space or external memory.  */
2
  .text :
3
  {
4
    *(.vectors)
5
    KEEP(*(.vectors))
6
    ...

diese beiden Zeilen, wo .vectors steht, muss man entweder 
auskommentieren oder löschen. Jetzt kann man .vectors frei verschieben, 
bzw man muss es machen, weil der Linker meckert. Un damit man nicht am 
Originalfile rumbastelt kann man die Datei in den Projektordner kopieren 
und dem Linker mit -T scriptname mitteilen, dass dieses Script anstatt 
dem normalen verwendet werden soll.

MfG Mark

von haube (Gast)


Lesenswert?

und das funktioniert so ??? also läuftts ?

von Mark .. (mork)


Lesenswert?

Ja, es läuft wunderbar, auch mit Interrupts.

von Tobi (Gast)


Lesenswert?

Nur noch so:

das IVSEL Bit muss doch dann gesetzt sein, oder?

von Mark .. (mork)


Lesenswert?

Jepp, IVSEL muss gesetzt werden.

von Dirk B. (sharandac)


Lesenswert?

Danke für die Antwort. Ich denke mal der Resetvektor liegt dann auch 
mitten im Code des "neuen" Bootloaders, bekommt er das so auch gebacken 
wenn er startet?

CA Dirk

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.