mikrocontroller.net

Forum: Compiler & IDEs Typenkonflikte in KeiluV5


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Fragender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Ich verstehe gerade überhaupt nicht, warum da ein Fehler auftritt.
Es ist wie es aussieht ein Typenkonflikt, aber ich sehe den Fehler 
nicht.
Es handelt sich um STM32F0

Ich habe in einem h-file xxx definiert:
typedef struct pin{
GPIO_TypeDef* port;
uint16_t pin;
}pin_t;


typedef struct tscGroupPort{
GPIO_TypeDef* tscGroup1,
tscGroup2,
tscGroup3,
tscGroup4,
tscGroup5,
tscGroup6;
}tscGroupPorts_t;

#define TSC_GROUP_PORT       (tscGroupPorts_t)  {GPIOA, GPIOA, GPIOB, GPIOA, GPIOB, GPIOB}
#define TSC_SHIELD             (pin_t)           {TSC_GROUP_PORT.tscGroup5,GPIO_PIN_3}
#define TSC_SHIELD_SAMPLE      (pin_t)           {TSC_GROUP_PORT.tscGroup5,GPIO_PIN_4}
#define TSC_TOUCHKEY2          (pin_t)           {TSC_GROUP_PORT.tscGroup6,GPIO_PIN_12}
#define TSC_LS1               (pin_t)           {TSC_GROUP_PORT.tscGroup6,GPIO_PIN_14}
#define TSC_LS1_SAMPLE         (pin_t)           {TSC_GROUP_PORT.tscGroup6,GPIO_PIN_13}
#define TSC_TOUCHKEY1          (pin_t)           {TSC_GROUP_PORT.tscGroup1,GPIO_PIN_1}
#define TSC_LS2               (pin_t)           {TSC_GROUP_PORT.tscGroup1,GPIO_PIN_2}
#define TSC_LS2_SAMPLE         (pin_t)           {TSC_GROUP_PORT.tscGroup1,GPIO_PIN_3}
#define TSC_LS3               (pin_t)           {TSC_GROUP_PORT.tscGroup3,GPIO_PIN_0}
#define TSC_LS3_SAMPLE         (pin_t)           {TSC_GROUP_PORT.tscGroup3,GPIO_PIN_1}


Dann nutze ich eine Funktion:
void configureGPIO(uint32_t pin, GPIO_TypeDef* port,...)
und übergebe dieser:
configureGPIO(TSC_LS2_SAMPLE.pin, TSC_LS2_SAMPLE.port, ...)

Dann meldet er zB den Fehler:
SC_LS2_SAMPLE.pin, 
SC_LS2_SAMPLE.port, GPIO_MODE_AF_OD, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, TSC_Alternate_FUNC);
..\Src\tsc.c(155): error:  #144: a value of type "GPIO_TypeDef *" cannot be used to initialize an entity of type "volatile uint32_t"
      configureGPIO(
SC_LS1_SAMPLE.pin, 
SC_LS1_SAMPLE.port, GPIO_MODE_AF_OD, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, TSC_Alternate_FUNC);
..\Src\tsc.c(158): error:  #144: a value of type "GPIO_TypeDef" cannot be used to initialize an entity of type "GPIO_TypeDef *"
      configureGPIO(
SC_LS1_SAMPLE.pin, 
SC_LS1_SAMPLE.port, GPIO_MODE_AF_OD, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, TSC_Alternate_FUNC);
..\Src\tsc.c(161): error:  #144: a value of type "GPIO_TypeDef *" cannot be used to initialize an entity of type "volatile uint32_t"

