mikrocontroller.net

Forum: Compiler & IDEs Bestimmter Speicheradresse einen Wert zuweisen


Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich sitze gerade an einem Projekt für den ATmega644 und möchte wie 
erwähnt an eine Speicheradresse einen Wert schreiben. Dabei ist die 
Speicheradresse als int gegeben. fptr ist ein vorher definierter 
Funktionspointer-Typ.

fptr tmp;
tmp=(fptr)Speicherdresse;
*tmp=Wert;

Dabei erhalte ich folgende Fehlermeldung für die 3. Zeile:
error: lvalue required as left operand of assignment

Könnt ihr mir sagen wo da mein Fehler liegt? Lässt sich das gar nicht so 
einfach realisieren?

Gruß
Alex

Autor: Werner B. (werner-b)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
MoingMoing!

Es stellt sich die Frage
 Was ist "fptr"?

Jedenfalls kein vordefinierter "C" Datentyp.
Ohne diese Information kann dir niemand helfen.

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn fptr tatsächlich ein Funktionspointer ist, also z.B.
typedef void fptr(int);
dann ist klar, dass das nicht geht, wie willst du an eine Funktion einen 
Wert zuweisen?

Wenn du die Funktion mit dem Wert als Übergabeparameter aufrufen willst, 
geht das mit
fptr(Wert);

Also: was hast du vor?

Autor: Imon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bin mir nicht sicher was du vor hast aber eine bestimmten Speicher 
Adresse  einen wert zu weisen, macht man so
 
 char *ptr;

 ptr = ( char *) 0xDEADBEEF; // Setze Address auf 0xDEADBEEF;
 *ptr = WERT;  // schreibe WERT nach 0xDEADBEF;
  

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das würde ein Byte zuweisen.

Er redet aber davon, eine int übertragen zu wollen.
Das ginge analog mit:
  int wert = ...; // was auch immer
  / an die Adresse 0xDEADBEEF die int WERT schreiben:
  *(int*)0xDEADBEEF = wert;

Aber was er wirklich will, ist mir auch nicht so recht klar.
DSas obige setzt ja eine Speichrstelle im RAM.
Ein Funktionszeiger würde aber gar nicht eine RAM-Adresse
beinhalten beim AVR.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> DSas obige setzt ja eine Speichrstelle im RAM.

Nö. Das weisst lediglich dem Pointer einen Wert zu. Der würde bei Aufruf 
der Funktion über den Pointer als Adresse im Flash interpretiert.

Alex schrieb:
> *tmp=Wert;
>
> Dabei erhalte ich folgende Fehlermeldung für die 3. Zeile:
> error: lvalue required as left operand of assignment

Nun ja, ein Funktionspointer ist ein Funktionspointer ist ein 
Funktionspointer. Das, worauf der zeigt (*tmp), ist eine Funktion, die 
kann man nur aufrufen, aber der kann man keinen Wert zuweisen.

Daher solltest du erst einmal beschreiben, was du eigentlich erreichen 
willst.

Oliver

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die vielen Antworten!

Ich war gestern Nacht wohl schon übermüdet und es hat am elementaren 
Verständnis für Pointer gefehlt.

Mithilfe von Imons Beitrag konnte ich mein Problem schon lösen.
Mein Problem dabei war das mein WERT die Adresse einer Funktion ist. 
(WERT ist also ebenfalls vom Typ fptr)
Ich wollte aber keine Funktion speichern sondern eben nur einen int-Wert 
der die Adresse einer Funktion beschreibt.

Der von mir gesuchte Code sieht also so aus:
unsigned int* tmp;
tmp=(unsigned int*)Speicherdresse;
*tmp=(unsigned int)WERT;

Das müsste eigentlich das tun was ich wollte.

Gruß
Alex

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und wozu dann tmp?
*(unsigned int*)Speicherdresse=(unsigned int)WERT;

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Edit:

Wahrscheinlich wäre unsigned char, sinniger als unsigned int wenn ich 
die Adresse einer Funktion speichern möchte, oder?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In ein char passt nur ein Byte.
Es gibt nicht viele Systeme, bei denen die Adresse einer
Funktion mit einem Byte auskommt.

int bzw. uint muß auch nicht passen, geht aber oft (zufällig).

Ich weiß immer noch nicht, was du wirklich willst.
Aber es kommt mir falsch vor.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PS:
Daß in C Adressen auch nur Zahlenwerte sind, heisst nicht, daß
es auch nur im Mindesten sinnvoll wäre Adressen und andere
Zahlen wild zu pürieren.
Das ist in 99% der Fälle böses Gemurkse und führt zu nichts,
zumindest wenn man nicht weiß was man tut.

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> Und wozu dann tmp?
> *(unsigned int*)Speicherdresse=(unsigned int)WERT;

Das ist natürlich noch einfacher.

Habs mal getestet und char ist wirklich zu klein für meine Zwecke.
Meine Fragen sind glaube ich alle geklärt. Danke :)

Gruß
Alex

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alex schrieb:
> Edit:
>
> Wahrscheinlich wäre unsigned char, sinniger als unsigned int wenn ich
> die Adresse einer Funktion speichern möchte, oder?


Am sinnigsten wäre es, ganz einfach den dafür vorgesehenen Datentyp, 
nämlich einen Funktionspointer, zu benutzen.

Speziell bei Pointer gilt nämlich oft die Daumenregel: Wenn man da wie 
wild rumcasten muss, dann stimmt etwas nicht.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Speziell bei Pointer gilt nämlich oft die Daumenregel: Wenn man da wie
> wild rumcasten muss, dann stimmt etwas nicht.

Außerdem dürfen Funktionszeiger ohnehin nur in (bzw. von) anderen
Funktionszeigern gecastet werden, eine Vermischung mit Objektzeigern
ist unzulässig und führt zu undefiniertem (meiner Erinnerung nach)
Verhalten.  Auch ein Cast von/nach "void *" ist damit unzulässig.
Wenn man einen "generischen" Funktionszeiger braucht (um einen Zeiger
auf eine Funktion beliebigen Typs speichern zu können, bei dem Typ
und Anzahl der Argumente erst zur Laufzeit feststehen), kann man
sich mit sowas helfen:
typedef void (*generic_func_ptr)(void);

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.