Forum: Compiler & IDEs R8C: Code fortsetzen oberhalb der Vektoren?


von Soul E. (Gast)


Lesenswert?

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.

von Olaf (Gast)


Lesenswert?

> 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

von Soul E. (Gast)


Lesenswert?

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...

von Soul E. (Gast)


Lesenswert?

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.

von Olaf (Gast)


Lesenswert?

> 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
Noch kein Account? Hier anmelden.