Forum: Compiler & IDEs globalen Variablen unter Keil C51


von Thomas Z. (usbman)


Lesenswert?

Ich arbeite gerne mit einem global.h was alle globalen Variablen des 
Projekts enthält, hauptsächlich weil ich die nur zentral in einem Platz 
deklarieren will. Wie gesagt es geht um globale Variablen die in 
mehreren Modulen sichtbar sein müssen. Das Problem ist, dass at nicht 
bei extern Deklarationen erlaubt ist.
Ich habe mir deshalb ein Macro geschrieben um mit extern und at 
umzugehen.

Ein gekürztes Beispiel:
1
#ifdef GLOBAL_EXTERN       
2
  #define EXTERN          // remove EXTERN
3
  #define _AT_ _at_       // replace with _at_
4
#else                     
5
  #define EXTERN extern   // replace with extern 
6
  #define _AT_ ;/ ## /    // replace _AT_  with ';//' 
7
#endif
8
...
9
EXTERN uint8_t xdata Buffer0 [64] _AT_ 0x0000; 
10
EXTERN uint8_t xdata Buffer1 [64] _AT_ 0x0040; 
11
...
In genau einem File wird dann GLOBAL_EXTERN definiert. Bei mir ist das 
meist das Modul welches Main enthält.
1
#define GLOBAL_EXTERN
2
#include "global.h"
3
....
Das funktioniert soweit auch wir gewünscht. Ich habe allerdings das 
Gefühl das man das auch anders (besser?) machen könnte.
Was meint ihr dazu? Wie macht ihr solche Sachen?

Thomas

von Dr. Sommer (Gast)


Lesenswert?

Thomas Z. schrieb:
1
#define _AT_ _at_       // replace with _at_

Bezeichner die mit Unterstrich + Großbuchstabe oder 2 Unterstrichen 
beginnen sind reserviert und der Standard-Bibliothek bzw. 
Compiler-Erweiterungen vorenthalten. Allerdings ist es kurios dass 
"_at_" eine C51-Erweiterung ist, denn laut Standard-C muss der 
Bezeichner "_at_" zur freien Verwendung zur Verfügung stehen!

von Thomas Z. (usbman)


Lesenswert?

ok dann machen wir halt daraus
#define AT_ at
Das war aber nicht die Frage.

Thomas

von Haare zu Berg Stehender (Gast)


Lesenswert?

Thomas Z. schrieb:
> Das funktioniert soweit auch wir gewünscht.

Das Wünschen mag andauern, der weitere Erfolg wird aber
zu Wünschen übrig lassen.

Thomas Z. schrieb:
> Wie macht ihr solche Sachen?

Gaaaanz sicher nicht Variablen in Header Files definieren!

Sondern in einem globalen Modul.

von Dr. Sommer (Gast)


Lesenswert?

Thomas Z. schrieb:
> Das war aber nicht die Frage.

Ich hatte das Gefühl dass allgemein nach Verbesserungsmöglichkeiten 
gefragt war.

Ich würde nicht so viele globale Variablen verwenden, dass so etwas 
nötig ist. Dinge in structs verpacken und Zeiger darauf übergeben 
verbessert die Programmstruktur. Im Idealfall hat man in der main.c eine 
Hand voll globaler struct-Variablen, auf die man Zeiger an die 
jeweiligen Funktionen übergibt. So kann man zentral den Programm-Aufbau 
sehen und modifizieren.

von Thomas Z. (usbman)


Lesenswert?

zum ersten mal gesehen hab ich das bei Cypress / Anchorchips die eine 
ganze Menge SFRs im xdata Bereich haben. Das Konstrukt hab ich dort 
geklaut.
Generell geb ich dir mit den Pointern recht. Wobei (generic) Pointer auf 
einem x51 teuer sind. Der c166 compiler von keil verwendet ebenfalls 
at. Wie das beim ARM Compiler ist kann ich nicht sagen den hab ich 
nicht.

Thomas

von Peter D. (peda)


Lesenswert?

Thomas Z. schrieb:
> Ich habe allerdings das
> Gefühl das man das auch anders (besser?) machen könnte.

Ja, es geht deutlich besser, man überläßt das Plazieren von Variablen 
einfach dem Linker.
Das at ist eigentlich nur dazu gedacht, um memory mapped Peripherie 
anzusprechen.

von Nop (Gast)


Lesenswert?

Thomas Z. schrieb:

