Hallo zusammen! Ich fange gerade ein Projekt mit dem M16C von Renesas an und möchte gerne so bald wie möglich von der HEW-Entwicklungsumgebung nach GCC unter Linux umsteigen. Deshalb habe ich mir schon Binutils/GCC/Newlib für das "m32c-elf"-Target gebaut. Ich verzweifele aber im Moment an einem minimalen Programm, dass ein paar LEDs zum Blinken bringen soll. Der Code und das ausgespuckte .mot-File sehen soweit gut aus, auch der Reset-Vektor wird geschrieben. Es folgen das C-Programm und das Makefile. Vielleicht kann mir jemand von euch den entscheidenden Tipp geben: main.c: -------------------------- #define pd7 (*((unsigned char *) 0x03EF)) // port P7 direction register #define p7 (*((unsigned char *) 0x03ED)) // port P7 register void start(void); typedef void (*ifunc)(void) __attribute__((mode(SI))); const ifunc __attribute__((section(".resetvec"))) reset_vector = start; void start(void) { int i; pd7 = 0xFF; // set direction to output while (1) { p7 = 0x00; // leds off i = 1000; while (--i); // wait p7 = 0xFF; // leds on i = 1000; while (--i); // wait } } -------------------------- Makefile: -------------------------- CC = m32c-elf-gcc AS = m32c-elf-gcc OBJCOPY = m32c-elf-objcopy CFLAGS = -mcpu=m16c LDFLAGS = -mcpu=m16c -nostartfiles ASFLAGS = --m16c all: mini.mot mini.mot: mini.elf $(OBJCOPY) -O srec $< $@ mini.elf: main.o $(CC) $(LDFLAGS) $^ -o $@ clean: rm -f *.o *.elf *.mot flash: mini.mot m16c-flash /dev/ttyS0 M16C mini.mot 0:0:0:0:0:0:0 -------------------------- Die Ausgaben beim Kompilieren/Flashen sehen vielversprechend aus: $ make flash m32c-elf-gcc -mcpu=m16c -c -o main.o main.c m32c-elf-gcc -mcpu=m16c -nostartfiles main.o -o mini.elf m32c-elf-objcopy -O srec mini.elf mini.mot m16c-flash /dev/ttyS0 M16C mini.mot 0:0:0:0:0:0:0 M16C-Flash Programmer Version 0.1 Looking for M16C/R8C... Confirming...board replied with clock confirm of B0. Statusregister: 80, 60 Reading boot ROM version info... VER.4.04 Sending ID data 0: 0: 0: 0: 0: 0: 0...OK. ID verified, additional commands may now be issued. Erasing block at FC000...OK. Erasing block at FA000...OK. Erasing block at F8000...OK. Erasing block at F0000...OK. Erasing block at E0000...OK. Erasing block at D0000...OK. Erasing block at C0000...OK. Writing page C0000...OK. Writing page FFF00...OK. finished. ...aber irgendwie tut sich nichts an den LEDs. Es sieht eher so aus, als ob die entsprechenden Pins noch immer Eingänge sind... Ich verwende übrigens binutils 2.17 und GCC 4.1.1. Viele Dank, Florian
Ich kenne den Compiler, bzw. den Startup-Code für dieses Target, zwar nicht, aber fehlt Dir nicht die "main"?
Die main() heisst bei mir start() und wird über den Reset-Vektor als Einsprungspunkt nach einem Reset eingetragen. Ist die Namensgebung ein Problem? Ich hatte diese eigentlich nur gewählt, weil gcc für main() standardmäßig einen Rückgabewert erwartet (der hier ja keinen Sinn ergibt) und das Linker-Script sowieso ein _start-Symbol erwartet...
Hi, >Deshalb habe ich mir schon Binutils/GCC/Newlib für das "m32c-elf"-Target >gebaut. würdest du deine Binutils/GCC/Newlib veroeffentlichen? Ganz ehrlich gesagt sagt mir die HEW-Entwicklungsumgebung auch nicht zu und wuerde gerne den GCC dafuer benutzen. Gruß, Dirk
hallo, kenne die mcu zwar auch nicht, aber indem du deine start direkt in den reset packst, geht dir imho die ganze initialisierung verloren (stackpointer, register etc.). das kann nicht gut sein. deshalb gcc selber den reset vector eintragen lassen, und eine main verwenden. wie das bei der mcu geht, weiß ich nicht, aus eingangs beschriebenen gründen. bye kosmo
Dirk wrote: > würdest du deine Binutils/GCC/Newlib veroeffentlichen? Ganz ehrlich > gesagt sagt mir die HEW-Entwicklungsumgebung auch nicht zu und wuerde > gerne den GCC dafuer benutzen. Ich habe mich grob an die folgende Anleitung gehalten: http://www.fischl.de/thomas/elektronik/r8c/r8c_gcc.html Allerdings sind die "--program-prefix"-Zeilen unnötig und ich musste wegen eines Bugs, der zum Abbruch der Kompilation der libc führte, das GCC-Makefile patchen (hängt an). Alles andere war eigentlich relativ unproblematisch. Nur, dass ich noch kein Programm zum Laufen bekommen habe... ;-)
Hallo Florian, tut sich gar nichts oder glimmt die LED nur so vor sich hin? Ich kenne Deine Taktfrequenz nicht, aber die Zeitschleife von 1000 dürfte eine Blinkfrequenz von einigen kHz erzeugen, das Blinken wäre also nur mit einem Oszilloskop sichtbar. Gruss Mike
Florian Pose wrote: > Ist die Namensgebung ein > Problem? Für C ist main() essenziell. > Ich hatte diese eigentlich nur gewählt, weil gcc für main() > standardmäßig einen Rückgabewert erwartet (der hier ja keinen Sinn > ergibt) Ja, und? Das ist halt der C-Standard. Das ist doch nur eine syntaktische Forderung, die kannst du leicht mit
1 | int
|
2 | main(void) |
3 | {
|
4 | // Initialisierung hier..
|
5 | for (;;) { |
6 | // Code hier
|
7 | }
|
8 | return 0; |
9 | }
|
erfüllen. Der Optimizer wird dann feststellen, dass die
Endlosschleife nicht verlassen werden kann, und wird das
"return 0;" letztlich ignorieren.
Die Forderung nach einem int als Returntyp besteht übrigens
nur, wenn man ein "hosted environment" hat, in einem "freestanding
environment" (-ffreestanding) besteht sie nicht. Allerdings
verbietet man damit dem Compiler auch, allerlei Annahmen über die
Funktionen der Standardbibliothek und damit mögliche Optimierungen
zu machen. Da zeigt sich das Dilemma, dass eben embedded applications
heutzutage keineswegs nur rein als "freestanding environment"
betrachtet werden können/sollten, da die Compiler zumindest einen
Subset der C-Standard-Bibliothek anbieten, der auch im Sinne des
Standards (und damit im Sinne eines hosted environments) genutzt
werden soll.
Damit ist das Anbringen des sinnlosen returns nach der Endlosschleife
meist der sinnvollste Kompromiss.
> und das Linker-Script sowieso ein _start-Symbol erwartet...
Das sollte aber die Bibliothek (bzw. das Laufzeitsystem aus dieser)
liefern.
Jörg Wunsch wrote: > Für C ist main() essenziell. Ok, ich habe die Funktion wieder nach main() umbenannt. >> und das Linker-Script sowieso ein _start-Symbol erwartet... > > Das sollte aber die Bibliothek (bzw. das Laufzeitsystem aus dieser) > liefern. Tut es auch, wenn ich das -nostartupfiles Flag für den Linker entferne. Mein Problem ist nur, dass der vom gcc erzeugte Startup-Code erstens riesig groß ist (.mot-File > 26K, was ich aber verschmerzen könnte), und zweitens, ein _start-Einsprungspunkt zwar erzeugt wird, aber dieser nicht in den Reset-Vektor eingetragen wird. Dem kann ich mit Einfügen von folgendem Code Abhilfe schaffen:
1 | void start(void); |
2 | typedef void (*ifunc)(void) __attribute__((mode(SI))); |
3 | const ifunc __attribute__((section(".resetvec"))) reset_vector = start; |
Allerdings läuft das Programm dann nicht richtig (die LEDS blinken zwar, aber völlig zufällig ;-)). Kann ich den GCC nicht überreden, den Reset-Vektor gleich richtig zu programmieren?
Der Aufruf von "main" gehört - nach meinem Verständnis - auch nicht in den Resetvektor. Es ist Aufgabe des Startupcodes "main" auszuführen. Genauso ist es dessen Aufgabe, den Returnwert von "main" zu interpretieren - selbst wenn er diesen "verwirft"...
Ist es Dir vielleicht möglich, das komplette Projekt, ohne irgendwelche Verbiegungen irgendwelcher Vektoren, fertig Kompiliert mit allen zwischenfiles zu zippen und mal hier anzuhängen? Ich würde mir das gerne mal ansehen. Und zwar das, was sich die Entwickler des Startupcodes haben einfallen lassen...
Patrick Dohmen wrote: > Ist es Dir vielleicht möglich, das komplette Projekt, ohne irgendwelche > Verbiegungen irgendwelcher Vektoren, fertig Kompiliert mit allen > zwischenfiles zu zippen und mal hier anzuhängen? Klar. Ist angehängt... In dieser Version ist also der Reset-vektor nicht gesetzt.
Auf der "fischl"-Site ist doch ein Blinkbeispiel angeführt. Dort ist im "main.c" beschrieben, daß man eine Datei namens "reset.S" erstellen soll, die den Code für den Resetvektor enthält. Hast Du dieses Beispiel mal ausprobiert?
Patrick Dohmen wrote: > Auf der "fischl"-Site ist doch ein Blinkbeispiel angeführt. > Dort ist im "main.c" beschrieben, daß man eine Datei namens "reset.S" > erstellen soll, die den Code für den Resetvektor enthält. > > Hast Du dieses Beispiel mal ausprobiert? Ich habe es mir angesehen, und festgestellt, dass es nur für den R8C passt. Mittlerweile habe ich mein Programm zum Laufen bekommen - und zwar nicht mit nur mit dem Startup-Code der GCC (bzw. newlib/libgloss) sondern auch mit einem, den ich mir von einem Beispiel der KPITGnuTools abgeschaut habe, was dazu geführt hat, dass das .mot-File nicht 26K sondern nur <1K groß ist. ;-) Das Problem war das Flash-Programm: Der M16C-Flasher (mit R8C-Erweiterung), der auf http://www.fischl.de/thomas/elektronik/r8c/r8c_flasher.html empfohlen war, arbeitet wohl nicht ganz richtig. Mit dem M16C-Flasher von http://www.m16c-flasher.de hat es geklappt. Leider gibt es diesen nur für Windows. Mit welchen Flashern (unter GNU/Linux) arbeitet Ihr? Viele Grüße und vor allem vielen Dank, Florian
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.