|
 |
 |
 |
|
|
c't Projekte - c't-Bot und c't-Sim -
Mailinglisten
[Voriger (Datum)]
[Nächster (Datum)]
[Voriger (Thread)]
[Nächster (Thread)]
[Nach Datum][Nach Thread]
Absender: Timo Sandmann
Datum: Fr, 09.03.2007 17:44:02
In-reply-to:
<45F1511A.2060709@xxxxxxxx>
References:
<BCF016D5ED5AC34FBB655D109519ABCF083EBE@xxxxxxxxxxxxxxxxxxxx> <45ED3B46.4030400@xxxxxx> <45EF385C.3080609@xxxxxx> <A2ED0A68-A8F1-438A-B1E3-18033ED489E3@xxxxxxxxxxxxxxx> <45F135B9.5030203@xxxxxx> <45F14847.3060907@xxxxxxxx> <45F1491C.2020201@xxxxxxxx> <45F1511A.2060709@xxxxxxxx>
Hallo,
Am 09.03.2007 um 13:20 schrieb Benjamin Benz:
Hallo,
ein weiterer Nachtrag:
objcopy funktioniert wie gedacht. Ein objdump -h FILENAME zeigt die
Resultate.
Allerdings ignoriert der Linker auf dem PC wohl noch die sections.
Dazu
muss man laut http://geek.vtnet.ca/doc/initcall/kernel.html das
Linker-Script anpassen. Das ist mir aber noch nicht gelungen und ich
komme vorerst auch nicht dazu. Vielleicht hilft es aber weiter.
folgendes funktioniert bei mir für's Target PC (und für MCU natürlich
weiterhin wie schon immer):
In global.h:
#ifdef MCU
#define EE_SECTION ".eeprom"
#else
#define EE_SECTION ".eeprom,#alloc"
#endif
Variablen-Deklaration (Beispiel):
uint8 __attribute__ ((section (EE_SECTION))) err15=1;
Linker- und Compiler-Settings nicht verändert.
Post-Build-Step:
objcopy -j LC_SEGMENT..eeprom --set-section-
flags=LC_SEGMENT..eeprom="alloc,load" --change-section-lma
LC_SEGMENT..eeprom=0 ct-Bot.elf ct-Bot.eep -O ihex
Die Optionen scheinen mir architekturabhängig zu sein, das ließe sich
aber ja im #define / Postbuild-Step anpassen.
Damit wird jedenfalls auch für Target PC eine eep-Datei erzeugt, die
den gleichen Inhalt hat wie die, die für Target MCU erzeugt wird. Es
gibt dabei aber noch ein Problem: Der PC-Compiler richtet ein Array
(Variablen mit mehr als 8 Bit vermutlich auch, wenn sie ungünstig
"liegen") wohl so aus, dass es in eine L1-/L2-Cache-Line passt => vor
einem uint32 data[10], das nicht an Adresse 0x0 beginnt z.B. wird die
Section mit einigen Nullen aufgefüllt. Der AVR-Compiler macht das
natürlich nicht (wäre ja auch sinnlos), folglich stimmen die Adressen
in der eep-Datei so nicht überein. Das lässt sich aber verhindern,
indem man als Attribut noch aligned (1) anhängt, zumindest bei Arrays
und Variablen > 1 Byte.
Einziger bleibender Unterschied: Die MCU-eep-Datei enthält nur die
wirklich belegten Daten, die PC-eep-Datei ist bei mir nach den
eigentlichen Daten noch bis Byte-Adresse 0xFFF mit Nullen aufgefüllt
(=> Pagesize?). Ob man das abstellen kann, weiß ich grad nicht =>
Hallo GCC-/GNU-Profis? ;-) Das ist aber eigentlich kein größeres
Problem, außer man möchte die PC-eep-Datei mit avrdude ins EEPROM
schreiben, das geht nicht, wenn man sie als ihex-Format erzeugt. Als
bin-Format geht's (scheinbar ist avrdude dann die Größe egal, denn es
sind nach wie vor 4 KB). Das Übertragen dauert dann allerdings recht
lange, weil avrdude das komplette EEPROM beschreibt (2 KB). Man kann
auch einfach die restlichen (Null-)Bytes aus der eep-Datei löschen,
funktioniert genauso, nur müsste man dafür die Größe ohne die
angehängten Nullbytes kennen, gibt's da vielleicht irgendwie so einen
Shell-Trick dafür, den man einfach an das Postbuild dranhängt?
Ich denke sonst steht der EEPROM-Emulation am PC mit dynamisch
vergebenen Adressen durch den gcc eigentlich nichts mehr im Wege. :)
Na ja soweit erstmal meine Erkenntnisse zu diesem Thema.
Viele Grüße und ein schönes Wochenende,
Timo
|
|
|