Forum: Compiler & IDEs MSP430: Problem mit IAR Linker


von Leon (Gast)


Lesenswert?

Hallo,

ich verwende einen MSP430 Mikrocontroller mit der dazugehörigen IAR 
Entwicklungsumgebung. Nun wirft der Linker mir folgende Fehlermeldung 
aus:
1
Error[e16]: Segment CODE (size: 0xa868 align: 0x1) is too long for segment definition. At least 0x1a more bytes needed. The problem occurred while processing the segment placement command "-Z(CODE)CODE=4400-FF7F,10000-13FFF", where at the moment of placement the available memory ranges were "CODE:5732-ff7f,CODE:10000-13fff"

Leider bin ich da nun etwas überfragt was den Fehler betrifft. Für mich 
scheint es so zu sein, dass es sich um ein Speicherplatz Problem 
handelt.
Wie müsste ich im Linker Skript den Bereich vergößern?

: Verschoben durch Moderator
von Stephan (Gast)


Lesenswert?

Leon schrieb:
> 5732-ff7f
==0xA84D

Dein CODE Segment will 0xA868 gross sein; da fehlen 0x1A Bytes (s.o.).
So weit so gut.

In der IAR WB gibts bei mir (ARM 9.10.2) einen Bereich 
Options->Linker->Config:
Dort im Linker configuration file "Memory Regions".

Ich kann leider nicht beantworten, warum da bei Dir diese krummen 
0x5732-0xff7f stehen; ich kenne aber auch den MSP430 nicht und Deine 
IAR-WB Version.

VG, Stephan

von Leon (Gast)


Lesenswert?

Ich weiß auch nicht wo ich da was exakt ändern muss.
Den Bereich kann ich nicht mehr vergößern.
1
//
2
// Core:                           MSP430Xv2
3
//
4
// Interrupt vectors:              56
5
//
6
// Signature memory:               16 Bytes
7
//
8
// JTAG Signature memory:          4 Bytes
9
//
10
// BSL Signature memory:           4 Bytes
11
//
12
// IPE Signature memory:           8 Bytes
13
//
14
// Peripheral units:               00100-00FFF
15
//
16
// Information memory (FRAM):      01800-019FF
17
//
18
// Read/write memory (RAM):        01C00-023FF
19
//
20
// Persistent memory (FRAM):       04400-0FFFF
21
//                                 10000-13FFF
22
//

von dll (Gast)


Lesenswert?

Leon schrieb:
> // Persistent memory (FRAM):       04400-0FFFF

Hmm, platz wäre ja also von da bis dort.
Da wo in deinem LinkerKonfigFile 0x5732 steht, einfach mal ein 0x5700 
draus machen; mehr als nicht funktionieren kann es ja nicht;)
Da wir aber nicht wissen, was und warum zwischen 0x4400 und 0x5732 
steht, bleibt die Diagnose schwammig…

von Clemens L. (c_l)


Lesenswert?

dll schrieb:
>> // Persistent memory (FRAM):       04400-0FFFF
>
> Hmm, platz wäre ja also von da bis dort.
> Da wo in deinem LinkerKonfigFile 0x5732 steht,

Das 0x5732 steht gerade nicht im Linker-Skript; laut Fehlermeldung ist 
das die Adresse, ab der gerade noch etwas frei ist.

Änderungen im Linker-Skript beeinflussen nicht die Anzahl der Bytes, die 
der Mikrocontroller wirklich speichern kann. Soweit ich sehe, ist die 
einzige Möglichkeit, den Code zu verkleinern.

von Stephan (Gast)


Lesenswert?

Clemens L. schrieb:
> das die Adresse, ab der gerade noch etwas frei ist.

Jupp; das fragt ich aber gaaanz oben schon: was ist zwischen 0x4400 und 
0x5732? Und: natürlich KÖNNTE 0x5732 auch im LinkerKonfigFile stehen... 
(z.B. weil der Bereich davor als "Ablage" verwendet wird - ist ja ein 
FRAM, kein Flash/ROM)
Egal was es ist: entweder das unbekannte BLOB zwischen 0x4400 und 0x5732 
kann kleiner oder der CODE muss (wieder) kleiner; die paar Byte wären ja 
sicher kein Problem.

von Michael F. (Firma: IAR Systems) (michael_iar)


Lesenswert?

Hallo,

Wenn das FRAM des unbekannten MSP430 bei 0x4400 anfängt, dann sollte der 
Linker da am Anfang die Konstanten platzieren, dann den Startup-Code und 
anschließend die Applikation.

