Forum: Mikrocontroller und Digitale Elektronik C Code Verständnis Problem


von Max (Gast)


Lesenswert?

Hallo Zusammen,

ich weiss man kann nicht einfach losgelöst Code erklären aber ich habe 
ein Verständnis Problem mit einem Code Fragment. Ich bin eher ein C 
Anfänger und arbeite mich derezeit durch einen Code aber der ist recht 
schwierig (für mich) zu verstehen.
1
static struct dev_spi gspi;
2
static struct dev_spi * m_spi = &gspi;
Was passiert hier ?

Danke

von sk8er (Gast)


Lesenswert?

static struct dev_spi gspi;

erzeugt ein Objekt/Variable vom Typ dev_spi

static struct dev_spi * m_spi = &gspi;

erzeugt einen Pointer m_spi, der auf das zuvor erstellte Objekt zeigt.

Jetzt kannst Du ein und dieselbe Datenstruktur

gspi.member1 = ...
gspi.member2 = ...

bedienen oder über den Pinter

m_spi->member1 = ...
m_spi->member2 = ...

usw.

Warum man das so macht, könnte man ggf. aus dem Kontext erkennen.

von Dirk B. (dirkb2)


Lesenswert?

Es wird eine nur lokal sichtbare struct vom Typ dev_spi mit dem Namen 
gspi angelegt.

Danach wird noch ein lokal sichtbarer Zeiger mit Namen m_spi angelegt, 
der auf die oben genannte struct verweist.

Das lokal sichtbare wird durch das static begründet.

von S. R. (svenska)


Lesenswert?

Dirk B. schrieb:
> Das lokal sichtbare wird durch das static begründet.

Das hängt davon ab, ob es so innerhalb einer Funktion steht (dann steht 
es nicht nur für "lokal sichtbar") oder global ist.

Beitrag #6186698 wurde von einem Moderator gelöscht.
von P. S. (namnyef)


Lesenswert?

Die erste Zeile erzeugt ein Objekt "gspi" des Typs "struct dev_spi".

Die zweite Zeile erzeugt ein Objekt "m_spi" des Typs "Pointer auf Typ 
'struct dev_spi'" und weist diesem Objekt die Adresse des Objekts "gspi" 
zu.

von Max (Gast)


Lesenswert?

P. S. schrieb:
> Die zweite Zeile erzeugt ein Objekt "m_spi" des Typs "Pointer auf Typ
> 'struct dev_spi'" und weist diesem Objekt die Adresse des Objekts "gspi"
> zu.

Vielen Dank für die Erklärung aber gspi hat doch gar keinen Wert. Wie 
kann das dann eine Adresse sein. Irgendwie gehts nicht in mein Hirn.

von Dirk B. (dirkb2)


Lesenswert?

S. R. schrieb:
> Das hängt davon ab, ob es so innerhalb einer Funktion steht

Ich habe mich im Wahrsagen probiert um die wahrscheinlichste Stelle zu 
finden.
Bin auf außerhalb einer Funktion gekommen.

Meine Vermutung ist eine struct, die irgendwelche 
Konfigurationsinformationen aufnimmt und dann über den Pointer 
angesprochen wird.

Globale Variablen, die Parameterübergabe in Ereignisgesteuerten 
Programmen.

von Dirk B. (dirkb2)


Lesenswert?

Max schrieb:
> aber gspi hat doch gar keinen Wert.

Da steht auch &gspi. & ist hier der Adressoperator.
Das Objekt gspi wurde in der Zeile darüber angelegt, also hat es eine 
Adresse.

Es ist die Initialisierung eines Pointers.

von P. S. (namnyef)


Lesenswert?

Max schrieb:
> P. S. schrieb:
>> Die zweite Zeile erzeugt ein Objekt "m_spi" des Typs "Pointer auf Typ
>> 'struct dev_spi'" und weist diesem Objekt die Adresse des Objekts "gspi"
>> zu.
>
> Vielen Dank für die Erklärung aber gspi hat doch gar keinen Wert. Wie
> kann das dann eine Adresse sein. Irgendwie gehts nicht in mein Hirn.

Der Adress-Operator ("&") führt eben dazu, dass nicht der Wert des 
Objekts zugewiesen wird, sondern die Adresse des Objekts.

Selbst wenn das Objekt "gspi" keinen definierten Wert hat, ist es eben 
immer noch ein Objekt, das irgendwo im Speicher liegt. Und als solches 
liegt es auf der Adresse "&gspi".

