mikrocontroller.net

Forum: Compiler & IDEs Variablen vs. Speicheradressen


Autor: Christian O. (derbrain)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich hab jetzt mal Beispielcode von Atmel durchgeackert, und dabei ist
mir aufgefallen, dass dort sowohl globale Variablen als auch direkte
Speicheradressen verwendet werden. Was für einen Sinn hat es, die
Adressen explizit anzugeben?
Ich nehme an, volatile wird dabei überflüssig (wird auch niemals
verwendet). Aber hat es auch andere Vorteile?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Was für einen Sinn hat es, die Adressen explizit anzugeben?

Das kann man nur mit dem Kontext entscheiden.  Man könnte zum Beispiel
den externen Speicher ,,mit der Hand'' verplanen, und den internen
RAM
dem Compiler für Variablen und Stack überlassen.

Man könnte externe Geräte über memory-mapped IO einbinden, dann hat
man auch feste Adressen.  Letztlich sind bei AVR-GCC/avr-libc alle
IO-Register auf diese Weise eingebunden, d. h. sie lösen alle auf eine
feste Adresse auf (die ja im Datenblatt steht).  Da alle IO-Register
über MMIO (memory-mapped IO, also über die STS/LDS-Befehle) erreichbar
sind, hat man so einen garantierten Weg.  Manche davon sind auch via
IN/OUT erreichbar und bei wiederum einem Teil lassen sich SBI und CBI
für die Bitmanipulation benutzen.  Es obliegt dann dem optimizer, das
entsprechend zu ersetzen.

> Ich nehme an, volatile wird dabei überflüssig (wird auch niemals
> verwendet).

Überhaupt nicht.  Für den Compiler ist und bleibt das ein Pointer.
Wenn man sichergestellt haben will, dass der entsprechende Inhalt auch
wirklich mit jeder Zuweisung im C-Programm zurückgeschrieben wird
bzw. jedes Lesen im C-Programm tatsächlich von der entsprechenden
Speicherstelle gelesen wird (bei MMIO will man das wohl immer), dann
muss man den volatile deklarieren.  Exakt so funktionieren auch die
IO-Makros (also PORTB usw.).

Dass der IAR (auf dem der meiste Atmel-Beispiel-Code aufsetzt) hier
anders optimiert und dadurch das volatile nicht unbedingt braucht, ist
letztlich Zufall.

Autor: Christian O. (derbrain)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die ausführliche Antwort :-)

Das mit den externen Geräten leuchtet mir ein, aber was ist der Sinn im
"normalen" Gebrauch?
Im Beispielprogramm werden werden normale globale Variablen nur
innerhalb einer Datei verwendet (im Header-File nicht vorhanden),
während die Speicher-Pointer allgemein sichtbar sind. Konkret sind das
Datum, Uhrzeit und Temperatur. Externer Speicher wird nicht verwendet,
RAMEND muss extra runtergesetzt werden damit die Speicherstellen nicht
überschrieben werden. Da also schon einiges an Aufwand dahintersteckt,
dachte ich mir, das muss einen tieferen Sinn haben. Auch möglich, dass
das nur verwendet wird um zu zeigen wie so was geht (weil
Beispielsoftware).

@ volatile: Ich habs mir nochmal genauer angeschaut, dass die das nicht
verwenden liegt wohl wirklich am anders optimierenden Compiler, sonst
würde das Programm kaum laufen.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nö, kein Gefühl, warum das dort so gemacht worden ist.

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Im Beispielprogramm..."

Welches ?

Wenn Du mal das Programm als Anhang oder nen Link darauf angibst, dann
könnte man vielleicht näheres dazu sagen.

Sonst ist das hier nur Rätsel raten.


RAMEND zu verbiegen klingt ja schon ziemlich krank.


Peter

Autor: Christian O. (derbrain)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ähm, sorry, das hätt ich auch gleich machen können... :-)

Der Code ist im Anhang, eine Beschreibung was das ist gibts hier:
http://www.atmel.org/dyn/resources/prod_documents/...

Da ist das Programm auch als Flussdiagramm dargestellt. Wie macht ihr
das eigentlich? Was ich so mitbekommen habe seid ihr so was wie
µC-Gurus ;-) Codet ihr gleich los oder wie geht ihr bei der Entwicklung
vor?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So auf die Schnelle ist mir beim durchschauen des Codes
nichts aufgefallen. Worauf moechtest Du konkret hinaus?
(ala: Schau mal in Datei xyz, Zeile abc)

Autor: Christian O. (derbrain)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Konkret geht es um die in Main.h definierten Pointer, bei Zeile 41 geht
die Beschreibung los (mit Hinweis darauf, dass RAMEND runtergesetzt
wird)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Autor wollte sicherstellen, dass die Variablen
tatsaechlich hintereinander und so wie er es moechte
im Speicher angeordnet werden.

Dadurch kann er in UART.C in den Funktionen
Send_TX_data bzw. Store_RX_data darauf wie
auf ein Array zugreifen.

            ...

            *(&HOUR + HEX_Cnt) = HEX_byte;

            ...

            Nr_ASCII_bytes = HEX2ASCII(*(&HOUR + Cnt++));

je nach Wert von HEX_Cnt bzw. Cnt wird dann in Wirklichkeit
eine der Variablen HOUR, MINUTE, SECOND, ...   genommen.

Ansonsten sehe ich keinen wirklichen Grund, warum das so gemacht
wurde. Und selbst wenn dies der einzige Grund ist, so gibt es
in C wesentlich bessere Moeglichkeiten sowas zu realisieren
(Stichworte: Reihenfolge und padding uber ein Array regeln.
Oder eine struct verwenden, dann muss man sich um das Padding
meist selbst kuemmern, ...)

Autor: Christian O. (derbrain)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachdem der tägliche Server-Error mein Posting gefressen hat, versuch
ichs nochmal so gut es geht zu rekonstruieren:

Mein Ansatz wäre auch ein Array gewesen für das Datum. Vielleicht
wollten die nur zeigen, DASS sowas geht.
Oder es ist einfach eine seltsame Art zu Programmieren. Z.B. sieht die
Funktion HEX2ASCII nach ziemlichem Overhead aus. Wenn man davon
ausgeht, dass es nur für Temperaturen von 0 bis 20 Grad verwendet wird
(negativ geht gar nicht), hält es sich noch in Grenzen, aber was wäre
bei 180 Grad? Wäre so was nicht besser:

Dec_L = Hex % 10;
Hex = Hex / 10;
...

und das Ganze noch in einem Array statt drei Variablen? Oder kommt das
in Assembler aufs Gleiche raus?

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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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