Hallo, der Betreff sagt eigentlich schon alles. Ich möchte ein 512Byte großes, konstantes Array (Daten werden während der Laufzeit nicht geändert) in einem 512Byte großen EEPROM speichern. Leider mag das mein Linker nicht so recht. Ich erhalte folgende Fehlermeldung, welche darauf schließen lässt, dass neben den 512Byte Nutzdaten noch irgendwelche Infos über das Array abgespeichert werden. Wenn ich das Array um ein Element verkleinere, funktioniert es. ***************** Error[e16]: Segment EEPROM_I (size: 0x200 align: 0) is too long for segment definition. At least 0x1 more bytes needed. The problem occurred while ... ***************** Sollte das mit den Zusatzinfos stimmen? Wie kann ich das Problem umgehen? Hat jemand eine Idee. Das Array liegt zur Zeit im FLASH, soll aber aus Optimierungsgründen ins nicht verwendete EERPOM. RAM kommt selbstverständlich auch nicht in Frage. ;o) Ich könnte natürlich 256 einzelne Variablen ins EEPROM legen und einen Zeiger vom FLASH aus darauf richten. Aber vielleicht kann ich mir die Schreibarbeit auch sparen(?). Kurzinfo über die verwendete Hard-/Software: ATMega88, IAR Compiler, IAR Embedded Workbench. Hoffe auf Hilfe. Danke! Gruß ewigerstudent74
Hallo Kurt, nö, bin mir sicher, dass es 512 Byte sind. Die Deklaration sieht in etwa so aus: unsigned short __eeprom ucArr[256] = { ... Hier stehen 256 2Byte-Werte ... }; Ein "unsigned short" belegt hier 2 Byte => 2Byte x 256 = 512Byte. Noch 'ne andere Idee? Gruß ewigerstudent74
1 Byte zu wenig? das ist komisch.... Hätte ja sein können dass das Array von 0...256 geht, dann wärns aber 514 Bytes gewesen. Also müsste der Compiler 2 Bytes zuviel melden.. kratz ?
Hallo, unelegante Lösung: Du könntest doch einfach eine kleine Schleife schreiben die Dir die Arraywerte einzeln vom Flash ins Eeprom kopiert und danach die Eeprom-nicht-lösch-fuse setzen...
Hallo Erwin, das kommt auch nicht in Frage. Würde ich in dieser Applikation eine EEPROM-Schreibroutine verwenden, müsste ich aus Sicherheitsgründen einen EEPROM-Handler einsetzen => Ist technisch und "finanziell" nicht vorgesehen. Gruß ewigerstudent74
Du weißt aber schon, daß bei Verwendung des EEPROM unbedingt das Brownout eingeschaltet werden muß ! In früheren AVRs war der EEPROM sehr unzuverlässig und besonders die Adresse 0x00. Kann sein, daß deshalb der Compiler erst bei Adresse 0x01 anfängt und deshalb genau ein Byte fehlt. Peter
könnte es sein, das dieses Array erst ab Adresse 0x0001 beginnt ? schau mal in das map des Linker bzw. in das HEX-File des EEPROM.
Kann sein das der erste hex wert eines arrays seine länge definiert ?? wenn so dann fehlen dir 2 bytes (2byte Len ; 2* 0-FF =256*2 =512 also der array als hex dump hat 514 bytes) Da du weist wie gross er ist köntest die erste zwei bytes sparen...my 2 cents
Könnte es nicht sein, dass das erste Byte im eingebauten EEPROM nicht für solche Sachen nutzbar ist ? Ich meine, sowas mal gelesen zu haben !
Probier mal folgende Deklaration: __eeprom __no_init unsigned char test[512] @ 0x00; Meine IDE (IAR) hat compiliert und gelinkt ohne Fehler; MW
Hallo an alle, danke für die tollen Tipps. Es war in der Tat so, dass der Linker das Array erst ab Adresse 0x001 angelegt hatte. Mit "@ 0x0" habe ich das Problem behoben. Atmel hatte bei ihren ersten AVRs das Problem, dass die Adresse 0x000 des EEPROMS teilweise defekt war. Deshalb gab es diesen Workaround von IAR. Jetzt ist aber etwas anderes "tolles" passiert. Bei dem Array handelt es sich ja um ein statisches Array, also ist es vorinitialisiert. Bei einem Blick ins EEPROM musste ich aber festellen, dass da nur Schrottwerte drin standen. Verkleinert man das Array auf 127 Werte (127 x 2Byte), dann wird korrekt initialisiert. Was ist denn nun noch korrupt? Gruß ewigerstudent74
Lies Dir trotzdem im Datenblatt "Preventing EEPROM Corruption" durch. Ich würde aber lieber den Mega168 nehmen, statt Konstanten im EEPROM abzulegen. Peter
P.S.: Es ist ein Irrtum zu glauben, die Daten im EEPROM sind sicher, wenn im Programm gar keine Schreibroutine ist. Sie sind gleich unsicher ohne den Brownout. Peter
Hallo Peter, auf die Wahl des Controller habe ich keinen Einfluss mehr. Aber irgendwie habe ich das nicht verstanden. Ich dachte, der Brownout macht nur Sinn, wenn ins EEPROM geschrieben wird? Können sich die Daten im EEPROM bei Leseoperationen, Shutdowns oder irgendwelchen Umwelteinflüssen ändern? Das Setzen des Brownout-Fuses wäre in meiner Applikation aber sicherlich möglich. Gibt es noch eine Idee zum oben beschriebenen Problem (mein letzter Thread) mit den korrupten Intial-Werten? Gruß ewigerstudent74
Irgendwo im Netzteil hast Du einen dicken Elko, der sich nach dem Abschalten ganz langsam entlädt. Und irgendwann reicht die Spannung für die CPU nicht mehr aus, um einwandfrei zu arbeiten und sie macht nur Unsinn. Sie kann z.B. einen Befehl falsch dekodieren, z.B. als Schreiben des EEPROM, obwohl ein solcher nicht im Flash steht. Der Brownoutreset soll nun die CPU im Reset halten, wenn beim Einschalten die VCC noch zu klein ist bzw. beim Auschalten langsam zu klein wird. "auf die Wahl des Controller habe ich keinen Einfluss mehr." Der 168 ist doch ein 88, nur eben mit doppelt Flash. Peter
>> Der 168 ist doch ein 88, nur eben mit doppelt Flash.
Ja, aber der ist auch teurer. Wir reden hier von späteren Serienteilen.
Da lassen wir lieber den Herrn Softwareentwickler ein paar Stunden mehr
schaffen und nehmen dafür den 2 Cent billigern µC. ;o)
Hallo, ich habe gerade die Lösung für das Problem mit den fehlerhaften Initial-Werten im EEPROM gelöst. In den Release Notes des AVR-Studios habe ich unter "Updates" folgenden Eintrag entdeckt: "- Large EEPROM arrays/structures in UBROF object files were incorrectly loaded." Nach dem Einspielen des Servicepacks 3 verläuft die Initialisierung nun korrekt. Gruß ewigerstudent74
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.