Forum: Mikrocontroller und Digitale Elektronik C Programm memory out of bounds


von Luks (Gast)


Lesenswert?

Hallo,

Ich hoffe ihr könnt mir helfen.
Ich habe ein Programm in C geschrieben (bin eher C Anfänger). Ich 
debugge den AT90CAN32 mit dem JTAG ice mkii. Das Programm hat etwas über 
2000 Zeilen ( in C).

Es ist nun so dass im Debug Modus der Debugger nach gewisser Zeit(wenn 
ich das Programm pausieren will) in Memory out of Bounds springt. Also 
in einen Bereich wo kein source code file ist.

Hatte dasselbe Problem schon in einem geschriebenen Assembler Programm.

Woran kann das liegen? Hab dasselbe Programm auch schon mal 24h laufen 
lassen. Da war keins dieser Probleme. Ich weiß nicht wo ich anfangen 
soll zu suchen, oder kann es sein dass das Programm an sich in Ordnung 
ist nur der JTAG ice mkii Debugger irgwann verrückt spielt?

Kann ich irgendwie überprüfen ob es z.B. einen Stack Overflow gibt und 
den dann zurück verfolgen?

Danke für Tipps.

LG

von Luks (Gast)


Lesenswert?

Hat keiner so etwas ähnliches schon mal gehabt?

Es passiert dann und das auch nicht immer wenn ich während des Debuggens 
auf Pause (Break all) drücke.

So kann ich nicht vernünftig debuggen...

von hp-freund (Gast)


Lesenswert?

heap trifft stack?

http://stackoverflow.com/questions/960389/how-can-i-visualise-the-memory-sram-usage-of-an-avr-program

Vielleicht hilft die freeRam Funktion aus der 2. Antwort.

von Luks (Gast)


Lesenswert?

Ich verstehe nicht wie mir das helfen könnte.

Ich dachte wenn man in C programmiert, kommt so ein Unsinn nicht 
zustande. Vorallem wenn das Programm lange durchläuft im Debug Modus 
..über 24h und da bricht es nie ab und dann irgwann wenn ich auf Pause 
drücke--> Memory out of bounds.

Wie kann so etwas überhaupt passieren? Jede Funktion die programmiert 
wird, wird ja automatisch auch ohne return; verlassen. Deswegen kann es 
kein Fehler durch Rücksprungadressen geben?
Lediglich durch zu viele Rücksprungadressen am Stack und der dann einen 
Overflow hat... aber wenn das Programm so lange durchläuft und irgwann 
nach vielen Stunden passiert das ganze kann es doch wohl nicht an einem 
Overflow im Stack liegen?

Ich weiß nicht ob das der Fehler gewesen sein könnte.. Verwende 
Interrupts habe aber nicht alle ISR programmiert, also die die nicht 
benutzt werden. Wenn jetzt fälschlicherweise aber ein Interrupt 
ausgeführt wird und keine ISR programmiert wurde was macht der Prozessor 
bzw. Compiler dann?
Habe jetzt mal zur Sicherheit alle ISR programmiert.


Wenn mir irgendwer einen Tipp geben könnte was zu so einem Fehler führt 
das der Debbugger Memory out of bounds geht, könnte ich danach suchen im 
Programmcode..
Beim Assembler währen das ja fehlende ret oder fehlende Pops. Aber wie 
kann das bei C passieren?

von Kaj (Gast)


Lesenswert?

Luks schrieb:
> Ich dachte wenn man in C programmiert, kommt so ein Unsinn nicht
> zustande.
Warum sollte das in C nicht passieren koennen?

Luks schrieb:
> Memory out of bounds.
Google doch einfach mal nach "Memory out of Bound", und was es damit auf 
sich hat...

von Luks (Gast)


Lesenswert?

Kaj schrieb:
> Google doch einfach mal nach "Memory out of Bound", und was es damit auf
> sich hat...

Ich versteh schon was Memory out of Bounds bedeutet, das Problem ist ich 
versteh nicht wie es in C dazu kommen kann!

von Peter D. (peda)


Lesenswert?

Luks schrieb:
> Ich dachte wenn man in C programmiert, kommt so ein Unsinn nicht
> zustande.

Nö, dafür ist allein der Programmierer zuständig, daß er keinen Unsinn 
hinschreibt.
C prüft nur die Syntax, mehr nicht.

Ungültige Zugriffe können mehrere Ursachen haben, z.B.:
- Stacküberlauf
- ungültige Pointer
- Zugriff außerhalb der Arraygröße oder des Variablenformats
- fehlende atomare Kapselung

