Der Renesas R8C hat einen durchgehenden ROM-Bereich, in dessen Mitte sich jedoch die (nicht verschiebbaren) Interrupt-Vektoren befinden. D.h. 0x04000-0x0FEDB darf ich benutzen, und 0x10000-0x13FF. Der Linker kennt eine .text-Section, die bei 0x04000 beginnt, daran schließt sich .rodata an. Der Bereich oberhalb 0x10000 hat den Namen .frodata. Nun hat mein Programmcode die 48k-Grenze überschritten und der Linker meckert, dass die für die Interruptvektoren vorgesehene Section überschrieben wird. Wie sage ich dem Ding, dass es bei 0x0FEDB aufhören und bei 0x10000 weitermachen soll? Gibt es eine Möglichkeit, bei einzelnen Funktionen oder String-Konstanten ("const u08 text[] = ...") anzugeben, dass sie in die .frodata-Section gepackt werden sollen? Ich verwende KPIT GNUM16CM32C v11 mit der Renesas HEW.
> sich jedoch die (nicht verschiebbaren) Interrupt-Vektoren befinden. D.h. > 0x04000-0x0FEDB darf ich benutzen, und 0x10000-0x13FF. Ach tatsaechlich? Ist mir noch garnicht aufgefallen. Meine Programme waren bisher wohl immer kleiner... Das folgende ist jetzt theoretisch weil ich immer den Renesascompiler unter HEW genutzt habe, oder gcc mit make. > Der Linker kennt eine .text-Section, die bei 0x04000 beginnt, Der Linker kennt jede Section die du ihm im Linkerscript definierst. Unter HEW sollte dieses Script von HEW aus der Oberflaeche raus erzeugt werden. Mit anderen Worten du kannst dort in einem der Menues angeben welche Section du an welcher Stelle haben willst. Dort muesste irgendwo den .frodata stehen und dort solltest du auch andere Sections einrichten koennen. > Gibt es eine Möglichkeit, bei einzelnen Funktionen oder > String-Konstanten ("const u08 text[] = ...") anzugeben, dass sie in die > .frodata-Section gepackt werden sollen? Ja sowas gab es. Allerdings wird das wahrscheinlich Compilerspezifisch sein. Du solltest dich also eher an die Doku vom gcc orientieren. Was auf jedenfall gehen sollte das du eine Section fuer alle Strings in den oberen Bereich legst. Ausserdem kennt der Renesascompiler ja far und near. Ich weiss jetzt nicht ob und wie das der gcc unterstuetzt. Es kann sein das er immer far erzeugt. Das solltest du aber auch mal ueberpruefen. Olaf
Habe etwas herumexperimentiert. 1) wenn ich eine Konstante so deklariere
1 | __attribute__((section(".frodata"))) |
2 | const u08 helptext10M[] = "\r\n\nUsbWidEx V" VERSN\ (...) |
wird sie in den .frodata-Bereich verschoben. Das funktioniert schonmal. Jetzt mache ich folgendes:
1 | serial0_WrStr((u08 *)helptext10M); |
mit der Funktion
1 | // send bytes at * until NULL
|
2 | void serial0_WrStr(u08 *ascii) { |
3 | while (*ascii) serial0_WrChar(*ascii++); |
4 | }
|
Das funtioniert problemlos mit Konstanten im .rodata, bei Definition im .frodata wird aber nur Müll ausgegeben. Mache ich da was falsch bei der Parameterübergabe, oder ist das ein generelles Problem? Mit "near" und "far hast Du mir zwei Stichworte gegeben, da habe ich Google drauf angesetzt. Es gibt also Pointer mit 16 bit und mit 24 bit, und Datenpointer scheinen immer 16 bit zu haben (http://gcc.gnu.org/ml/gcc/2003-10/msg00842.html). Wenn dem so ist, dann müssten Konstante und aufrufende Funktion im gleichen 64k-Bereich liegen. Werde ich mal testen. Aber warum ist das so? Das ist doch eine Neumann-Architektur, da sollte man Speicher lesen können wo man will? 2) ich habe eine Section ".ftext" deklariert, die hinter .frodata liegt. Wenn ich nun vor eine Funktion __attribute__((section(".ftext"))) schreibe, wird sie in den .ftext-Bereich verschoben. Dort scheint sie auch zu funktionieren, d.h ich kann sie von "unten" aufrufen und sie kann auch auf unten liegende Bibliotheken zugreifen. Kann ich dieses Attribut auch irgendwie dateiweise vergeben, d.h. für einen kompletten c-file? Oder muss das wirklich an jede einzelne Funktion dran? Mit Assembler war das einfacher. Einmal "org", und man wusste wo die Bytes hinkommen...
Update: Zugriff auf Konstanten in .frodata (also >0x10000) funktioniert auch dann nicht, wenn der zugreifende Code in .ftext, also im gleichen 64k-Bereich liegt. Konstanten müssen also immer in den unteren 64k sein.
> liegen. Werde ich mal testen. Aber warum ist das so? Das ist doch eine > Neumann-Architektur, da sollte man Speicher lesen können wo man will? Noe. Das was man addressieren kann haengt davon ab wie gross die Register sind und welchen Aufwand man treiben will. Der Compiler von Renesas unterstuetzt far/near deshalb weil 90% der Programme mit 64kb oder weniger auskommen. Immerhin sind die R8C-M16C jetz ja bestimmt so >10Jahre alt und hatten damals nur 20-32kb Flash. Und wenn man dann durchgaengig near benutzt spart das Flash und der Code ist etwas schneller. Es kann aber sein das der gcc kein far bei diesem Prozessor unterstützt. Ich glaube der hat so seine Probleme mit den 24Bit. Wie schon gesagt, fuer mich war das nie ein Problem. Aber ich meine da auch mal drauf gestossen zu sein. Allerdings habe ich mir den Compiler selber uebersetzt. Das KPIT Zeugs wird ja von Renesas irgendwie finanziert. Es koennte sein das die da was verbessert haben. Schreib denen doch mal eine Email und berichte hinterher. Du kannst ja auch mal DJ Deorie fragen. Ich meine der hat mir da auch schonmal was zu erzählt. Und kuck dir mal meinen Multitasker dazu an. (Source hab ich hier mal abgelegt) Ich glaube damals bin ich da auch drauf gestossen. Ich glaube der gcc hat ein umständliches Verfahren (trampolin) genutzt um seine Funktionen aufzurufen. Olaf
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.