Forum: Compiler & IDEs Gcc fuer R8c?


von Olaf (Gast)


Lesenswert?

Sagt mal Maedels benutzt hier jemand erfolgreich den GCC fuer R8c unter 
Linux?

Ich hab mir mal alles gezogen, compiliert und installiert. (neuester gcc 
und binutils)
Im Prinzip funktioniert auch alles. Ich kann problemlos Source 
uebersetzen und in den R8C laden. Solange ich mich darauf beschraenke 
nur mit einer Portleitung zu wackeln geht auch alles.

Sobald ich aber nur eine kleine Warteschleife mit einer Variable 
verwende haengt sich der Code weg. Wenn ich das richtig verstehe dann 
liegt das daran das es keine vernuenftige Initialisierung fuer den R8C 
gibt.

Hat da mal einer ein Beispiel?

Olaf

von Wolfram (Gast)


Lesenswert?

Warum überprüfst du deine Vermutung nicht erstmal an Hand der 
Assemblerlistings.
z.B. aufruf push/call ohne Stackinitialisierung
was in deiner Aufzählung fehlt ist eine Library die für etwas derartiges 
zuständig ist.

von Olaf (Gast)


Lesenswert?

Stimmt, hatte ich vergessen zu erwaehnen....

Die Libary besteht aus dem File start.s von dieser Homepage:

  http://www.ixbat.de/index.php?page_id=78

> Warum überprüfst du deine Vermutung nicht erstmal an Hand der
> Assemblerlistings.

Das ist es womit ich mir derzeit die Zeit vertreibe. Allerdings ist
das ganze doch eine recht complexe Angelegenheit. Zum Beispiel erzeugt
der Linker eine Reihe von Symbolen die garnicht genutzt werden.
Nur eines, aber offensichtlich nicht ganz unwichtiges davon ist z.B
__stack.
Allerdings fuehrt eine Aenderung von:
       ldc     #0x0400, sp     ; set user stack pointer

nach:
       ldc     #__stack, sp     ; set user stack pointer

zum totalversagen. Desweiteren kann ich eine ganze Menge fester 
Addressen im r8c.ld File finden. Ich frag mich da z.B wie das System mit 
verschiedenen R8Cs klarkommen will.

Oder anders gesagt, das System ist derzeit entweder noch an der Grenze 
zwischen unbrauchbar und Alpha-Version, oder es gibt irgendwo noch 
spezielle Anpassungen fuer den R8C von denen ich noch nichts weiss und 
die ihr mir bestimmt jetzt nennen koennt. :-)

Falls uebrigens mal eine Lust hat da reinzuschauen.
http://www.criseis.ruhr.de/R8C_Test1.tgz (230k)

Olaf

von A.K. (Gast)


Lesenswert?

Ich habe auch nicht das Gefühl von Bewegung bei dem Teil. Dass indirekte 
Funktionsaufrufe nicht reentrant sind (somit in Interrupts tabu), hatte 
ich mit dem Autor DJ Delorie schon vor 1,5 Jahren diskutiert - geändert 
hat sich zumindest in der offiziellen Version bis heute nichts.

Könnte ggf. sinnvoll sein, direkt mit ihm Kontakt aufzunehmen.

von Wolfram (Gast)


Lesenswert?

>Nur eines, aber offensichtlich nicht ganz unwichtiges davon ist z.B
>__stack.
Wildes rumprobieren mit Symbolen deren Inhalt man nicht kennt bringt 
nichts.

Wo stammt dein Makefile her ? Von der selben Seite wie der Initcode?
Irgendwo muss dem Linker mitgeteilt werden, wo die Datasection,die 
Textsection etc. sind und dies muss auch dein Initcode berücksichtigen, 
der ist nämlich dafür zuständig die vorinitialisierten Daten an ihren 
vorbestimmten Ort im Speicher zu bringen, den Stackpointer zu setzen und 
den Prozessor in einen Zustand zubringen, das in Main weitergemacht 
werden kann. Unter diesem Aspekt solltest du das Assemblerlisting und 
die Mapping-Datei prüfen. Wenn du damit Probleme hast, wäre eine 
Distribution vielleicht besser, da bei ihr schon alles passt. Du willst 
doch C programmieren und nicht eine C-Entwicklungsumgebung erstellen?