: Verschoben durch Moderator
Autor: Rufus Τ. F. (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mach doch mal den Textersatz, den der Präprozessor macht:

configureGPIO(TSC_LS2_SAMPLE.pin, TSC_LS2_SAMPLE.port, ...)


// wird im ersten Schritt zu 

configureGPIO({TSC_GROUP_PORT.tscGroup1,GPIO_PIN_2}.pin, {TSC_GROUP_PORT.tscGroup1,GPIO_PIN_2}.port, ...)


Das schluckt kein C-Compiler.

Autor: Fragender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rufus Τ. F. schrieb:
> Mach doch mal den Textersatz, den der Präprozessor macht:
>
> configureGPIO(TSC_LS2_SAMPLE.pin, TSC_LS2_SAMPLE.port, ...)
>
> // wird im ersten Schritt zu
>
> configureGPIO({TSC_GROUP_PORT.tscGroup1,GPIO_PIN_2}.pin,
> {TSC_GROUP_PORT.tscGroup1,GPIO_PIN_2}.port, ...)
>
> Das schluckt kein C-Compiler.

Ok, und weshalb funktioniert Folgendes? :
#define TOUCHKEY2_LED        (pin_t)             {GPIOB, GPIO_PIN_2}
configureGPIO(TOUCHKEY2_LED.pin, TOUCHKEY2_LED.port, 

Autor: Nico W. (nico_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist normales C.

Sieht irgendwie aus als ob da irgendwas verschoben ist.

Ein Minimalbeispiel würde da sicher besser helfen.

Autor: NichtWichtig (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Steht da doch:
a value of type "GPIO_TypeDef *" cannot be used to initialize an entity 
of type "volatile uint32_t"

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Fragender schrieb:
> typedef struct tscGroupPort{
> GPIO_TypeDef* tscGroup1,
> tscGroup2,
> tscGroup3,
> tscGroup4,
> tscGroup5,
> tscGroup6;
> }tscGroupPorts_t;

Du hast 2 Möglichkeiten, das zu fixen:

A) Du schreibst vor jeden Struct Member explizit den Typ hin und 
schließt die Zeilen mit Semikolon statt Komma ab.

B) Du wiederholst den Stern in jeder Zeile, damit tscGroup2 usw. auch 
wirklich Pointer sind - so wie Du es auch für tscGroup1 vorgesehen hast.

Ein oft gemachter Fehler, wie z.B.
int main ()
{
   int * a, b, c;
}

a ist dann ein Pointer, b und c sind aber keine.

So etwas passiert, wenn man alles möglichst knapp formulieren will. Das 
rächt sich dann.

P.S.

Ich vermeide prinzipiell, das Sternchen an den Typ zu kleben, sondern 
umgebe ihn immer mit Leerzeichen links und rechts. Denn es gehört nicht 
direkt zum Typ. Zum anderen habe ich mir angewöhnt, den Typ explizit vor 
jeden Identifier wie z.B. einer Variablen zu schreiben. Ist zwar mehr 
Schreibarbeit, ist aber lesbarer. Aus diesem Grund ist der Fehler in der 
obigen Definition auch extrem schlecht zu erkennen.

Ein Compiler sieht
   int* a, b, c;

als Kurzform von:
   int * a;
   int b;
   int c;

Ein Mensch sieht das auf den ersten Blick unter Umständen anders.

: Bearbeitet durch Moderator
Autor: Rufus Τ. F. (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Ich vermeide prinzipiell, das Sternchen an den Typ zu kleben, sondern
> umgebe ihn immer mit Leerzeichen links und rechts.

Man könnte das Sternchen an den Variablennamen kleben, das ist IMHO 
eindeutiger.

Autor: Fragender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Fragender schrieb:
>> typedef struct tscGroupPort{
>> GPIO_TypeDef* tscGroup1,
>> tscGroup2,
>> tscGroup3,
>> tscGroup4,
>> tscGroup5,
>> tscGroup6;
>> }tscGroupPorts_t;
>
> Du hast 2 Möglichkeiten, das zu fixen:
>
> A) Du schreibst vor jeden Struct Member explizit den Typ hin und
> schließt die Zeilen mit Semikolon statt Komma ab.
>
> B) Du wiederholst den Stern in jeder Zeile, damit tscGroup2 usw. auch
> wirklich Pointer sind - so wie Du es auch für tscGroup1 vorgesehen hast.
>
> Ein oft gemachter Fehler, wie z.B.int main ()
> {
>    int * a, b, c;
> }
>
> a ist dann ein Pointer, b und c sind aber keine.
>
> So etwas passiert, wenn man alles möglichst knapp formulieren will. Das
> rächt sich dann.
>
> P.S.
>
> Ich vermeide prinzipiell, das Sternchen an den Typ zu kleben, sondern
> umgebe ihn immer mit Leerzeichen links und rechts. Denn es gehört nicht
> direkt zum Typ. Zum anderen habe ich mir angewöhnt, den Typ explizit vor
> jeden Identifier wie z.B. einer Variablen zu schreiben. Ist zwar mehr
> Schreibarbeit, ist aber lesbarer. Aus diesem Grund ist der Fehler in der
> obigen Definition auch extrem schlecht zu erkennen.
>
> Ein Compiler sieht
>    int* a, b, c;
>
> als Kurzform von:
>    int * a;
>    int b;
>    int c;
>
> Ein Mensch sieht das auf den ersten Blick unter Umständen anders.



Hi Frank

So funktionierts.

Rufus Τ. F. schrieb:
> Mach doch mal den Textersatz, den der Präprozessor macht:
>
> configureGPIO(TSC_LS2_SAMPLE.pin, TSC_LS2_SAMPLE.port, ...)
>
> // wird im ersten Schritt zu
>
> configureGPIO({TSC_GROUP_PORT.tscGroup1,GPIO_PIN_2}.pin,
> {TSC_GROUP_PORT.tscGroup1,GPIO_PIN_2}.port, ...)
>
> Das schluckt kein C-Compiler.

Vonwegen es schluckt kein Compiler...

Wirklich top von dir Frank, danke für deine Hilfe.
Ich hatte gemeint, wenn der Stern am Typ hängt, gälte das für alle 
members. Wieder etwas neues gelernt.

Ich habe mich für deine Variante entschieden.
typedef struct tscGroupPort{
GPIO_TypeDef *tscGroup1;
GPIO_TypeDef *tscGroup2;
GPIO_TypeDef *tscGroup3;
GPIO_TypeDef *tscGroup4;
GPIO_TypeDef *tscGroup5;
GPIO_TypeDef *tscGroup6;
}tscGroupPorts_t;

Autor: Fragender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
NichtWichtig schrieb:
> Steht da doch:
> a value of type "GPIO_TypeDef *" cannot be used to initialize an entity
> of type "volatile uint32_t"

Woww! Suppper Tipp.

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rufus Τ. F. schrieb:
> Man könnte das Sternchen an den Variablennamen kleben, das ist IMHO
> eindeutiger.

Ja, könnte man, dagegen sträubt sich bei mir aber das ästhetische 
Empfinden. Daher habe ich für mich Leerzeichen links und rechts vom 
Sternchen als Kompromiss gewählt ;-)

