Forum: Mikrocontroller und Digitale Elektronik Frage: Pointer-Deklaration


von Bernd Bubble (Gast)


Lesenswert?

Hallo,

kurze Frage aus der Pfalz:

im Header-file zum LPC2294 wird die Adresse des CANMOD-Registers wie 
folgt definiert:

#define C1MOD (*((volatile unsigned long*)))  0xE0044000



Später im einer anderen Routine wird einem Pointer diese Adresse wie 
folgt zugewiesen:


unsigned long *pBase

pBase = (unsigned long*) &C1MOD;


Warum wird hier noch einmal der Typ angegeben? Das ist doch 
normalerweise ein Typecast, ist dieser hier wirklich nötig?
Und wofür das Doppel* in der Definition des Registers?

Kann mir jemand bei diesen Fragen helfen?

Danke,
Bernd

von Stefan E. (sternst)


Lesenswert?

Bernd Bubble schrieb:

> Warum wird hier noch einmal der Typ angegeben? Das ist doch
> normalerweise ein Typecast, ist dieser hier wirklich nötig?

Ohne den Cast würde es eine "discards qualifiers"-Warnung geben.

> Und wofür das Doppel* in der Definition des Registers?

Das erste '*' ist Bestandteil des Cast, um aus dem Hex-Wert einen 
Pointer zu machen, das zweite '*' ist zur Dereferenzierung dieses 
Pointers.

Edit: Oder umgekehrt, je nach dem, von welcher Seite man anfängt zu 
zählen. ;-)

von Karl H. (kbuchegg)


Lesenswert?

Dass sieht seltsam aus.

Bist du sicher, dass du das richtig hier ins Forum kopiert hast.

IMHO sollte das eigentlich lauten
1
#define C1MOD (*((volatile unsigned long*)0xE0044000))

so ergibt das Sinn, aber deine Variante ist ... zumindest seltsam

von Oliver (Gast)


Lesenswert?

Poste doch mal den richtigen Code. So, wie das da steht, kann das nicht 
sein.

Oliver

von Bernd Bubble (Gast)


Lesenswert?

Karl Heinz,

du hattest recht:

#define C1MOD          (*((volatile unsigned long *) 0xE0044000))

aber kannst du mir in wenigen verständlichen Worten die Deklaration 
erklären.

Mir ist klar, dass man dem Register einen Adresswert zuweisen will, und 
dass im Programm die Adresse an Pointer vom Typ unsigned long übergeben 
werden soll...ich hätte gesagt, dass der erste * zur Dereferenzierung 
verwendet wird???

von Karl H. (kbuchegg)


Lesenswert?

Bernd Bubble schrieb:
> Karl Heinz,
>
> du hattest recht:
>
> #define C1MOD          (*((volatile unsigned long *) 0xE0044000))
>
> aber kannst du mir in wenigen verständlichen Worten die Deklaration
> erklären.
>
> Mir ist klar, dass man dem Register einen Adresswert zuweisen will, und
> dass im Programm die Adresse an Pointer vom Typ unsigned long übergeben
> werden soll...ich hätte gesagt, dass der erste * zur Dereferenzierung
> verwendet wird???

Yep.

Aber gehe es doch einfach von innen nach aussen, beginnend beim Wert 
durch

  0xE0044000
               ist eine bestimmte Zahl

  (volatile unsigned long *) 0xE0044000
               diese Zahl wird zu einem Pointer gecastet

  *Pointer
               gibt den Inhalt an der Adresse die im Pointer steht

  Also

  * (volatile unsigned long *) 0xE0044000

      ergibt den Inhalt, der sich an dem unsigned long Pointer,
      dessen Wert 0xE0044000 beträgt. (Das volatile besagt lediglich,
      dass jedesmal nachgesehen werden muss, wenn mit dem Inhalt etwas
      passiert. Cachen ist nicht erlaubt)

Und dann noch eine Klammer rundherum, wie es bei Makros generell ratsam 
ist.

von Klaus W. (mfgkw)


Lesenswert?

Erstmal ist das keine Zuweisung, sondern nur ein #define.
Es wird also in Zukunft C1MOD erstzt durch das, was hier dahinter steht.

Das ist dann wiederum so zu interpretieren:
a) 0xE0044000 ist eine ganze Zahl
b) (volatile unsigned long *) 0xE0044000 ist eben diese Zahl, aber
  interpretiert als Zeiger auf unsigned long.
  Gemeint ist damit die Adresse einer unsigned long an der Stelle
  0xE0044000 im Speicher.
c) *((volatile unsigned long *) 0xE0044000) ist dann das, was an
  besagter Stelle im Speicher steht, also die unsigned long an
  der Stelle 0xE0044000
d) die Klammern drumrum sollen Ärger verhindern, der durch
  die unglückliche Auswertungsreihenfolge der Operatoren
  bei der jeweiligen Verwendung vorkommen kann.
  Man gewöhnt sich einfach an, solche Ersetzungen zu klammern.

Tip: In jedem besseren C-Buch die Operatoren anschauen und
dabei die Prioritäten und Auswertungsreihenfolge beachten
(Zusammenfassung von links oder von rechts).

von Klaus W. (mfgkw)


Lesenswert?

ja; bin ja auch nicht Karl-Heinz und war damit nicht gemeint.

von Bernd Bubble (Gast)


Lesenswert?

Ok..ist jetzt klar...danke an Karl-Heinz und ausdrücklichen Dank auch an 
Klaus...

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.