von Olaf (Gast)


Lesenswert?

> Wildes rumprobieren mit Symbolen deren Inhalt man nicht kennt
> bringt nichts.

Naja, wieso kenn ich den Inhalt nicht? Das wird doch im r8c.ld 
beschrieben.
Allerdings passt wohl das start.s File nicht mit dem File zusammen. Da 
dort ein eine andere Position fuer den Stack angeben wird als im r8c.ld.
Ich vermute mal das liegt daran das ich jeweils den neuesten Source fuer 
Compiler, bintutils, newlib usw. genommen habe und das File von der 
Homepage von jemanden stammt der alles eine Nummer aelter hatte.


> Wo stammt dein Makefile her ? Von der selben Seite wie der Initcode?

Noe, das stammt aus meinen kreativen Fingern. :-) Allerdings habe ich da 
ein bischen was abgekuckt.

> Irgendwo muss dem Linker mitgeteilt werden, wo die Datasection,die
> Textsection etc. sind und dies muss auch dein Initcode berücksichtigen,
> der ist nämlich dafür zuständig die vorinitialisierten Daten an ihren
> vorbestimmten Ort im Speicher zu bringen, den Stackpointer zu setzen und

Ich weiss das dies normalerweise so ist. Aber auf der benannten Homepage 
wurde das mit "-nostartfiles" unterdrueckt weil sonst der Source 
explodiert und nicht mehr in einen R8C passt. Das ist auch jetzt noch 
so. Vielleicht mache ich ja auch einfach nochwas in meinem Makefile 
falsch. Deshalb waer ich ja ein fertiges Hello-World Project fuer die 
aktuelle Compilerversion interessiert. Allerdings konnte ich bis jetzt 
noch nichts finden. Es scheint wirklich niemand damit zu arbeiten. 
Deshalb ja meine Theorie das dies noch alles nicht richtig funktioniert.

> die Mapping-Datei prüfen. Wenn du damit Probleme hast, wäre eine
> Distribution vielleicht besser, da bei ihr schon alles passt. Du willst
> doch C programmieren und nicht eine C-Entwicklungsumgebung erstellen?

Ich habe keinen fertigen Compiler fuer den R8C gesehen, ausserdem muss 
sich der ja auch in mein System einfuegen und ich benoetige zusaetzlich 
noch Crosscompiler fuer M16C, Avr, Arm und 68k. Von daher hat sich das 
selber aufsetzen angeboten.
Und wenn alles laeuft koennte ich es nochmal fuer Arm als Host 
uebersetzen und unterwegs auf meinem Zaurus Programme fuer den R8C 
entwickeln. :-)

Olaf

von Wolfram (Gast)


Lesenswert?

Probiers mal mit:
www.kpitgnutools.com

von Olaf (Gast)


Lesenswert?

> Probiers mal mit:
> www.kpitgnutools.com

Aufgeben? Und was kommt dann als naechstes? Die WinXP (ausspuck) 
Installation? :-)

So langsam komm ich der Sache auf die Schliche. Hauptursache des Problem 
ist mein sfr_r813.h File. Ich hatte das einfach von Renesas 
rueberkopiert, aber das file gibt es in verschiedenen Versionen. Ich 
hatte die neuste hier  in der es eine Menge #pragma Anweisungen gibt. 
Das fuehrt dazu das der gcc ohne einen Fehler auszugeben vollkommen 
falsche Register beschreibt.

LED an und ausschalten funktioniert nun immer zuverlaessig. Jetzt noch 
Stack initialisierung, und die Variablen aus dem Flash in Ram kopieren 
und es sollte eigentlich laufen.

Olaf

p.s: Folgendes hilft ungemein bei der Fehlersuche:
m32c-elf-objdump -C -g -h -l -S -t -d start.elf >program.asm

von Olaf (Gast)


Lesenswert?

Nach dem ich gerade noch einen fetten und sehr aegerlichen Bug
gefunden habe, habe ich den Compiler jetzt laufen. :-)

Den will ich der Nachwelt natuerlich nicht vorenthalten...

Im r8c.ld file wird folgende Annahme gemacht:

  RESETVEC (r) : ORIGIN = 0xfffc, LENGTH = 4

Das ist aber falsch. Der Resetvektor bei den R8C ist nur 16Bit und nicht
32Bit. Trotzdem wird er aber spaeter vom Linker dort 32bittig 
reingeschrieben.
Danach stehen sogar die richtigen Werte im Resetvektor, aber die beiden
Highbytes ueberschreiben dann 0xfffe und 0xffff mit 0x00. Nun ist aber
leider 0xffff das OFS Register. Auf diese Weise wird leider der Watchdog
eingeschaltet.

Besonders fies ist das vor allem deshalb weil man das erst garnicht 
merkt
wenn man ein Testbord mit Brennadapter am Rechner stecken hat. Man kann
in OFS naemlich reinbrennen was man will, das Byte wird auch bei einem
Reset der CPU ueber den Reseteingang nicht uebernommen. Erst wenn die
CPU einmal wirklich ohne Strom war wirkt sich das aus und das Programm
haengt sich dann immer nach kurzer Zeit weg wenn der Watchdog 
zuschlaegt.

Olaf

von Stefan (Gast)


Lesenswert?

Wo stammt denn dein r8c.ld File her?

von Olaf (Gast)


Lesenswert?

Das gehoert entweder zum Compiler, zu den binutils, newlib oder 
libgloss. Jedenfalls hat es sich irgendwie bei meiner compilierung und 
installation in /usr/local/m32c-elf/lib materialisiert.
Ich habs mir jedenfalls nicht extra irgendwo besorgt.

Olaf

von Stefan (Gast)


Lesenswert?

Ja, klar, aber wo hast du das Gesamtpaket, wie sagst du, "gezogen"?
Bei www.kpitgnutools.com ja anscheinend nicht.

von Olaf (Gast)


Lesenswert?


> Ja, klar, aber wo hast du das Gesamtpaket, wie sagst du, "gezogen"?

Ich bin im Prinzip nach dieser Anleitung vorgegangen:

 http://www.fischl.de/thomas/elektronik/r8c/r8c_gcc.html

Bloss das ich halt jeweils die neueste Soft genommen habe.

Also von hier: http://ftp.gnu.org/gnu/binutils/
               http://sources.redhat.com/newlib/
               http://gcc.gnu.org/

> Bei www.kpitgnutools.com ja anscheinend nicht.

Noe, von dort nicht.

Ich hab uebrigens gerade mal ein groesseres Project (Ansteuerung
eines Grafikdisplays mit SED1520 am SPI-Port) das ich fuer den
Compiler von Renesas geschrieben habe neu uebersetzt.
Lief auf anhieb. Lediglich eine Definition hat der gcc im sfr_r813.h
angemeckert, die musste ich noch nachtragen.
Das finde ich in sofern bemerkenswert weil ich das sehr mit dem Ram 
rumhampel da ich ein Schattenregister des Grafikdisplays verwalten muss.
Ich haette nicht gedacht das die Compiler SO kompatible sind.

Olaf

von Olaf (Gast)


Lesenswert?

Gerade kam uebrigens eine Email from DJ Delorie rein.

Er schreibt das die Vektoren 20Bit gross sind. Womit er auch recht hat,
Renesas hat da wohl noch einen Druckfehler in ihrem Softwaremanual da 
sie dort schreiben: Reset FFFFC(16) Was etwas verwirrend ist.

Trotzdem ist 20 natuerlich weniger wie 32. Er schlaegt daher folgende 
Loesung vor:

