Forum: Compiler & IDEs STM32F407: Stack ins CCRAM gelegt erzeugt Hard Fault Error


von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

vorab: Bitte keine Ratschläge diesen Error zu debuggen mittels Assembler 
Routinen usw. Ich verstehe davon nur Bahnhof und kann es doch nicht 
ändern, wenn da im tiefsten Inneren etwas schief läuft.

Es geht einfach nur darum den Stack in das CCCRAM zu legen, was ich 
intuitiv so gemacht habe im Linker Script:
1
.stack_dummy (NOLOAD):
2
  {
3
    *(.stack)
4
  } > CCRAM
5
6
  /* Set stack top to end of RAM, and stack limit move down by
7
   * size of stack_dummy section */
8
  __StackTop = ORIGIN(CCRAM) + LENGTH(CCRAM);
9
  __StackLimit = __StackTop - SIZEOF(.stack_dummy);
10
  PROVIDE(__stack = __StackTop);
11
12
  /* Check if data + heap + stack exceeds RAM limit */
13
  /*ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") */

Der Debugger zeigt dann auch, dass das sp register sich korekt bei 
0x1000FFFF befindet, also im CCRAM.

Nun ist es so, dass das komplexe Programm dann abschmiert und zwar bei 
einer sprintf Funktion, nachdem es zuvor zig davon abgearbeitet hat. Die 
Stelle ist eigentlich völlig unbedeutend, da passiert nichts weiter.

Das CCRAM ist 64k gross, ich habe nichts drin ausser dem Stack, das 
müsste also reichen.

Kurz bevor der Hard Fault Handler angesprungen wird sieht es so aus bei 
mir.
Da sieht noch alles normal aus, der Step über sprintf aber ist der 
letzte, der ausgeführt wird :-( Setze ich den PC drüber hinweg springt 
er eben beim nächsten Mal sprintf da rein.

sprintf ist eine Funktion der libs, ich nutze die nano-branch, habe die 
Linker Option -lm gesetzt für float Ausgabe in printf und auch die Flags 
diese Funktionen aus der Nano-Branch zu nehmen.

Nutze ich die default lib stürzt er zwar nicht ab, aber alle float 
printf Ausgaben sind "leer".

Was ist da strubbelig?

Gruss,
Christian

von eric (Gast)


Lesenswert?

Benutzt du irgendwelche Funktionen, die DMA benutzen? Die 
Grafikfunktionen klingen verdächtig danach. Wenn du jetzt Variablen auf 
dem Stack hast und damit diese Funktionen aufrufst kann das fürchterlich 
schief gehen, weil der DMA-Controller nicht auf den CCM zugreifen kann.

von Dr. Sommer (Gast)


Lesenswert?

Christian J. schrieb:
> Der Debugger zeigt dann auch, dass das sp register sich korekt bei
> 0x1000FFFF befindet, also im CCRAM.
Nö, das ist nicht korrekt. Der Stack Pointer zeigt immer auf das erste 
Element hinter dem Stack. Vor dem "push" wird der Stackpointer 
dekrementiert, und nach dem "pop" inkrementiert. Somit muss der SP auf 
0x10010000 zeigen. Wenn man das nicht macht, sind alle Zugriffe um ein 
Byte verrutscht. Beim Cortex-M4 funktioniert das zwar, ist aber langsam. 
Bei Zugriffen größer als 1 word - also z.B. double oder uint64_t - 
funktionierts aber nicht mehr und resultiert in einem Crash. 
float-Argumente an (s)printf werden immer auf double konvertiert, somit 
führt auch die Übergabe eines float an (s)printf zu einem Crash. Hat 
also nichts mit dem CCM zu tun, sondern mit dem Alignment deiner 
Stack-Adresse.

PS: Selbst ST macht das in den eigenen Linker-Scripten falsch. Da gibts 
hier irgendwo einen Thread zu...

von Christian J. (Gast)


Lesenswert?

eric schrieb:
> Benutzt du irgendwelche Funktionen, die DMA benutzen? Die
> Grafikfunktionen klingen verdächtig danach.

Ja klar, die ganze Comm mit dem Display läuft über SPI DMA ab und auch 
der AD Wandler spielt seine Daten per DMA ins SRAM rein.

Aber wieso hat der DMA was mit dem Stack zu tun? Den verschiebe ich doch 
bloss an eine andere Adresse und das Linker Script gilt global für 
alles.

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Dr. Sommer schrieb:
> Nö, das ist nicht korrekt. Der Stack Pointer zeigt immer auf das erste
> Element hinter dem Stack. Vor dem "push" wird der Stackpointer
> dekrementiert, und nach dem "pop" inkrementiert. Somit muss der SP auf
> 0x10010000 zeigen. Wenn man das nicht macht, sind alle Zugriffe um ein
> Byte verrutscht. Beim Cortex-M4 funktioniert das zwar, ist aber langsam.
> Bei Zugriffen größer als 1 word - also z.B. double oder uint64_t -
> funktionierts aber nicht mehr und resultiert in einem Crash.

Müsste aber richtig sein, habs noch mal gescheckt.... das ist der erste 
Stack Wert, wobei main () ja bereits einen Aufruf aus dem Startup Code 
heraus darstellt.

Auf "Stack overflow" berichten einige über dieses Problem.... glaube das 
lag an der Compiler Version.

von Dr. Sommer (Gast)


Lesenswert?

Wo kommt denn dann die 0x1000FFFF her?? Die ist in jedem Fall falsch und 
sollte niemals im SP stehen, weder am Anfang noch später.

von Lukas K. (carrotindustries)


Lesenswert?

Christian J. schrieb:
> Aber wieso hat der DMA was mit dem Stack zu tun?

DMA kann auf den CCRAM nicht zugreifen.

Dr. Sommer schrieb:
> PS: Selbst ST macht das in den eigenen Linker-Scripten falsch. Da gibts
> hier irgendwo einen Thread zu...
Beitrag "[ARM] Nützliches newlib-nano float printf"

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.