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.
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.
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.
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.
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.
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.
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.
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.
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".
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?
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.
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).
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
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.
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.
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.
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.