Problem bei Erstellung eines Arrays

Gast #3640995
Lesenswert?

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.
1
void estimator_qmethod(float a1, float a2, float r1[3], const float r2[3], float b1[3], float b2[3], float q[4])
2
{
3
  float B[9] = {0,0,0,0,0,0,0,0,0};
4

5
  float V_f[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
6

7
  B[0] = V_f[1] * B[2];
8
}


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
Gast #3640999
Lesenswert?

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.
Gast #3641016
Lesenswert?

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.
Gast #3641494
Lesenswert?

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.
#3641632
Lesenswert?

Also, wenn das bei dir nicht irgenwo anders definiert ist, dann such mal 
in der startup_stm32f4xx.s nach diesem Code:
1
Stack_Size      EQU      0x00001000
2

3
                AREA  STACK, NOINIT, READWRITE, ALIGN=3
4
Stack_Mem      SPACE  Stack_Size
5
__initial_sp
Hier wird der Stack eingerichtet.
In diesem Fall 0x00001000 = 4KByte
Gast #3641711
Lesenswert?

Danke für den Tipp Detlef Kunz.

Bei mir steht folgendes
1
/*----------Stack Configuration-----------------------------------------------*/
2
#define STACK_SIZE       0x00000200      /*!< The Stack size suggest using even number    */
3
__attribute__ ((section(".co_stack")))
4
unsigned long pulStack[STACK_SIZE];

Könnte ich den Stack einfach auf z.B. 0x00000600 erhöhen?
Wie hoch könnte man den Stack treiben?
#3641930
Lesenswert?

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.
#3641944
Lesenswert?

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.
Gast #3642217
Lesenswert?

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).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren