hallo
mein Programm läuft auf einem ATtiny und hat noch einen kleinen Fehler -
also hab ich das AVR Studio installiert und wollt das Ganze mal
debuggen. Im Watch -Window krieg ich dann auch gleich die erste
Fehlermeldung. Das seltsame ist nur sie kommt schon kurz nach
Programmstart bei der Variablendeklaration;
int main(void)
{
int i;
unsigned int c;
char buffer[65];
char Datensatz[7];
i = 0;
....
Wenn der Debugpfeil über diese Zeilen gesprungen ist, steht im
Watch-Window:
c Location not valid
buffer Location not valid
i 0
Datensatz [...]
Damit gibts für den weiteren Programmablauf wohl nur noch die Variablen
Nr. 3 und 4. Gibts dafür ne einleuchtende Erklärung?
danke
Martin
Ohne mich auszukennen würde ich vermuten, dass "Location not valid" nur
heißt, dass die Variable noch nicht initialisiert ist.
Oder sie wurde vom Compiler wegoptimiert. Soweit ich weiß darf er das.
Schalt halt zum Debuggen mal die Optimierung aus.
Sebastian
Das sind Variablen, die nur in Registern existieren, nicht im RAM.
Entweder du schaust in den Assembler-Code, um zu sehen, in welchem
Register die Variable steckt, dann kannst du einfach das Register im
Auge behalten, oder du schaltest die Optimierungen aus, dann stehen sie
im RAM und du kannst sie "normal" beobachten.
Ich muss mich korrigieren. Das "Watchen" funktioniert auch bei Variablen
in Registern. Offenbar werden sie wohl doch komplett wegoptimiert worden
sein.
Guten Tag
Ich weis dass dieser Beitrag etwas älter ist aber ich habe genau dass
selbe Problem.
Ich bekomme immer wieder bei einigen Variablen die Meldung "Location not
valid".
Hier ist ein Beispielcode bei dem der Fall auftritt:
Weis wer warum "uch" und "uchTmpVal" als "Location not valid" angezeigt
werden?
1
voidUnterfunktion(void)
2
{
3
unsignedcharuch;//Zählervariable
4
unsignedcharuchTmpVal=PINC;/* Zwischenspeichern damit sich die Daten während der Bearbeitung nicht ändern*/
5
6
for(uch=0x00;uch<0x08;uch++)
7
{
8
PORTB=uchTmpVal&uch;
9
...
10
// Hier wird uchTmpVal weiter bearbeitet.
11
}
12
}
13
14
voidmain(void)
15
{
16
...
17
//uC initialisieren
18
...
19
20
while(1)
21
{
22
...
23
Unterfunktion();
24
...
25
}
26
}
Ist es jetzt die einzige Möglichkeit dass überall ein volatile vor die
Variablen zu setzen damit sie mir nicht wegoptimiert werden?
Ich habe übrigens extra die neueste Version von AVR-Studio und WinAVR
installiert um sicher zu sein dass es nicht daran liegt.
Nur für en nächsten der fragt:
Bei
Project -> Configuration Options -> General
unter 'Optimization' von s auf 0 stellen oder, wenn ein externes
Makefile verwendet wird, dann diese Änderung im Makefile vornehmen.
Auch wenn der Beitrag schon uralt ist, bin ich mir sicher dass er noch
oft gelesen wird. Also: Danke für die klaren Tips !
Noch'n Tip, auch auf die Gefahr hin dass er selbstverständlich
erscheint.
Um das Programm nach Rückstellen auf -0s zu überprüfen: Um dann den Wert
einer (z.B. int) Variablen "int X" zu überprüfen, einfach im gleichen
Gültigkeitbereich 'ne volatile Variable "int vV" definieren. im
Programm "vV = X"; setzen und vV in die Watchlist übernehmen.
Natürlich kann vV mehrfach auch für das Verfolgen weiterer Variablen
wiederverwendet werden.
Funzt: Hermann
Sven P. schrieb:> Hat da der Optimierer zugeschlagen...? Wenn du die Variable nicht> verwendest, dann schmeißt der die nämlich komplett raus.
Hallo Gemeinde
Habe auch gerade so ein Problem bei der Funktion:
unsigned char NMEA_checksum(char *string)
{
char check[2];
unsigned char value = 0;
unsigned char Ergebnis;
while(*string != '*' )
{
value ^= *(string++);
}
string++;
check[0] = *(string++);
check[1] = *(string++);
Ergebnis = 0;
if (strtol(check, NULL, 16) == value) Ergebnis = 1;
return Ergebnis;
}
Hier wird "value" in WATCH als "Lacation not valid" angezeigt.
SIe wird aber offensichtlich gebrtaucht.
Kann das jemand erklären ???
Grüße
TOrsten
Sven P. schrieb:> Hat da der Optimierer zugeschlagen...? Wenn du die Variable nicht> verwendest, dann schmeißt der die nämlich komplett raus.
Für den Code trifft das zwar zu, nicht aber für die Debug-Info. (Was
allerdings nicht bedeutet, daß der eingesetzte Debugger diese
Information auch auswertet).
Wer das "volatile" umgehen will, kann das Entsorgen einer Variablen auch
dadurch verhindern, indem er sie einfach nochmal benutzt.
Kurz vor dem return am Ende der Funktion ein:
if (value == 0);
Sollte den Compiler dazu zwingen, das Teil bis zu dieser Stelle am Leben
zu erhalten. Es sei denn Du optimierst zu aggressiv.
amateur schrieb:> Wer das "volatile" umgehen will, kann das Entsorgen einer Variablen auch> dadurch verhindern, indem er sie einfach nochmal benutzt.> Kurz vor dem return am Ende der Funktion ein:> if (value == 0);> Sollte den Compiler dazu zwingen, das Teil bis zu dieser Stelle am Leben> zu erhalten. Es sei denn Du optimierst zu aggressiv.
Tut er aber.
amateur schrieb:> kann das Entsorgen einer Variablen auch> dadurch verhindern,
Abgeshen davon, daß Compiler auch in der niedrigsten Optimierungsstufe
nicht blöd sind, und leere Programmanweisungen erkennen, geht es
überhaupt nicht darum, das entsorgen zu verhindern.
Volatile sorgt dafür, daß die Variable bei jedem Lesen neu aus dem
Speicher gelesen wird, und nicht einfach der Wert, der noch vom letzten
lesen in einem Prozessorregister steht genommen wird. Den der bekommt
von einer zwischenzeitlichen Änderung des Wertes im Speicher durch eine
ISR nichts mit.
Oliver
OK Verstanden.
Aber noch einmal zurück zu den Fehlern in der Routine.
Was kann man hier besser machen ?
Immerhin macht sie was sie soll...
Karl Heinz Buchegger schrieb:> Aber du könntest allerdings auch erst mal all die anderen Fehler in der> Funktion beheben.
Torsten B. schrieb:> Danke, werde ich so machen.> Hab die Funktion im Netz geklaut.
Weißt du noch wo?
Ein Tip: klau nie wieder bei dem Typen.
Stringbehandlung ist der erste Stolperstein für jeden C-Programmierer.
Und da siehts bei ihm eher düster aus, wenn er nicht weiß, dass er für
einen String mit 2 sichtbaren Buchstaben ein Array der Länge 3 braucht
und was er mit dem 3.ten char im Array machen muss.
> Was ist dann daran alles falsch?
Du könntest zb mal sicher stellen, dass strtol sauber arbeitet, indem du
ihm einen korrekten String mit 2 Buchstaben (der in einem Array aus 3
chars angelegt werden muss, wegen dem abschliessenden \0) vorlegst.
Und den potentiellen Fehler in der Abbruchbedingung der while Schleife
würde ich auch behandeln. Schliesslich ist die Checksumme im NMEA
optional und nicht zwingend vorgeschrieben.
Torsten B. schrieb:> Na das ist doch mal ne Ansage, Danke !> Macht Sinn, wenn man drüber nachdenkt.> Noch etwas verbesserungswürdig ?
recht viel mehr ist ja nicht mehr in der Funktion :-)
Ich finde 1 schweren Fehler und eine versäumte Absicherung ohnehin genug
für diesen 5-Zeiler.