von Luks (Gast)


Lesenswert?

Peter Dannegger schrieb:
> - Zugriff außerhalb der Arraygröße oder des Variablenformats

Zugriff außerhalb eines Variablenformats... : Kann das bei Berechnungen 
passieren? bzw. wie?

Kannst du mir ein Beispiel geben?

von Rolf Magnus (Gast)


Lesenswert?

Luks schrieb:
> Ich verstehe nicht wie mir das helfen könnte.
>
> Ich dachte wenn man in C programmiert, kommt so ein Unsinn nicht
> zustande.

Warum nicht? Soll C auf magische Weise dafür sorgen, daß der Speicher 
nie ausgeht?

> Wie kann so etwas überhaupt passieren? Jede Funktion die programmiert
> wird, wird ja automatisch auch ohne return; verlassen. Deswegen kann es
> kein Fehler durch Rücksprungadressen geben?

Die Rücksprungadresse steht aber auf dem Stack. Wenn der überschrieben 
wird, wird auch die Rücksprungadresse überschrieben, und er springt beim 
return halt irgendwo hin und nicht zurück zum Aufrufer.

> Lediglich durch zu viele Rücksprungadressen am Stack und der dann einen
> Overflow hat...

Nicht nur Rücksprungadressen stehen auf dem Stack, sondern auch alle 
lokalen Variablen und Parameter, bei denen der Compiler entscheidet, sie 
nicht in Register zu stecken.

> Wenn jetzt fälschlicherweise aber ein Interrupt ausgeführt wird und keine
> ISR programmiert wurde was macht der Prozessor bzw. Compiler dann?

Der Prozessor springt an die Adresse, die in der 
Interrupt-Vektor-Tabelle steht. Was da steht, ist dann Compiler- bzw. 
Startupcode-abhängig. Da du keinen Compiler nennst, kann man dir auch 
nicht sagen, was dieser tut.

Luks schrieb:
> Peter Dannegger schrieb:
>> - Zugriff außerhalb der Arraygröße oder des Variablenformats
>
> Zugriff außerhalb eines Variablenformats... : Kann das bei Berechnungen
> passieren? bzw. wie?

Es kann z.B. beim Zugriff über einen falschen Pointer passieren oder bei 
Übergabe von Variablen des falschen Typs über variable Argumentlisten.

> Kannst du mir ein Beispiel geben?
1
char c;
2
int* p = (int*)&c;
3
*p = 100;

hier ist c ein Byte groß, aber da man über einen Pointer auf int 
zugreift, werden zwei Byte statt nur eins überschrieben. Hier natürlich 
recht offensichtlich, aber das ist nicht immer so.

von Karl H. (kbuchegg)


Lesenswert?

Luks schrieb:
> Kaj schrieb:
>> Google doch einfach mal nach "Memory out of Bound", und was es damit auf
>> sich hat...
>
> Ich versteh schon was Memory out of Bounds bedeutet, das Problem ist ich
> versteh nicht wie es in C dazu kommen kann!

Nicht?

Ganz einfach
1
int main()
2
{
3
  int i[3];
4
5
  i[5] = 8;
6
}

klassischer Fall von 'Memory out of bounds Access'. Wobei derartige 
Dinge natürlich in der Praxis nicht so offensichtlich sind.

Anderes Beispiel
1
char* foo( const char* str)
2
{
3
  char* pCopy = malloc( strlen( str ) );
4
  strcpy( pCopy, str );
5
  return pCopy;
6
}

wo ist der Fehler?
Hier
1
  char* pCopy = malloc( strlen( str ) );
... es müsste
1
  char* pCopy = malloc( strlen( str ) + 1 );
heissen.

Der Effekt ist aber derselbe. Es wird Speicher beschrieben, der nicht 
zum 'Objekt' gehört. Und damit bügelt man sich dann eben irgendwas im 
Speicher nieder. Was genau, kann im Vorfeld keiner sagen.

Es gibt noch Zig andere klassische Szenarien, in denen man im Speicher 
schreibt, der einem nicht gehört. Was dann konkret passiert, kann man 
nur im Nachhinein analysieren, wenn man den Fall vorliegen hat, und 
solche Dinge sind bei realen Programmen meistens verdammt schwer im Code 
zu finden. Aber es gibt kein allgemeines Schema, so dass man sagen 
könnte dieses oder jenes wurde im Programm gemacht. Irgendwo ist der 
Speicher niedergebügelt worden und was dann passiert kann man zwar im 
nachhinein analysieren aber nicht im Vorfeld einfach angegeben. Denn das 
hängt von den dann vorliegenden, ganz konkreten Speichersituationen ab. 
Wenn du das Programm im Debugger in einem Speicherbereich 
'wiederfindest', in dem gar kein Code liegt, dann würde ich mal die 
Vermutung anstellen, dass du irgendwo den Stack zerschossen hast. Aber 
wo und wie ... auch dafür gibt es wieder unzählige mögliche Szenarien.

