Ich weiß, daß man normalerweise dem Compiler/Linker die Anordnung der Variablen im Speicher überlässt, aber es gibt ja z.B. die Konvention, in die oberste EEPROM-Stelle den Wert zu schreiben, der ins OSCCAL-Register geladen werden soll. Das hätt ich nun gern als Variable in meinen C-Code geschrieben. Kann ich dem Compiler irgendwie sagen, daß er diese spezielle Variable ans Ende des EEPROM stecken soll?
Bedeutet das Fehlen einer Antwort, daß es nicht geht, oder daß keiner weiß, wie es geht?
Hi du könntest die Variable in eine eigene Sektion packen und diese dann beim Linken an eine bestimmte Addresse verschieben und dann mit avr-objcopy aus dem Binary rausfummeln (evtl. zusammen mit den anderen EEPROM Variablen). Das sollte eigentlich funktionieren. Aber Jörg hat da sicher eine einfachere Idee :-) Matthias
> Aber Jörg hat > da sicher eine einfachere Idee :-) Harhar. :) Naja, wenn's eine feste Adresse sein soll und man den Kram ohnehin mit eeprom_read_foo() lesen muss, warum den Pointer nicht gleich über E2END (aus <avr/io.h>) berechnen?
Ich wollt's halt als Variable im C-Code haben, so daß ich da direkt den Wert angeben kann und er automatisch im eeprom-hex-File landent, statt dieses eine Byte immer nachträglich einzeln von Hand ändern zu müssen.
Hmm, du willst den OSCCAL-Wert im C-File festlegen? Das verstehe ich nicht so recht. Wenn du nur einen Vorgabewert haben willst, kannst du doch einfach nachsehen, ob die Speicherstelle noch 0xFF hat und in diesem Falle OSCCAL belassen, wie es ist.
> Hmm, du willst den OSCCAL-Wert im C-File festlegen? Genau. > Das verstehe ich nicht so recht. Naja, wenn ich eine µC-Schaltung bastle und programmiere, verwende ich normalerweise immer denselben µC und wechsle sie nicht ständig durch. Also habe ich auch immer denselben OSCCAL-Wert (bis ich halt den µC aus Dämlichkeit kapputgemacht hab). Und damit ich nicht jedes Mal nach dem Programmieren den OSCCAL-Wert nochmal extra schreiben muß, möchte ich, daß er gleich im C-Code und daduch auch nachher im hex-File steht. Falls ich mal einen anderen (oder mehrere) µC programmieren will, weil die Schaltung mehrmals aufgebaut wird, könnte ich dann immer noch für jeden einzeln den Wert für OSCCAL an die richtige Stelle schreiben, weil sie immer am Ende des EEPROM ist und ich nicht abhängig von der Software-Version die Adresse erst raussuchen muß. Klingt das so unsinnig? > Wenn du nur einen Vorgabewert haben willst, kannst du doch einfach > nachsehen, ob die Speicherstelle noch 0xFF hat und in diesem > Falle OSCCAL belassen, wie es ist. Belassen kann ich es nicht bei z.B. einem Mega8, den ich mit dem internen 8-Mhz-RC-Oszillator takten will, weil der für 1, 2, 4 und 8 Mhz jeweils einen eigenen RC-Oszillator mit eigenem OSCCAL-Wert hat und immer der für 1 Mhz vorgeladen wird.
Hmm, warum willst du den aber immer wieder neu beschreiben und nicht einfach nur einmal? (EESAVE-Fuse setzen.)
Du musst dafür eine neue Sektion im EEPROM anlegen. Ändern musst Du dafür: im Makefile (letzte Zeile neu + Backslash vorletzte Zeile): COFFCONVERT=$(OBJCOPY) --debugging \ --change-section-address .data-0x800000 \ --change-section-address .bss-0x800000 \ --change-section-address .noinit-0x800000 \ --change-section-address .eeprom-0x810000 \ --change-section-address .eetest-0x820000 %.eep: %.elf @echo @echo $(MSG_EEPROM) $@ -$(OBJCOPY) -j .eeprom -j .eetest \ --set-section-flags=.eeprom="alloc,load" \ --change-section-lma .eeprom=0 \ --change-section-lma .eetest=100 -O $(FORMAT) $< $@ In Deinem Sourcecode: uint8_t eeprom_test _attribute_ ((section (".eetest"))) = 0xAA; uint8_t eeprom_dummy _attribute_ ((section (".eeprom"))) = 0x80; Ich gehe von dem Beispiel-Makefile der WINAVR-Distribution aus. Die neue Sektion eetest beginnt in diesem Beispiel ab der Adresse 100(hex) (einstellbar im objcopy-Kommando --change-section-lma .eetest=100). Falls Du das elf-File mit AVRStudio verwendest: das hatt (bei mir) früher Probleme mit neuen Sektionen. Ob das in der mittlerweile neueren Version anders ist, habe ich noch nicht ausprobiert. Gruß, Stefan
Warum nicht einfach eine EEPROM-Adresse so definieren #define MyCalVal (u08*)E2END // Pointer auf's letzte Byte im EEPROM . . . if (eeprom_read_byte(MyCalVal)==0xFF) { eeprom_write_byte(MyCalVal,MyDefaultConst) } . . . OSCCAL=eeprom_read_byte(MyCalVal); // Get Calibration Value .
@Peter: Das geht natürlich auch, vor allem für diesen speziellen Fall, wo nur eine Variable benötigt wird. Allerdings sollte man beachten, dass der Compiler dabei keinen Speicher für eine Variable belegt, d.h. man ist selbst für das Speichermanagement verantwortlich (nicht wirklich ein Problem, wenn es nur eine Variable am Ende des EEPROMs ist). Gruß, Stefan
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.