Variable nur innerhalb einer Header Datei einsehbar

Gast #3816494
Lesenswert?

Hallo,

wie mache ich dass, das eine Variable nur von ISR angepasst werden kann. 
Am besten soll die in der main.c überhaupt nicht bekannt sein, sondern 
nur über die Anfrage der ms() als Rückgabewert bekannt gegeben werden.

Beispiel:
1
// main.c
2
#include "time.h"
3

4
void main()
5
{
6
time_init();
7
while(1) { /*...*/ }
8
}
9

10
// time.h
11
volatile uint16_t _ms;
12

13
ISR(/* ... */)
14
{
15
_ms++;
16
}
17

18
uint16_t ms(void) { return _ms; }
#3816555
Lesenswert?

Bei der Anweisung
1
#include "time.h"
macht der Preprozessor nichts anderes, als den ganzen Inhalt von time.h 
an dieser Stelle in main.c einzufügen. Erst danach sieht der Compiler 
den Code. Es macht hier also keinen Unterschied, ob etwas in main.c oder 
in time.h steht, denn es ist für den Compiler nicht zu unterscheiden.

Du bekommst allerdings ein Problem, wenn Du time.h in eine zweite 
C-Datei (z.B. modul2.c) inkludierst. Dann steht da nämlich nochmal die 
Definition der Variable, der Funktion und der ISR. Darüber wird sich der 
Linker beschweren, denn jede Funktion darf nur einmal definiert werden.

Der richtige Weg ist, aus Deiner time.h eine time.c zu machen und eine 
neue time.h zu erstellen, dir nur Deklarationen enthält, die ein anderes 
Modul (main.c) kennen muss, um die Funktionalität nutzen zu können.
1
// time.h
2
uint16_t time_ms(void);
3

4
// time.c
5
static volatile uint16_t ms;
6

7
ISR(/* ... */)
8
{
9
ms++;
10
}
11

12
uint16_t time_ms(void) { return ms; }

Ich habe noch zwei Änderungen vorgenommen:

1. Die Variable "_ms" static gemacht (und das Unterstrich-Prefix 
entfernt, das ist nämlich für die C-Standardbibliothek reserviert). 
Dadurch kann sie nur von Funktionen aus time.c verwendet werden. Von 
main.c aus ist sie nicht sichtbar. Das war ja Deine ursprüngliche Frage.

2. Der Funktion "ms" das Prefix "time_" gegeben. Somit kann man sofort 
erkennen, zu welchem Modul diese Funktion gehört. Gewöhn Dir am besten 
gleich an, dass alle Funktionen, die in einer H-Datei aufgeführt sind, 
das gleiche Prefix haben. Ansonsten wirst Du schnell den Überblick 
verlierten und die Gefahr von unbeabsichtigten Namenkollisionen steigt.
#3816567
Lesenswert?

Fabian O. schrieb:
> Du bekommst allerdings ein Problem, wenn Du time.h in eine zweite
> C-Datei (z.B. modul2.c) inkludierst. Dann steht da nämlich nochmal die
> Definition der Variable, der Funktion und der ISR. Darüber wird sich der
> Linker beschweren, denn jede Funktion darf nur einmal definiert werden.

Deswegen macht man immer sowas:
1
//time.h
2

3
#ifndef TIME_H
4
#define TIME_H
5

6
//Inhalt der Headerdatei
7

8
#endif /*TIME_H*/

mfg.
#3816586
Lesenswert?

Das hilft in dem Fall nichts, denn jede C-Datei wird unabhängig von 
anderen C-Dateien kompiliert. Ist ja auch gut so, sonst ließe sich so 
eine H-Datei nur in eine einzige C-Datei einbinden und wäre in den 
anderen wirkungslos.

Diese Includeguards haben den Sinn zu verhindern, dass der Inhalt einer 
H-Datei mehrmals in die gleiche C-Datei inkludiert wird, wenn die 
H-Datei noch von (mehreren) anderen H-Dateien inkludiert wird. In 
ungünstigen Konstellationen könnte das sogar zu Endlosschleifen führen.

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