Forum: Mikrocontroller und Digitale Elektronik Unknown identifier bei Funktionsaufruf


von Peter (Gast)


Lesenswert?

Hallo,
ich habe lange gezögert den Beitrag hier reinzustellen weil er eigl 
primitiv ist aber iwie finde ich keine lösung.

beim funktionsaufruf will ich die varible x überwachen (AVR studio --> 
watch)...
dabei bekomme ich immer wieder die meldung "Unknown identifier x 
error"....
aber x habe ich doch deklariert???? würde mich über hilfe freuen. 
vielleicht sollte ich noch erwähnen das es sich hierbei um die usart - 
schnittstelle handelt

/* die Funktion der verzweiflung...*/
void putch(unsigned char x) // warten und Zeichen senden
{

   while( ! (UCSRA & (1 << UDRE))); // warte solange Sender besetzt
  UDR = x; // Zeichen nach Sender
}

/* der mainpart*/
int main(void)
{
  DDRA = 0xff;
  DDRD=0b00000010;
  PORTD = 0x00;
  PORTD=0x00;

  initusart();        // USART init
  sbi(UCSRB, RXCIE);  // Empfängerinterrupt frei
  sei();              // Interrupts global enable

  while(1)
  {
    putch('>'); //hex 62
  }
  return 0;
}

von Achim M. (minifloat)


Lesenswert?

Gibts ne Headerdatei zu dem .c-Schnipsel? steht da vllt. was anderes als 
x drin?
mfg mf

von STK500-Besitzer (Gast)


Lesenswert?

Bastel dir in die "putch(...)" noch eine Hilfsvariable, der du den Wert 
von x zuweist, bevor du die While-Schleife beginnt.
Das könnte was bringen.

von Tom M. (tomm) Benutzerseite


Lesenswert?

Peter schrieb:
> dabei bekomme ich immer wieder die meldung "Unknown identifier x
> error"....
> aber x habe ich doch deklariert????

Jein, sie existiert nur "temporär", falls/wenn die putch() Funktion 
aufgerufen wird. Dann wird das Argument nämlich auf dem Stack platziert 
und über den Namen "x" referenziert. Ansonsten ist "x" nicht existent. 
Ist das ev. das Problem für den Debugger?

von Peter (Gast)


Angehängte Dateien:

Lesenswert?

hier der komplette code inklusive der header - datei
(könnte etwas übersichtlicher sein... ich weis...)

von Karl H. (kbuchegg)


Lesenswert?

Der springende Punkt liegt hier

> beim funktionsaufruf will ich die varible x überwachen
> (AVR studio -->watch)...
> dabei bekomme ich immer wieder die meldung "Unknown identifier x
> error"....

Du redest vom Debugger.

x existiert nur, solange sich die Programmausführung innerhalb der 
Funktion putch befindet. Ausserhalb dieser Funktion gibt es kein x, 
daher kann der Debugger auch eine nicht existente Variable nicht 
überwachen.

von Peter (Gast)


Lesenswert?

wow danke für die antworten...
-ja leider sagt der debugger mir auch den fehler wenn ich mich in der 
fkt putch befinde....

-hilfsvariable bringt leider nichts

von Achim M. (minifloat)


Lesenswert?

Karl Heinz Buchegger schrieb:
> daher kann der Debugger auch eine nicht existente Variable nicht
> überwachen.

Zum Test kann man sie ja auch "static" machen.

mfg mf

von Karl H. (kbuchegg)


Lesenswert?

Peter schrieb:
> wow danke für die antworten...
> -ja leider sagt der debugger mir auch den fehler wenn ich mich in der
> fkt putch befinde....

Dann hat zusätzlich noch der Optimizer des Compilers zugeschlagen und 
die Variable wegoptimiert indem er Funktionsinlining betrieben hat. 
Sprich: Er hat den Code der Funktion direkt an der Aufrufstelle 
eingebaut und braucht daher das x nicht mehr.

