mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik absolute Adressen in C?


Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Folgendes Problem: Ich möchte ne ganze Menge Kennlinien als Konstanten 
im Flash unterbringen, allerdings sollen die per download später 
verändert werden können.
Es sind exakt 43200Byte, den Rest der zu 64kB würde ich gerne unbenutzt 
lassen, da diese beim Blocklöschen (64kB) auch verloren gehen würden.
Das Feld beginnt bei 0xD0000, der Rest soll dann ab 0xE0000 beginnen 
(M16C62).
Im Moment behelfe ich mir mit:
const char dummy[0x5740];
Fragen: warum funktioniert folgendes nicht:
const char dummy[0x10000-3*3600*4];
//64k-3Felder a 3600 float-Werte zu je 4 Byte
Anfangsadresse für Rest der Konstanten wird vom Compiler (NC30) nicht 
wie erwartet zu 0xE0000 sondern zu 0xF0000 berechnet??
Wahrscheinlich werden später noch weitere Daten in die 64k kommen, so 
dass ich mir die ganze Bytezählerei gerne sparen würde.
Wie also kann man absolute Adressen festlegen?
const char version[]="...."; soll also in jedem Fall bei 0xE0000 
beginnnen.

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

Bewertung
0 lesenswert
nicht lesenswert
const char* Version = (const char*)0xE0000;

Damit hast du einen Pointer der auf die absoulte Adresse
0xE0000 zeigt. Benutzen kannst du den ganz normal, so wie
du auch das Array benutzt hättest.

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ne, das hilft mir gar nichts. Es geht ja darum, dass die restlichen 
Konstanten wirklich erst ab 0xE0000 im Flash stehen und eben nicht schön 
platzsparend aneiander gepappt werden.
In Assembler würde das so aussehen:
.org 0xD0000
.db .....//7200 float-Werte

.org 0xE0000
der Rest

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dafür gibt es keine generelle Antwort in C.

Es ist von Deinem speziellen Compiler abhängig.

Was sagt den Dein Compiler- und Linker-Manual dazu ?

Beim Keil C51 gibt es z.b. 2 Wege.
Man kann im Source-File ein Variablen-Array an einer bestimmten Adresse 
anlegen (at) oder dem Linker angeben, daß er ein Objekt an eine 
bestimmte Adresse linken soll.
Ich benutze das z.B., um einen Gerätestring immer an 0x0100 zu linken. 
Damit weiß ich immer, wozu ein Hex-File gehört.


Peter

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, habe ich mir schon gedacht.
Ich werde mich vielleicht später nochmal damit beschäftigen, im Moment 
bleibts dann erstmal bei den dummy-Daten.
Bleibt die Frage, warum das nicht funktioniert:
const char dummy[0x10000-3*3600*4];
sollte eigentlich ein Array alegen, dass die restlichen Bytes bis zur 
64k-Grenze verbrät. Vertut aber 0x15740 Bytes statt 0x5740. Mach ich da 
einen Denkfehler oder spinnt der Compiler?

Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Verstehe, Du möchtest, dass der Compiler die Größe des Dummy-Feldes 
automatisch berechnet, und alle weiteren Variablen (nicht nur 
einzelne)danach anordnet.
Evtl. hilft es, mit  sizeof  die Größe der einzelnen chars und floats
und Array mal anzeigen zu lassen.

Was ich auch schon öfters hatte: Der Compiler rechnet Konstanten erstmal 
mit 16 Bits, außer man hängt ein L daran an.
Versuchs mal mit char dummy[65536L-3L*3600L*4L]

"Vertut aber 0x15740 Bytes statt 0x5740."
schon komisch, wenn dann hätte ich mir noch eher vorstellen können, dass 
er wg. Padding  2* 0x5700 reserviert.

Kannst Du mal hilfsweise das Dummy in zwei oder drei aufteilen und im 
Assembler nachschauen, was er wirklich macht, wohin er die arrays legt?

const char dummy1[8]=(0,1,2,3,4,5,6,7);
const char dummy2[0x57400-16];
const char dummy3[8]=(7,6,5,4,3,2,1,0);

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na, super :-)
Mit L klappte es wie gewünscht
habe es jetzt mit sizeof gelöst:
const char 
dummy[0x10000-sizeof(kennlinie1)-sizeof(kennlinie2)-sizeof(kennlinie3)];
passt :-)
Da wiederum brauch ich kein L.
Egal, vielen Dank

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Was ich auch schon öfters hatte: Der Compiler rechnet Konstanten
> erstmal mit 16 Bits, außer man hängt ein L daran an.

Genauer gesagt sind Konstanten vom Typ int, wenn dieser Typ groß genug 
ist. Ich nehme mal an, daß int beim gegebenen Controller 16 Bit breit 
ist. Wenn bei einer Berechnung alle Operanden vom Typ int sind, ist es 
auch das Ergebnis. 65536 passt zwar nicht mehr und ist daher sowieso 
long, aber 3, 3600 und 4 nicht. Das Ergebnis der zuerst ausgeführten 
Multiplikation ist also vom Typ int, aber die 43200 passen nicht mehr da 
rein. Durch den Überlauf ergibt sich stattdessen ein Wert von -22336. 
Erst danach wird dann zur Subtration wegen der 65536 auf 32Bit 
erweitert. Die Größe des Blocks ist also nicht 65536-43200=22336 
(=0x5740), sondern 65536+22336=87872 (=0x15740)

> Versuchs mal mit char dummy[65536L-3L*3600L*4L]

Damit gehst du auf Nummer Sicher. Theoretisch würde es auch rechen, nur 
bei einer der letzten drei Zahlen das L anzuhängen, aber mit allen Ls 
ist der Code leichter verständlich.

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.