PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : STM32 Array[500] zu groß?



NRicola
21.11.2019, 10:22
Hallo zusammen,

ich programmiere aktuell ein Nucleo-64-Board (STM32F411), Keil µVision v5.25.
Ich habe bereits ein kleines Grundgerüst an Code, aber Veriablen-seitig kaum der Rede wert - vielleicht sowas wie 30 Bytes, die ich zusätzlich zum Standard-generierten Code (durch CubeMX) definiert habe.
Nun habe ich ich folgendes Code-Segment:


int main(void)
{
[...]
uint16_t testvar[400];
for(uint16_t i=0;i<399;i++){
testvar[i] =0;
}
[...]
while(1){
LED_Blinker();
}
}

(Die main-while(1)-Prozedur habe ich zum Debuggen mal nur auf das LED-Blinken reduziert.)

Der Code läuft gut durch, die LED blinkt. Folgende Fälle lassen sich hier beobachten:

Ändere ich int16_t testvar[400]; zu int16_t testvar[500]; , kommt er nicht bis zur while-Schleife, LED blinkt nicht.
Deaktiviere ich die for-Schleife, dann kommt er in die while-Schleife und die LED blinkt.
for-Schleife bleibt deaktiviert, aber ich greife händisch auf das Array zu, dann kommt er in die while-Schleife, LED blinkt. Der Code sieht dann so aus:



int main(void)
{
[...]
uint16_t testvar[500];
testvar[495] = 0xFFFF;

[...]
while(1){
if(testvar[495]==0xFFFF){
LED_Blinker();
}
}
}


Also kommt er irgendwie nicht mit der for-Schleife klar. Aber warum?
Ausgangspunkt von mir war, fünf Arrays in einem Struct zusammenzufassen. Je mehr Arrays es sind, desto kleiner ist die Array-Größe, bei der das Problem auftritt. Bei den 5 Arrays ist das Problem bei einem index von um die 80, bei 3 Arrays um die 180 (ich hab die Grenzen nur sehr grob rausgefahren.) Die for-Schleife sieht dann so aus:


for(uint16_t i=0;i<70;i++){
structvar.array1[i] =0;
structvar.array2[i] =0;
structvar.array3[i] =0;
}


Hat jemand eine Idee, warum hier die for-Schleife nicht klar kommt?

Im Debug-Modus werde ich nicht so richtig schlau. Er verfängt sich da dann im Fall des Problems immer im GPIO-init (der eigentlich immer davor ist).
Wenn ich dazu nähere Informationen liefern soll, gebt bitte Bescheid.

Grüß,
NRicola

- - - Aktualisiert - - -

Neue Erkenntnis:
Ich habe gerade die Variable als globale eingeführt, also


uint16_t testvar[500];
int main(void)
{
[...]
for(uint16_t i=0;i<499;i++){
testvar[i] =0;
}
[...]
while(1){
LED_Blinker();
}
}

Dann funktioniert es und die for-Schleife kommt klar.
Verstehen würde ich das Problem natürlich trotzdem. Hat jemand eine Erklärung dazu?

Grüß,
NRicola

Moppi
21.11.2019, 10:25
Hallo NRicola,

Du kannst noch mehr ausprobieren:


int main(void){
[...]
uint16_t testvar[500];
for(uint16_t i=0;i<399;i++){
testvar[0] =0;
}
[...]
while(1){
LED_Blinker();
}




Blinkt das Programm dann hier?



Ich habe gerade die Variable als globale eingeführt

War auch so eine Idee, die ich hatte. Das aus der main-Funktion raus zu verlegen, in den globalen Scope. Allerdings ohne schlüssige Erklärung, warum das besser funktionieren sollte.




MfG

NRicola
21.11.2019, 10:40
Hallo Moppi,

ja, da blinkt es auch. Scheint erst zu stocken, wenn ein laufender Index rein kommt. Ich habe auch das Abbruchkriterium der for-Schleife auf i<1 heruntergesetzt: auch dann hängt er.

Grüß,
NRicola

Holomino
21.11.2019, 11:23
In einer Funktion definierte Variablen landen auf dem Stack, modulglobale Variablen hingegen auf dem Heap.

Du könntest mal schauen, ob Du eine den Stack betreffende Deklaration in Deinen Projekteinstellungen findest.

NRicola
26.11.2019, 20:37
Hallo Holomino,

tendenziell gingen meine Überlegungen in eine ähnliche Richtung - auch wenn ich sie nicht hätte benennen können. :)
Allerdings wüsste ich nicht, wo ich Einstellmöglichkeiten dazu hätte. Hast du eine Idee, wo ich suchen sollte?

Grüß,
NRicola

Holomino
27.11.2019, 14:16
Praktisch sagen kann ich's Dir nicht, ich hab dem Keil nicht.
Du könntest aber mal nach "Stack size" googeln. Das sitzt entweder in irgendeinem eingebundenen Header (da üblicherweise abhängig von der RAM-Größe des verwendeten Controllers) oder der eingebundenen Bootroutine.