Forum: Compiler & IDEs arm-gcc -Os Problem in reset Handler


von Ingo S. (ingo-s)


Lesenswert?

Hi,
bis zur Optimierung (-O3) funktionierts noch.

Umgebung: CoIDE gcc 4.8 2013q4 mit STM32F050F6

Bei (-Os) kommt schon in der mit *** gekennzeichneten Stelle ein fault.

  .section .text.Reset_Handler
  .weak Reset_Handler
  .type Reset_Handler, %function
Reset_Handler:
  ldr   r0, =_eram
  mov   sp, r0          /* set stack pointer */

/* Copy the data segment initializers from flash to SRAM */
  movs r1, #0
  b LoopCopyDataInit

CopyDataInit:
  ldr r3, =_sidata
  ldr r3, [r3, r1]
  str r3, [r0, r1] ***
  adds r1, r1, #4

Was kann das für Ursachen haben? Da scheinen doch schon die Adressen 
nicht zu stimmen, aber wieso?

Gruß Ingo

von Detlef K. (adenin)


Lesenswert?

Ingo Stahl schrieb:
> .section .text.Reset_Handler
>   .weak Reset_Handler
>   .type Reset_Handler, %function
> Reset_Handler:
>   ldr   r0, =_eram
>   mov   sp, r0          /* set stack pointer */
>
> /* Copy the data segment initializers from flash to SRAM */
>   movs r1, #0
>   b LoopCopyDataInit
>
> CopyDataInit:
>   ldr r3, =_sidata
>   ldr r3, [r3, r1]
>   str r3, [r0, r1] ***
>   adds r1, r1, #4

Ja, das leidige Problem der -O3 Optimierung von Fragestellern ist 
bekann, bei dem die "relevanten Teile" zusammencopiert und gepostet 
werden.

Mal sehen was wir diesmal haben:
-hmm, der Compiler tut Assemblercode optimieren sollen? glaube ich ja 
fast ;)
Nunja, der linker könnte höstens nicht benutzten Code entfernen
-der ResetHandler initalisiert den Stack?
ich bin mir 100.1% sicher, das der Stack automatisch initialisiert wird.
woher die CPU weis wo der Stack ist? Na das steht in der 
Interruptvektortabelle an Position Null.
-die CPU macht einen einfachen Sprung nach LoopCopyDataInit
och, das Teil hat man uns unterschlagen (na ich seh hier nix davon)
Also kommt die CPU vielleicht, aber wohl eher nicht, bei CopyDataInit 
an,
wo der aktuelle Wert von r0 uns, und wahrscheinlich auch der CPU, 
unbekannt ist.
Damit macht mein Hirn jetzt Hard fault und steigt hier aus. :P

Fröhliches Glaskugelgucken.

von Ingo S. (ingo-s)


Lesenswert?

Bin zwar nicht weiter, habe aber mal den Unterschied zwischen -Os und 
-O3 im Reset Handler mir angesehen.

Optimierung  (-Os)           (-O3)
//
_eram   = 0x20001000     = 0x20001000
SP      = 0x20001000     = 0x20001000
_sdata  = 0x20000000     = 0x20000000
_edata  = 0x20000034     = 0x20000034
//start address for the initialization values of the .data section.
_sidata = 0x08002dbe     = 0x08003c64

CopyDataInit:
  ldr r3, =_sidata
  ldr r3, [r3, r1]  // r1 = 0

Der fault kommt schon eine Zeile früher, bei ldr r3, [r3, r1] als 
anfangs angegeben.

Beide _sidata Adressen entsprechen den vom Compiler als text Größe 
angegebenen Wert und scheinen korrekt.
Was aber beim genauen hinsehen auffällt, ist das die Adresse 0x08002dbe 
ein 2byte alignment hat im Gegensatz zum 4byte Alignment bei der (-O3) 
Optimierung.

Jetzt müsste ich mal genauer in das Cortex Manuell schauen, oder weiß 
jemand direkt, das das Alignment die Ursache für den fault ist?

Wenn ja, wo muss ich drehen, das der gcc so etwas nicht generiert?

Gruß Ingo

von adenin (Gast)


Lesenswert?

There is no support for unaligned accesses on the Cortex-M0 processor. 
Any attempt to perform an unaligned memory access operation results in a 
HardFault exception.

von Markus F. (mfro)


Lesenswert?

Ingo Stahl schrieb:
> wo muss ich drehen, das der gcc so etwas nicht generiert?

Linker script. Ein paar taktisch klug eingestreute
1
. = ALIGN(4);
 an der richtigen Stelle dürften das Problem beheben. gcc ist hier 
völlig unschuldig.

: Bearbeitet durch User
von Ingo S. (ingo-s)


Angehängte Dateien:

Lesenswert?

Es ist wirklich das Alignment.
Ich habe einige strncpy() mit integriertem String verwendet und jedes 
Byte an Längenänderungen wirkt sich bei -Os byteweise in der Flash Größe 
aus.

Mit Linker Scripts hatte ich bisher noch keine direkte Berührung. Im 
armm-gcc.lnk.ld sind schon einige ". = Align (4)" enthalten.

wo müsste man denn da eingreifen? Meine Versuche in der .text section 
waren erfolglos.

Gruß Ingo

von Markus F. (mfro)


Lesenswert?

Ingo Stahl schrieb:
> Mit Linker Scripts hatte ich bisher noch keine direkte Berührung. Im
> armm-gcc.lnk.ld sind schon einige ". = Align (4)" enthalten.

Offensichtlich kracht's ja beim (unaligned) Zugriff auf _sidata. Also 
sollte das ALIGN unmittelbar davor (bzw. vor das "_etext = .", das - 
zumindest in den einschlägigen Linkerscripts, die ich auf die Schnelle 
gefunden habe - _sidata festlegt).

von Ingo S. (ingo-s)


Lesenswert?

Ja, es kracht's beim (unaligned) Zugriff auf _sidata. Im Debugger kann 
ich sehen, das die Strings direkt vor _sidata liegen. Und die enden nun 
mal willkürlich und nicht an einer 4er alignment Grenze.

Eine . = ALIGN(4); Anweisung vor "_etext = ." hat leider keinen Erfolg 
gebracht. Als Notlösung funktioniert, einen String in der Länge so 
anzupassen, das ein 4er alignment raus kommt.

Gruß Ingo

von Markus F. (mfro)


Lesenswert?

Ingo Stahl schrieb:
> Eine . = ALIGN(4); Anweisung vor "_etext = ." hat leider keinen Erfolg
> gebracht.

Nicht ausgeschlossen, aber das wäre das erste Mal, daß das nicht 
funktioniert.

Laß' mal dein Linkerscript sehen. Sicher, daß er das nimmt, das Du 
geändert hast und kein anderes?

von Ingo S. (ingo-s)


Lesenswert?

Mit dem Linker File bin ich auf die Coocox IDE reingefallen.
Aus irgend einem Grund war in meinem Projektverzeichnis ein Linker File, 
das wurde aber nicht benutzt.
Im IDE Installationspfad wird in einem Projekt bezogenem temporären 
Verzeichnis beim Öffnen des Projektes ein Linker File angelegt, das beim 
Build refresht wird.

Habe das Quell Linker-File gefunden und dort geändert, wird auch brave 
ins temporäre Projektverzeichnis Verzeichnis übernommen. Aber leider 
auch ohne Erfolg.

Gruß Ingo

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.