: Bearbeitet durch User
von Luks (Gast)


Lesenswert?

Nachdem ich Anfänger in C bin werde ich wohl irgendwo einen klassischen 
Fehler machen der für mich nicht ersichtlich, für euch wahrscheinlich 
ein Kinderspiel ist.

Würde sich den Code wer durchschauen?
Bei 2000 Zeilen weiß ich nicht wie lang so etwas dauert.
Problem ist ich kann den Code nicht einfach öffentlich posten.

Weiß sonst nicht mehr weiter...

von Karl H. (kbuchegg)


Lesenswert?

Luks schrieb:

> Bei 2000 Zeilen weiß ich nicht wie lang so etwas dauert.

lang!

Die Frage ist eigentlich: wie kommt es, dass du 2000 Zeilen geschrieben 
hast, ohne die im Zuge der Entwicklung immer wieder exzessiv zu testen, 
während sie entstehen?

> Problem ist ich kann den Code nicht einfach öffentlich posten.

Tja.

von Mike Roh (Gast)


Lesenswert?

Jetzt mal ohne das Derivat genau zu kennen: Mir ist deine Frage unklar 
und damit dein Problem.

"Es ist nun so dass im Debug Modus der Debugger nach gewisser Zeit(wenn
ich das Programm pausieren will) in Memory out of Bounds springt. Also
in einen Bereich wo kein source code file ist."

Die Definition von Memory out of Bounds kann einiges sein, aber sicher 
nicht "Wo kein Sourcefile ist".

1. Wo stehst du denn beim Stoppen(ist das noch gültiger Speicher deines 
Systems?)
2. Ist Memory out of Bounds eine Fehlermeldung die dir der Debugger so 
gibt oder hast du das erfunden?
3. Es ist grundsätzlich nicht ungewöhnlich dass du in einem C-Programm 
Programmteile ohne Sourcecode hast. Meistens bindet der Linker jede 
Menge Funktionen aus der CRT (C Runtime) Library ein. Für die hast du 
üblicherweise keinen Source und er sollte dich auch nicht interessieren. 
Wenn du weiterläufst ist dann dein System funktionstüchtig oder nicht?
4. Werden vom Debugger auch Interrupts angehalten oder laufen die 
weiter?

Gruss,
Mike

von Luks (Gast)


Lesenswert?

Sorry konnte nicht zitieren weil
Ichs am handy getippt hab.

1. beim stoppen des systems öffnet avr studio(6) das dissassembler 
fenster und der cursor zeigt auf 0000FFFE wodann steht: memory out of 
bounds. Und es werden alle register auf 0XFF gesetzt i/o register des 
prozessors usw.

2. hab ich nicht erfunden. Steht eben dann im disassembler fenster.

3. wenn ich das system weiterlaufen lasse und dann wieder auf pause 
springt er immer wieder in memory out of bounds. Ich glaube es läuft 
aber weiter. Ich muss das nochmal überprüfen kann das aber erst am 
montag machen

4. vom debugger werden keine interrupts angehalten wenn du meinst ob ich 
dort breakpoints gesetzt habe.

lG

von Luks (Gast)


Angehängte Dateien:

Lesenswert?

Mike Roh schrieb:
> 3. Es ist grundsätzlich nicht ungewöhnlich dass du in einem C-Programm
> Programmteile ohne Sourcecode hast. Meistens bindet der Linker jede
> Menge Funktionen aus der CRT (C Runtime) Library ein. Für die hast du
> üblicherweise keinen Source und er sollte dich auch nicht interessieren.
> Wenn du weiterläufst ist dann dein System funktionstüchtig oder nicht?

Das System ist dann nicht mehr funktionstüchtig. Es läuft nicht mehr 
weiter.

Im Anhang habe ich einen Screenshot gemacht was passiert wenn der 
Debugger dann hängen bleibt und wie das aussieht.
Wonach sieht das für euch aus?

Habe es heute wieder getestet das Programm, 8 Stunden lang rauf und 
runter getestet. Funktioniert alles einwandfrei Keinerlei Probleme und 
dann auf einmal bleibt es hängen.

