Forum: Compiler & IDEs avr-gcc: Linken mit fest vorgegebenen Offsets


von Matthias H. (retrode)


Lesenswert?

Hallo zusammen,

ich möchte gern eine AVR-Anwendung, bestehend aus mehreren C-Quellfiles, 
so linken, dass der Code der einzelnen Komponenten an wohldefinierten 
Adressen beginnt. Also main.C an 0x000, library1.C an 0x200, und so 
weiter. In Assembler würde dem ja etwas wie
1
.org 0x200

entsprechen, aber asm volatile (".org 0x200") in den C-Quellen scheint 
aus verschiedenen Gründen nicht zu funktionieren:

(1) wird die Adresse relativ zum Offset der C-Datei interpretiert und 
beim Linken dann nochmal verschoben, und
(2) komme ich mit asm volatile auch nicht ganz an den Anfang der Datei 
heran, denn das kann offenbar nur innerhalb von Funktionen stehen. Das 
Resultat ist dann eine Funktion, die mit gut 1000 NOP s anfängt.

Der Linker kann mit Option -M wohl eine Map ausgeben, aber ich will die 
Anlage ja aktiv kontrollieren.

Irgendwelche Ideen? Bin dankbar für jedwede Tipps.

Schönen Gruß,
Matthias

: Verschoben durch Moderator
von Guru (Gast)


Lesenswert?

Stichwort sections

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


Lesenswert?

Wofür soll denn die Übung gut sein?  Es ist doch gerade der Sinn
des Linkens, dass man das, was zusammen gehört, auch zusammen packen
lässt.

von Matthias H. (retrode)


Lesenswert?

Okay, dann frage ich mal andersherum: wie bekomme ich ein 
AVR-GCC-Projekt am einfachsten in einen statischen Bootloaderteil und 
einen veränderlichen Anwendungsteil segmentiert, wobei letzterer an 
einer Flash-Seitengrenze ausgerichtet sein sollte?

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


Lesenswert?

Bootloader separat bauen und laden.  Schließlich soll der ja auch dann
noch bestehen bleiben, wenn die Applikation mal neu geflasht werden
muss, also muss er komplett unabhängig von der Applikation sein.

Wenn die Applikation Funktionen aus dem Bootloader benutzen können
will, dann geht das am einfachsten und sichersten über eine Vektor-
tabelle am Anfang des Bootloaders.  Diese verzweigt dann zu den
eigentlichen Funktionen, die Lage der Eintrittspunkte in der Tabelle
ist fest, aber wo sie tatsächlich im Bootloader liegen, muss die
Applikation nicht mehr wissen.

von Matthias H. (retrode)


Lesenswert?

Hallo Jörg,

danke für deine Antwort. Da fehlte euch allen, wie mir gerade klar wird, 
leider noch ein entscheidendes Stück Information von meiner Seite. Der 
verwendete uC (ATTiny85) unterstützt von Hause aus leider keinen 
Bootloader mit eigener Interrupttabelle im Sinne von IVCE/IVSEL. Sonst 
wäre ein "klassischer" Bootloader natürlich die beste Lösung. (Bevor 
jemand nachfragt: ein dickerer AVR ist aus Platzgründen nicht drin; 
unsere Platine ist winzig und auch mit ihren 6x6mm schon weitaus größer 
als es uns lieb ist.)

Wie können wir also unter den gegebenen Voraussetzungen unser Programm 
am elegantesten in einen Bootloader und eine Anwendung segmentieren? 
Unser Bootloader hat (sozusagen als Mini-BIOS) je eine Pin-Change- und 
eine Timer-ISR sowie einige globale Variablen, die auch von der 
Anwendung genutzt werden. Alle anderen Interrupts soll die Anwendung 
nutzen können, was wahrscheinlich auf eine RJMP-Lösung im Bootloader 
hinausläuft.

Ich sehe außerdem kein prinzipielles Problem darin, BL und App gemeinsam 
zu bauen, hingegen aber viele Vorteile. Der BL weiß ja seine eigene 
Größe und kann die entsprechenden Flash-Pages vor Schreibzugriffen 
schützen. Die Anwendung kennt Funktions- und Variablendeklarationen des 
Bootloaders, ohne wilde Pointerspiele.

Viele Grüße,
Matthias

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


Lesenswert?

Matthias H. schrieb:
> Der
> verwendete uC (ATTiny85) unterstützt von Hause aus leider keinen
> Bootloader mit eigener Interrupttabelle im Sinne von IVCE/IVSEL.

Das hindert dich doch trotzdem nicht, einen Einsprungvektor für den
Bootloader zu schaffen.  Da du auch Interrupts im Bootloader nutzen
können willst, musst du wohl oder übel die komplette page #0 als
nicht beschreibbar (zum Bootloader gehörig) deklarieren, damit du
nicht riskierst, dass dem Bootloader die ISRs weggeschossen werden.
Eine page auf dem ATtiny85 ist 64 Byte groß, und du hast 15 Vektor-
Eintrittspunkte (einschließlich Reset), also 30 Bytes.  Da bleiben
dir noch 34 Bytes (17 Einträge) für weitere Sprünge in den Bootloader,
die dann später ihren Platz nie wieder ändern.

Die eigentliche Applikation würde ich dann auf Adresse 0x0040 linken,
einschließlich ihrer normalen Interruptvektortabelle etc. pp.  Die
"richtige" Vektortabelle verzweigt dann jeweils mit (festen) RJMPs
in diese Tabelle für alle Vektoren, die nicht durch den Bootloader
belegt werden.

> Ich sehe außerdem kein prinzipielles Problem darin, BL und App gemeinsam
> zu bauen, hingegen aber viele Vorteile. Der BL weiß ja seine eigene
> Größe und kann die entsprechenden Flash-Pages vor Schreibzugriffen
> schützen. Die Anwendung kennt Funktions- und Variablendeklarationen des
> Bootloaders, ohne wilde Pointerspiele.

Was passiert, wenn du später die Applikation neu bauen willst?  Der
Bootloader ist ja schon da.  Es könnte sich dabei um einen anderen
Bootloader handeln als den, der wirklich bereits im Device ist (falls
du nämlich nachträglich einen Fehler im Loader gefunden und korrigiert
hast, wenn schon eine Reihe an Geräten "ausgerollt" ist).

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.