Die Fehlermeldung deutet darauf hin, dass bis zu Adresse 0x5732 alles 
glatt geht (z.B. Konstanten + Startup-Code) und der nächste Block (z.B. 
die Applikation) passt dann nicht mehr in die verbleibenden Bytes.

Die krumme Endadresse von 0xFF7F müsste ganz am Ende vom *.xcl 
aufgeschlüsselt sein, weil da so Sachen wie JTAG Signatur, BSL Signatur, 
... des MSP430 liegen sollten.

Darf man fragen, welche Version der IAR Embedded Workbench für den 
MSP430 und welcher MSP430 genutzt werden?

Gruß,
Michael

von Patrick L. (Firma: S-C-I DATA GbR) (pali64)


Lesenswert?

Ähm du hast da was falsch im Config (Entweder im IAR Config) oder im 
Programm selbst (eher warscheinlich)
So wie es aussiht ist der Platz für die Interrupts schon vergeben.
Fragen:
1.) Welchen MSP430FRxxx verwendest du ?
2.) Software in "C" oder Assembler ?
3.) Wie sieht das Init deiner Software aus?
4.) Wie sieht deine Interrupt Config im Programm aus?

Beispiel?
Oder Kompletes Programm mal anhängen.
Dan kann dir Geholfen werden ;-)
Beispiel:
1
;-------------------------------------------------------------------------------
2
            RSEG   CSTACK                   ; Define stack segment
3
;-------------------------------------------------------------------------------
4
            RSEG   CODE
5
//--------------------------Program Starts here---------------------------------
6
MAIN
7
.
8
.
9
.
10
;-------------------------------------------------------------------------------
11
            COMMON  INTVEC                  ; Interrupt Vectors
12
;-------------------------------------------------------------------------------
13
            ORG     RESET_VECTOR            /* 0xFFFE */ ; Reset Vector
14
            DW      RESET

: Bearbeitet durch User
von Leon (Gast)


Lesenswert?

IAR Version 7.20.1
Mikrocontroller: msp430fr5949

von Leon (Gast)


Lesenswert?

Programmierung erfolgt in "C"

von Michael F. (Firma: IAR Systems) (michael_iar)


Lesenswert?

Es gibt bei manchen MSP430 die Möglichkeit, Teile des Information Memory 
für Code oder Konstanten zu nutzen:

https://www.iar.com/knowledge/support/technical-notes/general/placing-code-in-the-msp430-information-memory/

Laut Fehlermeldung fehlen gerade mal 0x1a Bytes und da könnte der in der 
Tech-Note beschriebene Ansatz eine Möglichkeit sein.

Alternativ könntest Du auch (sofern noch nicht geschehen) die 
Optimierung des Compilers für einzelne Files erhöhen und schauen, ob 
dadurch die nötigen Bytes eingespart werden können.

Gruß,
Michael

von Entwickler (Gast)


Lesenswert?

Ich habe nun die Optimierung auf Medium umgestellt. Da meckert der 
Linker nicht.

von Entwickler (Gast)


Lesenswert?

1
// Constant data
2
-Z(CONST)DATA16_C,DATA16_ID,TLS16_ID,DIFUNCT,CHECKSUM=4400-FF7F
3
4
// Code
5
-Z(CODE)CSTART,ISR_CODE,CODE16=4400-FF7F
6
7
-Z(CODE)CODE=4400-FF7F,10000-13FFF
8
9
// Constant data
10
-Z(CONST)DATA20_C,DATA20_ID,CODE_ID=4400-FF7F,10040-13FFF

von Entwickler (Gast)


Lesenswert?

So wie es aussieht wird der Speicherbereich 0x10040-0x13FFF nicht 
genutzt obwohl im Linkerskript der Bereich eingetragen wurde.

von Michael F. (Firma: IAR Systems) (michael_iar)


Lesenswert?

Hallo,

mit dem *.xcl des MSP430FR5949 aus dem Installationsverzeichnis der IAR 
Embedded Workbench erhalte ich bei einem Beispielprojekt eine 
Platzierung von CODE sowohl in 0x4400-0xFF7F, als auch in 
0x10000-0x13FFF:
1
SEGMENT              SPACE    START ADDRESS   END ADDRESS     SIZE  TYPE  ALIGN
2
=======              =====    =============   ===========     ====  ====  =====
3
...
4
DATA16_C                               4400 - 8425            4026   rel    1
5
DATA16_ID                              8426 - 8427               2   rel    1
6
CSTART                                 8428 - 8457              30   rel    1
7
ISR_CODE                               8458 - 8519              C2   rel    1
8
<CODE> 1                               851A - 8FFF             AE6   rel    1
9
DATA16_AN                              9000 - F007            6008   rel    0
10
<CODE> 2                               F008 - FF7F             F78   rel    1
11
INTVEC                                 FF90 - FFF1              62   com    1
12
RESET                                  FFFE - FFFF               2   rel    1
13
<CODE> 3                           00010000 - 00011109        110A   rel    1