LG

von Karl H. (kbuchegg)


Lesenswert?

Luks schrieb:

> Im Anhang habe ich einen Screenshot gemacht was passiert wenn der
> Debugger dann hängen bleibt und wie das aussieht.
> Wonach sieht das für euch aus?

... dass du eine längere Bug_such/Bug_fix/Debug Sitzung vor dir hast.

Trags wie ein Mann. Das ist nicht ungewöhnlich, dass es mal auch etwas 
länger dauert. Meine lägste 'Debug_Sitzung' dauerte 10 Jahre. Danach hab 
ich eingesehen, dass mit diesem Solid-Modelling Code kein Blumentopf zu 
gewinnen ist und hab ihn weggeworfen.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Luks schrieb:
> 4. vom debugger werden keine interrupts angehalten wenn du meinst ob ich
> dort breakpoints gesetzt habe.

Vermutlich füllt dann ein Interrupt einen Puffer, aber das Main holt ihn 
nicht ab und er läuft über in fremden RAM.

von Luks (Gast)


Lesenswert?

Karl Heinz schrieb:
> ... dass du eine längere Bug_such/Bug_fix/Debug Sitzung vor dir hast.

Problem ist ich weiß nicht wo ich anfangen soll zu suchen, da ich nicht 
weiß wo ich einen Fehler gemacht haben könnte. Für mich scheint es 
richtig zu sein.

Außerdem traue ich dem Debugger und AVR Studio nicht ganz. Hatte ein 
Assembler Programm in AVR Studio 4 im Debugmodus und es ist immer wieder 
IDR Event 0xFF aufgetreten und das Programm hat abgebrochen.
Nach Umstellung auf AVR Studio 5 und upgrading des JTAGs für das 5er 
Studio gab es das nicht mehr und das Programm lief einwandfrei weiter im 
Debugmode.

von Bitflüsterer (Gast)


Lesenswert?

Wenn Dein Programm sich ohne großen Aufwand in Teile zerlegen lässt die 
von einander unabhängig sind, dann würde ich das zuerst versuchen 
(Leider geht das meist nicht).

Ich würde an Deiner Stelle zweistufig vorgehen:

1. Jage den Code durch einen Lint. (Suche mal hier im Forum). Der prüft 
Dir den Code auf alle Fehler, die zu finden sind, ohne das der Code 
läuft. Darunter auch einen Teil der Fehler die auf 
Speicherfehlbehandlungen zurückzuführen sind. Damit deckst Du schon mal 
eine Reihe von "Ach-bin-ich-blöd"-Fehlern ab. Tröste Dich. Die passieren 
immer wieder mal.

2. Den Test der Funktionen nachholen. (Bei grösseren Programmen ohnehin 
sinnvoll). Du musst jede Funktion einzeln testen.

Als Anfänger fällt es Dir vermutlich schwer da überhaupt einen Anfang zu 
finden und ein Ende abzusehen. Dazu gibt es verschiedene systematische 
Vorgehensweisen, mit jeweils eigener Charakterstik. Suche dazu mal im 
Internet; das ist ein Thema für sich. Leider ist das Thema auch nicht 
gerade übersichtlich, falls Du ein paar einführende Worte gebrauchen 
kannst, frage hier im Forum.

Im wesentlichen geht es darum, jeden möglichen Verlauf durch die 
Funktionen mindestens einmal abzudecken und zumindest alle - jetzt wird 
es ein wenig schwammig, aber es gibt dazu detaillierte Erklärungen - 
wesentlichen Daten, das sind insbesondere Minima und Maxima aber auch 
andere Werte durch die Funktionen zu schicken.
Wesentlich ist immer auch, das man sich vor dem Test festlegt, was das 
Ergebnis sein soll. Nicht erst hinterher so vor sich hinmurmelt: Wird 
schon passen. :-)

von Luks (Gast)


Angehängte Dateien:

Lesenswert?

Hier ist ein Auszug von den Funktionen vom programmierten TWI. Wenn ein 
Fehler im Programm ist dann möglicherweise dort. Ich kann aber leider 
keinen Fehler erkennen.

Vielleicht könnte es sich wer anschauen ob ich da irgendwo einen 
Schnitzer drinnen habe.
Das Programm ist bis jetzt immer nur abgebrochen wenn sich ein Wert im 
Register DataByte1_receive_twi oder Databyte2_receive_twi verändert hat, 
aber auch nicht immer.

LG

von Bitflüsterer (Gast)


Lesenswert?