> If you know your start address is in the first 64k, you can do this:
>
>       .section ".resetvec"
>       .short  _start
>       .byte   0
>       .byte   0xff

Olaf

von Olaf (Gast)


Lesenswert?

Vielleicht interessiert es ja jemand das DJ Delorie gerade einen
Patch fuer den gas gepostet hat:

        * config/tc-m32c.c (md_pseudo_table): Add .3byte.

Damit kann man dann 24bit definieren und das Problem korrekt loesen.

Interessant das wir dafuer keinen eigene Begriff haben. Ich haette es
ja .triple genannt. .-)

Olaf

von Sebastian V. (fogman)


Lesenswert?

Hallo Olaf,

ich beschäftige mich seit kurzer Zeit mit dem R8C.
Leider bekomm ich das Problem mit dem Watchdog nicht gelöst, was 
wiederrum das benutzen der UART1 unmöglich macht.
Kanst Du mal bitte deine Lösung (oder ein Beispiel bzw. start.s) posten?
Bei mir sind die neuesten Tools (binutils, gcc, newlib usw. aus CVS 
Stand 02.02.2007) installiert.

Danke im Vorraus.

von Sebastian V. (fogman)


Lesenswert?

Hallo,

mit dem binutils cvs checkout von Gestern funktioniert nun auch die 
Definition des .3byte  richtig.

von Olaf (Gast)


Lesenswert?

Mein start.s sieht so aus:
        .section ".resetvec", "a"
                .short  _start  ; Startadresse nach einem Reset
                .byte   0       ; Fuellbyte
                .byte   0xff    ; Watchdog ist abgeschaltet


        .text
                .global _start
                .type _start, @function
_start:

                ldc     #__stack, sp ;  set user stack pointer
;               ldc     #0x0000,isp  ;  Set Interupt stack pointer

        ;; Loeschen der Variablen
                mov.b   #0x00, r0l
                mov.w   #__bssstart, a1
                mov.w   #__bsssize, R3
                sstr.b

        ;; Kopieren von Variablen aus dem Rom ins Ram
                mov.w   #__romdatastart,a0
                mov.b   #0x00,r1h ; Stimmt das? Noch pruefen!
                mov.w   #__datastart,a1
                mov.w   #__romdatacopysize , r3
                smovf.b

                jsr.w   _main   ;  go to main in main.c

loop:
                jmp.w loop



Wie man sieht war ich noch zu faul auf die neueste Version mit 3byte 
upzudaten. :-)

Ausserdem an den Stackpointer denken wenn man IRQs benutzt...

Ich schalte auch nicht auf den externen Quarz um! Wenn ich das brauche
dann mache ich das im C-Programm.

Olaf

von Olaf (Gast)


Lesenswert?

Und ehe ich es vergesse....

Vergiss einen Blick in dein  /usr/local/m32c-elf/lib/r8c.ld
zu werfen:

        RAM (w) : ORIGIN = 0x500, LENGTH = 0x300
        ROM (r) : ORIGIN = 0xe000, LENGTH = 0x3f24  /* Fuer R8C13 mit 
16kb Rom */

Olaf

von Peter S. (Gast)


Lesenswert?

Hallo,

habe vor kurzem mein R8C-Glyn-Board in Betrieb genommen,
nachdem es ein Jahr lang herumgelegen hat. Als Basis
habe ich das R8C-Ctrl-Board von
http://mikrocontroller.cco-ev.de/de/R8C13-Ctrl.php
verwendet.

Das R8C-Ctrl hat eine spezielle Beschaltung, um mit dem
DTR- bzw. RTS-Signal der seriellen Schnittstelle MODE bzw.
RESET aktivieren zu können. Diese Beschaltung führt zur
Auslösung eines Voltage Detection Interrupts über den
Power-On Reset (siehe Hardware Manual Kapitel 5.1.3.),
was zur Folge hat, daß das Programm nicht richtig
anläuft, wenn der isp nicht initialisiert wird und die
Interrupt Vector Table nicht angelegt wird.

