Forum: Compiler & IDEs Initialisierung von globalen Variablen in Codesourcery


von Andreas (Gast)


Lesenswert?

Hallo

Ich habe ein Programm für den LPC2148 mit Codesourcery compiliert.

Im Source ist eine globale Variable PWM_Frequency definiert
1
uint32_t PWM_Frequency=1000;
2
3
4
void InitPWM(uint32_t InitialFreqency)
5
{
6
  SetFrequency(InitialFrequency);
7
  ...
8
}
Wenn ich das Programm ausführe, dan steht in der Variablen PWM_Frequency 
der Wert 0. In SetFrequency wird u.a. das MR0-Registger gesetzt. Meiner 
Ansicht nach müsste die Variable mit dem Wert 1000 initialisiert werden.

Übergebe ich allerdings:
1
 void InitPWM(uint32_t InitialFreqency)
2
{
3
  SetFrequency(1000);
4
  ...
5
}
dann funktioniert das Programm.

Habt ihr vielleicht eine Idee wo das Problem liegt? Optimierung ist 
ausgeschaltet. Das Problem tritt mit und ohne Debugging auf.

Grüsse

Andy

von Andreas (Gast)


Lesenswert?

Eine Erkenntnis habe ich noch gewonnen.

Das Problem tritt bereits im im Startup-File in der Section

crt.s
1
 
2
3
snipp
4
  /* copy .data section (Copy from ROM to RAM) */
5
                ldr     R1, =_etext
6
                ldr     R2, =_data
7
                ldr     R3, =_edata
8
1:            cmp     R2, R3
9
                ldrlo   R0, [R1], #4
10
                strlo   R0, [R2], #4
11
                blo     1b                 <== Änderung der Variablen
12
13
    /* Clear .bss section (Zero init)  */
14
                mov     R0, #0
15
                ldr     R1, =_bss_start
16
                ldr     R2, =_bss_end
17
2:        cmp     R1, R2
18
                strlo   R0, [R1], #4
19
                blo     2b
20
21
        /* Enter the C code  */
22
                b       main
23
24
.endfunc
25
.end

Zuvor hat die Variable noch den richtigen Wert.

von Andreas (Gast)


Angehängte Dateien:

Lesenswert?

Und hier noch das Linker-File

von Hans (Gast)


Lesenswert?

Dir ist schon klar, dass in Deinem Codeausschnitt nirgends PWM_Frequency 
benutzt wird, sondern nur InitialFrequency?

von Andreas (Gast)


Lesenswert?

Hallo Hans

Ja, das ist mir klar. Habe es nur nicht hingeschrieben. Ich rufe es so 
auf:
1
  InitPWM(PWM_Frequency);

Beste Grüsse

Andy

von Andreas (Gast)


Lesenswert?

Nun ist mir noch folgendes aufgefallen, dass alle initalisierenten 
Variaben um 8 verschoben im RAM stehen:

Im Map-File steht:
1
 .data          0x4000024b        0x0 ./obj/lpcextio.o
2
 .data          0x4000024b        0x0 ./obj/lpc2148_spi.o
3
 *fill*         0x4000024b        0x1 00
4
 .data          0x4000024c        0x8 ./obj/lpcspindle.o
5
                0x4000024c                PWM_Frequency
6
                0x40000250                PWM_RCFrequency
7
 .data          0x40000254        0x0 ./obj/misc.o
8
 .data          0x40000254        0x0 ./obj/ucmdbuf.o

Bei der Initialisierung im Startup-Code wird die Variable PWM-Frequency 
also auf die Adresse 0x40000254 anstatt auf 0x4000024c geschrieben.

Das Problem liegt daran, dass bereits die Adresse von _etext um 8 Byte 
verschoben ist. So wird sie zumindest im Startup-File geladen

Abschnitt Kopiere ROM to RAM im Startup-File
1
        /* copy .data section (Copy from ROM to RAM) */
