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.
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.
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
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
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?
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);
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
> 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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.