Ich habe den Anfang meines crt0.S deshalb dem Original von
Renesas (ncrt0.a30) nachempfunden:

        .text
        .global _start

_start:
  ldc     #__istack, isp  ; set interrupt stack pointer

  mov.b  #0x02, 0x0a  ; PM0, PM1 protection off
  mov.b  #0x00, 0x04  ; set processer mode
  mov.b  #0x00, 0x0a  ; PM0, PM1 protection on

  ldc  #0x0080, flg  ; select user stack pointer
  ldc  #__stack, sp  ; set stack pointer

  ...

Wozu der Zugriff auf das Processor Mode Register 0 (PM0)
erfolgt, habe ich allerdings nicht in Erfahrung bringen
können.

Weiterhin habe ich die RESETVEC-Section aus dem Linker-Skript
entfernt und dafür die VEC-Section um 4 Bytes vergrößert.
Die Vector Table inklusive einem "Dummy Interrupt Handler"
sieht dann folgendermaßen aus:

  ;; dummy interrupt handler
_dih:  reit

  ;; ---------------------------------------------
  ;; Vector Table Section
  ;; ---------------------------------------------

  .section ".vec", "a"

  ;; ID = 00:00:00:00:00:00:00
  ;; (see R8C Hardware Manual p. 164)
  .equ  ID_1, 0x00
  .equ  ID_2, 0x00
  .equ  ID_3, 0x00
  .equ  ID_4, 0x00
  .equ  ID_5, 0x00
  .equ  ID_6, 0x00
  .equ  ID_7, 0x00

  .short  _dih    ; undefined instruction
  .byte  0x00
  .byte  ID_1

  .short  _dih    ; overflow
  .byte  0x00
  .byte  ID_2

  .short  _dih    ; BRK instruction
  .short  0x00

  .short  _dih    ; address match
  .byte  0x00
  .byte  ID_3

  .short  _dih    ; single step
  .byte  0x00
  .byte  ID_4

  .short  _dih    ; watchdog timer,
  .byte  0x00    ; osc. stop detection,
  .byte  ID_5    ; voltage detection

  .short  _dih    ; (reserved)
  .byte  0x00
  .byte  ID_6

  .short  _dih    ; (reserved)
  .byte  0x00
  .byte  ID_7

  .short  _start    ; reset
  .short  0x00

  ;; newer binutils snapshots support this:
  ; .byte3  _dih
  ; .byte    ID_1
  ; .byte3  _dih
  ; .byte    ID_2
  ; ...


Gruß,
Peter

von Soul E. (Gast)


Lesenswert?

Auch wenn der Thread schon ein paar Tage alt ist, hier noch ein Hinweis:

>   mov.b  #0x02, 0x0a  ; PM0, PM1 protection off
>   mov.b  #0x00, 0x04  ; set processer mode
>   mov.b  #0x00, 0x0a  ; PM0, PM1 protection on

Das muss man beim M16C machen, der kennt einen Processor Mode (mit 
Adressbus) und einen Controller Mode (mit internem ROM). Beim R8C, 
zumindest beim R8C/34E, geht das böse daneben.

In dem von KPIT mitgelieferten startup.asm für den R8C/35A stehen diese 
Zeilen auch drin. Ich hatte eine Interrupt-Routine definiert, die von 
Timer 0 zyklisch aufgerufen wurde. Da stand nichts besonderes drin, es 
wurde nur eine Variable hochgezählt. Im Debug-Mode mit E8a lief das 
einwandfrei. Im Run-Mode, also geflashed und fertig, wurde die Routine 
genau einmal aufgerufen und danach nie wieder. Irgendwann bin ich auf 
die Idee gekommen, diese drei Zeilen auszukommentieren und den Zugriff 
auf das lt. Datenblatt überhaupt nicht existente Register zu 
unterlassen. Danach lief es.

Auf Adresse 0x00004 scheint der R8C irgend eine interne Funktion liegen 
zu haben, eine Testroutine oder ein Debug-Register. Also Finger weg 
davon!

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.