Forum: Mikrocontroller und Digitale Elektronik typedef struct führt zu unknown type name


von Kostjan K. (Gast)


Lesenswert?

Hi,

ich habe versucht ein Demoprogramm was 2006 programmiert wurde mit Atmel 
Studio 6.1 nachzubilden und kriege vom Compiler die folgende 
Fehlermeldung: unknown type name 'CANMessage'

Ich habe es ohne typedef probiert. Oder in dem ich dieses struct vor den 
relevanten Funktionen deklariert habe (und auch definiert). Jetzt bin 
ich ziemlich ratlos. Kann mir Anfänger jemand erklären, woran sich der 
Compiler genau stört und wie ich das lösen kann?

Anbei die relevanten Code-Ausschnitte:
1
void can_send_message(CANMessage *p_message)
2
{
3
    uint8_t length = p_message->length;
4
   
5
    // ID einstellen
6
    mcp2515_write_register(TXB0SIDH, (uint8_t) (p_message->id>>3));
7
    mcp2515_write_register(TXB0SIDL, (uint8_t) (p_message->id<<5));
8
   
9
    // Ist die Nachricht ein "Remote Transmit Request"
10
    if (p_message->rtr)
11
    {
12
        /* Eine RTR Nachricht hat zwar eine Laenge,
13
           aber keine Daten */
14
       
15
        // Nachrichten Laenge + RTR einstellen
16
        mcp2515_write_register(TXB0DLC, (1<<RTR) | length);
17
    }
18
    else
19
    {
20
        // Nachrichten Laenge einstellen
21
        mcp2515_write_register(TXB0DLC, length);
22
       
23
        // Daten
24
        for (uint8_t i=0;i<length;i++) {
25
            mcp2515_write_register(TXB0D0 + i, p_message->data[i]);
26
        }
27
    }
28
   
29
    // CAN Nachricht verschicken
30
    PORT_CS &= ~(1<<P_CS);
31
    spi_putc(SPI_RTS | 0x01);
32
    PORT_CS |= (1<<P_CS);
33
}
34
35
36
37
int main(void)
38
{
39
  mcp2515_init();
40
  
41
typedef struct{
42
    uint16_t  id;
43
    uint8_t   rtr;
44
    uint8_t   length;
45
    uint8_t   data[8];
46
} CANMessage;
47
48
// Neue Nachricht erzeugen
49
CANMessage message;
50
51
// Daten eintragen
52
message.id = 0x0123;
53
message.rtr = 0;
54
message.length = 2;
55
message.data[0] = 0x04;
56
message.data[1] = 0xf3;
57
58
59
// Nachricht verschicken
60
    while(1)
61
    {
62
        can_send_message(&message);
63
    _delay_ms(5);
64
    }
65
}

von Peter II (Gast)


Lesenswert?

teste mal so

struct CANMessageS {
    uint16_t  id;
    uint8_t   rtr;
    uint8_t   length;
    uint8_t   data[8];
};

typedef CANMessageS CANMessageT;


und jetzt kannst du CANMessageT als variablen Type verwenden.

CANMessageT message;

von Jim M. (turboj)


Lesenswert?

Du benutzt den Typ bevor er definiert wurde:
1
void can_send_message(CANMessage *p_message)
2
//...
3
int main(void)
4
{
5
  mcp2515_init();
6
  
7
typedef struct{
8
    uint16_t  id;
9
    uint8_t   rtr;
10
    uint8_t   length;
11
    uint8_t   data[8];
12
} CANMessage;
13
//...
14
}

Hier ist der Typ außerdem nur innerhalb von "main()" definiert. Besorge 
Dir ein gutes Buch über die "C" Programmiersprache und arbeite es durch 
- das ist ein Anfängerfehler.

von Nase (Gast)


Lesenswert?

Den Typ CanMessage vielleicht vor can_send_message() bekanntmachen?

von Kostjan K. (Gast)


Lesenswert?

Peter II schrieb:
> teste mal so
>
> struct CANMessageS {
>     uint16_t  id;
>     uint8_t   rtr;
>     uint8_t   length;
>     uint8_t   data[8];
> };
>
> typedef CANMessageS CANMessageT;
>
>
> und jetzt kannst du CANMessageT als variablen Type verwenden.
>
> CANMessageT message;


Das führt bei mir zu einer weiteren "unknown type 
CANMessageT"-Fehlermeldung. Und vier Fehlermeldungen mit diesem Inhalt: 
request for member 'id' in something not a structure or union

Nase schrieb:
> Den Typ CanMessage vielleicht vor can_send_message() bekanntmachen?

Hab ich wie oben erwähnt bereits probiert. Wie muss so eine 
Bekanntmachung denn aussehen?
Ich habe probiert:
struct CANMessage;
struct CANMessage message;
Dann noch mit eckigen Klammern, sogar die ganze Definition vom struct 
habe ich vor der relevanten Funktion und der main() probiert. Das hat 
die eine Fehlermeldung aber nicht gelöst, sondern sogar weitere 
Fehlermeldungen hervorgerufen.

Ich habe den Code bloß übernommen und laut Kommentatoren soll er bereits 
funktionsfähig sein.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Peter II schrieb:
> teste mal so
>
> struct CANMessageS {
>     uint16_t  id;
>     uint8_t   rtr;
>     uint8_t   length;
>     uint8_t   data[8];
> };
>
> typedef CANMessageS CANMessageT;
>
> und jetzt kannst du CANMessageT als variablen Type verwenden.
>
> CANMessageT message;

Warum schreibst du so'n Käse? Der Ursprüngliche Typedef war korrekt, 
vermutlich steht der nur an der falschen Stelle.

Wenn überhaupt dann

typedef struct CANMessageS CANMessageT;

aber weil das Original in der Beziehung bereits korrekt ist braucht's 
hier echt keine Nebelkerzen!

von Peter II (Gast)


Lesenswert?

Johann L. schrieb:
> Warum schreibst du so'n Käse? Der Ursprüngliche Typedef war korrekt,
> vermutlich steht der nur an der falschen Stelle.

er hat aber geschrieben, das er es schon "oben" hingeschrieben hat.

> Wenn überhaupt dann
> typedef struct CANMessageS CANMessageT;

ja ok, war ein fehler.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Peter II schrieb:
> er hat aber geschrieben, das er es schon "oben" hingeschrieben hat.

Hat er nicht, er hat nur einen Versuch einer Vorwärtsdeklaration dort 
untergebracht.

Das typedef hat nichts innerhalb einer Funktion verloren, und es 
gehört vollständig --d.h. nicht als "Vorwärtsdeklaration"-- vor die 
erste Stelle, an der es genutzt wird.

Beim oben geposteten Codefragment also ganz an den Anfang, nocht vor 
die Funktion can_send_message.

Die Struktur, die mit dem typedef genutzt wird, kann eine namenlose 
Struktur bleiben,
1
typedef struct
2
{
3
  uint16_t  id;
4
  uint8_t   rtr;
5
  uint8_t   length;
6
  uint8_t   data[8];
7
} CANMessage;

ist also zulässig.

Soll aus irgendwelchen Gründen die Struktur zuätzlich ohne typedef 
genutzt werden, dann kann ihr noch ein Name verpasst werden:
1
typedef struct CANMessage_struct
2
{
3
  uint16_t  id;
4
  uint8_t   rtr;
5
  uint8_t   length;
6
  uint8_t   data[8];
7
} CANMessage;

*Aber:* Das muss alles vor dem allerersten Gebrauch geschehen, also 
vor der Deklaration und erst recht der Definition von Funktionen oder 
Variablen des Typs.

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.