> Das Problem ist, dass at nicht bei extern Deklarationen erlaubt ist.

Dann laß es einfach ganz weg. Chip-spezifische Register sollten sich eh 
schon in den entsprechenden Headerfiles finden, die Keil bereitstellt.

von fop (Gast)


Lesenswert?

1
#define _AT_ ;/ ## /

Finde ich nicht so prickelnd. Ist eine super Stolperfalle, wenn mal nach 
dem At noch was Wichtiges kommt. Da sucht man sich dumm und dusselig.

Auch wenn Du Alles umschreiben musst, wäre es besser zu schreiben
1
#define AT(H) _at_ (H)
2
#else
3
#define AT(H)

von DPA (Gast)


Lesenswert?

Thomas Z. schrieb:
> #define AT ;/ ## /    // replace AT  with ';//'

Ein Compiler der das zulässt ist ohnehin nicht Standardkonform und 
sollte vermieden werden. Erstens gehört / nicht zu den Zeichen, die man 
mit ## an irgendwas anheften darf, und zweitens müssen Kommentare schon 
vor der Makroauswertung mit leerzeichen ersetzt werden, korrekterweise 
müsste ein Compiler wenn in der phase trotzdem noch ein // da ist also 
einen syntaxfehler werfen.

von Thomas Z. (usbman)


Lesenswert?

Erst mal danke für eure Meinungen. Ich war leider zu sehr im Stress um 
früher zu antworten.
Ich hätte ja schon befürchtet dass ihr alle auf at anspringt. Das ist 
aber gar nicht der hauptsächliche Grund für mein Konstrukt. Das ist eher 
Keil spezifisch und somit auch in keiner Weise portable.
Die eigentliche Frage war eher Deklaration vs Definition in einem File. 
Das hätte ich genauer beschreiben sollen.

Thomas

von Nop (Gast)


Lesenswert?

Thomas Z. schrieb:

> Ich hätte ja schon befürchtet dass ihr alle auf at anspringt.

Ja zurecht, denn wenn Du das nicht nutzt, dann stellt sich das 
ursprüngliche Problem auch nicht, welches da lautete:

> Das Problem ist, dass at nicht bei extern Deklarationen erlaubt ist.

von Peter D. (peda)


Lesenswert?

Thomas Z. schrieb:
> Die eigentliche Frage war eher Deklaration vs Definition in einem File.

Die Deklaration gehört in ein *.h File.
Die Definition gehört in ein *.c File.
Das *.h wird bei Bedarf includiert, das *.c einmalig zum Build 
hinzugefügt.
Steht aber auch in jedem C Lehrbuch.

von Philipp Klaus K. (pkk)


Lesenswert?

Dr. Sommer schrieb:
> […]Allerdings ist es kurios dass
> "_at_" eine C51-Erweiterung ist, denn laut Standard-C muss der
> Bezeichner "_at_" zur freien Verwendung zur Verfügung stehen!

Bei µC gibt es einige Compiler (z.B. Keil und Raisonance), die es mit 
dem Standard nicht so genau nehmen, von daher überrascht mich das nicht.
Bei SDCC war das bis vor 15 Jahren (SDCC 2.5.0) ähnlich.

von Dr. Sommer (Gast)


Lesenswert?

Philipp Klaus K. schrieb:
> Bei µC gibt es einige Compiler (z.B. Keil und Raisonance), die es mit
> dem Standard nicht so genau nehmen, von daher überrascht mich das nicht.

Das stimmt wohl. Aber bei so etwas einfachem wie Benennung von 
Spezial-Schlüsselwörtern wäre das ja einfach korrekt zu machen... 
Vielleicht kann man die strikte Standard-Konformität ja einschalten?

von Thomas Z. (usbman)


Lesenswert?

Philipp Klaus K. schrieb:
> Bei µC gibt es einige Compiler (z.B. Keil und Raisonance), die es mit
> dem Standard nicht so genau nehmen, von daher überrascht mich das nicht.
> Bei SDCC war das bis vor 15 Jahren (SDCC 2.5.0) ähnlich.

mir ist es ehrlich gesagt wichtiger effektiven Code zu erhalten. Ob sich 
der Compiler an die akademischen Standards hält ist zwar wünschenswert 
aber nicht alles.
Gerade der SDCC ist noch verbesserungswürdig in Bezug auf die Codegröße.
Keil und Raisonance haben die gleichen Wurzeln.

Thomas

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.