Typenkonflikte in KeiluV5

Gast #5654908
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:
1
typedef struct pin{
2
GPIO_TypeDef* port;
3
uint16_t pin;
4
}pin_t;
5

6

7
typedef struct tscGroupPort{
8
GPIO_TypeDef* tscGroup1,
9
tscGroup2,
10
tscGroup3,
11
tscGroup4,
12
tscGroup5,
13
tscGroup6;
14
}tscGroupPorts_t;
15

16
#define TSC_GROUP_PORT       (tscGroupPorts_t)  {GPIOA, GPIOA, GPIOB, GPIOA, GPIOB, GPIOB}
17
#define TSC_SHIELD             (pin_t)           {TSC_GROUP_PORT.tscGroup5,GPIO_PIN_3}
18
#define TSC_SHIELD_SAMPLE      (pin_t)           {TSC_GROUP_PORT.tscGroup5,GPIO_PIN_4}
19
#define TSC_TOUCHKEY2          (pin_t)           {TSC_GROUP_PORT.tscGroup6,GPIO_PIN_12}
20
#define TSC_LS1               (pin_t)           {TSC_GROUP_PORT.tscGroup6,GPIO_PIN_14}
21
#define TSC_LS1_SAMPLE         (pin_t)           {TSC_GROUP_PORT.tscGroup6,GPIO_PIN_13}
22
#define TSC_TOUCHKEY1          (pin_t)           {TSC_GROUP_PORT.tscGroup1,GPIO_PIN_1}
23
#define TSC_LS2               (pin_t)           {TSC_GROUP_PORT.tscGroup1,GPIO_PIN_2}
24
#define TSC_LS2_SAMPLE         (pin_t)           {TSC_GROUP_PORT.tscGroup1,GPIO_PIN_3}
25
#define TSC_LS3               (pin_t)           {TSC_GROUP_PORT.tscGroup3,GPIO_PIN_0}
26
#define TSC_LS3_SAMPLE         (pin_t)           {TSC_GROUP_PORT.tscGroup3,GPIO_PIN_1}


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

Dann meldet er zB den Fehler:
1
SC_LS2_SAMPLE.pin, 
2
SC_LS2_SAMPLE.port, GPIO_MODE_AF_OD, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, TSC_Alternate_FUNC);
3
..\Src\tsc.c(155): error:  #144: a value of type "GPIO_TypeDef *" cannot be used to initialize an entity of type "volatile uint32_t"
4
      configureGPIO(
5
SC_LS1_SAMPLE.pin, 
6
SC_LS1_SAMPLE.port, GPIO_MODE_AF_OD, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, TSC_Alternate_FUNC);
7
..\Src\tsc.c(158): error:  #144: a value of type "GPIO_TypeDef" cannot be used to initialize an entity of type "GPIO_TypeDef *"
8
      configureGPIO(
9
SC_LS1_SAMPLE.pin, 
10
SC_LS1_SAMPLE.port, GPIO_MODE_AF_OD, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, TSC_Alternate_FUNC);
11
..\Src\tsc.c(161): error:  #144: a value of type "GPIO_TypeDef *" cannot be used to initialize an entity of type "volatile uint32_t"
Gast #5654974
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? :
1
#define TOUCHKEY2_LED        (pin_t)             {GPIOB, GPIO_PIN_2}
2
configureGPIO(TOUCHKEY2_LED.pin, TOUCHKEY2_LED.port,
Moderator Persönliche Seite #5655494
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.
1
int main ()
2
{
3
   int * a, b, c;
4
}

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
1
   int* a, b, c;

als Kurzform von:
1
   int * a;
2
   int b;
3
   int c;

Ein Mensch sieht das auf den ersten Blick unter Umständen anders.
Gast #5655569
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.
1
typedef struct tscGroupPort{
2
GPIO_TypeDef *tscGroup1;
3
GPIO_TypeDef *tscGroup2;
4
GPIO_TypeDef *tscGroup3;
5
GPIO_TypeDef *tscGroup4;
6
GPIO_TypeDef *tscGroup5;
7
GPIO_TypeDef *tscGroup6;
8
}tscGroupPorts_t;
Moderator Persönliche Seite #5655589
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:
1
int main ()
2
{
3
    unsigned char * bytearray;
4
    int *           intarray;
5
    int             counter;
6
    int             noch_ein_counter;
7
    unsigned int    errorcode;
8
}

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

Die Kurzform
1
    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.
Gast #5662010
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
1
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren