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
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...
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?
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...
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!
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
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?
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
charc;
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.
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
intmain()
2
{
3
inti[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(constchar*str)
2
{
3
char*pCopy=malloc(strlen(str));
4
strcpy(pCopy,str);
5
returnpCopy;
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.
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...
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.
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
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
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
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.
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.
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.
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. :-)
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
>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.
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.
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.
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!
> 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.
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".
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?
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.
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
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.
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
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).
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
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.
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
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.
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.
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..
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.