Zudem ziehe ich die Variablennamen auf dieselbe Spalte. Dann sieht es 
bei mir so aus:
int main ()
{
    unsigned char * bytearray;
    int *           intarray;
    int             counter;
    int             noch_ein_counter;
    unsigned int    errorcode;
}

Das wäre für mich noch eine Alternative:
int main ()
{
    unsigned char * bytearray;
    int           * intarray;    // beachte Lage des Sternchens
    int             counter;
    int             noch_ein_counter;
    unsigned int    errorcode;
}

Die Kurzform
    int* intarray, counter, noch_ein_counter;
vermeide ich jedoch grundsätzlich. Da braucht man viel zu lange, es mit 
den Augen korrekt zu erfassen. Siehe oben: Das eigentliche Problem, dass 
der TO hat, hat keiner der Leser auf Anhieb gesehen. Ich musste da auch 
erst dreimal draufschauen.

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fragender schrieb:
> So funktionierts.

Freut mich.

> Ich habe mich für deine Variante entschieden.

Finde ich soweit okay. ;-)

Autor: W.S. (Gast)
Datum:

Bewertung
-3 lesenswert
nicht lesenswert
Fragender schrieb:
> error:  #144: a value of type "GPIO_TypeDef *" cannot be used to
> initialize an entity of type "volatile uint32_t"

Warum verstehst du die Fehlermeldung eigentlich nicht?

du hast eine Variable
volatile unsigned long blabla;
und willst selbige mit einem Zeiger, nämlich GPIO_TypeDef* belegen. 
Jetzt müßtest du bloß mal nachschauen, wie dein Typ "GPIO_TypeDef" denn 
überhaupt definiert ist. Ich vermute mal, daß sich dahinter ein dicker 
fetter struct befindet, der sämtliche Register eines der GPIO's enthält. 
Aber das kannst du ja selber herauskriegen.

Warum mußt du eigentlich alles so unsäglich verkomplizieren, bis keiner 
mehr durchsieht, was du da eigentlich gemacht hast (im Gegensatz zu 
gemeint hast)

W.S.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.