Wurde das von Dir genutzte *.xcl angepasst oder ist das noch original?

Gruß,
Michael

von Entwickler (Gast)


Lesenswert?

Hi, das File wurde nicht angepasst.
Welche Einstellung veranlasst, dass auch der ober Bereich 
0x10040-0x13FFF genutzt wird?

von Entwickler (Gast)


Lesenswert?

Moin,

ich habe nun mal ein neues Projekt erstellt und da kann ich im Linker 
File auch die Einstellung sehen
1
-P(CODE)CODE=4400-FF7F,10000-13FFF
2
-Z(CODE)CODE_PAD

Wenn ich dies so in mein Linker File integriere erhalte ich nicht mehr 
die gleiche Fehlermeldung sondern meine andere.
1
Error[e171]: The segment "CODE" that is used in a checksum command is a packed segment.

Am Ende von dem Linker File wird vom Code Segment eine Prüfsumme 
gebildet
1
-J2,sum=={CODE}

Kann nicht nachvollziehen worum dies nicht funktioniert.

von Michael F. (Firma: IAR Systems) (michael_iar)


Angehängte Dateien:

Lesenswert?

Hallo,

im Anhang ein "quick'n'dirty" Beispiel, bei dem auch der obere 
Speicherbereich ab 0x10000 genutzt wird, ohne was spezielles im Projekt 
eingestellt zu haben. Das Projekt wurde mit v7.20.2 erstellt, da ich die 
v7.20.1 gerade nicht installiert habe...

Vorgehensweise:
- ein frisches Projekt auf Basis des "main.c" Templates erstellt
- die Ziel-MCU auf den MSP430FR5949 geändert
- das *.xcl aus dem Installationsverzeichnis der Toolchain ins Projekt 
kopiert
- in main.c ein paar sinnfreie Berechnungen mit Double und ein CONST 
UINT32 Array eingefügt, um Speicherverbrauch >47kByte zu erzeugen
1
SEGMENT              SPACE    START ADDRESS   END ADDRESS     SIZE  TYPE  ALIGN
2
=======              =====    =============   ===========     ====  ====  =====
3
...
4
DATA16_C                               4400 - E088            9C89   rel    1
5
CSTART                                 E08A - E0A1              18   rel    1
6
<CODE> 1                               E0A2 - FF7F            1EDE   rel    1
7
RESET                                  FFFE - FFFF               2   rel    1
8
<CODE> 2                           00010000 - 00010075          76   rel    1
9
CODE_ID                                 00010076                     rel    1
10
DATA20_C                                00010076                     rel    1
11
DATA20_ID                               00010076                     rel    1

Sind in Deinem Projekt grundlegende Einstellungen (z.B. Code & Data 
Model) unterschiedlich?

Gruß,
Michael

von Entwickler (Gast)


Lesenswert?

Guten Morgen Michael,

zunmächst vielen Dank für deine Untersützung. Ich habe mal das Linker 
File von dir und meines verglichen. Es gibt da nur sehr wenig 
unterscheide.
Nachfolgende Zeilen habe ich ja bereits getestet und funktioniert auch.
1
-P(CODE)CODE=4400-FF7F,10000-13FFF
2
-Z(CODE)CODE_PAD

Nun ist es so dass noch eine Checksummen Berechnung gemacht werden soll.
1
// Build a checksum of the code segment
2
-J2,sum=={CODE};

In der Checksum.c Datei wird ein pragama ausgeführt.
Ich vermute dass das damit zusammenhängt.
1
  #pragma segment = "CODE"
2
  
3
  u16 u16startAddr[2];  
4
  u16startAddr[0] = (u16)__segment_begin("CODE");  
5
  
6
  u32 u32endAddr[2];  
7
  u32endAddr[0] = (u16)__segment_end("CODE");

Fehlermeldung Linker:
Error[e171]: The segment "CODE" that is used in a checksum command is a 
packed segment.

von Michael F. (Firma: IAR Systems) (michael_iar)


Lesenswert?

Hallo,

ich habe beim Beispiel aus dem ZIP mal in den General Options das Code 
Model von "Large" auf "Small" umgestellt und dann meckert der Linker die 
Bytes als "fehlend" an, die ansonsten ab 0x10000 liegen. Das könnte also 
schon mal ein Grund dafür sein, dass in Deinem Projekt der obere 
Speicherbereich nicht genutzt wird.

