Hi Ich habe ein kleines ARM-Problem, von dem ich als ARM-Neuling leider nicht sagen kann woran es liegt. Ich habe mir ein Evaluationsboard von Olimex mit AT91SAM7S64 und passendem Wiggler-kompatiblen-JTAG gekauft. Das funktioniert auch mit dem passenden Beispiel ganz hervorragend, nur mein erstes eigenes Programm will nicht so ganz. Ich verwende die YATARGO-IDE und lade meine Programme per OpenOCD auf den ARM. Symptome: Das einfache Programm, das eigentlich 2 LEDs zum leuchten bringen soll, wird scheints gar nicht ausgeführt, sprich die LEDs leuchten nicht. Komisch: Wenn vorher ein Beispielprogramm auf dem ARM war, funktioniert es. Ich vermute entweder, dass ich Mist beim Programmieren gebaut habe, oder das was im Makefile nicht stimmt (-> Linkerscript?!). (Davon habe ich erst seit ich mit den ARMs beschäftige Kontakt, beim AVR macht das ja das Studio). Ich habe hier mal das gesamte Projekt auf meinen Webspace geladen: http://www.tobias-schlegel.de/PublicData/test2.zip Leider finde ich keine Tutorials, die die Sache mit dem Tiefgang beleuchten, den ich gerne hätte. Deshalb bitte auch nicht erschrecken: Ich versuche die ARM-CPU zu verstehen, und nicht Bibliotheken einzubinden. Für Hilfe wäre ich wirklich sehr dankbar. Viele Grüße, Tobi
Hallo, irgendwie scheint OpenOCD mit dem Wiggler murks zu sein. Bei mir wurde das Programm zwar geladen und ausgeführt, aber wenn ich die Spannung wegnahm, war auch das Programm weg. Dann habe ich H-JTAG verwendet und dann ging es problemlos: http://www.hjtag.com/
Hi, Ok, ich habe das gerade mit dem Beispiel getestet, und das bleibt im Speicher, selbst wenn keine Betriebsspannung dran ist. Es fängt ja auch garnicht mit Ausführen an, wenn ich es hochlade. Was vielleicht noch zu erwähnen ist: Beim Compilieren gibt es keinerlei Warnungen o.ä.. Das HJTAG sieht sehr gut aus, ich werd das mal genauer unter die Lupe nehmen... VLG Tobi
Hallo Tobias, das Projekt sieht ziemlich verstümmelt aus. Dein main.out (und damit auch main.bin) enthält nur die main() Funktion, der Startup Code aus crt.S fehlt. Hat es einen Grund, dass du das Linker Skript im Makefile auskommentiert hast? @Steven: Sorry, aber das ist ein Piloten-Fehler... Wenn das Programm nach Wegnehmen der Spannung nicht mehr im Speicher ist hattest du es nie im Flash, sondern nur im RAM. Der OpenOCD funktioniert wunderbar mit einem Wiggler, allerdings verlangt eine GNU Toolchain mit dem OpenOCD mehr Einarbeitungszeit als eine Lösung mit IAR/Keil/... und H-JTAG. Gruß, Dominic
Hi Oooops. Ja, das war auskommentiert weil ich erst einen anderen Linkerscript hatte... der dann nicht funktioniert hat etc. Jetzt sollte es stimmen... http://www.tobias-schlegel.de/PublicData/test2.zip Der Startup-code. Das sollte eigentlich meine main() machen, weil die ja die Clocks etc. initialisiert. Die crt.s ist eigentlich auch nur zu Testzwecken da... Oder liege ich dahingehend total falsch und man braucht immer einen Startup-Code? Wenn ja: Wie kann man ihn einbinden, und wozu braucht man das überhaupt? Der AVR braucht das ja auch nicht...?? Oder? Danke! VLG Tobi
Schau dir mal die Beispielcodes von Martin Thomas an. http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/index_at91.html Damit hab ich es auch relativ schnell hinbekommen von AVR auf ARM umzusteigen.
HI Ja, ich habe diese Beispiele gesehen, ich bin gerade dabei das Beispiel fürs PIO nachzuprogrammieren, aber ich hab den Ehrgeiz das ohne fertig-Funktionen zu schaffen. Theoretisch sollte es jea eigentlich funktionieren. Ich hoffe auf den Startupcode... ;) VLG Tobi
Hallo Tobi, irgend eine Form von Startup-Code brauchst du immer. Ich habe nie mit einem AVR gearbeitet, weiss also nicht, wie dort der Startup realisiert wird, ein ARM sieht nach einem Reset allerdings wie folgt aus: - R14_SVC (die Return Addresse) ist unpredictable - SPSR_SVC (das Saved Program Status Register) ist unpredictable - CPSR[4:0] = b10011 (Supervisor Mode) - CPSR[5] = 0 (ARM State, nicht Thumb State) - CPSR[6] = 1 (FIQ disabled) - CPSR[7] = 1 (IRQ disabled) - PC = 0x0 (oder 0xffff0000 bei high-vectors, der SAM7 verwendet allerdings low-vectors) Alle anderen Register dürften wohl ihren vorherigen Zustand beibehalten, allerdings ist der bei einem Poweron-Reset natürlich auch undefiniert. Der Startup Code muss jetzt zumindest die Stack Pointer (R13) der verschiedenen Modi initialisieren und den Einsprung in die Main-Routine machen. Dazu müssen die Register entsprechend der Calling-Convention initialisiert werden: int main(int argc, char *argv[]); die Parameter werden von links nach rechts in r0-r3, alle Weiteren auf dem Stack übergeben. Ausserdem sollte der Framepointer (r11) auf NULL initalisiert werden, damit der Debugger nicht bei der Suche nach weiteren Stackframes auf ungültige Speicheraddressen zugreift. Bei Ausführung aus dem Flash muss ausserdem der Startup Code das BSS Segment auf Null initialisieren und das DATA Segment vom Flash in's RAM kopieren. (ohne Anspruch auf Vollständigkeit) Gruß, Dominic
Hi ähh... Okay. Gut, dann ist das ETWAS komplizierter als ich gedacht habe ;) . -> Jetzt verstehe ich auch, warum der Startup-Code in ASM geschrieben wird...! Hm. Wo kann ich so einen Code herbekommen, der nichts anderes macht, als für mich den ARM zu "resetten" und in die main-Routine zu springen? Ich werd mich damit noch auseinandersetzen (müssen) aber für den Anfang dürfte das etwas zu komplex sein oder? Also ich habe ja diese crt.s. Da ist ja Startup-Code drin? Wenn ja, was hat das da zu suchen:
1 | /* Turn on LED3 (write 0x0008 to PIOA_CODR at 0xFFFFF434) */ |
2 | ldr r12, =AT91C_PIOA_CODR |
3 | mov r11, #0x04 |
4 | str r11, [r12] |
Line 115-118 Jetzt ist also "nur" noch die Frage, wie ich dem Linker sage, dass der das dazu linken soll... Sagts mir, wenn ich euch auf die Nerven geh... :) Danke auf jeden Fall!! VLG Tobi
Es ist wohl eine Stil-Frage, was im Startup-Code gemacht wird. Bei komplexeren Boards signalisiert man z.B. mit LEDs den Fortschritt des Bootens, also PLL initialisiert, PLL locked, SDRAM initialisiert, etc. Schau dir nochmal das Original des Makefiles an, das du verwendet hast. Dort sollte crt.S in ein crt.o assembliert werden, das dann mit main.o und den Libraries zu main.out gelinkt wird (wohl via $OBJECTS). Gruß, Dominic
>Hm. Wo kann ich so einen Code herbekommen, der nichts anderes macht, als >für mich den ARM zu "resetten" und in die main-Routine zu springen? Ich >werd mich damit noch auseinandersetzen (müssen) aber für den Anfang >dürfte das etwas zu komplex sein oder? JA! ich kann dir nur empfehlen dich an fertige beispiele zu halten (die von martin thomas sind für den anfang schion mal sehr gut) und zuertst zu versuchen, die einzelnen peripherie-böcke kennenzulernen. dazu findest du auch gute beispiele auf www.atmel.com bzw. www.at91.com. wenn du die peripherie mittels c programmierung durch hast dann kannst du dir ja mal ansehen wie der assembler befehlssatz aussieht. auch dazu gibt es einige gute tutorials. und wenn du das alles durch hast dann machst du dich übe den startup code her. gruss gerhard
Hi Ok, der Startup-Code wird eingebunden, aber es treten lustige Fehler auf. Aber das gefällt mich schonmal. Wenn man Fehler hat, kann man wenigstens was machen... ;P Ich werde mich mit der Peripherie beschäftigen - nachdem ein Standard-Projekt funktioniert. Ich denke, dass ich nicht lernen kann, wenn das Beispiel schon alles fix und fertig mitbringt. Bin da vielleicht ein bisschen Dickköpfig in der Richtung. Aber ich möchte mir das selber ein bisschen erschließen, und naja. OK, morgen Abend gehts weiter, morgen ist HAM RADIO ;) Bis dann, VLG, Tobi
Hi So ganz hat mich die Sache jetzt doch nicht in Frieden gelassen, deshlab habe ich gestern Abend noch ein bisschen Rumgebastelt. Die Struktur des Startup-Codes ist mir soweit klar, es werden verschiedene Vektoren an Funktionen übergeben, auch _vec_reset, in dem der Prozessor initialisiert wird. So weit so gut, ich habe den projektspezifischen (?) Code entfernt, und so müsste es jetzt eigentlich funktionieren, aber der Linker kann verschiedene Symbole nicht finden:
1 | make all |
2 | MAKE Version 5.2 Copyright (c) 1987, 2000 Borland |
3 | .compiling |
4 | arm-elf-gcc -I./ -c -fno-common -O0 -g main.c |
5 | .assembling |
6 | arm-elf-as -ahls -mapcs-32 -o crt.o crt.s > crt.lst |
7 | ..linking |
8 | arm-elf-ld -v -Map main.map -TAT91SAM7S64-ROM.ld -o main.out main.o crt.o D:/Programme/yagarto/arm-elf/lib/libc.a D:/Programme/yagarto/arm-elf/lib/libm.a D:/Programme/yagarto/arm-elf/lib/libgcc.a |
9 | GNU ld version 2.17 |
10 | crt.o: In function `AT91F_Spurious_handler': |
11 | (.text+0xfc): undefined reference to `_stack_end' |
12 | crt.o: In function `AT91F_Spurious_handler': |
13 | (.text+0x10c): undefined reference to `_bss_start' |
14 | crt.o: In function `AT91F_Spurious_handler': |
15 | (.text+0x110): undefined reference to `_bss_end' |
16 | |
17 | ** error 1 ** deleting main.out |
http://www.tobias-schlegel.de/PublicData/test2.zip _stack_end : Line 105 _bss_start : Line 144 _bss_end : Line 145 (Jeweils erstes Auftreten) Den Linkerscript und den Startupcode habe ich soweit von http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/index_at91.html#at91gpio übernommen. Hm. Wo hat er das deklariert? (-> Müsste das nicht im Linkerscript stehen?) Danke für die Hilfe! VLG Tobi
Linker-Script und Startup-Code müssen zusammen passen. Das ist hier nicht der Fall. Beispiel: Das Linker-Script definiert __bss_start, der Startup-Code benötigt _bss_start. Ich kann mir kaum vorstellen, dass die beiden aus dem gleichen Projekt stammen.
Wo immer dein crt.s herkommt, aus dem SAM7 GPIO Beispiel jedenfalls
nicht.
> MAKE Version 5.2 Copyright (c) 1987, 2000 Borland
Und daran solltest du erkennen, dass du das falsche MAKE Tool erwischst.
> @Steven: > Sorry, aber das ist ein Piloten-Fehler... Wenn das Programm nach > Wegnehmen der Spannung nicht mehr im Speicher ist hattest du es nie im > Flash, sondern nur im RAM. > Der OpenOCD funktioniert wunderbar mit einem Wiggler, allerdings > verlangt eine GNU Toolchain mit dem OpenOCD mehr Einarbeitungszeit als > eine Lösung mit IAR/Keil/... und H-JTAG. Ich interessiere mich da weniger für den ARM, als für die Programmer. Für den Test habe ich mir ein kleines ARM-Board gekauft und mit der Kickstartversion den Progranmmer mit OCD getestet. Warum der Code ins RAM geladen wurde, ist unverständlich. Mit dem H-JTAG hat es wenigstens ohne Probleme geklappt. Aber irgendwie ist es leider typisch, dass eine Gnu-Toolchain viel Einarbeitungszeit benötigt. Das muss nicht sein. Nicht der Mensch soll sich an die Software anpassen, sondern diese sollte so geschrieben werden, dass sie einfach zu bedienen ist. Aus diesem Grund empfehle ich hier immer H-JTAG.
> Aber irgendwie ist es leider typisch, dass eine Gnu-Toolchain viel > Einarbeitungszeit benötigt. Das muss nicht sein. Nicht der Mensch soll > sich an die Software anpassen, sondern diese sollte so geschrieben > werden, dass sie einfach zu bedienen ist. Aus diesem Grund empfehle ich > hier immer H-JTAG. Das sind schlichtweg unterschiedliche Philosophien. Der Großteil der GNU Software wurde (zumindest ursprünglich) von Entwicklern für Entwickler geschrieben, und diese Entwickler wollen möglichst direkte Kontrolle haben. Daher darf bzw. muss bei einer GNU Toolchain der User alles selbst machen. Wer die GNU Toolchain nur benutzt weil diese umsonst ist, ist vermutlich schlecht beraten. Wer aber zu schätzen weiss, dass die selbe Toolchain von 16-bit Micros bis hinauf zu Server Architekturen skaliert, ist dann wohl auch gerne bereit, die längere Einarbeitungszeit darin zu investieren. Dass dir H-JTAG und IAR EWARM einfacher zu bedienen erscheinen liegt doch nur daran, dass du dich an diese Art Software angepasst hast. Ich hatte verschiedene IDEs ausprobiert, inkl. IAR, Keil und Crossworks, und während jede einzelne sicher ihre Vorzüge hat komme ich persönlich mit den GNU Tools und einem simplen VIM als Editor deutlich schneller zu meinem Ziel. Gruß, Dominic
> Daher darf bzw. muss bei einer GNU Toolchain der User alles > selbst machen. Kommt eben drauf an, wie man die Prioritäten setzt. Ob nun die Bedienung der Tools, die Konfiguration derselben oder das Schreiben von irgendwelchen Skripten für die Steuerung dieser Tools hoher bewertet, als die Programmierung des Controllers und damit die Lösung des Problems, muss jeder selber wissen. Ich bevorzuge Tools, die so geschrieben wurden, dass sie meine Oma bedienen kann.
Hi Also ich habe jetzt soweit die Dateien von (s. Link) übernommen. Gute Nachricht: Es Funktioniert. Ich weis nicht, es stört mich irgendwie, dass das so kompliziert ist. Andererseits ist es ein Vorteil, wenn man die Startup-Geschichte einfach in C ändern kann. Frage: Bin ich mit diesem Paket jetzt All-Round abgedeckt, oder muss ich da bei jeder Gelegenheit dran herumschrauben? VLG Tobi
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.