von Peter (Gast)


Lesenswert?

ahh ok das könnte sein... ich habe optim-level auf 3

von fdssd (Gast)


Lesenswert?

das passiert beim AVR studio sehr oft wenn man mit optimierung debuggen 
will

manchmal kommen sehr kuriose sprünge zustande
weil man selbst zu kompliziert gedacht hat

( ging mir sehr oft so ^^  ... aber man hat was zu lernen wenn man 
durchsteppt :)  )

entweder optimierng weghauen oder :
- variable als static
- variable als volatile
- oder globale variable

von Sven P. (Gast)


Lesenswert?

fdssd schrieb:
> entweder optimierng weghauen oder :
> - variable als static
> - variable als volatile
> - oder globale variable

Oder in diesem Fall noch besser:
Assemblerlisting lesen :-)

von Noname (Gast)


Lesenswert?

Nur so zur Diskussion:

Genau genommen ist x ja keine Variable sondern ein Parameter. Soweit ich 
das verstehe wird dafür kein Speicher belegt sondern der Wert auf dem 
Stack vorgehalten (was zwar auch Speicher ist, aber im Ggs. zu 
Variablen, keine Labels hat).

Demnach halte ich es für plausibel, wenn auch nicht für wünschenswert, 
das der Debugger diesen Namen nicht kennt. Ich habe es nicht 
systematisch ausprobiert bin aber der Meinung, das nur Parameter die in 
der Funktion auch noch manipuliert werden (links vom Gleichheitszeichen 
auftreten) auch im Debugger zu sehen sind. Soweit ich weiss ist das 
unabhängig von einem evtl. Inlining.

Apropos: Hat der TO mal probiert sämtliche Optimierungen abzuschalten?
Was passiert dann?

von Noname (Gast)


Lesenswert?

Oops. Sorry für die Anrede in der dritten Person, Peter.

von Peter (Gast)


Lesenswert?

omg...
also mit optimize none funktioniert alles super, danke wäre ich nie 
darauf gekommen.
das problen ist aber das ich schon optimize auf level 3 halten möchte..
ich habe jetzt die variable als global volatile und static deklariert... 
ohne erfolg... deklariere ich die variable global behält sie diesen wert 
und verändert diesen bei fkt- aufruf nicht :(

wie kann ich dem compiler x verbergen?

von Noname (Gast)


Lesenswert?

>das problen ist aber das ich schon optimize auf level 3 halten möchte..

Das wäre schon fast einen eigenen Thread wert.
Wie Du siehst kannst Du dann schonmal nicht debuggen.
Also schalte die Optimierungen aus.

>ich habe jetzt die variable als global volatile und static deklariert...
ohne erfolg...
Wundert mich nicht. Ob volatile oder static interessiert den Optimierer 
an der Stelle garnicht denke ich.

>deklariere ich die variable global behält sie diesen wert
>und verändert diesen bei fkt- aufruf nicht

Huch? Wieso sollte sich x verändern? In der fraglichen Funktion wird ja 
x garnichts zugewiesen. Ein Missverständnis?

>wie kann ich dem compiler x verbergen?

Da fallen mir nur Scherzantworten ein. :-)

von Karl H. (kbuchegg)


Lesenswert?

mit
1
void putch(unsigned char x) __attribute__ ((noinline)) // warten und Zeichen senden
2
{
3
4
   while( ! (UCSRA & (1 << UDRE))); // warte solange Sender besetzt
5
  UDR = x; // Zeichen nach Sender
6
}

sollte es gehen.
ALlerdings ist das zweifelhaft. Da kannst du auch gleich den Optimizer 
vorübergehend ausschalten und dich davon überzeugen, dass putch so 
funktioniert wie du dir das vorstellst (was du mit dem Simulator sowieso 
nicht kannst) und danach den Optimizer gleich wieder einschalten.

