www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Frage zu ARM-Modi und Assembler


Autor: Henry (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tach,
ich bin ganz neu in der ARM-Welt. Habe erst angefangen, mit LPC2000 zu 
basteln :-) Genauer gesagt verwende ich einen LPC2364.
So, und nun habe ich dazu ein paar kleine Fragen...

1. Der ARM-Core kennt ja verschiedene Modi - UND, ABT, SVC und so 
weiter. Im Startup-Code wird dann ja einmal in jeden dieser Modi 
umgeschaltet, und der Stackpointer initialisiert. Das ist schön und gut; 
aber was bringen denn diese Modi, wenn man einfach so zwischen denen 
umschalten kann? Was unterscheidet die Modi von einander?
Früher habe ich mit Motorola 68k gebastelt; die haben auch einen 
"Supervisor" und einen "User" Mode. Nach dem Reset war man immer im 
Supervisor, und konnta da alles initialisieren; wenn man erst einmal in 
den User-Mode geschaltet hatte, konnt man bestimmte Register nicht mehr 
verändern und auch den Status nür über spezielle Befehle wieder 
wechseln. Sozusagen als "Schutz", damit der User das System nicht 
zerschiessen kann, indem er unberechtigte Sachen ändert.
Kann das der ARM auch?

2. Der Assembler ist ja ein bisschen gewöhnungsbedürftig ;-) man kann 
Konstanten manchmal mit mov in ein Register laden, und manchmal benötigt 
man LDR, und manchmal LDR mit diesem komischen = Operator (LDR r0, 
=0x1234).
Frage: Findet sich irgendwo eine übersichtliche Liste der Befehle, die 
der ARM7 kann, und wie die Syntax dieser auszusehen hat?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Henry schrieb:

> Was unterscheidet die Modi von einander?

Link-Register, Stack-Pointer und SPSR.

Die Modi sind nötig, weil im Unterschied zum 68000 Return-Adresse und 
alten Statusregister bei Abort/... Exceptions nicht auf dem Stack 
landen, sondern im R14 und SPSR des jeweiligen Exception-Modus. RISC 
lässt grüssen.

Die manuelle Umschaltung ist nur für die Initialisierung von R13 
(Stack-Pointer) nötig. 68K macht das über Spezialbefehl, ARM über 
Modusumschaltung.

> Kann das der ARM auch?

Ja. Das unterscheidet USER und SYSTEM Mode.

> Frage: Findet sich irgendwo eine übersichtliche Liste der Befehle, die
> der ARM7 kann, und wie die Syntax dieser auszusehen hat?

Es gibt auf arm.com zwei Kurzreferenzen. Da ist allerdings alles drin, 
nicht nur ARM7.

