Forum: Compiler & IDEs GCC Cortex M3/M4 flashbereich splitten


von Michael D. (Gast)


Lesenswert?

Hallo Leute,

bei meinem aktuellen Projekt (CortexM4) würde ich gerne den Flashbereich 
"splitten":

Sector0 - Applikation
Sector1 - Seperates File
Sector2 und folgend - Applikation

Sinn dahinter ist der dass das File klein ist, nicht mit der Applikation 
geflasht wird und ich keinen der großen Sektoren dafür verwenden möchte.

Unter Keil geht das definitiv, nur wie funktioniert es unter gcc?

Ich vermute mal im Linkersript.

/* Specify the memory areas */
MEMORY
{
  FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 16K
  FLASH_2 (rx)    : ORIGIN = 0x08010000, LENGTH = 192K
  RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 112K
}

Funktioniert so leider nicht, da ich später in den SECTIONS eine 
Location angeben muss:

 /* The program code and other data goes into FLASH */
  .text :
  {
    .....
    .....
  } >FLASH

Wie macht man sowas am besten?

Vielen Dank,
Mike

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Man kann z.B. die Funktionen die in den "Sector0" in eine extra 
Input-Section legen (vgl. gcc Dokumentation zu function attributes), 
diese Section dann im Linker-Script in den Block Output-Section "FLASH" 
eintragen und "Sector2"-Funktionen, die in *.text* input-sections liegen 
in eine Output-Section für "FLASH_2". Eine weitere Möglichkeit besteht 
darin Objekte aus bestimmten Dateien in die jeweiligen Output-Sections 
inzutragen (w.r.e. kann man das bei Scatter-Load-Files auch). Vgl. dazu 
binutils-Dokumentation->ld (so in der Art *objectfile.o(.text.*) und 
*(EXCLUDE_FILE (*objectfile.o) .text - genauen Syntax gerade nicht im 
Kopf). Falls es nur darum geht die Vektortabelle im "Sector 1" 
unterzubringen: die hat ohnehin schon eine eigen Input-Section, die man 
im Linker-Script dann in eine weitere Output-Section eintragen kann.

von Michael D. (Gast)


Lesenswert?

Hallo Martin Thomas,

vieln Dank für den Beitrag.

Klingt schön kompliziert und ich muss zugeben davon nichts verstanden zu 
haben.

Im Prinzip möchte ich das Programm ganz normal flashen, beginnend von 
Sector 0 aufsteigend, nur eben dass Sector 1 nicht verwendet wird.

Mfg,
Michael

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Das ist nicht wirklich kompliziert nur leider sind die Begriffe etwas 
ungewohnt und die Dokumentation ist keine allzu leichte Kost. Wie auch 
immer: Falls "section 0" nicht randvoll sein muss, also nur die 
Vektortabelle am Beginn des Flash-Speichers stehen muss, damit der 
Cotroller den Einstieg findet, kann man so etwas machen:
1
.text {
2
  KEEP(*(.vector_table))
3
  . = 0x10000;
4
  *(.text*)
5
  (...)

siehe auch: 
http://sourceware.org/binutils/docs/ld/Location-Counter.html#Location-Counter


"Unter Keil geht das definitiv" - wirklich? Also der Linker kann einfach 
um Löcher im Speicherbereich herumlinken? Intressant - aber das ist ja 
das GCC-Forum und damit Realview-Tools OT.

von Michael D. (Gast)


Lesenswert?

Hallo Martin Thomas,

nochmals vielen Dank, dass hat so geklappt!

Dass ganze sieht jetzt so aus (im Atollic Linkerscript für den STM32F4):
1
/* Define output sections */
2
SECTIONS
3
{
4
  /* The startup code goes first into FLASH */
5
  .isr_vector :
6
  {
7
    . = ALIGN(4);
8
    KEEP(*(.isr_vector)) /* Startup code */
9
    . = ALIGN(4);
10
  } >FLASH
11
12
  /* The program code and other data goes into FLASH */
13
  .text :
14
  {
15
    . = ALIGN(4);
16
17
    . = 0x7E78;
18
    ......

Die 0x7E78 ergeben sich aus Sector2 Adresse 8000 (0x8008000) minus 0x188 
Bytes Startup Code.

Der Bereich von 0x8000188 bis 0x8008000 wird dann mit 0x00 aufgefüllt 
;-)

Martin Thomas schrieb:
> Also der Linker kann einfach
> um Löcher im Speicherbereich herumlinken?

Ja, das kann er. In den Projektsettings lassen sich (unter anderem) 
IROM1 und IROM2 Bereich angeben.

Danke,
Michael

von Mic R. (microller)


Lesenswert?

Hi,
bin auch GCC Neuling und muß zu dem Thema noch was Fragen:

> Der Bereich von 0x8000188 bis 0x8008000 wird dann mit 0x00 aufgefüllt

Für ein Binärfile ist das klar, dass der Bereich aufgefüllt werden muß.
Kann man denn aber kein Hex (Intel-Hex, Motorola-Hex, etc) generieren 
lassen, hier sind im Format 'Lücken' erlaubt. Dadurch bekäme man das 
Programm schneller geflasht.
Geht das irgendwie mit GCC?

Gruß,
Mic Roller

von Michael D. (Gast)


Lesenswert?

Mic Roller schrieb:
> Für ein Binärfile ist das klar, dass der Bereich aufgefüllt werden muß.
> Kann man denn aber kein Hex (Intel-Hex, Motorola-Hex, etc) generieren
> lassen, hier sind im Format 'Lücken' erlaubt. Dadurch bekäme man das
> Programm schneller geflasht.
> Geht das irgendwie mit GCC?

Ich lasse ein hexfile generieren, in diesem sind aber die 0x00 
enthalten.

von Mic R. (microller)


Lesenswert?

Hallo Michael,
danke, aber genau das ist ja das "Problem" - dann dauert das Flashen 
'ewig' ... ist irgendwie ein großer Nachteil vom GCC, dass die 
HEX-Ausgabe anscheinend nicht optimiert ist.
Schade :-(
Gruß,
Mic Roller

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Mic Roller schrieb:
> Hallo Michael,
> danke, aber genau das ist ja das "Problem" - dann dauert das Flashen
> 'ewig' ... ist irgendwie ein großer Nachteil vom GCC, dass die
> HEX-Ausgabe anscheinend nicht optimiert ist.

zwar nicht Michael, dennoch: mit einer Aufteilung in output-sections 
wird von objcopy augenscheinlich eine "optimierte" Ausgabe erzeugt. 
Beispiel in Kurzform folgt, Erläuterungen siehe Betrag weiter oben. Ist 
zwar für anderen ARM-Kern aber sollte relativ leicht übertragbar sein. 
Toolchain: GNU Tools for ARM Embedded Processors Q2/2012 
(launchpad.net).

im Linker-Script (nur Ausschnitt):
1
MEMORY
2
{
3
  FLASH0 (rx)  : ORIGIN = 0x100000,     LENGTH = 10k
4
  FLASH  (rx)  : ORIGIN = 0x100000+10k, LENGTH = 64k-10k
5
  RAM    (rwx) : ORIGIN = 0x200000,     LENGTH = 16k
6
}
7
8
SECTIONS
9
{
10
  .text0 :
11
  {
12
    KEEP(*(.isr_vector))
13
    KEEP(*(.startup))
14
  } > FLASH0
15
16
  .text :
17
  {
18
    /* KEEP(*(.isr_vector))
19
       KEEP(*(.startup))   */
20
    *(.text*)
21
(...gekürzt)
22
  } > FLASH
23
(...gekürzt)

Ausschnitt Disassembly:
1
FLASH_RUN/project.elf:     file format elf32-littlearm
2
3
Sections:
4
Idx Name          Size      VMA       LMA       File off  Algn
5
  0 .text0        0000009c  00100000  00100000  00008000  2**2
6
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
7
  1 .text         00007054  00102800  00102800  0000a800  2**3
8
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
9
  2 .ARM.extab    00000018  00109854  00109854  00011854  2**2
10
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
11
  3 .ARM.exidx    00000028  0010986c  0010986c  0001186c  2**2
12
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
13
  4 .data         0000090c  00200000  00109894  00018000  2**3
14
                  CONTENTS, ALLOC, LOAD, CODE
15
  5 .bss          00000040  0020090c  0010a1a0  0001890c  2**2
16
                  ALLOC
17
(...gekürzt...)
18
 
19
Disassembly of section .text0:
20
21
00100000 <Reset_Handler>:
22
entry:
23
resetHandler:
24
Reset_Handler: 
25
26
        ldr     r0, =resetVector
27
  100000:  e59f006c   ldr  r0, [pc, #108]  ; 100074 <Reset_Handler+0x74>
28
29
(...gekürzt...)
30
31
Disassembly of section .text:
32
33
00102800 <ISR_Pit>:
34
35
void ISR_Pit(void)
36
{
37
  102800:  b538        push  {r3, r4, r5, lr}
38
39
(...gekürzt...)

Ausschnitt Dateiinhalt "hex-Datei":
1
:020000040010EA
2
:100000006C009FE56CF09FE56C409FE504D0A0E19B
3
:1000100068009FE50FE0A0E110FF2FE160009FE581
4
:1000200060109FE560209FE5020051E104309034AC
5
:1000300004308134FBFFFF3A50009FE550109FE5EC
6
:100040000020A0E3010050E104208034FCFFFF3ACF
7
:10005000D2F021E304D0A0E1604044E253F021E378
8
:1000600004D0A0E12C009FE50FE0A0E110FF2FE1FC
9
:10007000FEFFFFEA00002000080010000040200002
10
:10008000592A100094981000000020000C0920004C
11
:0C0090000C0920004C092000A9281000D9
12
:1028000038B500F0DDF8C30706D5054C256800F0A3
13
:10281000DDF8000D4519256038BC01BC0047C046F5
14
(...gekürzt...)

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.