Entweder du akzeptierst, dass der Optimizer den Code umbaut (ohne die 
eigentliche Funktionalität zu verändern), dann musst du damit leben, 
dass du im Debugger seltsame Dinge siehst.
Oder du akzeptierst letzters nicht und willst haben, dass im Debugger 
alles so ausgeführt wird, wie du das hingeschrieben hast, dann darfst du 
den Optimizer nicht einschalten.

von Peter (Gast)


Lesenswert?

natürlich wird x ein wert zugewiesen
mit
putch('>');....

wenn ich optimierung wegmache, stimmen wunderlicherweise meiene delays 
nicht mehr deswegen....

von Karl H. (kbuchegg)


Lesenswert?

Peter schrieb:
> natürlich wird x ein wert zugewiesen
> mit
> putch('>');....
>
> wenn ich optimierung wegmache, stimmen wunderlicherweise meiene delays
> nicht mehr deswegen....

Davon sieht man aber im Originalcode nichts.
Und meistens ist es sowieso so: _delay_ms wird überschätzt :-)
Vor allen Dingen im Debugger.

Deine Funktion putch funktioniert sowieso, da brauchst du nicht viel 
debuggen.

von Tom M. (tomm) Benutzerseite


Lesenswert?

Peter schrieb:
> natürlich wird x ein wert zugewiesen
> mit
> putch('>');....

? -- "x" aus dem Funktionsprototypen "putch(char x)" ist eine temporäre 
Variable (Argument bei Funktionsaufruf).

> wenn ich optimierung wegmache, stimmen wunderlicherweise meiene delays
> nicht mehr deswegen....

Das ist ein bekanntes Feature der avr-libc und auch so dokumentiert, 
siehe Doku zu util/delay.h, wo es heisst: "In order for these functions 
to work as intended, compiler optimizations must be enabled..."

von Noname (Gast)


Lesenswert?

>Peter schrieb:
> natürlich wird x ein wert zugewiesen

Hm. Also ein Missverständnis. Da x keine Variable ist, sondern ein 
Parameter wird auch nichts "zugewiesen". Anders ausgedrückt ist die 
Übergabe eines Parameters keine Zuweisung.
Aber naja. Wohl eher eine akademische Frage. Finde gerade meine K&R 
nicht.

>wenn ich optimierung wegmache, stimmen wunderlicherweise meiene delays
>nicht mehr deswegen....
... ein trefflicher Grund über Sinn und Unsinn von Optimierungen zu 
diskutieren. Ein Programm sollte mit Optimierungen auf besser, schöner, 
weiter funktionieren aber keine Dysfunktion zeigen.

Karl Heinz schrieb:
>Deine Funktion putch funktioniert sowieso, da brauchst du nicht viel
debuggen.

Eben. :-)

von Peter (Gast)


Lesenswert?

also nochmal danke!
ich habe jetzt einfach den wert vorher, also von Variable zu Variable 
zugewiesen.
x=y;
und danach putch(); aufgerufen...
dann sehe ich zumindest was sich in meiner fkt tut.

 _attribute_ ((noinline)) hat leider nicht funktioniert
(bekomme ich eine fehlermeldung)

MfG Peter

von Karl H. (kbuchegg)


Lesenswert?

Peter schrieb:
> also nochmal danke!
> ich habe jetzt einfach den wert vorher, also von Variable zu Variable
> zugewiesen.
> x=y;
> und danach putch(); aufgerufen...
> dann sehe ich zumindest was sich in meiner fkt tut.
>
>  _attribute_ ((noinline)) hat leider nicht funktioniert
> (bekomme ich eine fehlermeldung)

Mein Fehler.
Das Attribut muss vor die Funktion
1
__attribute__ ((noinline)) void putch(unsigned char x)
2
{
3
  ...
4
}

von Martin Beuttenmüller (Gast)


Lesenswert?

Vieleicht noch ein Hinweis:
_attribute_   hat vorn und hinten 2 Unterstriche!

( kann man leicht übersehen, finde ich )

Gruß Martin

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.