Forum: Mikrocontroller und Digitale Elektronik avr-gcc Linker-Script


von M. H. (doktorgnadenlos)


Lesenswert?

Der Bereich für die Interrupteinsprünge des AT90USB128x  erstreckt sich 
von Byteadresse 0x00000 – 0x00097. Danach beginnt üblicherweise der 
Programmcode. Meine Aufgabe ist es das Makefile so zu gestalten, dass 
der Bereich von 0x00100 bis 0x001FF mit 0xFF ausgefüllt wird, weil dort 
applikationsspezifische Daten untergebracht werden sollen, die ein 
Bootloader reinprogrammieren soll. Dazu habe ich im Makefile

-Wl,-section-start=.devicedata=0x00100

versucht eine Section zu erstellen und im C-Code mit

const unsigned char str3[]  _attribute_ ((section(".devicedata"))) = { 
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
0xFF, 0xFF, 0xFF, 0xFF };

mit Daten zu befüllen.

Jetzt meckert der Linker

section .devicedata [00000100 -> 0000010f] overlaps section .text 
[00000000 -> 00001575]

, weil er an dieser Stelle seinen Programmcode plazieren möchte. Das 
Konstrukt funktioniert nur dann, wenn ich meine Section in einem Bereich 
plaziere, wo (derzeit) noch kein Code vorgesehen ist. Da ich meine 
Sourcen auch für andere AVR-Derivate flexibel halten will, möchte ich 
meine Section nicht am Ende des Flashs, sondern möglichst weit vorne 
plazieren, in einem Bereich, der bei allen AVR-Derivaten vorhanden ist.

Gibt es einen Trick, um diesen Konflikt zu umgehen ? In den zahlreichen 
Threads zu diesem Thema ist mir nichts untergekommen, was mein Problem 
lösen würde.

von ./. (Gast)


Lesenswert?

Den Start der Section .text auf das Ende der section .devicedata legen. 
Ich weiß nicht, ob das über Parameter geht (--section-start nimmt nur 
absolute Adressen) oder nur in einem eigenen Linkerscript (sowas wie "AT 
((LOADADDR (section) + SIZEOF (section)" + ggf Alignment).

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

.text zu verschieben ist keine gute Idee, weil sich damit auch die 
Vektor-Tabelle (.vectors) verschiebt. Hier das Default ld-Skript avr5.x:
1
/* Internal text space or external memory.  */
2
  .text   :
3
  {
4
    *(.vectors)
5
    KEEP(*(.vectors))
6
    /* For data that needs to reside in the lower 64k of progmem.  */
7
    *(.progmem.gcc*)
8
    *(.progmem*)
9
    . = ALIGN(2);
10
     __trampolines_start = . ;
11
    /* The jump trampolines for the 16-bit limited relocs will reside here.  */
12
    *(.trampolines)
13
    *(.trampolines*)
14
     __trampolines_end = . ;
15
    /* For future tablejump instruction arrays for 3 byte pc devices.
Nack .bectors deine Section mit den gewünschten Eigenschaften einfügen 
und die Anwendung mit dem neuen Skript generieren anstatt mit dem 
default-Skript.
Beachte daß es für jede Architektur ein eigenes Skript gibt.

von M. H. (doktorgnadenlos)


Lesenswert?

Vielen Dank für die schnellen Inputs. In der Tat, das Verschieben der 
.text-Section bedeutet auch ein Verschieben der Interrupttabelle und das 
ist in der AVR-Architektur nun mal nicht möglich.
Der Ansatz mit dem ld-Skript funktioniert bestens, Johann L, Danke.
Es ist aber große Vorsicht geboten, weil dieses ld-Skript für alle 
weiteren AVR-Projekte dieser Architektur ebenfalls Verwendung finden 
würde.

von Stefan E. (sternst)


Lesenswert?

M. H. schrieb:
> Es ist aber große Vorsicht geboten, weil dieses ld-Skript für alle
> weiteren AVR-Projekte dieser Architektur ebenfalls Verwendung finden
> würde.

Man ändert ja auch nicht das Default-Skript an Ort und Stelle. Man 
kopiert es in sein Projekt, ändert es, und teilt dem Linker dann auf der 
Kommandozeile mit, dass er jenes Skript nutzen soll anstelle des 
Default-Skripts.

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.