Was die Checksum angeht, so werde ich versuchen, mir das heute mal im 
Detail anzuschauen, falls ich Zeit für finde. Zum Thema gibt es auch 
eine Tech-Note, die Du Dir vorab mal anschauen kannst:
https://www.iar.com/knowledge/support/technical-notes/general/checksum-calculation-with-xlink/

Gruß,
Michael

von Entwickler (Gast)


Lesenswert?

Ich habe bei mir die Settings auch angeschaut.

General Options:

-> Code Model: Large
-> Data Model: Medium

von Entwickler (Gast)


Lesenswert?

Den Tech-Note habe ich gestern auch im Netz gefunden.

Da ich aufgrund von der -P Option sich um ein packed segment handelt 
kann ich dann in meiner Checksummen Berechnung #pragma segment = "CODE" 
nicht beutzen.

Zu der -P Option gibt es wohl kein Beispiel.

von Michael F. (Firma: IAR Systems) (michael_iar)


Lesenswert?

Entwickler schrieb:
> Error[e171]: The segment "CODE" that is used in a checksum command is a
> packed segment.

Zitat aus dem Linker Handbuch zu Fehler "E171":
Segment names used in a checksum command must be sequentially placed.
Place the segment using the option -Z or use an explicit address range 
(like 0x200–0x37F) in the checksum command.

Wenn ich beim Beispielprojekt aus dem ZIP in den Linkeroptionen die 
Prüfsummenberechnung aktiviere (und -Z(CODE)CHECKSUM=13FF6-13FF7 ins 
*.xcl einfüge), dann führt das zu folgenden Parametern für den Aufruf 
des Linkers und damit baut das Projekt:
-Hff -J2,crc16,,,,2,0

(rechts-klick in das Build-Message Fenster und dann den Filter auf "all" 
umstellen, um den kompletten Aufruf der Tools zu sehen)

Ergebnis im *.map:
1
SEGMENT              SPACE    START ADDRESS   END ADDRESS     SIZE  TYPE  ALIGN
2
=======              =====    =============   ===========     ====  ====  =====
3
...
4
CHECKSUM                           00013FF6 - 00013FF7           2   rel    1
5
6
...
7
8
Symbol      Checksum  Memory  Start  End    Initial  #Initial
9
------      --------  ------  -----  ---    -------  --------
10
__checksum    0x4733   CODE   4400 - FF7F    0x0000   #0x0000
11
                       CODE   FFFE - 13FF5

Kopieren des "-H" und "-J" in das *.xcl und abschalten der Optionen für 
den Linker führt zum gleichen Ergebnis.

Laut den Adressen aus dem *.map würde die Prüfsumme den kompletten CODE 
Bereich + den Reset-Vector umfassen, abzüglich des Platzhalters für die 
Prüfsumme.

Nun zu checksum.c:
Das CODE Segment besteht aus 2 Teilen und somit hast Du 2x Start- und 
Endadressen. Aktuell fällt mir außer der expliziten Angabe der Adressen 
kein Weg ein, das sinnvoll im C-Code zu verarbeiten.

Gruß,
Michael

: Bearbeitet durch User
von Michael F. (Firma: IAR Systems) (michael_iar)


Lesenswert?

Moin,

wäre es ein gangbarer Weg, im *.xcl Symbole für die beiden unteren und 
oberen Grenzen des FRAM zu definieren und damit zu arbeiten?

Also so in der Art:
1
// ---------------------------
2
// Read/write data in FRAM
3
//
4
5
-DCODE_LOWER_START=4400
6
-DCODE_LOWER_END=FF7F
7
-DCODE_UPPER_START=10000
8
-DCODE_UPPER_END=13FF7
9
10
-Z(CONST)DATA16_P,DATA20_P=CODE_LOWER_START-CODE_LOWER_END

Du könntest dann innerhalb des *.xcl mit den Symbolen + Offset arbeiten.
1
// ---------------------------
2
// Constant data
3
//
4
5
-Z(CONST)DATA20_C,DATA20_ID,CODE_ID=CODE_LOWER_START-CODE_LOWER_END,(CODE_UPPER_START+40)-CODE_UPPER_END

In der Applikation wären diese Symbole verfügbar und Du könntest deren 
Adressen als Grenzen für die Prüfsummenberechnung nutzen:
1
extern uint32_t CODE_LOWER_START;
2
extern uint32_t CODE_LOWER_END;
3
extern uint32_t CODE_UPPER_START;
4
extern uint32_t CODE_UPPER_END;

Gruß,
Michael

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.