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
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.
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
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.
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
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
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).
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
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?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.