von Walter S. (avatar)


Lesenswert?

Max schrieb:
> aber gspi hat doch gar keinen Wert. Wie
> kann das dann eine Adresse sein

gspi ist doch ein Speicherplatz an dem Daten gespeichert werden, warum 
sollte dieser Speicher keine Adresse haben?

von Max (Gast)


Angehängte Dateien:

Lesenswert?

https://www.stupid-projects.com/driving-an-ili9341-lcd-with-an-overclocked-stm32f103/

Hier mal der Link zur Software. Mir gehts es um den Teil des Codes wo 
der Touch controller ausgewertet wird.

Dirk B. schrieb:
> Meine Vermutung ist eine struct, die irgendwelche
> Konfigurationsinformationen aufnimmt und dann über den Pointer
> angesprochen wird.

Ja, seh ich auch so aber ich kapier es nicht. Mich interresiert nur der 
Touch code in xpt2046.c, ich habe es mal angehangen. Ich denke da wird 
zwischen SPI1 und SPI2 hin und her geschaltet aber der Code is für mich 
maximal verwirrend.

von S. R. (svenska)


Lesenswert?

Max schrieb:
> Vielen Dank für die Erklärung aber gspi hat doch gar keinen Wert.

Doch, sie wird initialisiert. In C++ vom Konstruktor, in C mit Nullen 
(wenn global).

von Dirk B. (dirkb2)


Lesenswert?

Max schrieb:
> Ich denke da wird
> zwischen SPI1 und SPI2 hin und her geschaltet

Nö, da wird nur SPI2 benutzt. Beim Aufruf von
dev_spi_init(m_spi, DEV_SPI2, SPI_MODE_0, SPI_BaudRatePrescaler_32);

Dann taucht m_spi nur noch in der xpt2046_read Funktion auf.

Das ist im Grunde sowas wie ein globaler Filedeskriptor von fopen

von Max (Gast)


Lesenswert?

Dirk B. schrieb:
> Nö, da wird nur SPI2 benutzt. Beim Aufruf von
> dev_spi_init(m_spi, DEV_SPI2, SPI_MODE_0, SPI_BaudRatePrescaler_32);

OK, weiter zu meinem Verständnis Problem. Mir geht es in der Tat um die 
SPI und die Initialisierung in der genannten Zeile. Wenn diese Zeile 
ausgeführt wird dann ist SPI 2 aktiv und läuft. Im gleichen Augenblick 
funktioniert aber SPI1 nicht mehr. Das Display kann nicht mehr 
angesteuert werden. Was entscheidet denn hier wann welche SPI 
angesteuert wird ? sorry das ich es nicht besser formulieren kann.

von Max (Gast)


Lesenswert?

Anders gefragt, wie kann ich beide SPIs parallel benutzen ? oder eben 
wahlweise ?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

S. R. schrieb:
> in C mit Nullen (wenn global).

Nein, auch sonst – es steht ja eh "static" davor. ;-) Statische Daten 
werden auch lokal in Funktionen mit Nullen initialisiert.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Max schrieb:
> wie kann ich beide SPIs parallel benutzen ?

Indem du noch ein zweites Objekt vom Typ dev_spi anlegst und dessen 
Adresse an den entsprechenden Stellen benutzt. Natürlich nicht 
vergessen, das zweite Peripheral auch passend zu aktivieren.

Überall in dem von dir gezeigten Code, wo "m_spi" steht, hätte man 
stattdessen genauso gut "&gspi" schreiben können. Da war der 
Programmierer wohl nur zu tippfaul oder was – eines separaten 
Zeigerobjekts hätte es eigentlich nicht bedurft.

von Max (Gast)


Lesenswert?

Jörg W. schrieb:
> Indem du noch ein zweites Objekt vom Typ dev_spi anlegst und dessen
> Adresse an den entsprechenden Stellen benutzt. Natürlich nicht
> vergessen, das zweite Peripheral auch passend zu aktivieren.

Die beiden SPIs sind ja initialisiert aber es funktioniert nicht 
gemeinsam. Ich schlaf mal ne Nacht drüber. Danke einstweilen.

von Dirk B. (dirkb2)


Lesenswert?

Max schrieb:
> Die beiden SPIs sind ja initialisiert aber es funktioniert nicht
> gemeinsam.

Das liegt dann aber mehr an der SPI-Soft- oder Hardware.

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.