2
                ldr     R1, =_etext
3
                ldr     R2, =_data
4
                ldr     R3, =_edata
5
1:            cmp     R2, R3
6
                ldrlo   R0, [R1], #4
7
                strlo   R0, [R2], #4
8
                blo     1b
9
10
        /* Clear .bss section (Zero init)  */
11
                mov     R0, #0
12
                ldr     R1, =_bss_start
13
                ldr     R2, =_bss_end
14
2:         cmp     R1, R2
15
                strlo   R0, [R1], #4
16
                blo     2b

An welcher Schraube muss man nun drehen damit die Adresse stimmt?

Vielen Dank für eure Tipps.

von Andreas (Gast)


Lesenswert?

Im Mapfile steht bei  _etext die Adresse 0x000144b0
Diese wird im Startupfile bei
1
ldr     R1, =_etext

auch so geladen.

1
.rodata.str1.4
2
                0x000144ac        0x4 c:/program files (x86)/codesourcery/sourcery_codebench_lite_for_arm_eabi/bin/../lib/gcc/arm-none-eabi/4.6.3/../../../../arm-none-eabi/lib\libc.a(lib_a-impure.o)
3
 *(.glue_7)
4
 .glue_7        0x00000000        0x0 linker stubs
5
 *(.glue_7t)
6
 .glue_7t       0x00000000        0x0 linker stubs
7
                0x000144b0                _etext = .
8
9
.ARM.extab      0x000144b0        0x0
10
 .ARM.extab     0x000144b0        0x0 c:/program files (x86)/codesourcery/sourcery_codebench_lite_for_arm_eabi/bin/../lib/gcc/arm-none-eabi/4.6.3\libgcc.a(_divdi3.o)
11
 .ARM.extab     0x000144b0        0x0 c:/program files (x86)/codesourcery/sourcery_codebench_lite_for_arm_eabi/bin/../lib/gcc/arm-none-eabi/4.6.3\libgcc.a(_udivdi3.o)
12
13
.ARM.exidx      0x000144b0        0x8
14
 .ARM.exidx     0x000144b0        0x8 c:/program files (x86)/codesourcery/sourcery_codebench_lite_for_arm_eabi/bin/../lib/gcc/arm-none-eabi/4.6.3\libgcc.a(_divdi3.o)
15
 .ARM.exidx     0x000144b8        0x0 c:/program files (x86)/codesourcery/sourcery_codebench_lite_for_arm_eabi/bin/../lib/gcc/arm-none-eabi/4.6.3\libgcc.a(_udivdi3.o)
16
                                  0x8 (size before relaxing)

Stimmt vielleicht die Adresse im ROM nicht...?

von holger (Gast)


Lesenswert?

>Stimmt vielleicht die Adresse im ROM nicht...?

Wo ist dein kompletter Quellcode?

Bei dem ganzen was du da oben von dir gegeben hast
sehe ich überhaupt kein einziges Problem außer das du wohl
einen Knoten im Hirn hast.


> .data          0x4000024c        0x8 ./obj/lpcspindle.o
>                0x4000024c                PWM_Frequency
>                0x40000250                PWM_RCFrequency
> .data          0x40000254        0x0 ./obj/misc.o
>
>Bei der Initialisierung im Startup-Code wird die Variable PWM-Frequency
>also auf die Adresse 0x40000254 anstatt auf 0x4000024c geschrieben.

Wie kommst du darauf? Die Adresse ist
0x4000024c                PWM_Frequency

Wie kommst du auf 0x40000254?

von Andreas (Gast)


Lesenswert?

Den Code habe ich bisher mit WINARM übersetzt und dort hat alles 
einwandfrei funktioniert. Das Problem habe ich erst seit Umstieg auf 
Codesourcery. "Lediglich" der Compiler hat sich geändert. Startup-File 
und Linker-File sind gleich geblieben. Habe noch ein kleineres Projekt 
übersetzt und dort tritt das Problem nicht auf.