Autor: Henry (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo A.K.,
warum kann ich dann im Startup-Code einfach so zwischen User und System 
Mode umschalten? Sollte diese Umschaltung nicht auch irgendwie 
eingeschränkt sein, sodass man vom einen Mode zwar in den anderen kommt, 
aber nicht mehr zurück? sonst würde das ja keinen Sinn ergeben.

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kenne deinen Startup-Code nicht, aber normalerweise wird nicht in 
den User-Mode geschaltet.

Der System-Mode benutzt die gleichen Register wie der User-Mode, 
deswegen reicht es, den zu Initialisieren.

Jürgen

Autor: Henry (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also braucht man den User-Mode eigentlich gar nicht?

Autor: Maxxie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Den brauchst du dann, wenn du ein Programm(teil) laufen lassen willst, 
das nicht über priveligierte Rechte verfügen soll.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Henry schrieb:

> warum kann ich dann im Startup-Code einfach so zwischen User und System
> Mode umschalten?

Von System nach User geht. Umgekehrt nicht.

Überlicherwise verwendet mal bei Verwendung als Mikrocontroller ohne 
Betriebssystem entweder den einen oder den anderen Modus, je nach 
persönlichem Geschmack.

Ansonsten verwenden Handler für verschachtelte Interrupts u.U. den 
System Modus, denn der Interrupt Modus ist nicht reentrant. Ein 
Konstruktionsfehler der ARM Architektur.

Autor: Maxxie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber klar doch. Nested IRQ oder FIQ gehen ohne Probleme.

Modespezifische-Register sichern, I/F Flags wieder löschen. Irgendwann 
wieder setzen, Mode register zurückspielen.

Kannst machen bis dir der Speicher ausgeht.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur solange der Handler keine Funktion aufruft. Auch keine 
Compiler-Runtime.

Der Interrupt-Handler verwendet genauso R14 als Link-Register für seinen 
eigenen Code wie jeder andere. Und wenn er eine Funktion aufruft, dann 
landet die Return-Adresse wie üblich ebendort. Und wird beim ersten 
Schachtelinterrupt von der Hardware überschrieben.

Weshalb ein Handler für nested Interrupts vor/mit Freigabe des 
Interrupts den Modus wechselt. Das fällt nur nicht so auf, weil das mit 
der Freigabe vom I-Flag kombiniert wird. Siehe 
http://infocenter.arm.com/help/index.jsp?topic=/co....

Wissen sollte man es aber schon, denn es bedeutet, dass solche 
Interrupt-Handler hauptsächlich den System/User-Stack beanspruchen, nur 
2 Worte pro Level landen im Interrupt-Stack.

Autor: Maxxie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erm, wie bei jedem branch with link, sicherst du R14(lr) auf dem Stack.

Da ist kein Unterschied zu rekursiven Funktionsaufrufen in Hinsicht des 
LR.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Maxxie schrieb:

> Erm, wie bei jedem branch with link, sicherst du R14(lr) auf dem Stack.

Eine Funktion, die keine weitere Funktion aufruft, ist nicht 
verpflichtet R14 zu sichern. Wird dies meistens auch nicht tun, wie bei 
jedem branch with link.

Selbst wenn du den Compiler dazu bringen könntest dies immer zu tun 
besteht dennoch zwischen BL und dem STM-Befehl immer noch ein Fenster in 
dem R14 zerstört wird, wenn der Interrupt genau da hinein rutscht.

Hältst du ARM für blöd?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Maxxie schrieb:

> Da ist kein Unterschied zu rekursiven Funktionsaufrufen in Hinsicht des
> LR.

Oh doch. Der Interrupt ist asynchron, kann zu jedem Zeitpunkt auftreten 
zu dem er freigegeben ist. Der rekursive Funktionsaufruf hingegen 
geschieht nur an genau kontrollierter Stelle. Das genau ist der 
Unterschied.

Autor: Maxxie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Leute,

der LR wird gesichert (gemeinsam mit dem cpsr und evtl anderen genutzten 
registern, wärend das i flag noch gesetzt ist. Damit sind diese Werte 
verlässlich.

Danach kann ich zu jedem Zeitpunkt gerne wieder unterbrochen werden, und 
lösche das i flag.

Am Ende der (unterbrechenbaren) Interruptbehandlung wirds i flag wieder 
gesetzt. LR und co wieder hervorgeholt und per MOVS pc,lr 
herausgesprungen.

Wo seht ihr da ein Problem?
@ISR:
  stmdb sp!,{r0-r4,r12,lr} ; ABI conform: in whatever_wherever veränderbare register
  MRS r0,CPSR
  stmdb sp!,{r0}
  BIC r0,#0xC0
  MSR CPSR, r0          ; bis hier kann kein reentry auftreten

  BL @whatever_wherever

  ldmia sp!,{r0} 
  MSR CPSR,r0           ; ab hier wieder nicht
  ldmia sp!{r0-r4,r12,lr}
  movs pc,lr

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Maxxie schrieb:

>   BL @whatever_wherever

Explizit passiert hier;
  R14_irq = PC
  PC = whatever

Und nun kommt an genau dieser Stelle, also direkt unmittelbar sofort 
nach BL, der Schachtelinterrupt und macht:

  R14_irq = PC
  SPSR_irq = CPSR
  PC = 0x000000xx

schwupps, weg ist der vorherige Inhalt von R14. Wenn also 
irgendwannwhatever beendet wird, geht es ab in den Wald, genauer gesagt 
dorthin wo der Schachtelinterrupt auftrat. Und nicht hinter den BL.

Autor: Maxxie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> und weg ist das vorherige R14. Wenn also irgendwannwhatever beendet
> wird, geht es ab in den Wald

Ok, ja hab mein Problem jetzt gesehen.
Danke

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.