Hallo, kurze Frage an vlt. jemanden der dasselbe schonmal gemacht hat. Ich benutze einen MSp430F5659 der sollte an die 66 kB RAM besitzen. Jetzt habe ich schon ein paar Byte arrays aufgespannt für MEssergebnisse alle 16bit array[2048] die ich gerne global hätte, einfach aus Mangel an "guten" Programmierkenntnissen so geschehen. Jetzt wollte ich ein 32bit array[2048] lokal aufgrund einer Berechnung hinzufügen und dachte in meiner Naivität ich mach das mal lokal, dann holt sich ja der MSP430 einen unbelegten Speicherplatz und benutzt das und nach der Funktion wird das wieder freigegeben bzw. kann für andere Zwecke benutzt werden. Das Riesenarray überschreibt mir allerdings Speicherbereiche von anderen Variablen, auch globalen Variablen. Nun befasse ich mich das erste mal mit malloc und soweiter, vielleicht hat ja einer eine Pauschalantwort und sagt nein machs mit globalen und gut ist. Platz hab ich ja zum Glück noch frei, wird wohl auf mein nächster Versuch sein, daher arbeite ich und vielleicht andere auch gerne mit vielen globalen, die kommen sich einfach Gegenseitig nie ins Gehege, oder ist das nur meine Sichtweise? RTOS hab ich nichts am laufen, einfach nur mein eigener Code. Also Danke schonmal fürs lesen. Grüße
:
Verschoben durch Moderator
Stefan S. schrieb: > Jetzt wollte ich ein 32bit array[2048] lokal aufgrund einer Berechnung > hinzufügen und dachte in meiner Naivität ich mach das mal lokal, dann > holt sich ja der MSP430 einen unbelegten Speicherplatz Tut er auch, aber auf dem Stack - und nicht automatisch via malloc auf dem Heap. Zu letzterem müßtest Du malloc schon selber aufrufen. Der Stack hat eine statische Größe, die Du irgendwo festlegst, und wenn der zu klein für so ein Array ist, hast Du einen Stacküberlauf. Entweder, Du machst den Stack größer, oder Du läßt es als globale Variable. Von malloc würde ich grundsätzlich abraten, sofern es auch ohne malloc geht.
Sven B. schrieb: > Klingt nach Stack Overflow? Würd ich zustimmen, aber ich benutzt ja grad mal ein Viertel vom RAM, ich test gleich mal wenn ichd as Riesenarray auch als globale definiere. Was ich nicht verstehe: auf globale Variablen passt mein Compiler, CodeComposerStudio8 gut auf, die funktionieren immer miteinander, aber was machen die lokalen Variablen, irgendwie scheinen die eben keiner Kontrolle zu unterliegen, wobei das ja eigentlich nciht sein kann.
Ach ja, wenn es Dir mehr um halbwegs sauberes Programmieren geht, kannst Du das array in der Funktion auch einfach mit "static" deklarieren. Dann hast Du es gekapselt, es wird aber nicht auf den Stack gelegt. Es ist dann eine globale Variable, die immer ihren Speicher belegt, aber nur aus dieser FUnktion heraus ansprechbar ist. So eine Funktion darfst Du dann aber nicht von verschiedenen Kontexten her aufrufen, also nicht z.B. sowohl aus dem Hauptprogramm als auch aus einem Interrupt heraus. Oder von verschiedenen Tasks, wenn Du ein RTOS hättest.
Nop schrieb: .. > Tut er auch, aber auf dem Stack - und nicht automatisch via malloc auf > dem Heap. Hammer, danke, die Info hat mir irgendwie gefehlt, ich dachte dass der Compiler einfach irgendwie ins Ram schreibt und der stack benutzt wird wenn Funktionen aufgerufen werden um pointer etc anzulegen, aber das macht ja vollkommen Sinn dass der Stack genau dafür und eben auch für die lokalen Variablen genutzt wird. mein Stack ist 160Bytes groß, kann ich auch umstellen, ich denke aber ich lass den so, aus historischern Gründen. Da passen natürlich keine 2048 Bytes rein. Was mich jetzt ein wenig wundert, ich kann auch die Heap-size festlegen, die wäre 160Bytes aktuell, ich vermute jetzt mal ich benutze den Heap niemals, weil ich auf ihn nur mit malloc zugreifen kann, richtig? Das Thema war mir irgendwie nie so bewusst, da globale natürlich meistens einfach funktionieren oder garnicht funktionieren. Noch kurz die Frage, mein Stack wächst Rückwärts vom Speicherende in meinen "Code" hinein, daher ja auch der Überlauf wenn zu große Daten reinlaufen. Wie kann ich mir den Heap vorstellen, leg ich den vorher fest, oder beginnt der immer an der RAM Start adresse? Danke schonmal.
Stefan S. schrieb: > mein Stack ist 160Bytes groß Das erklärt einiges. Oftmals ist die Speicheranordnung so, daß man erst die globalen Variablen hat, an noch höheren Adressen den Heap, und darüber den Stack. Bei Benutzung wächst der Stack dann nach unten. In Deinem Fall wächst der Stack also nicht nur in den Heap, sondern noch weiter, und deswegen werden die globalen Variablen überschrieben. > Was mich jetzt ein wenig wundert, ich kann auch die Heap-size festlegen, > die wäre 160Bytes aktuell, ich vermute jetzt mal ich benutze den Heap > niemals, weil ich auf ihn nur mit malloc zugreifen kann, richtig? Genau. Wobei z.B. printf() hinter den Kulissen u.U. auch noch malloc() benutzt. > Wie kann ich mir den Heap vorstellen, leg ich den vorher fest, oder > beginnt der immer an der RAM Start adresse? Der Heap ist letztlich einfach ein Datenbereich, genau wie der Stack. Effektiv wird da ein großes Array irgendwo angelegt und dessen Anfangsadresse gespeichert.
Danke NOP. Jetzt dacht ich ich find den heap auch in meinen files, aber nein. also Stack ist kein Problem der ist benannt: aber heap nicht so wirklich, naja vielleicht wird er ja wirklich einfach spontan irgendwohingelegt. Und ja sprintf benutze ich für Fließkommaumwandlungen, von daher wirds da schon auch irgendwo drinstecken, hätt ich jetzt fast übersehen, danke also.
1 | SECTIONS
|
2 | {
|
3 | .bss : {} > RAM | RAM2 /* Global & static vars */ |
4 | .data : {} > RAM | RAM2 /* Global & static vars */ |
5 | .TI.noinit : {} > RAM | RAM2 /* For #pragma noinit */ |
6 | .sysmem : {} > RAM /* Dynamic memory allocation area */ |
7 | .stack : {} > RAM (HIGH) /* Software system stack */ |
8 | |
9 | #ifndef __LARGE_CODE_MODEL__
|
10 | .text : {} > FLASH /* Code */ |
11 | #else
|
12 | .text : {} >> FLASH2 | FLASH /* Code */ |
13 | #endif
|
14 | .text:_isr : {} > FLASH /* ISR Code space */ |
15 | .cinit : {} > FLASH /* Initialization tables */ |
16 | #ifndef __LARGE_DATA_MODEL__
|
17 | .const : {} > FLASH /* Constant data */ |
18 | #else
|
19 | .const : {} >> FLASH | FLASH2 /* Constant data */ |
20 | #endif
|
21 | .cio : {} > RAM /* C I/O Buffer */ |
22 | |
23 | .pinit : {} > FLASH /* C++ Constructor tables */ |
24 | .binit : {} > FLASH /* Boot-time Initialization tables */ |
25 | .init_array : {} > FLASH /* C++ Constructor tables */ |
26 | .mspabi.exidx : {} > FLASH /* C++ Constructor tables */ |
27 | .mspabi.extab : {} > FLASH /* C++ Constructor tables */ |
28 | #ifdef __TI_COMPILER_VERSION__
|
29 | #if __TI_COMPILER_VERSION__ >= 15009000
|
30 | #ifndef __LARGE_CODE_MODEL__
|
31 | .TI.ramfunc : {} load=FLASH, run=RAM, table(BINIT) |
32 | #else
|
33 | .TI.ramfunc : {} load=FLASH | FLASH2, run=RAM, table(BINIT) |
34 | #endif
|
35 | #endif
|
36 | #endif
|
Stefan S. schrieb: Der Heap müßte das da sein: > .sysmem : {} > RAM /* Dynamic memory allocation > area */ Das wird wahrscheinlich von Deiner IDE verwaltet.
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.