>Hier ist ein Auszug von den Funktionen vom programmierten TWI. Wenn ein
>Fehler im Programm ist dann möglicherweise dort.

... oder möglicherweise auch nicht. Das hat so keinen Sinn. Solange man 
keinen konkreten Anhaltspunkt dafür hat, dass der Fehler dort liegt, ist 
das reine Zeitverschwendung - ein Lottospiel.

Wie stellst Du Dir das vor? Das wir hier ein Stück von Deinem Code nach 
dem anderen anschauen (ok Karl Heinz guckt sich vielleicht Deinen 
Schnipsel an) und dann ist es doch nicht da, und dann das nächste Stück 
und so weiter, bis sich herausstellt, dass der Fehler nicht durch 
statische Analyse zu finden ist sondern durch ein Zusammenspiel von 
Umständen entsteht? ;-)

Wesentlich wichtiger ist, das Du 1. Eine Spezifikation hast und 2. 
Testfälle hast. Alles andere ist würfeln.

von Bitflüsterer (Gast)


Lesenswert?

Falls Du "instinktiv" vermutest, dass der Fehler dort liegt, dann 
isolieren den TWI-Teil in einem eigenen Programm, bastle ein Loop-Back 
oder eine passende Gegenstelle (die natürlich schon gesichert 
funktionieren sollte) und teste den Teil für sich.
Aber erst vermuten, dann suchen und dann testen, empfehle ich nicht.

von Karl H. (kbuchegg)


Lesenswert?

Luks schrieb:

> Vielleicht könnte es sich wer anschauen ob ich da irgendwo einen
> Schnitzer drinnen habe.

Ist ganz einfach.

Da werden nirgends kritische Operationen gemacht. Es gibt keine Arrays, 
es gibt keine Pointer. Damit kannst du dir den Stack nicht zerschossen 
haben.

Selbst wenn diese Funktionen tatsächlich nicht korrekt funktionieren, 
Ursache für einen derartigen Programmcrash sind sie nicht. Zumindest 
nicht direkt. Was indirekt passieren könnte, kann man nicht sagen, weil 
man ja nicht weiß, was die restlichen Programmteile tun, wenn 
tatsächlich über das TWI falsche Werte reinkommen. Wenn im Programm an 
anderer Stelle steht, dass die Herz-Lungen Maschine abgeschaltet werden 
soll, wenn ein bestimmter Messwert kleiner als 512 ist UND die TWI 
Routinen für keinen vernünftigen Wert in Falle eines Übertragunsfehlers 
sorgen, dann sind zwar die TWI Routinen erst mal nicht die unmittelbar 
schuldigen, so ganz unbeteiligt sind sie aber trotzdem nicht.



PS
so was
1
  for(tmp= 0;tmp<5000;tmp++){
2
    if((PIND & (1<<PD0)) == 1){
3
      if((PIND & (1<<PD1)) == 1){
4
        break;}
5
    }}
ist fehlerhaft. Die Abfrage von PD1 wird niemals 1 ergeben.
Bitte gewöhn dir die C Gepflogenheiten an. Teste NICHT explizit auf 0 
oder 1, wenn es nicht sein MUSS. Hier muss es nicht sein. Du maskierst 
die vom PIND ein einzelnes Bit aus (indem alle anderen Bits auf 0 
gesetzt werden) und das Ergebnis davon wird einfach nur getestet, ob es 
0 oder nicht 0 ist.


Test auf 'nicht 0'
1
  if( PIND & ( 1 << PD1 ) )
2
    ...


