Hallo zusammen,
ich arbeite mit einem STM32F4 und CooCox (mit neuster GCC Version).
Ich habe ein etwas größeres Programm (hier die gekürzte Fassung!!!)
geschrieben, in dem ich ein Array V_f[16] innerhalb einer Funktion
erstelle.
Bei den anderen Funktionen, in denen ich solche Arrays erstelle,
funktioniert das auch, aber bei dieser Funktion verhält sich der
Compiler etwas merkwürdig.
Beim Debuggen übernimmt die Funktion estimator_qmethod keine Werte, z.B.
ist a1 = 0 obwohl ich eine 1.0f übergeben habe. Die Variable B nimmt
auch Werte an, wie zum Beispiel 2.67421E-49 anstatt 0.0, nachdem V_f
deklariert wurde. Danach bricht dann auch der Debugger ab bzw. geht in
eine Endlosschleife (Ohne Debugger bleibt die MCU auch hängen)
Wenn ich die Größe von V_f[2] ändere, funktioniert das wie gewohnt.
Beim Kompilieren erhalte ich keine Warnungen.
Ich habe keinerlei Code-Optimierungen an.
Hat jemand eine Idee woran das liegen könnte?
Falls ihr mehr Informationen braucht, stelle ich die gerne bereit!
MfG
Peter
Peter schrieb:> mit neuster GCC Version
Also 4.9.0? Wo hast du die denn her?
Mit dieser homöopathischen Dosis an Code kann man jedenfalls gar nichts
sagen, außer "Speicherfehler" oder "Stack Overflow". Zeige ein
kleinstmögliches Programm (max 30 Zeilen+evtl.Startupcode), das ich
kompilieren und so direkt auf meinen eigenen STM32F4 packen kann und das
genau das problematische Verhalten zeigt.
Ich habe noch die 4.8er Version.
Ihr habt recht, es findet ein Stack Überlauf statt.
Nachdem ich vor dieser Funktion ein paar Arrays gekürzt hatte, lief die
Funktion. Wie gesagt, das Programm ist etwas komplexer (Matrizen
Operationen mit vielen Arrays).
Gibt es eine Möglichkeit den Stack zu erweitern bzw. optimaler
auszunutzen, ohne die Arrays zu verkleinern.
> Gibt es eine Möglichkeit den Stack zu erweitern bzw. optimaler> auszunutzen, ohne die Arrays zu verkleinern.
Mehr Speicher einbauen oder woanders Speicher einsparen.
Peter schrieb:> Gibt es eine Möglichkeit den Stack zu erweitern
Ja. Dafür gibt es Compileroptionen.
Lies das Manual zu GCC durch. da steht das irgendwo drin.
> bzw. optimaler> auszunutzen, ohne die Arrays zu verkleinern.
Du kannnst den Heap (malloc & free) nutzen.
Peter schrieb:> Wie hoch könnte man den Stack treiben?
Sinnvoll .... kommt auf Deinen Anwendungsfall an. Denk daran, daß die
Stackvariablen bei jedem Eintritt in die Funktion neu initialisiert
und/oder kopiert werden und beim Austritt vom Stack geworfen. Gegenüber
einer Standard-Vorgehensweise mit malloc/free gewinnst Du eigentlich
nichts.
Bei letzterem kannst Du Dir allerdings überlegen, ob Du die Variablen
nicht länger leben läßt (static oder global), was Dir Zeit sparen kann.
Peter schrieb:> Könnte ich den Stack einfach auf z.B. 0x00000600 erhöhen?
Ja, das könntest Du. Das wären 1536 Byte.
Sei etwas goßzügiger mit dem Zeug;)
Peter schrieb:> Wie hoch könnte man den Stack treiben?
Das ist etwas kompliziert zu beantworten.
Das hat damit zu tun, das der STM324 drei SRAM-Breiche hat, die für
verschiedene Aufgaben mehr oder weniger oder überhaupt nicht geeignet
sind.
Daher gibt da verschiedene Möglichkeiten, den Stackbereich zu setzen.
zB. Könnte man dem Stack den gesammten CCM geben, das wären 64K.
Aber bleiben wir hier bei "Stack für programmtechnisch Herausgeforderte"
;)
Das hier ist eine Methode, wenn man wirklich keinen Plan von der
Speicherplanung hat.
Da ich nicht weiß, wie groß der SRAM von deinem STM32F4 ist und ob Du
Heap (Sachen wie malloc) verwendest, machen wir das auf die (wirklich)
grobe Tour.
Vergrössere solange den Stack, bis der Linker irgendsowas meldet:
.\obj\application.axf: Error: L6406E: No space in execution regions with
.ANY selector matching startup_stm32f4xx.o(STACK).
Dann verkleinere den Stack wieder, bis der Linker zufrieden ist. Das
Ergebnis ist der größtmögliche Stack, den Du ohne die Benutzung von Heap
in deiner aktuellen Source benutzen kannst.
Halbier diesen Wert, und Du hast erst mal eine Weile Ruhe und kannst
auch noch Heap benutzen.
Nochmal langsam, zum mitschreiben: Das hier war ein Methode (ja
sicher, es gibt noch zigtausend andere, bessere, schönere) wie man ohne
viel Wissen die Stackgröße setzen kann.
Walter Tarpan schrieb:> Gegenüber einer Standard-Vorgehensweise mit malloc/free gewinnst Du> eigentlich nichts
Nur dass malloc/free langsam ist (Algorithmus zum Suchen eines freien
Speicherbereichs drin) und den Speicher nicht 100% nutzen kann, während
Stack-(de)-allokation je 1 Takt benötigt und keinen Speicher- overhead
hat.
Allerdings kann es tatsächlich sinnvoll sein die Variable global/static
zu machen (falls die Funktion nicht rekursiv ist...) weil dies die
Verwaltung dem Linker überlässt und damit einfacher macht (man merkt
beim Linken wenn's nicht passt).