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