Test auf 0
1
  if( !( PIND & ( 1 << PD1 ) )
2
    ...

Das nutzt aus, dass in C alles was nicht 0 ist automatisch den 
Wahrheitswert TRUE hat. Mehr braucht es dazu nicht. Ob bei
1
    PIND & ( 1 << PD3 )
die Werte 0 oder 8 rauskommen können, weil das Bit 3 entweder auf 0 oder 
auf 1 ist, ist recht uninteressant. 8 ist nicht 0 und gilt damit genauso 
als logisch wahr, wie es 1, 2 oder 4 tun würde, je nachdem welche 
anderen Bitpositionen du untersuchst. Was wir aber sicher wissen: Wenn 
PD3 auf 0 steht, dann kommt in diesem Ausdruck mit Sicherheit 0 heraus. 
Und mehr interssiert uns nicht. Wir wollen nur wissen: ist der Ausdruck 
in Summe 0 oder ist er nicht 0. Wenn 'nicht 0', dann ergibt sich da 
irgendein wert. Welcher genau, ist uninteressant. Das er nicht 0 ist, 
ist schon Information genug.


In C ist oft weniger tatsächlich mehr. Mit solche explizit geforderten 
Vergleichen schiesst man sich ganz schnell schon mal ins Knie. Denn 
korrekt müsste der Vergleich so aussehen
1
   if( ( PIND & ( 1 << PD1 ) ) == ( 1 << PD1 ) )
2
     ....

das ist aber wesentlcih langatmiger als die kürzere Form
1
   if( PIND & ( 1 << PD1 ) )
2
     ...
und hat auch mehr Fehlerpotential, weil der Begriff PD1 links und rechts 
vom == übereinstimmen muss, damit die ganze Sache korrekt wird. In der 
Langform hast du dir also ein Fehler-Türchen offen gelassen, das nur 
davon abhängt, ob du sorgfältig arbeitest (und wie man gesehen hat: du 
tust es nicht). In der Kurzform existiert dieses Fehlertürchen von vorne 
herein gleich gar nicht. Zumindest diesen Fehler kannst du daher PER 
DEFINITION an dieser Stelle gar nicht machen.

: Bearbeitet durch User
von Rudolph (Gast)


Lesenswert?

Luks schrieb:
> Nach Umstellung auf AVR Studio 5

Mal auf Atmel Studio 6 updaten?
6.1 und dann die aktuelle Toolchain dazu.

von Luks (Gast)


Lesenswert?

Karl Heinz schrieb:
> Da werden nirgends kritische Operationen gemacht. Es gibt keine Arrays,
> es gibt keine Pointer. Damit kannst du dir den Stack nicht zerschossen
> haben.

Das ganze Programm ist so einfach.. also auch der Rest. Bis auf eine 
String Ausgabe am LCD die einen Pointer verwendet. Sonst verwende ich 
keine Pointer und keine Arrays... im ganzen Programm nicht. Also kann es 
nicht der Stack sein..dann ist die Frage was noch dazu führen kann.
Dass das JTAG oder AVR Studio Blödsinn macht kann nicht sein?

Wie gesagt, hatte so was schon mal dass das Studio und jtag ICE mkii 
schuld war.


Karl Heinz schrieb:
> PS
> so was  for(tmp= 0;tmp<5000;tmp++){
>     if((PIND & (1<<PD0)) == 1){
>       if((PIND & (1<<PD1)) == 1){
>         break;}
>     }}
> ist fehlerhaft. Die Abfrage von PD1 wird niemals 1 ergeben.

Stimmt das ist Unsinn.

Karl Heinz schrieb:
> Test auf 'nicht 0'  if( PIND & ( 1 << PD1 ) )
>     ...

Ja das ist viel einfacher.
Danke!

von Luks (Gast)


Lesenswert?

Rudolph schrieb:
> Mal auf Atmel Studio 6 updaten?

Mit der Version arbeite ich ja zurzeit

von Karl H. (kbuchegg)


Lesenswert?

> Bis auf eine String Ausgabe am LCD

Zum Beispiel wird ja in den meisten typischen Programmen dieser String 
irgendwo zusammengebaut. Zum Beispiel weil eine Zahl auszugeben ist.

Sag niemals nie.
Es gibt immer irgendeinen Grund. Die Kunst besteht darin, ihn zu finden. 
Und ja, hinterher ist alles ganz einfach und es ist sonnenklar, was da 
das Problem war.

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Luks schrieb:

> Ich dachte wenn man in C programmiert, kommt so ein Unsinn nicht
> zustande.

Natürlich kann das auch in C passieren. C ist nur ein aufgebrezelter 
Makroassembler und läßt einem auch alle Freiheiten, die man mit einem 
Makroassembler hat, insbesondere die Freiheit, jegliche Speichergrenzen 
zu überschreiten.

> Wie kann so etwas überhaupt passieren? Jede Funktion die programmiert
> wird, wird ja automatisch auch ohne return; verlassen. Deswegen kann es
> kein Fehler durch Rücksprungadressen geben?

Natürlich kann es das. Die Rücksprungadressen liegen auf demselben 
Stack, auf dem auch die lokalen Variablen liegen. Schreibst du bei einer 
lokalen Variablen über ihr Ende hinaus: futsch ist die korrekte 
Rücksprungadresse und der Rücksprung landet irgendwo im Wald.

> Lediglich durch zu viele Rücksprungadressen am Stack und der dann einen
> Overflow hat... aber wenn das Programm so lange durchläuft und irgwann
> nach vielen Stunden passiert das ganze kann es doch wohl nicht an einem
> Overflow im Stack liegen?

Ach du heilige Einfalt. Es hängt doch fast immer von der 
Programmsituation ab, welche Funktionen aufgerufen werden. Wenn eine 
Situation nur einmal in zwei Jahren auftritt, dann wird das Programm 
nach den Gesetzen der Statistik im Schnitt ein Jahr lang laufen, ohne 
das es abstürzt. Es ist aber trotzdem fehlerhaft.

> benutzt werden. Wenn jetzt fälschlicherweise aber ein Interrupt
> ausgeführt wird und keine ISR programmiert wurde was macht der Prozessor
> bzw. Compiler dann?

Der Prozessor macht das, was er soll: den entsprechenden Interruptvektor 
anspringen. Was der Compiler dort hingeschrieben hat, hängt davon ab, 
was du dem Compiler gesagt hast, was er tun soll. Wenn du ihm nix 
spezielles gesagt hast, wird er sein Standardverhalten zeigen. Was genau 
das ist, steht in der Doku des Compilers.

> Wenn mir irgendwer einen Tipp geben könnte was zu so einem Fehler führt
> das der Debbugger Memory out of bounds geht, könnte ich danach suchen im
> Programmcode..
> Beim Assembler währen das ja fehlende ret oder fehlende Pops

...und hunderttausend andere Möglichkeiten, sich in's Knie zu schießen. 
Es sind aber effektiv wirklich nur unwesentlich mehr als in C...

Naja, die häufigsten Fehler dürften der allseits beliebte "off by one" 
beim Manipulieren an Strings oder Arrays sein. Aber auch Rechenfehler 
bei Pointer-Arithmetik werden immer wieder gern gemacht. Und, last but 
not least, der Evergreen "integer overflow".

von CC (Gast)


Lesenswert?

Was erhoffst du dir von
1
TWSR = (0<<TWPS1)|(0<<TWPS0);
?
<< a ist das gleiche wie mal 2 hoch a.
Da steht also
1
TWSR = 0 | 0;
bzw.
1
TWSR = 0;

von Robert (Gast)


Lesenswert?

Ich hatte solche Probleme mit einem MCU von microchip. Dort waren es 
resets (watchdog) die den Programmcounter auf Werte außerhalbs des 
Programmspeichers setzten. Kannst du Resets ausschließen?

von Luks (Gast)


Lesenswert?

Ich habe das Programm jetzt soweit minimiert, dass nur Schütze im 2 
Sekunden Rhythmus ein- und ausgeschaltet werden. Das Programm springt in 
unter 2 min. in den oben beschriebenen Zustand. Nach Memory out of 
bounds or read error.

Kann das an meiner Reset Beschaltung liegen? Habe einen 10k Widerstand 
nach +5V und einen 47nF Kondensator gegen Masse an der Reset Leitung.

Habe mal testweise die BROWN OUT Detection eingeschaltet bei 4V. Die 
reagiert aber nicht. Es gibt also keinen Reset im Programm bevor es 
wieder nach Memory out of bounds read error springt. Das heißt ja wohl 
dass die Spannung für die Brown out zeit nicht unter 4V liegt am 
Mikrocontroller.
Sonst müsste ich ja einen Reset haben bei schalten der Schütze und den 
auch mitbekommen.

von Mark B. (markbrandis)


Lesenswert?

Ich würde rein zur Sicherheit mal den Watchdog komplett abschalten. 
Kann natürlich an was völlig anderem liegen - aber schaden tut's auch 
nicht, wenn man eine potenzielle Fehlerquelle sicher ausschließen kann.

Siehe Kapitel 7.3 hier:
http://www.atmel.com/Images/doc7679.pdf

: Bearbeitet durch User
von Luks (Gast)


Lesenswert?

Mark Brandis schrieb:
> Ich würde rein zur Sicherheit mal den Watchdog komplett abschalten.

Watchdog Timer ist in den Fuses nicht programmiert somit auch 
deaktiviert.

von Luks (Gast)


Angehängte Dateien:

Lesenswert?

Im Anhang ein Bild von den FUses.
So sind sie programmiert..

von TTL (Gast)


Lesenswert?

Dann lass das Schalten der Schütze mal weg, das ist sicher ein EMV 
Problem.

oder besorg dir einen Debugger mit galvanischer Trennung, das hilft 
manchmal

von Luks (Gast)


Lesenswert?

TTL schrieb:
> oder besorg dir einen Debugger mit galvanischer Trennung, das hilft
> manchmal

Hab ich vergessen zu schreibe. Zur Versorgung meiner Schaltung verwende 
ich einen galvanisch getrennten DC/DC Wandler (wo ja auch das JTAG 
versorgt wird).

von spess53 (Gast)


Lesenswert?

Hi

>Hab ich vergessen zu schreibe. Zur Versorgung meiner Schaltung verwende
>ich einen galvanisch getrennten DC/DC Wandler (wo ja auch das JTAG
>versorgt wird).

Das JTAGICE mkII wird nicht aus der Schaltung versorgt.

MfG Spess

von Luks (Gast)


Lesenswert?

spess53 schrieb:
> Das JTAGICE mkII wird nicht aus der Schaltung versorgt.
>
> MfG Spess


Naja er wird zwar nicht davon versorgt, benötigt aber wohl die 
Versorgungsspannung des µC.

von spess53 (Gast)


Lesenswert?

Hi

>Naja er wird zwar nicht davon versorgt, benötigt aber wohl die
>Versorgungsspannung des µC.

Ja. Damit werden die Pegelwandler des JTAG ICE auf die richtige Spannung 
gestellt.

VTref 4 Target voltage reference. The JTAGICE mkII samples the target 
voltage on this pin in order to power the level converters correctly

Versorgt wird er über den USB-Anschluss.

MfG Spess

von TTL (Gast)


Lesenswert?

Das hat mit der Versorgungsspannung nur bedingt zu tun. Das ist einfach 
eine gestörte Datenübertragung.
Wir habe hier schon bei mehren Projekten Probleme damit gehabt, bei 
Renesas ATmelAVR und STM Cortex.  Sowohl Keil für den ULinkPro als auch 
Segger und Renesas bieten dafür sogar spezielle Hardware an. ST hat 
dafür neuerdings auch ein STLink/ISO.

Das war bisher immer reproduzierbar. Sorg mal dafür dass das Schütz 
nicht schalten kann.

von TriHexagon (Gast)


Lesenswert?

CC schrieb:
> Was erhoffst du dir vonTWSR = (0<<TWPS1)|(0<<TWPS0);

Oje, simpleste Bitmanipulation nicht beherrschen und schon ein Programm 
mit 2000LOC schreiben, damit war ein schwerwiegendes Problem 
vorprogrammiert. Also das nächste mal klein Anfangen und größere 
Programme Stück für Stück schreiben und testen. Ich weiß das hilft dir 
jetzt im Moment nicht gerade weiter, soll aber ein nett gemeinter Rat 
sein. Glaub mir sowas hat jeder schon mal durchgemacht, jeder hat mal 
angefangen.

von Luks (Gast)


Lesenswert?

TriHexagon schrieb:
> CC schrieb:
>> Was erhoffst du dir vonTWSR = (0<<TWPS1)|(0<<TWPS0);
>
> Oje, simpleste Bitmanipulation nicht beherrschen und schon ein Programm
> mit 2000LOC schreiben, damit war ein schwerwiegendes Problem
> vorprogrammiert. Also das nächste mal klein Anfangen und größere
> Programme Stück für Stück schreiben und testen.


Ich erhoffe mir davon gar nichts. Wollte es aber so hinschreiben, dass 
man gleich erkennt dass der Prescaler auf 0 gesetzt ist. Ja muss nicht 
sein. Ich habe es absichtlich so gemacht.

Ich hab auch kleiner angefangen und Stück für Stück getestet.
Wie auch immer es liegt jetzt nicht am Programm sondern an der 
Hardware..

von Luks (Gast)


Lesenswert?

TTL schrieb:
> Das war bisher immer reproduzierbar. Sorg mal dafür dass das Schütz
> nicht schalten kann.

Wenn das Schütz nicht schaltet ist das Problem weg.

Hab jetzt die Versorgungsspanung an der Platine mit dem Oszilloskop 
gemessen beim Schalten der Schütze. Es treten da Störungen im Bereich 
von über 1 V auf (bei einer Versorgungsspannung von 5V) für ca. 1µs lang 
genau in dem Moment des Schalten der Schütze. Ich weiß nicht ob ich da 
mit dem Oszi misst messe.

Aber habe am Eingang der Versorgungsspannung schon eine common mode 
choke und Kondensatoren. Und dann noch einen potentialgetrennten DC/DC 
Wandler.

Trotz all dessen geht so eine hohe Störung durch. Auch wenn sie nur kurz 
ist. Den Debugger stört das wohl.

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
Noch kein Account? Hier anmelden.