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