Forum: Compiler & IDEs Configurationsdaten an definierte Speicherstelle compilieren


von FindetMemo (Gast)


Lesenswert?

Hallo,

Ich habe ein Array in dem eine ganze Menge Konfigurationsdaten stehen.
Das ganze ist eigentlich nur in einem Header definiert als
unsigned char config[] = {...};

Es wäre enorm hilfreich, wenn ich dieses Array in einem definierten 
Speicherbereich abspeichern könnte und zugleich sicherstellen könnte, 
dass damit genau 4096 Byte gefüllt werden, damit kein anderer 
Programmcode auf diesem Flash-Block mit untergebracht wird.

Kann man dieses Array irgendwie einer ganz bestimmte Speicheradresse zum 
liegen kommen lassen, eben so dass es exakt eine Flash-Zelle 
beansprucht?

Es geht um Eclipse mit dem GCC Compiler in C

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


Lesenswert?

Separate section anlegen und per Linkerscript dann entsprechend
platzieren.
1
const uint8_t xxx[] = { ... } __attribute__((section(".foo")));

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

...und hier ein Beispiel für ein solches Script bzw. Augmentation des 
Standard-Scripts:
1
SECTIONS
2
{
3
  .flash1 :
4
  {
5
    . = MAX (ABSOLUTE(0x10000), .);
6
    PROVIDE (__flash1_start = .);
7
    . = ALIGN(2);
8
    *(.text.flash1.*)
9
    *(.progmem1.data*)
10
    PROVIDE (__flash1_end = .);
11
12
    ASSERT (__flash1_start == __flash1_end || __flash1_start >= ABSOLUTE(0x10000),
13
          "__flash1 data in .progmem1.data below 0x10000");
14
    ASSERT (__flash1_start == __flash1_end || __flash1_end <= ABSOLUTE(0x20000),
15
          "__flash1 data in .progmem1.data exceeds 0x20000");
16
  }
17
18
  .flash2 :
19
  {
20
    . = MAX (ABSOLUTE(0x20000), .);
21
    PROVIDE (__flash2_start = .);
22
    . = ALIGN(2);
23
    *(.text.flash2.*)
24
    *(.progmem2.data*)
25
    PROVIDE (__flash2_end = .);
26
27
    ASSERT (__flash2_start == __flash2_end || __flash2_start >= ABSOLUTE(0x20000),
28
          "__flash2 data in .progmem2.data below 0x20000");
29
    ASSERT (__flash2_start == __flash2_end || __flash2_end <= ABSOLUTE(0x30000),
30
          "__flash2 data in .progmem2.data exceeds 0x30000");
31
  }
32
}
33
34
INSERT AFTER .text
und die Datei dann qua -T<name> dem Linker-Treiber (also avr-gcc) 
übergeben und das Ergebnis im Map-File überprüfen.

Das Beispiel ist zwar für den Support der avr-gcc Address-Spaces 
__flash1/2, aber in deinem Fall kann man das ähnlich angehen.  Kommt 
halt darauf an, wo das Zeug genau hin soll.  Das MAX fällt bei dir weg, 
und das ALIGN brauchst auch nicht.  Die definierten Symbole können 
hilfreich sein wenn z.B. eine Checksumme zu berechnen ist.

: Bearbeitet durch User
von FindetMemo (Gast)


Lesenswert?

hallo nochmal,

was hat es mit den Zeilen:

> *(.text.flash1.*)
> *(.progmem1.data*)

auf sich?


Ich habe in anderen Beispielen auch Zeilen gefunden die da wären:

> *(.data)
> .bss : { *(.bss) }


und kann das irgendwie noch nicht so richtig übersetzen...

Welche von diesen Keywörtern benötigt man denn noch so, um die 
Initialisierung auch richtig zu machen?

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


Lesenswert?

FindetMemo schrieb:
> Welche von diesen Keywörtern

Das sind keine „Keywörter“, sondern die Namen deiner Speicherbereiche
(sections), die du explizit oder implizit (.text, .data, .bss) im
Programm vergibst.

Die Dokumentation zu den Linkerscripten des GNU Linkers solltest du
als Referenz schon mal daneben halten, damit du am Ende weißt, was
darin welchen Zweck hat.  Johanns und meine Antworten sollten kein
Kochrezept darstellen, das du blind befolgen kannst, sondern nur
Ideen und Anregungen in die Runde werfen.

: Bearbeitet durch Moderator
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.