mikrocontroller.net

Forum: Compiler & IDEs globalen Variablen unter Keil C51


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Thomas Z. (Firma: Unaffiliated) (usbman)
Datum:

Bewertung
0 lesenswert
nicht 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:
#ifdef GLOBAL_EXTERN       
  #define EXTERN          // remove EXTERN
  #define _AT_ _at_       // replace with _at_
#else                     
  #define EXTERN extern   // replace with extern 
  #define _AT_ ;/ ## /    // replace _AT_  with ';//' 
#endif
...
EXTERN uint8_t xdata Buffer0 [64] _AT_ 0x0000; 
EXTERN uint8_t xdata Buffer1 [64] _AT_ 0x0040; 
...
In genau einem File wird dann GLOBAL_EXTERN definiert. Bei mir ist das 
meist das Modul welches Main enthält.
#define GLOBAL_EXTERN
#include "global.h"
....
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

Autor: Dr. Sommer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas Z. schrieb:
#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!

Autor: Thomas Z. (Firma: Unaffiliated) (usbman)
Datum:

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

Thomas

Autor: Haare zu Berg Stehender (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Dr. Sommer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thomas Z. (Firma: Unaffiliated) (usbman)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter D. (peda)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Nop (Gast)
Datum:

Bewertung
1 lesenswert
nicht 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.

Autor: fop (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#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
#define AT(H) _at_ (H)
#else
#define AT(H)

Autor: DPA (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thomas Z. (Firma: Unaffiliated) (usbman)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Nop (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter D. (peda)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.