Forum: Mikrocontroller und Digitale Elektronik ARM Startschwierigkeiten


von Tobias (Gast)


Lesenswert?

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

von S. W. (Gast)


Lesenswert?

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/

von Tobias (Gast)


Lesenswert?

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

von Dominic R. (dominic)


Lesenswert?

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

von Tobias (Gast)


Lesenswert?

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

von JJ (Gast)


Lesenswert?

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.

von Tobias (Gast)


Lesenswert?

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

von Dominic R. (dominic)


Lesenswert?

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

von Tobias (Gast)


Lesenswert?

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

von Dominic R. (dominic)


Lesenswert?

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

von gerhard (Gast)


Lesenswert?

>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



von Tobias (Gast)


Lesenswert?

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

von Tobias (Gast)


Lesenswert?

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

von Andreas K. (a-k)


Lesenswert?

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.

von Andreas K. (a-k)


Lesenswert?

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.

von S. W. (Gast)


Lesenswert?

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

von Dominic R. (dominic)


Lesenswert?

> 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

von S. W. (Gast)


Lesenswert?

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

von Tobias (Gast)


Lesenswert?

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