Wenn folgender Code aus dem Startup-File ausgeführt wird
1
/* copy .data section (Copy from ROM to RAM) */
2
                ldr     R1, =_etext
3
                ldr     R2, =_data
4
                ldr     R3, =_edata
5
1:            cmp     R2, R3
6
                ldrlo   R0, [R1], #4
7
                strlo   R0, [R2], #4
8
                blo     1b

dann ist der Registerstatus bei Label 1: folgender:

R1 0x00014358
R2 0x00000420
R3 0x00000690

Nach meiner Ansicht:
R1 Startadresse im Flash
R2 Zieladresse der ersten zu initialisieren Variable im RAM
R3 Endadresse RAM

Nach Ende der Schleife steht dann PWM Frequency
 (z.B 0xAABBCCDD) erst achten Stelle weiter hinten im RAM - also 
0x4000024C + 8 = 0x40000254 !

0x4000024c: xx xx xx xx xx xx xx xx DD CC BB AA xx xx xx xx

Deshalb komme ich auf 0x40000254
1
 *(.data)
2
 .data          0x40000200        0x0 ./obj/crt.o
3
 .data          0x40000200        0x0 ./obj/main.o
4
 .data          0x40000200        0x0 ./obj/manual.o
5
 .data          0x40000200        0x0 ./obj/cal.o
6
 .data          0x40000200        0x0 ./obj/ujo.o
7
 .data          0x40000200        0x0 ./obj/umot.o
8
 .data          0x40000200       0x4c ./obj/upc.o
9
                0x40000200                FIRMWARE_VERSION
10
                0x40000224                CONTROLLER_VERSION
11
                0x40000234                COMPILAT
12
 .data          0x4000024c        0x0 ./obj/ujogbuf.o
13
 .data          0x4000024c        0x0 ./obj/lpcusb.o
14
 .data          0x4000024c        0x0 ./obj/usbstdreq.o
15
 .data          0x4000024c        0x0 ./obj/usbcontrol.o
16
 .data          0x4000024c        0x0 ./obj/usbhw_lpc.o
17
 .data          0x4000024c        0x0 ./obj/usbinit.o
18
 .data          0x4000024c        0x8 ./obj/lpcspindle.o
19
                0x4000024c                PWM_Frequency
20
                0x40000250                PWM_RCFrequency
21
 .data          0x40000254        0x0 ./obj/armvic.o
22
 .data          0x40000254        0x0 ./obj/console.o
23
 .data          0x40000254        0x3 ./obj/lpchardw.o

Bereits in der Variable FIRMWARE_VERSION sind die ersten 8 Byte falsch 
d.h:
1
#ifdef  DEBUG 
2
  #define DGB_POSTFIX  "d\0"
3
#else
4
  #define DGB_POSTFIX  "\0"
5
#endif
6
char FIRMWARE_VERSION[] = "Example 2, 2012" DGB_POSTFIX;

Nach der Initialisierung steht drin:

FIRMWARE_VERSION[] = xx xx xx xx xx xx xx xx Example 2, 2012d

von Andreas (Gast)


Angehängte Dateien:

Lesenswert?

Also eine Erkenntnis habe ich nun noch gewonnen:

Programm mit Startup- und Linkerfile von WINARM compiliert läuft stabil. 
Allerdings Problem mit der oben beschriebenen Initialisierung von 
Variablen.

Programm mit Startup- und Linkerfile eines Codesourcery-Beispiels 
compiliert. Programm instabil (nach etwa 2 Minuten). Variablen richtig 
initialsiert.
Eine kleine Verbesserung (Programm läuft etwas länger) konnte ich 
erreichen indem ich die Stackgrösse auf 1024 Byte erhöht hatte.

Vielleicht hängen die beiden Probleme aber nicht miteinander zusammen.

Anbei das Linkerfile, welches ich im Netz gefunden habe

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.