Hallo zusammen =) Ich verwende einen STM32 mit FreeRTOS. Im linker script wird momentan 1kB für Stack und ein halbes kB für Heap reserviert. Der FreeRTOS Kernel holt sich ja nochmal eigenen Heap, also kann ich ja den Heap im Linker Script einfach auf 0Byte setzen, richtig? Jetzt zu dem 1kB Stack: wozu genau brauche ich den und wie finde ich die optimale Größe raus? Ich dachte, dass Funktionen, die von einem FreeRTOS Task heraus aufgerufen werden, für lokale Variablen auch den ihnen zugewiesenen Stack innerhalb des FreeRTOS Heaps nutzen. Damit brauche ich den globalen Stack doch nur so lange, bis der Scheduler des OS läuft, also nur für ein paar Initialisierungen? da würden doch 100Byte locker ausreichen? Und wo kommen lokale Variablen hin, die in Interrupts genutzt werden? Danke euch & viele Grüße, Michael
:
Bearbeitet durch User
Der Globale Stack wird vom Free-RTOS Kernel benutzt sobald du vTaskStartScheduler() aufrufst. Jeder Task hat seinen eigenen Stack der über die Funktion xTaskCreate() vom Heap reserviert wird. Es gibt nur einen Heap alle Tasks und der Kernel benutzen den gleichen. mit xTaskCreateStatic() kannst du Task erstellen die ihren Speicher nicht vom Heap bekommen.
Michael S. schrieb: > Damit brauche ich den > globalen Stack doch nur so lange, bis der Scheduler des OS läuft, also > nur für ein paar Initialisierungen? da würden doch 100Byte locker > ausreichen? Da landen auch Interrupts drauf. Und die können bei STM32 verschachtelt sein, und bei vorhandener FPU mit recht vielen zu sichernden Registern...
C. schrieb: > Es gibt nur einen Heap alle Tasks und der Kernel benutzen den gleichen. mh, alle tasks und der kernel nutzen den FREERTOS Heap, der aber doch nicht der gleiche ist, wie der Heap, der im Linker script reserviert wird. Wenn ich das richtig verstanden habe, würde ein normales malloc() einen Speicher im globalen heap holen, aber FreeRTOS hat ja seinen eigenen Speicher (configTOTAL_HEAP_SIZE) von Anfang an, aus dem dann mit pvPortMalloc() Speicher für die threads und den KErnel geholt wird. Soweit bin ich mir eigentlich ziemlich sicher. >Der Globale Stack wird vom Free-RTOS Kernel benutzt sobald du vTaskStartScheduler() aufrufst. wie meinst du das? bist du dir sicher? der Kernel reserviert sich doch seinen eigenen Heap mit der Größe von configTOTAL_HEAP_SIZE, wozu soll der noch Speicher aus dem globalen Stack holen? >Da landen auch Interrupts drauf. Und die können bei STM32 verschachtelt sein... die kommen also nicht in den stack vom gerade laufenden thread sondern in den globalen? gut zu wissen, dann brauch ich in den thread-stack-größen ja kaum Buffer für interrupts einbauen.
Noch was Grundsätzliches zu Stack, Heap und Linkerscripts: Die "Reservierung" von Stack bzw. Heap innerhalb des Linkerscripts ist nur insofern von Bedeutung, dass der Linker meckert wenn durch globale und statische Variablen bereits so viel RAM belegt ist, dass die "Reservierung" den Speicher zum überlaufen bringen würde. Ansonsten wird da nämlich gar nichts reserviert. Es ist somit eine Garantie, dass wenn Stack und Heap innerhalb der angegebenen Grenzen bleiben, es zu keinem Überlauf kommt. Der Stack und auch der Heap können (sofern denn noch genug freier Speicher verfügbar ist) ohne Probleme größer werden als im Linkerscript angegeben.
Christopher J. schrieb: > Noch was Grundsätzliches zu Stack, Heap und Linkerscripts: Das hängt sehr von deiner Umgebung ab.
:
Bearbeitet durch User
Von welcher Umgebung denn? Ich denke wir reden hier vom "normalen" ST-Linkerscript, was bei CubeMX und Co dabei ist und im Grunde dem 08/15-Linkerscript aus dem GCC(-ARM) entspricht. Das Verhalten sollte aber für andere Cortex-M exakt gleich sein und es hängt auch nicht von irgendeiner IDE oder dergleichen ab.
:
Bearbeitet durch User
Christopher J. schrieb: > Von welcher Umgebung denn? Ich denke wir reden hier vom "normalen" > ST-Linkerscript, was bei CubeMX und Co dabei ist und im Grunde dem > 08/15-Linkerscript aus dem GCC(-ARM) entspricht. Das Verhalten sollte > aber für andere Cortex-M exakt gleich sein und es hängt auch nicht von > irgendeiner IDE oder dergleichen ab. Generiere mal für MDK-ARM V5. Technisch hängt es natürlich vom Linkerscript und vom startup file ab. Doch davon gibt es verschiedenen. Daher ist es leichter durch die Benennung der Umgebung zu beschreiben. Auszug aus dem Mapping file für einen STM32L476
1 | Component: ARM Compiler 5.06 update 6 (build 750) Tool: armlink [4d35ed] |
2 | ...
|
3 | |
4 | 0x200004ac - 0x00000060 Zero RW 3014 .bss c_w.l(libspace.o) |
5 | 0x2000050c 0x080047b0 0x00000004 PAD |
6 | 0x20000510 - 0x00000200 Zero RW 131 HEAP startup_stm32l476xx.o |
7 | 0x20000710 - 0x00000400 Zero RW 130 STACK startup_stm32l476xx.o |
Man sieht, der Stack wird hier direkt hinter die Variablen (und Heap) gelegt und überschriebt beim Überlauf sofort relevante Daten. Da man das Ganze allerdings durch verändern des Linker- und startup files beeinflussen kann, ist es auch noch von den eigenen Settings abhängig.
Das ist ja genau das was ich dem TO versucht hatte zu erklären, weil ich das Gefühl hatte, dass er da einem Missverständnis aufsitzt. Der Stack liegt nicht da, wo der Linker ihn hin packt bzw. wo das Map-File sagt, sondern er wächst vom initialen Stackpointer aus nach unten. Im Linker-Script und dementsprechend auch im Map-File findest du nur eine Dummy-Section, welche den bereits oben erwähnten Zweck hat. Deshalb ist es auch egal wohin genau der Linker den Stack "platziert", weil den Stack das ohnehin nicht interessiert.
Wieder kommt es auf dein startup file an. Der Cortex-M legt den MSP auf den Wert im ersten Vector. Im startup file wird dies ggf. umdefiniert. gcc
1 | Reset_Handler:
|
2 | ldr sp, =_estack |
Im Linkerfile ist dann fest codiert: _estack = 0x20020000; /* end of RAM */ Und dort liegt beim gcc dann auch der Stack. Da gebe ich dir auch recht, dass es nicht der Bereich ist, den man im Mapfile sieht. Der hat aber auch einen anderen Namen. Bei den anderen Umgebungen ist es anders. Für den TO ist es aber auch nur teilweise interessant, da hier auch noch der PSP genutzt wird, der durch FreeRTOS vergeben wird. Aber darauf ist C. bereits in der ersten Antwort eingegangen.
:
Bearbeitet durch User
Steffen R. schrieb: > Bei den anderen Umgebungen ist es anders. Sicherheitshalber nochmal beim RealARM gecheckt. Der Stackpointer liegt auch nach der Initialisierung noch direkt hinter den Variablen.
Steffen R. schrieb: > Wieder kommt es auf dein startup file an. Natürlich, ich war lediglich davon ausgegangen, dass der TO die Standard-Startupfiles von ST nutzt und da ist zumindest beim GCC der initiale Stackpointer fix und hängt damit nicht vom Linkerscript ab. Auch meine Aussage bezüglich der Unabhängigkeit der IDE war auf den GCC bezogen, weil ich davon ausgegangen bin, dass der TO den benutzt, da er eben nichts anderes dazu geschrieben hatte. Noch ein letzter Nachtrag: Steffen R. schrieb: > Für den TO ist es aber auch nur teilweise interessant, da hier auch noch > der PSP genutzt wird, der durch FreeRTOS vergeben wird. Aber darauf ist > C. bereits in der ersten Antwort eingegangen. Alles was ich dem TO sagen wollte war (unter der Annahme, dass er den GCC mit "Standard"-Linkerscript und -Startupfile verwendet): Mach dir keine Gedanken um die Angaben zur Größe von Stack und Heap im Linkerscript, da diese Größenangaben sowieso Makulatur sind.
:
Bearbeitet durch User
Christopher J. schrieb: > Standard-Startupfiles von ST Ich gehe auch von den Standard-Startupfiles von ST aus, aber eben nicht für den gcc. Ich bin eigentlich nur so penetrant, weil du suggerierst, der gcc sei Standard. Naja, und weil du nebenbei auch schwer zu findende sporadische Fehler als tolerabel suggerierst. Christopher J. schrieb: > Die > "Reservierung" von Stack bzw. Heap innerhalb des Linkerscripts ist nur > insofern von Bedeutung, dass der Linker meckert wenn Das ist eigentlich der wichtigste Punkt am ganzen. Der Linker soll meckern, wenn der Speicher zur Neige geht. Daher ist es wichtig, die benötigte Stackgröße (oder mehr) anzugeben. Nicht immer ist der RAM so reichlich, dass dir die Hilfe des gcc dir Arbeit abnimmt. Insofern ist die Frage des TO sehr berechtigt und er sollte sich darüber Gedanken machen. Mit OS wird ein Fehler an der Stelle noch schwieriger zu finden.
Steffen R. schrieb: > Ich gehe auch von den Standard-Startupfiles von ST aus, aber eben nicht > für den gcc. Ich bin eigentlich nur so penetrant, weil du suggerierst, > der gcc sei Standard. Ich gehe mal davon aus, dass du so penetrant bist, weil du es selber nicht wusstest. Sonst hättest du nicht das Beispiel mit Keil gebracht, für den eben genau das gleiche gilt wie für den GCC... Steffen R. schrieb: > Generiere mal für MDK-ARM V5. > [...] > Man sieht, der Stack wird hier direkt hinter die Variablen (und Heap) > gelegt und überschriebt beim Überlauf sofort relevante Daten. ... weil genau das ist eben nämlich nicht der Fall. Steffen R. schrieb: > Naja, und weil du nebenbei auch schwer zu findende sporadische Fehler > als tolerabel suggerierst. > > Christopher J. schrieb: >> Die >> "Reservierung" von Stack bzw. Heap innerhalb des Linkerscripts ist nur >> insofern von Bedeutung, dass der Linker meckert wenn > > Das ist eigentlich der wichtigste Punkt am ganzen. Der Linker soll > meckern, wenn der Speicher zur Neige geht. Daher ist es wichtig, die > benötigte Stackgröße (oder mehr) anzugeben. Nicht immer ist der RAM so > reichlich, dass dir die Hilfe des gcc dir Arbeit abnimmt. > > Insofern ist die Frage des TO sehr berechtigt und er sollte sich darüber > Gedanken machen. Mit OS wird ein Fehler an der Stelle noch schwieriger > zu finden. Ach komm, jetzt erzähl hier nicht so einen Käse. Ich habe nie behauptet, dass man sich keine Gedanken um den Speicherverbrauch machen muss. Natürlich muss man das und man muss es umso mehr, wenn man ein RTOS einsetzt. Ich habe lediglich gesagt, dass durch die Angaben im Linkerscript kein Speicher "reserviert" wird und sowohl Stack, als auch Heap sowohl größer, als auch kleiner sein können als im Linkerscript angegeben. Der "Verbrauch" richtet sich nicht nach dem Linkerscript, sondern nach der tatsächlichen Nutzung. Um diese tatsächliche Nutzung muss man sich natürlich unbedingt Gedanken machen.
Treffen Sich Heap und Stack. Fragt der eine den anderen "Hi schon lange nicht mehr gesehen, was machst Du hier" und der antwortet "Hard_Fault_Handler" Wer ist jetzt wer?
Das juckt den Hardfault ueberhaupt nicht du Laie. Hoechstens dabei verbogene Pointer im weiteren Ablauf...
Jemand hier im Forum legt den Stack an den Anfang des RAM Bereichs. Dann klappt es auch sofort beim Stackoverflow mit dem Hardfault ohne das Daten überschrieben werden.
Christopher J. schrieb: > Noch was Grundsätzliches zu Stack, Heap und Linkerscripts: Die > "Reservierung" von Stack bzw. Heap innerhalb des Linkerscripts ist nur > insofern von Bedeutung, dass der Linker meckert wenn durch globale und > statische Variablen bereits so viel RAM belegt ist, dass die > "Reservierung" den Speicher zum überlaufen bringen würde. Ansonsten wird > da nämlich gar nichts reserviert. Es ist somit eine Garantie, dass wenn > Stack und Heap innerhalb der angegebenen Grenzen bleiben, es zu keinem > Überlauf kommt. Der Stack und auch der Heap können (sofern denn noch > genug freier Speicher verfügbar ist) ohne Probleme größer werden als im > Linkerscript angegeben. Jap, das hatte ich schon so verstanden. Ich möchte trotzdem einen immer ausreichend großen Stack schon im Linker reservieren, sodass ich den freien Platz danach komplett für FreeRtos verwenden kann, ohne mir sorgen machen zu müssen, dass der Stack da reinwächst. Also zusammenfassend (korrigiert mich wenn ich was falsch formuliere): -der Heap im linkerscript kann ruhig 0 sein, weil der eh nie genutzt wird, solange ich kein malloc() verwende -die einzelnen Tasks bekommen ihren Stack innerhalb des von FreeRTOS reservierten Speichers und verwenden nicht den globalen Stack, der im Linker script reserviert wird - der globale Stack im Linker script wird nur für ISRs verwendet (die auch verschachtelt sein können) und für alle Variablen, die vor dem start des FreeRTOS-schedulers angelegt werden. Daher muss er nicht sonderlich groß sein, 128Byte sollten in meinem Fall ausreichen
:
Bearbeitet durch User
Michael S. schrieb: > Jap, das hatte ich schon so verstanden. Offensichtlich nicht, weil sich das ganz böse mit Michael S. schrieb: > Ich möchte trotzdem einen immer > ausreichend großen Stack schon im Linker reservieren, sodass ich den > freien Platz danach komplett für FreeRtos verwenden kann, ohne mir > sorgen machen zu müssen, dass der Stack da reinwächst. widerspricht. Ich versuche es nochmal. Im Linkerscript wird abgesehen von Platz für globale (.bss) und statische Variablen (.data) nichts reserviert. Die Angaben zu der Größe von Stack und Heap führen lediglich zu einem Compiletime-Check (bzw. Linktime-Check), ob .bss+.data+heap+stack > RAM-Größe. Ist das der Fall, dann spuckt der Linker einen Fehler aus. Zur Laufzeit (i.e. "runtime") hat die "Reservierung" von Stack bzw. Heap absolut keine Bedeutung mehr. Du kannst beides auf Null setzen und es wird trotzdem problemlos funktionieren, so lange der Gesamtverbrauch (.bss+.data+heap+stack) zur Laufzeit kleiner ist als die Größe des RAMs. Michael S. schrieb: > -der Heap im linkerscript kann ruhig 0 sein Ja > , weil der eh nie genutzt > wird, solange ich kein malloc() verwende Nein, das ist nicht der Grund. FreeRTOS kann z.B. den Heap verwenden und wird dies auch sehr wahrscheinlich tun. > -die einzelnen Tasks bekommen ihren Stack innerhalb des von FreeRTOS > reservierten Speichers FreeRTOS reserviert für die Tasks nur dann Speicher, wenn man den Task mit xTaskCreateStatic erstellt, ansonsten nimmt sich FreeRTOS für den Task-Stack RAM aus dem Heap. Siehe auch https://www.freertos.org/Static_Vs_Dynamic_Memory_Allocation.html > verwenden nicht den globalen Stack, der im > Linker script reserviert wird Ja, den "globalen Stack" verwenden sie nicht aber der wird auch nicht im Linkerscript reserviert. > - der globale Stack im Linker script wird nur für ISRs verwendet (die > auch verschachtelt sein können) und für alle Variablen, die vor dem > start des FreeRTOS-schedulers angelegt werden korrekt > Daher muss er nicht > sonderlich groß sein, 128Byte sollten in meinem Fall ausreichen Das kommt natürlich auf deine ISR drauf an und wie verschachtelt die gegebenenfalls ist. Bei jeder Verschachtelung landen automatisch 8*4 Byte auf dem Stack und da sind 128 Byte schnell weg. Wie oben schon gesagt musst du dir aber nicht direkt Gedanken machen ob dein Exception-Stack jetzt 128 Byte oder doch eher 256 Byte haben wird. Der Stack wächst nach unten in Richtung Heap und solange da noch Platz ist kann er weiter wachsen, ohne dass das zu irgendwelchen Problemen führen würde. Wie viel Platz da jetzt noch genau zwischen Heap und Stack ist, dass musst du genau beobachten und alles mit einbeziehen, z.B. auch deine Task-Stacks die auf dem Heap landen und somit zur Linkzeit im RAM-Verbrauch noch nicht auftauchen.
Danke dir für die ausführliche Erklärung. > Ich versuche es nochmal. Im Linkerscript wird abgesehen von Platz für > globale (.bss) und statische Variablen (.data) nichts reserviert. Die > Angaben zu der Größe von Stack und Heap führen lediglich zu einem > Compiletime-Check (bzw. Linktime-Check), ob .bss+.data+heap+stack > > RAM-Größe. Ist das der Fall, dann spuckt der Linker einen Fehler aus. > > Zur Laufzeit (i.e. "runtime") hat die "Reservierung" von Stack bzw. Heap > absolut keine Bedeutung mehr. Du kannst beides auf Null setzen und es > wird trotzdem problemlos funktionieren, so lange der Gesamtverbrauch > (.bss+.data+heap+stack) zur Laufzeit kleiner ist als die Größe des RAMs. doch, das hatte ich tatsächlich richtig verstnden. Ich will nur bereits beim linken sicher sein, dass mir der Stack hinterher ausreicht, also will ich einen Speicher reservieren, der sicher groß genug ist, also dass der Stack zur Laufzeit sicher nie größer wird, als der Stack, der beim linken angegeben wird. > Michael S. schrieb: >> -der Heap im linkerscript kann ruhig 0 sein > Ja > >> , weil der eh nie genutzt >> wird, solange ich kein malloc() verwende > Nein, das ist nicht der Grund. FreeRTOS kann z.B. den Heap verwenden und > wird dies auch sehr wahrscheinlich tun. aber FreeROTS hat doch seinen eigenen Heap im .bss Bereich von Anfang an reserviert, das sind bei mir 14kB (bei einem insgesamt-Ram von 20kB), aus denen sich FreeRTOS seinen Speicher holt... siehe angehängten Screenshot. Damit ist der globale heap doch komplett überflüssig, solange ich kein malloc verwende. > FreeRTOS reserviert für die Tasks nur dann Speicher, wenn man den Task > mit xTaskCreateStatic erstellt, ansonsten nimmt sich FreeRTOS für den > Task-Stack RAM aus dem Heap. aber aus dem eigenen Heap, der wie gesagt im .bss Bereich liegt > Bei jeder Verschachtelung landen automatisch 8*4 > Byte auf dem Stack und da sind 128 Byte schnell weg. oha, warum so viel bzw für was? In den ISRs verwende ich kaum stack-Speicher > Wie oben schon > gesagt musst du dir aber nicht direkt Gedanken machen ob dein > Exception-Stack jetzt 128 Byte oder doch eher 256 Byte haben wird. Naja, wenn globaler heap (0Byte) + globaler stack zusammen nur 128Byte zugewiesen bekommen, weil der FreeRTOS Stack im .bss Bereich maximal groß gemacht wird, dann kann der Stack auch nirgends mehr raus wachsen. Oder mache ich etwas grob falsch?
:
Bearbeitet durch User
Wie ich oben schonmal schrieb, vieles ist von deiner speziellen Umgebung und deiner speziellen Konfiguration abhängig. Diese hast du bisher nie angegeben. Christopher J. bezieht sich auf gcc und einer bestimmten FreeRTOS Konfiguration.
:
Bearbeitet durch User
Eine FreeRTOS Anpassung, welche heap3.c nutzt, würde wohl malloc() nutzen. Die Anpassungen, welche ich bisher für den STM32 (welcher Core?) gehabt habe, nutzen wie bei dir heap4.c. Michael S. schrieb: >> Wie oben schon >> gesagt musst du dir aber nicht direkt Gedanken machen ob dein >> Exception-Stack jetzt 128 Byte oder doch eher 256 Byte haben wird. > Naja, wenn globaler heap (0Byte) + globaler stack zusammen nur 128Byte > zugewiesen bekommen, weil der FreeRTOS Stack im .bss Bereich maximal > groß gemacht wird, dann kann der Stack auch nirgends mehr raus wachsen. > Oder mache ich etwas grob falsch? Da du lt. Bild scheinbar den gcc verwendest: Dein main()-Funktion usw. welche du außerhalb von FreeRTOS nutzt, nutzen auch diesen Stack. Beim gcc reservierst du nicht, sondern prüfst, ob der freie Bereich entsprechend deiner Angaben groß genug ist. Der Stack beginnt hier im Normalfall immer am Ende des RAM Bereichs. Wenn du dich verschätzt hast, wächst er aus diesem Bereich heraus (Stack Overflow). Da Du diesen gesamten übrigen freien RAM FreeRTOS zur Verfügung stellen willst, wächst er somit dort hinein. Wie sehr deine Interrupte verschachteln können, hängt davon ab, wieviele Prioritätsgruppen du hast. Und dann noch die Exceptions. Die Cortex-M CPUs sichern automatisch alle Register bei einem Interrupt.
Michael S. schrieb: > doch, das hatte ich tatsächlich richtig verstnden. Da habe ich meine Zweifel... > Ich will nur bereits > beim linken sicher sein, dass mir der Stack hinterher ausreicht, also > will ich einen Speicher reservieren, der sicher groß genug ist, also > dass der Stack zur Laufzeit sicher nie größer wird, als der Stack, der > beim linken angegeben wird. Genau das geht nämlich nicht. Es ist ausgeschlossen durch eine Angabe im Linkerscript sicherzustellen, dass der Stack zur Laufzeit nicht größer wird als zur Compiletime angegeben. Der Stack schert sich nicht um die Grenzen des Linkerscripts. Er wächst einfach (ohne Ankündigung oder Nachfrage !!!) darüber hinaus. Michael S. schrieb: >> FreeRTOS reserviert für die Tasks nur dann Speicher, wenn man den Task >> mit xTaskCreateStatic erstellt, ansonsten nimmt sich FreeRTOS für den >> Task-Stack RAM aus dem Heap. > aber aus dem eigenen Heap, der wie gesagt im .bss Bereich liegt Ja, wenn du das so konfiguriert hast, dann ist das so. Michael S. schrieb: >> Wie oben schon >> gesagt musst du dir aber nicht direkt Gedanken machen ob dein >> Exception-Stack jetzt 128 Byte oder doch eher 256 Byte haben wird. > Naja, wenn globaler heap (0Byte) + globaler stack zusammen nur 128Byte > zugewiesen bekommen, weil der FreeRTOS Stack im .bss Bereich maximal > groß gemacht wird, dann kann der Stack auch nirgends mehr raus wachsen. > Oder mache ich etwas grob falsch? Nein, für den Fall hast du recht und es kommt bei einem Stack-Overflow direkt zum Überschreiben von relevanten Daten in .data oder was auch immer unterhalb des Stacks liegt.
>> Naja, wenn globaler heap (0Byte) + globaler stack zusammen nur 128Byte >> zugewiesen bekommen, weil der FreeRTOS Stack im .bss Bereich maximal >> groß gemacht wird, dann kann der Stack auch nirgends mehr raus wachsen. >> Oder mache ich etwas grob falsch? > > Nein, für den Fall hast du recht und es kommt bei einem Stack-Overflow > direkt zum Überschreiben von relevanten Daten in .data oder was auch > immer unterhalb des Stacks liegt. und genau deshalb will ich den Stack im Linker Script auf jedenfall groß genug für den worst case haben, damit ich den freeRTOS Heap maximieren kann. Ich verwende einen Stm32L0 mit einem M0+ core, da habe ich nur drei interrupt prio level. d.h. es müssen nur drei Interrupts gleichzeitig in den Stack passen. 3*8*4 = 96Bytes für die gesicherten Register plus das was ich in der ISR brauche (max 3*5*32bit = 60Bytes), damit reichen mir also 200Byte Stack locker aus. Gut, dann lege ich meine minimum stack size auf 200Byte und mach dann den FreeRtos Heap im .bss so groß wie möglich bis der Linker meckert. Danke für die Infos =)
Michael S. schrieb: > und genau deshalb will ich den Stack im Linker Script auf jedenfall groß > genug für den worst case haben, Wie willst Du denn den worst case ermitteln? Es reicht doch schon der (versehentliche) rekursive Aufruf einer Funktion, bei der die Abbruchbedingung falsch formuliert ist, um Deinen "worst case" ad absurdum zu führen.
"Irgendeinen" Wert muss er nunmal ansetzen. Und er setzt hier den worst case im Gutfall an. Was auch sonst. Ob der Wert in seinem Fall knapp oder reichlich ist möchte ich hier garnicht bewerten. Frank M. schrieb: > (versehentliche) rekursive Aufruf einer Funktion, In dem Falle kann er angeben was er will. Alles führt zu einem Problem. Du machst zwar auf ein Problem aufmerksam. Der TO steht jetzt aber weiterhin vor dem Problem, wieviel Speicher er nun seinem RTOS gönnen darf.
Frank M. schrieb: > Es reicht doch schon der > (versehentliche) rekursive Aufruf einer Funktion, bei der die > Abbruchbedingung falsch formuliert ist, um Deinen "worst case" ad > absurdum zu führen. Deswegen sagt MISRA "keine Rekursion". Das wiederum bedeutet, wenn man doch Rekursion verwendet, dann muß man eine entsprechende Analyse vorlegen mit Stackverbrauch pro Ebene und Nachweis der maximalen Tiefe. Das ist Aufwand, aber kein Hexenwerk.
Frank M. schrieb: > Michael S. schrieb: >> und genau deshalb will ich den Stack im Linker Script auf jedenfall groß >> genug für den worst case haben, > > Wie willst Du denn den worst case ermitteln? Es reicht doch schon der > (versehentliche) rekursive Aufruf einer Funktion, bei der die > Abbruchbedingung falsch formuliert ist, um Deinen "worst case" ad > absurdum zu führen. na das hab ich doch geschrieben. > Ich verwende einen Stm32L0 mit einem M0+ core, da habe ich nur drei > interrupt prio level. d.h. es müssen nur drei Interrupts gleichzeitig in > den Stack passen. 3*8*4 = 96Bytes für die gesicherten Register plus das > was ich in der ISR brauche (max 3*5*32bit = 60Bytes), damit reichen mir > also 200Byte Stack locker aus. dass ich in den ISRs keine rekursion verwende ist ja wohl sonnenklar. Wenn ich "versehentlich" einen Bug einbaue, ist natürlich einer drin, aber dagegen hilft ein großer Stack nur für Bugs auch nicht weiter.
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.