Forum: Compiler & IDEs Adresscodierung mit Pointer


von müllo (Gast)


Lesenswert?

Ich habe mir interessenhalber mal das Buch "Softwareentwicklung in C"
von Jörg Wiegelmann ausgeliehen und habe bei Kapitel 9.2 eine Frage.

Es geht dabei um Ansprechen von Hardwarebausteinen über Ihre Adresse
und dabei wird folgendes Beispiel gebracht:

-----------------------------------------------------------------
// Auszug Beispiel 9.10
char *z_reg = (char *)0x5513; //Def. Zeiger und Init mit Adresse
*z_reg = 44;                  //Laden des Wertes
-----------------------------------------------------------------

Ich habe ein Problem mit der Initialisierung der Zeile 1. Wieso wird
die Zuweisung mit dem cast-Operator gemacht? Würde eine direkte Angabe
der Adresse (siehe unten) nicht reichen?

-----------------------------------------------------------------
char *z_reg;                  //Definition
z = 0x5513;                   //Zuweisung Adresse
*z_reg = 44;                  //Laden des Wertes
-----------------------------------------------------------------

Viele Grüße
müllo

von Werner B. (Gast)


Lesenswert?

Weil 0x5513 ein intergertyp ist, die zuweisung an einen zeiger/pointer
aber einen zeigertyp benötigt/erwartet.

von müllo (Gast)


Lesenswert?

Also kann ich die Adresscodierung anstatt mit einem char-Pointer (wie im
Buch beschrieben) besser mit einem int-Pointer realisieren, oder???

-----------------------------------------------------------------
int *z_reg;                  //Definition
z = 0x5513;                   //Zuweisung Adresse
*z_reg = 44;                  //Laden des Wertes
-----------------------------------------------------------------

Oder wird der char-Pointer wegen des Speicherplatzes benutzt???

Viele Grüße
müllo

von Matthias (Gast)


Lesenswert?

Hi

das kommt eben drauf an was an der Addresse angeschlossen ist. Ist da
8-Bit-Peripherie benutzt man einen char * (besser uint8_t *). Ist da
16-Bit-Peripherie benutzt man einen uint16_t *.

Um den cast kommst du nicht herum wenn du ordentlichen Code produzieren
willst den ein Compiler auch ohne Warning schluckt. 0x5513 ist eben kein
Addresse sondern eine Zahl. Um aus einer Zahl eine Addresse zu machen
mußt du diese Zahl umwandeln (casten).

BTW:
Nicht jede Architektur läßt 16-Bit Speicherzugriffe auf ungerade
Addressen zu. Und selbst wenn sie es tut sind die meist schreklich
ineffektiv da aus dem einen Zugriff häufig zwei werden.

Matthias

von müllo (Gast)


Lesenswert?

Ich glaube, jetzt habe ich es geschluckt :))) Es geht also darum, dass
mittels cast (typ *) aus der jeweiligen Typvariablen eine
Zeigervariable (Adressvariable) wandelt. Vielen Dank an Euch Beide...


Kannst Du mir nochmal die Sache mit den Zugriffen auf ungerade Adressen
und daraus resultierende Probleme näher erläutern? Wie kann ich denn als
Programmierer dieses umgehen, zumal ich ja bei 8-Bit Zugriffen ebenfalls
auf ungerade Adressen zugreifen könnte?

Schonmal vielen Dank und schönes Wochenende...

müllo

von Matthias (Gast)


Lesenswert?

Hi

Das ganze hängt erstmal stark von der Architektur ab. Bei x86 kannst du
z.B. beliebige Zugriffe auf jede Addresse machen.

Ein 8-Bit Zugriff auf ungerade Addressen ist kein Problem. Aber ein
16-Bit Zugriff auf eine ungerade Addresse ist eben nicht auf jeder
Hardware möglich. SH4 erlaubt z.B. nur 16-Bit Zugriffe auf gerade
Addressen. Dito für 32Bit-Zugriffe. Da muß die Addresse eben x%4==0
erfüllen sonst wirft der Prozessor eine Exception. ARM macht das AFAIK
ganz ähnlich nur das dort jeder Zugriff die Bedingung x%4==0 erfüllen
muß.

x86 führt diese "unaligned"-Speicherzugriffe zwar aus macht aber
effektiv zwei "aligned"-Zugriffe (die allerdings atomar, d.h. nicht
unterbrechbar, sind) und bastelt das Ergebnis dann wieder zusammen.


Matthias

von Jörg Wunsch (Gast)


Lesenswert?

Nicht vergessen: memory-mapped IO (um sowas geht's ja hier) ist ein
typischer Kandidat für einen `volatile' qualifier.  Also

volatile char *z_reg = (volatile char *)0x5513;

Damit wird der Compiler gezwungen, tatsächlich jedesmal beim
Auftauchen von "*z_reg" auch auf den Speicherbus (und damit den
EA-Baustein) zuzugreifen, ohne den Wert zwischendrin zu cachen.  (Die
AVR-IO-Register machen letztlich auch genau dies im AVR-GCC.)

von müllo (Gast)


Lesenswert?

Herzlichen Dank an Euch beide...wenn ich beim Durchlesen der restlichen
Kapitel noch "blöde" Fragen habe, nerve ich nochmal.

Schönes Wochenende und viele Grüße
müllo

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.