Forum: Mikrocontroller und Digitale Elektronik Struct in Funktion initialisieren


von Elias B. (bouni)


Lesenswert?

Hallo allerseits,

ich habe einen USART der mit einem Struct als Ringbuffer funktioniert.
Das Setup des entsprechenden UARTS wird mit einer Funktion erledigt.
Das struct ist im Header File deklariert.
Initialisiert wird es im c-File.
So weit so gut.
Wenn ich nun das setup nur für den ersten USART aufrufe, dann werden 
trotzdem alle Ringpuffer initialisiert und verbrauchen demnach Speicher 
obwohl nur 2 davon (rx,tx) genutzt werden, oder?.
Ich bin immer noch nicht ganz sicher im Arbeiten mit Pointern.

Die Frage ist nun, kann ich eine globale Pointer Variable für jden 
Puffer anlegen. Die Setup Funktion initialisiert nun die Puffer nur wenn 
der USART auch initialisiert wird, und setzt den Zeiger auf das struct.

Geht das, und wenn ja, wie?

Im Moment mache ich Präprozessor Direktiven um die nicht genutzten 
Puffer ein und auszublenden.
1
#if USART0 == 1
2
// Receive Buffer
3
serialBuffer_t usart0_rx_buffer = {{}, 0, 0, 0};
4
// Transmit Buffer
5
serialBuffer_t usart0_tx_buffer = {{}, 0, 0, &UCSR0B};
6
#endif
7
#if USART1 == 1
8
// Receive Buffer
9
serialBuffer_t usart1_rx_buffer = {{}, 0, 0, 0};
10
// Transmit Buffer
11
serialBuffer_t usart1_tx_buffer = {{}, 0, 0, &UCSR1B};
12
#endif
13
#if USART2 == 1
14
// Receive Buffer
15
serialBuffer_t usart2_rx_buffer = {{}, 0, 0, 0};
16
// Transmit Buffer
17
serialBuffer_t usart2_tx_buffer = {{}, 0, 0, &UCSR2B};
18
#endif
19
#if USART3 == 1
20
// Receive Buffer
21
serialBuffer_t usart3_rx_buffer = {{}, 0, 0, 0};
22
// Transmit Buffer
23
serialBuffer_t usart3_tx_buffer = {{}, 0, 0, &UCSR3B};
24
#endif

Danke schon mal für die Hilfe!

Elias
von cskulkw (Gast)


Lesenswert?

Elias B. schrieb:
> #if USART0 == 1
>
> // Receive Buffer
>
> serialBuffer_t usart0_rx_buffer = {{}, 0, 0, 0};
>
> // Transmit Buffer
>
> serialBuffer_t usart0_tx_buffer = {{}, 0, 0, &UCSR0B};

Hallo Elias,

was bezweckst Du mit den geschweiften Klammern im ersten Parameter?

Wo ist Dein Ringpuffer bzw. wer ist für die Überlaufbehandlung 
zuständig?
Nicht dargestellte Funktion?

Ansonsten ist UCSROB bereits eine Adresse und braucht nicht zwingend mit 
dem &-Operator dereferenziert werden.
von Elias B. (bouni)


Lesenswert?

Hi,

ich hätte den Teil aus dem Header file noch mitposten sollen:
1
typedef struct _serial_buffer {
2
    uint8_t data[BUFFERSIZE];
3
    volatile uint8_t read; 
4
    volatile uint8_t write;
5
    volatile uint8_t *ucsrb;
6
} serialBuffer_t;

Das schreiben/lesen des Puffers passiert jeweils in einer eigenen 
Funktion.
Wie gesagt das arbeiten mit Pointern ist (noch) nicht meine Stärke ;)
von Karl H. (kbuchegg)


Lesenswert?

Das hat erst mal mit Pointern nicht viel zu tun  bzw. Pointer sind ja 
kein Allheilmmittel. Wenn du nicht in die dynamische Allokierung willst 
(wovon ich abraten würde) dann helfen dir Pointer genau gar nichts.

Sieh deine UART Puffer nicht als voneinander unabhängige Variablen an, 
sondern fasse sie alle zusammen in ein Array, dessen Größe genau so 
gross ist, wie du eben Puffer brauchst um für jede UART einen Sende und 
einen Empfangspuffer zu haben.


> Wenn ich nun das setup nur für den ersten USART aufrufe,
> dann werden trotzdem alle Ringpuffer initialisiert und verbrauchen
> demnach Speicher

Ja, natürlich.
Das hat aber weniger mit dem Aufruf des Setup zu tun, sondern damit, 
dass du die entsprechenden globalen Variablen dafür hast. Sind die 
globalen Variablen da, dann belegen sie auch Speicher.
von Elias B. (bouni)


Lesenswert?

Hallo Karl Heinz,

erst mal Danke für deine Erklärung :)

Das heisst, du würdest ein Puffer Array anlegen und das in der Setup 
funktion mit Puffer structs "befüllen"?
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.