Hallo zusammen
Ich habe mir zu Pointern nun einiges durchgelesen, aber bzgl. meines
Problems habe ich nichts Konkretes gefunden. Immer wenn es interessant
wurde, was mein Problem fast gelöst hätte, wurde die notwendige
Erklärung irgendwie ausgelassen.
Nun versuche ich dies selbst zu implementieren und habe da einige
Fragen.
Ich habe hier im def.h einen struct definiert.
Im sendperiph.h bzw. c eine Funktion mit dem Typ struct Numbers.
Im main habe ich einen struct erzeugt.
Jetzt ist es mein Ziel, der Funktion transmit den struct zu übergeben
bzw. die Adresse des ersten Elements, sodass ich mir aussuchen kann, ob
ich zuerst die 0, 1 oder 2 schicke mittels SPI.
Wie mache ich das jetzt am Besten?
So wie unten ausgeführt heisst es im header-file, dass die Deklaration
von struct Numbers ausserhalb der Funktion nicht sichtbar ist als
Warnung und als error conflicting types for transmitCode.
Ich hätte jetzt gemeint, dass ich einen pointer übergeben muss, denn
damit übergebe ich ja die Adresse des structs. Aber diese ist vom Typ
struct Numbers und die SPI Funktion verlangt einen pointer vom Typ
uint8_t.
Ich verstehe irgendwie nicht wie das funktionieren soll. Casten kann man
ja auch nicht so einfach.
Könnte mir hierbei jemand vielleicht behilflich sein?
Übrigens ist die SPI-Funkt. vom STM32. Die sind ja immer gleich
aufgebaut.
Hi,
Warum nutzt Du überhaupt eine struct, wenn die SPI_Transmit ein uint_8*
erwartet ?
Oder Lehrzwecke ?
Seis drum:
struct Numbers{
uint8_t data[3];
};
HAL_SPI_Transmit(&hspi1, (uint8_t*) number->data ,
sizeof(number->data), x_ms);
Gruß
Sebastian Kaulitz schrieb:> So wie unten ausgeführt heisst es im header-file, dass die Deklaration> von struct Numbers ausserhalb der Funktion nicht sichtbar ist als> Warnung und als error conflicting types for transmitCode.
Das stimmt ja auch.
> Ich verstehe irgendwie nicht wie das funktionieren soll. Casten kann man> ja auch nicht so einfach.
Kann man schon. Besser ist es aber, das Programm so zu schreiben, dass
möglichst wenig Casts nötig sind. Hier wäre der Cast nötig, weil du eine
struct statt ein Array verwendet hast. Und weil HAL_SPI_Transmit aus
irgendeinem Grund einen uint8_t* statt einen void* haben will.
> Übrigens ist die SPI-Funkt. vom STM32. Die sind ja immer gleich> aufgebaut.> #ifndef DEF_H> #define DEF_H>> struct Numbers{> uint8_t zero,> one,> two;> };>> #ifndef sendperiph_H> #define sendperiph_H>> void transmit(struct Numbers *number);>> #endif
Werden diese beiden Header auch irgendwo verwedet?
> sendperiph.c> void transmit(struct Numbers *number)> {> HAL_SPI_Transmit(&hspi1, &number , sizeof(number), x_ms);> angenommen hier werden neben der SPI Transmit noch andere> Operationen> mit dem Pointer number ausgeführt.
So überträgst du den Zeiger, nicht das, worauf er zeigt. number ist ein
Zeiger auf deine Daten, aber du übergibst nicht den Zeiger, sondern
seine Adresse an die Transmit-Funktion. Und auch das sizeof ermittelt
die Größe des Zeigers und nicht die von dem, worauf er zeigt.
Sebastian Kaulitz schrieb:> HAL_SPI_Transmit(&hspi1, &number , sizeof(number), x_ms);
Mal abgesehen davon, wie es Andere viel toller machen würden, denke ich,
dass hier Dein Fehler liegt. &number ergibt einen Zeiger auf einen
Zeiger auf ein Struct. Das ist vermutlich nicht das, was die
HAL_SPI_Transmit erwartet.
Sollte wohl ein
sein, oder ? Wobei ein -> zwei Dinge auf einmal macht :
- den Inhalt auf den der Zeiger zeigt rauskramen, wie man es sonst mit
dem Ausdruck *Zeiger macht
- ein Element des Structs auszuwählen, was man sonst mit Struct.Element
macht
Ansonsten hast Du Dein Beispiel so weit gekürzt, dass man nicht mehr
sieht, was in welcher Reihenfolge eingebunden wird. Die def.h muss immer
eingebunden sein, bevor Du den Namen Numbers benutzt. Also auch bevor Du
sendperiph.h einbindest.
Sebastian Kaulitz schrieb:> struct Numbers{> uint8_t zero,> one,> two;> };
Was hast Du dir dabei gedacht?
Warum kein Array, wie es jeder macht?
Sebastian Kaulitz schrieb:> void transmit(struct Numbers *number)> {> HAL_SPI_Transmit(&hspi1, &number , sizeof(number), x_ms);
Das ist Bullshit, Du mußt die Länge des Arrays übergeben.
Die Größe eines Pointers ist konstant 4 Byte aufm ARM.
Man kann auch die Länge mit in einem Struct übergeben:
Sebastian Kaulitz schrieb:> HAL_SPI_Transmit(&hspi1, &number , sizeof(number), x_ms);
Das &number im Aufruf ist schon falsch, da number bereits ein Pointer
ist. Pointer von Pointer ist hier Murks. sizeof() wird ebenso falsch
angewendet, weil das der Größe des Pointers entspricht und nicht der
Länge der Daten.
Allein schon wegen dem möglichen Alignment, welches auf bestimmten
Prozessoren dafür sorgt, dass zwischen den Struct-Members Lücken
auftreten, sollte man hier auf eine Struct verzichten und einfach ein
Array nehmen:
Hallo zusammen
Einige Beiträge wurden hier irgendwie entfernt. ZB das von mir und Dr.
Sommer.
Ich würde gerne wissen, woher ihr das Wissen habt. Ich habe nun schon
etwas über structs gelesen, aber von Alignment etc. habe ich noch nichts
gehört oder gesehen.
Wo findet man denn eine Lektüre, welches die Grundlagen von C wirklich
behandelt?
Sebastian Kaulitz schrieb:> Einige Beiträge wurden hier irgendwie entfernt. ZB das von mir und Dr.> Sommer.
Nein, hier wurde nichts gelöscht. Du verwechselst offenbar diesen Thread
mit jenem hier, den Du ebenso eröffnet hast:
Beitrag "SPI DMA Adresse"
Auch dort wurde nichts gelöscht. Die Beiträge von Dr. Sommer sind dort
alle sichtbar.
Sebastian Kaulitz schrieb:> Ich würde gerne wissen, woher ihr das Wissen habt
Aus C++ Büchern.
Sebastian Kaulitz schrieb:> von Alignment etc. habe ich noch nichts> gehört oder gesehen.
Das ist auch von C bzw. C++ nicht spezifiziert; in einem korrekten
Programm bekommt man davon nichts mit. Wenn man aber einfach Pointer
umcastet und z.B. ein struct als char-Array betrachtet fangen die fiesen
plattformspezifischen Details an. Siehe auch: Serialisierung
Sebastian Kaulitz schrieb:> Wo findet man denn eine Lektüre, welches die Grundlagen von C wirklich> behande
Der K&R (in der zweiten Ausgabe) und der ISO-Standard zu C (gibt es auch
als freien Draft im Netz)
Sebastian Kaulitz schrieb:
> Wo findet man denn eine Lektüre, welches die Grundlagen von C wirklich> behande
Ich finde
Harbison & Steele, C: A Reference Manual, 5th Edition | Pearson
https://www.pearson.com/us/higher-education/progra...
deutlich besser als den K&R.
Ein Kommentar auf https://news.ycombinator.com/item?id=1245535
sieht's ähnlich:
I personally find Steele's C: A Reference Manual far more useful in day
to day hacking.
und:
I found K&R great ... until I got to the arrays and pointers chapter. It
wasn't my inability to get the concept, I think, the Lions' Commentary n
UNIX 6th Edition, with Source Code which I tried next did the trick.
And nowadays I too keep Harbison and Steele handy, I lost track of my
copy of K&R sometime in the '80s.