-
Guten Morgen PCMan,
wie Besserwessi im letzten Satz schreibt, solltest du die mal deinen Speicher etwas genauer ansehen.
Deine Aussage: vorher ging das immer alles, deutet da doch auf ein hineinlaufen des Stackpointers in den Heap hin.
Da gibts einen recht brauchbaren Tipp hier im rn wissen
// __heap_start is declared in the linker script
extern unsigned char __heap_start;
...
uint16_t momentan_frei = SP - (uint16_t) &__heap_start;
Hatte auch mal einen ähnlichen Fall, in dem an völlig unerklärlichen Stellen das Programm ausgestiegen ist. Geholfen hat dann am Ende, dass ich nun die ganzen Menüstrings und Errorcodes aus dem Flash hole und nicht mehr im Programm abgespeichert habe.
sast
-
Hi Besserwessi und sast,
danke für eure Beteiligung. Gut ich gebe zu, Aussagen wie "es ging ja schonmal" sind in der Technik wohl fehl am Platze. Ich habe das Programm über Nacht wieder laufen lassen und diesmal hat sich der µC nach 1100min resettet.
Aber zunächst zu den vielen Denkanstößen:
1) Ich habe die Motoren abgesteckt, es gibt also keine Aktivität diesbezüglich. Das Programm bleibt trotzdem "hängen". Ich habe einen Taster am INT2, der dann eine Aktion hervorrufen sollte (legt den contrast pin des Displays auf High). Das passiert aber nicht, also wird auf dieses Interrupt garnicht reagiert.
2) Die ISRs sind soweit abgespeckt, so dass bstenfalls mal eine if abfrage drin ist und ein Flag gesetzt wird. Absolut unkritisch. Es sind auch keine sei() oder cli() oder sonstwas drin (soweit ich das verstanden habe, kann man auf diese Weise ja einen Stack Overflow sogar provozieren)
3) das mit dem Buchstaben schicken habe ich schon probiert. Das Programm befand sich immer in main(), wenn es "abstürzte". Da ich aber inzwischen ein Update durchgeführt habe, sollte ich das nochmal machen.
4) Es gibt bei mir ein paar Dinge in den UART Routinen die malloc verwenden. Dort habe ich Speicherlecks aber schon ausgeschlossen. Ich könnte den Parser aber einfach mal abschalten und gucken, ob es daran liegt. Der Parser wird aber eigentlich erst dann aktiviert, wenn das zeichen 13 empfangen wurde. Hm, könnte sein, dass mir ein Störsignal das induziert, aber dazu brauchts ja auch gleich mal 12V Spannungshub, da glaube ich irgendwie nicht so dran.
5) Alle Strings liegen im Flash und bleiben durch die PROGMEM Direktive auch dort. Also dass der Ram überläuft glaube ich auch eher weniger.
Ich würde gerne den Stack-Pointer überwachen. Wenn ein Stack-Overfloe eintritt, dann sollte der Pointer doch eine bestimmte maximumgrenze überschreiten, oder? Ist das __heap_start? Wenn diese Grenze erreicht wird (oder sagen wir mal 1-Grenze), dann möchte ich eine LED togglen, um zumindest mal das auszuschließen.
Viele Grüße und schönen dank nochmals,
Simon
-
Zu heap und stackpointer lies dir mal
https://www.roboternetz.de/wissen/in...en_mit_avr-gcc
durch
Da ist auch noch eine Routine zur Anzeige des maximalen Verbrauchs mit dabei. Ist ja auch gut zu wissen, dass es daran nicht liegt wenn du sowieso schon alles im Flash hast. Aber vielleicht rufst du ja irgend eine Funktion oder ISR rekursiv auf.
sast
-
Update: ich überwache jetzt seit 8 Stunden den Stackpounter (lasse mir ihn über UART alle Sekunde zusenden). Dabei hat er asich bis jetzt nicht verändert: 2141
Blöde Frage: Wenn ich SP direkt umwandle und schicke, da bekomme ich doch den Inhalt des SP, und nicht die Adresse vom Stackpointer oder? (das wäre dabnn wahrscheinlich &SP).
Simon
-
zur Info aus der common.h
Code:
/*
Stack pointer register.
AVR architecture 1 has no RAM, thus no stack pointer.
All other architectures do have a stack pointer. Some devices have only
less than 256 bytes of possible RAM locations (128 Bytes of SRAM
and no option for external RAM), thus SPH is officially "reserved"
for them.
*/
#if __AVR_ARCH__ >= 100
# ifndef SPL
# define SPL _SFR_MEM8(0x3D)
# endif
# ifndef SPH
# define SPH _SFR_MEM8(0x3E)
# endif
# ifndef SP
# define SP _SFR_MEM16(0x3D)
# endif
#elif __AVR_ARCH__ != 1
# ifndef SPL
# define SPL _SFR_IO8(0x3D)
# endif
# if XRAMEND < 0x100 && !defined(__COMPILING_AVR_LIBC__)
# ifndef SP
# define SP _SFR_IO8(0x3D)
# endif
# else
# ifndef SP
# define SP _SFR_IO16(0x3D)
# endif
# ifndef SPH
# define SPH _SFR_IO8(0x3E)
# endif
# endif /* XRAMEND < 0x100 && !defined(__COMPILING_AVR_LIBC__) */
#endif /* __AVR_ARCH__ != 1 */
Code:
/* Stack Pointer (combined) Register */
#if defined(SP)
# define AVR_STACK_POINTER_REG SP
# if __AVR_ARCH__ >= 100
# define AVR_STACK_POINTER_ADDR _SFR_MEM_ADDR(SP)
# else
# define AVR_STACK_POINTER_ADDR _SFR_IO_ADDR(SP)
# endif
#endif
Hast du mal die nicht verwendete Speichergröße ermittelt? Wenn du immer das Selbe machst, steht der Stackpointer auch immer an der selben Stelle bei der Abfrage.
sast
-
hi sast.
Ja hast recht, das muss ich jetzt als nächstes mal machen.
Grüßle Simon
-
Hi,
abschließend wollte ich mitteilen, dass jetzt alles stabil läuft. Offensichtlich handelte es sich doch um eine Art DeadLock, da in einer ISR eine LCD-Schreibroutine aufgerufen wird, die aber im Innern auf ein "Pin-Low" wartet. Nachdem ich das alles aus den ISRs rausgemodelt hatte und nur noch Flags gesetzt hatte, gings dann. Man sollte sich wenn, dann richtig an die ratschläge der Profis handeln ;)
Vielen Dank,
Simon