Forum: Mikrocontroller und Digitale Elektronik Cortex M3 Interrupt


von Leopold N. (leo_n)


Angehängte Dateien:

Lesenswert?

Hallo,

heißt das (siehe Anhang), dass der Cortex M3 die Prozessorregister in 
Hardware pusht (innerhalb wievieler Taktzyklen?) oder muss ich das in 
Software noch machen?

Grüße

von Jürgen S. (starblue) Benutzerseite


Lesenswert?

Das ARM v7-M Architecture Reference Manual (DDI 0403E.d) sagt dazu:

"B1.5.6 Exception entry behavior
[...]
When pushing context to the stack, the hardware saves eight 32-bit 
words, comprising xPSR, ReturnAddress, LR (R14), R12, R3, R2, R1, and 
R0."

Beitrag #5794282 wurde vom Autor gelöscht.
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Leopold N. schrieb:
> innerhalb wievieler Taktzyklen?

Im Cortex-M3 Technical Reference Manual (s.u.) steht auf S. 3-45:

To reduce interrupt latency, the processor implements both interrupt 
late-arrival and interrupt tail-chaining mechanisms, as defined by the 
ARMv7-M architecture:
- There is a maximum of a twelve cycle latency from asserting the 
interrupt to execution of the firstinstruction of the ISR when the 
memory being accessed has no wait states being applied. The 
firstinstruction to be executed is fetched in parallel to the stack 
push.
- Returns from interrupts similarly take twelve cycles where the 
instruction being returned to is fetchedin parallel to the stack pop.
- Tail chaining requires six cycles when using zero wait state memory. 
No stack pushes or pops areperformed and only the instruction for the 
next ISR is fetched.

https://developer.arm.com/docs/100165/0201

von Leopold N. (leo_n)


Lesenswert?

Aber konkret heißt das, dass ich in der ISR (bzw. der Compiler) keine 
push oder pop Anweisungen zum Sichern der Prozessorregister einfügen 
muss oder?

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Leopold N. schrieb:
> Aber konkret heißt das, dass ich in der ISR (bzw. der Compiler) keine
> push oder pop Anweisungen zum Sichern der Prozessorregister einfügen
> muss oder?

Doch, wenn du mehr als die 5 Register r0-r4, r12 nutzt oder weitere 
Funktionen aufrufst (LR / r14).

von Leopold N. (leo_n)


Lesenswert?

Niklas G. schrieb:
> Leopold N. schrieb:
>> Aber konkret heißt das, dass ich in der ISR (bzw. der Compiler) keine
>> push oder pop Anweisungen zum Sichern der Prozessorregister einfügen
>> muss oder?
>
> Doch, wenn du mehr als die 5 Register r0-r4, r12 nutzt oder weitere
> Funktionen aufrufst (LR / r14).

Ok,
aber die Register R0, R1, R2, R3, R12, R14, R15 und PSR pusht der 
Prozessor selbst automatisch richtig?
Ich muss mich also um R4, R5, R6, R7, R8, R9, R10, R11, R13 und R14 
(sofern ich weitere Funktionen aufrufe) kümmern.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

r13 (SP) nicht unbedingt, wenn du damit nicht spezielles machst kannst 
du den auch ganz normal verwenden. Man kann auch separate Stacks für 
ISRs und mainloop nutzen (PSP vs. MSP).

Ansonsten stimmts.

von Leopold N. (leo_n)


Angehängte Dateien:

Lesenswert?

Noch eine Frage,

beim Eintritt in eine ISR pusht der Cortex M3 in Hardware ja 8 Register.
Wie lange dauert der gesamte Eintritt in Zyklen?
Dasselbe für den Austritt.

Außerdem: Wieviele Zyklen nimmt ein push / pop Befehl in Anspruch?
Hab dazu nur das hier gefunden, bin mir aber nicht sicher, ob ich N = 1 
oder N = 0 gilt.

Edit: Sry 2mal das gleiche angehängt. Hab ich vom ARM Information Center

Grüße

: Bearbeitet durch User
von Niklas G. (Gast)


Lesenswert?

Wie am 2.4. schon geschrieben: 12 Takte.
N=1, weil jede Load/Store Instruktion mind. 2 Takte braucht. Es kommt 
aber ggf. noch Latenz für Flash Zugriff drauf.

von RAc (Gast)


Lesenswert?

Leopold N. schrieb:
> Noch eine Frage,
>
> beim Eintritt in eine ISR pusht der Cortex M3 in Hardware ja 8 Register.
> Wie lange dauert der gesamte Eintritt in Zyklen?
> Dasselbe für den Austritt.
>
> Außerdem: Wieviele Zyklen nimmt ein push / pop Befehl in Anspruch?
> Hab dazu nur das hier gefunden, bin mir aber nicht sicher, ob ich N = 1
> oder N = 0 gilt.
>
> Edit: Sry 2mal das gleiche angehängt. Hab ich vom ARM Information Center
>
> Grüße

Kannst Du nicht zumindestens den pop mit Hilfe des DWT cycle Counters 
selbst ausmessen (viele IDEs haben da sogar plugins, die für Dich 
zählen)? Ich habe gerade mal einen Test gemacht: Im Laufenden Betrieb 
einen bp auf eine pop instruction gesetzt und den DWT cycle Counter 
(0xe0001004) vorher und nachher ausgelesen (natürlich mit Vorsicht zu 
geniessen, da das Auslesen selber nach dem step vermutlich auch noch 
Zklaen verbrät; ich kenne die IDE nicht gut genug um zu wissen ob das in 
den Zähler mit einfliesst). Delta 6 in meinem Fall. Am genauesten wäre 
natürlich ein zyklengenauer trace.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Darf man fragen, was du entwickelst, das so super zeitkritisch ist?

von Stefan F. (Gast)


Lesenswert?

Gemäß dem Buch von Joseph Yiu, sind es mindestens 12 Takte (inclusive 
vector fetch und register stacking). Häufig ist es aber mehr, wegen 
diverser Wait States/Flash Latency (auch von der vorherigen Operation).

Für die FPU bei Cortex M4 kommen weitere 12 Takte dazu, um Speicherplatz 
für das lazy-stacking der FPU Register zu reservieren. Wirklich 
gesichert werden sie erst später, falls sie tatsächlich verwendet 
werden, was innerhalb der ISR weitere Takte in Anspruch nimmt.

Das Buch gibt es hier kostenlos: 
https://www.eecs.umich.edu/courses/eecs373/labs/refs/M3%20Guide.pdf

von Carl D. (jcw2)


Lesenswert?

Das schöne am NVIC-"Stacking" ist, daß die Hardware genau das macht, was 
nach ARM-Calling-Convention auch beim Aufruf einer Funktion gemacht 
werden müßte, d.h. eine ISR ist genau so zu "bauen", wie jede andere 
C-Funktion. Es sind keine Spezialattribute wie "ISR", etc. notwendig.

von Leopold N. (leo_n)


Lesenswert?

Ok danke,

ich habe inzwischen herausgefunden, dass mein Debugger einen 
Cyclecounter hat... push, bzw pop benötigen zwei Takte.

Niklas G. schrieb:
> Darf man fragen, was du entwickelst, das so super zeitkritisch
> ist?

RTOS, der Kontextswitch sollte möglichst schlank sein.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Leopold N. schrieb:
> RTOS, der Kontextswitch sollte möglichst schlank sein.

Ach! Dann musst du aber sowieso alle Register sichern, egal wie lange es 
dauert. Die FPU-Register kann man ggf. "lazy" sichern.

von Stefan F. (Gast)


Lesenswert?

Der Cortex M3 hat keine FPU, sorry falls ich diesbezüglich Verwirrung 
gestiftet habe.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Öh, ja, uhps. Dann nur normale Register sichern.

von Leopold N. (leo_n)


Lesenswert?

Niklas G. schrieb:
> Leopold N. schrieb:
>> RTOS, der Kontextswitch sollte möglichst schlank sein.
>
> Ach! Dann musst du aber sowieso alle Register sichern, egal wie lange es
> dauert. Die FPU-Register kann man ggf. "lazy" sichern.

Ja ist mir schon klar, läuft auch alles schon...wollte nur mal grob 
nachrechnen, wieviele Zyklen das Ganze in Anspruch nimmt.

Stefanus F. schrieb:
> Der Cortex M3 hat keine FPU, sorry falls ich diesbezüglich
> Verwirrung
> gestiftet habe.

Nicht schlimm, dass wusste ich schon :)



Noch eine Frage:
Ich habe in Inline Assembler eine Berechnung ausgeführt, deren Ergebnis 
in R0 steht.
An diesem Punkt würde ich gerne mit C weitermachen unter Verwendung des 
Inline Assembler Rechenergebnisses in R0, also eine Variable 
deklarieren, deren Inhalt in R0 (und somit dem Rechenergebnis) steht.
Das geht doch mit dem Keyword "register" oder?
Aber wie mach ich dem IAR Compiler klar, dass der "Speicherort" R0 ist?

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Leopold N. schrieb:
> Ja ist mir schon klar, läuft auch alles schon...wollte nur mal grob
> nachrechnen, wieviele Zyklen das Ganze in Anspruch nimmt.

Messen hilft! Am Besten mit Pins die man toggelt, das kann man dann 
präzise in Echtzeit mit Oszilloskop oder LA messen.

Leopold N. schrieb:
> Das geht doch mit dem Keyword "register" oder?

Das ist eigentlich für was anderes und wird nicht mehr verwendet.

Leopold N. schrieb:
> Aber wie mach ich dem IAR Compiler klar, dass der "Speicherort" R0 ist?

Beim GCC ist das so, dass man sich vom Compiler ein Register geben lässt 
und dieses im Inline Assembler nutzt. Für den IAR musst du in dessen 
Doku nachsehen wie das geht...

Für den GCC könnte ich empfehlen:
https://hardwarebug.org/2010/07/06/arm-inline-asm-secrets/
http://www.ethernut.de/en/documents/arm-inline-asm.html

von Carl D. (jcw2)


Lesenswert?

Leopold N. schrieb:
> Ok danke,
>
> ich habe inzwischen herausgefunden, dass mein Debugger einen
> Cyclecounter hat... push, bzw pop benötigen zwei Takte.
>
> Niklas G. schrieb:
>> Darf man fragen, was du entwickelst, das so super zeitkritisch
>> ist?
>
> RTOS, der Kontextswitch sollte möglichst schlank sein.

Dann such mal nach "M3 pendsv Contextswitch". Die Dinger haben noch mehr 
Support für so was.

von Ruediger A. (Firma: keine) (rac)


Lesenswert?

Leopold N. schrieb:
>
>
> Noch eine Frage:
> Ich habe in Inline Assembler eine Berechnung ausgeführt, deren Ergebnis
> in R0 steht.
> An diesem Punkt würde ich gerne mit C weitermachen unter Verwendung des
> Inline Assembler Rechenergebnisses in R0, also eine Variable
> deklarieren, deren Inhalt in R0 (und somit dem Rechenergebnis) steht.
> Das geht doch mit dem Keyword "register" oder?
> Aber wie mach ich dem IAR Compiler klar, dass der "Speicherort" R0 ist?

Einfacher wäre es in diesem Fall, das Ganze nicht inzulinen, sondern als 
Funktion in Assembler zu schreiben (lt. AAPCS werden Funktionsreturns 
immer in R0 zurückgegeben, d.h. wenn Du in C eine Funktion aufrufst, 
wird die aufrufende Funktion automatisch davon ausgehen, dass das 
Ergebnis in R0 steht, egal ob die aufgerufen Funktion in C oder 
Assembler geschrieben ist).

Vielleicht (!) kannst Du das Ganze dann von Hinten durch die Brust ins 
Auge wieder so hinbiegen, dass Du deine Assemblerfunktion zwar als 
eigenständige Funktion schreibst, aber mit attribute inline wieder in 
den Code einarbeitest. Das ist aber sehr stark Conpilerabhängig und kann 
je nach Optimierungsstufen oder anderen Faktoren auch mal wieder in 
einen tatsächlichen Funktionsaufruf übersetzt werden.

von Lothar (Gast)


Lesenswert?

Carl D. schrieb:
> Das schöne am NVIC-"Stacking" ist

Ja der Cortex-M ist für sicherheitskritische ISR ganz toll: langsam und 
wenn der Stack ungültig wird sofort Hardfault.

Daher gibt es immer noch den Cortex-R mit klassischer FIQ ISR als 
Alternative. Die dann in ASM realisiert werden muss.

Noch besser wäre ein Cortex der wie 8051 mehrere ganze Registerbänke 
hätte, oder wenigstens je eine für USR und ISR

von Stefan F. (Gast)


Lesenswert?

Lothar schrieb:
> Carl D. schrieb:
>> Das schöne am NVIC-"Stacking" ist
>
> Ja der Cortex-M ist für sicherheitskritische ISR ganz toll: langsam und
> wenn der Stack ungültig wird sofort Hardfault.
>
> Daher gibt es immer noch den Cortex-R mit klassischer FIQ ISR als
> Alternative. Die dann in ASM realisiert werden muss.
>
> Noch besser wäre ein Cortex der wie 8051 mehrere ganze Registerbänke
> hätte, oder wenigstens je eine für USR und ISR

Wenn der Stackpointer ungültig wird, geht sowieso nichts mehr.

von (prx) A. K. (prx)


Lesenswert?

Stefanus F. schrieb:
> Wenn der Stackpointer ungültig wird, geht sowieso nichts mehr.

Es gibt Architekturen, die auch solche Fehler überleben können. 
Protected mode x86 beispielsweise, via Task Gate - braucht dann aber ein 
paar Takte länger.

: Bearbeitet durch User
von Lothar (Gast)


Lesenswert?

Stefanus F. schrieb:
> Wenn der Stackpointer ungültig wird, geht sowieso nichts mehr

Cortex-A und Cortex-R landen dann bei FIQ ISR in einer eigenen "halben" 
Registerbank R8-R12 und Cortex-M landet dank Autostacking nirgends.

von (prx) A. K. (prx)


Lesenswert?

Lothar schrieb:
>> Wenn der Stackpointer ungültig wird, geht sowieso nichts mehr
>
> Cortex-A und Cortex-R landen dann bei FIQ ISR in einer eigenen "halben"
> Registerbank R8-R12 und Cortex-M landet dank Autostacking nirgends.

Cortex M landet dann im HardFault Handler. Man sollte darin also nicht 
blind davon ausgehen, dass der Stack lesbar ist.

: Bearbeitet durch User
von S. R. (svenska)


Lesenswert?

Stefanus F. schrieb:
> Das Buch gibt es hier kostenlos:
> https://www.eecs.umich.edu/courses/eecs373/labs/refs/M3%20Guide.pdf

Danke! Das Ding liegt bei mir auf dem Tisch und scheint wirklich 
gebrauchbar zu sein...

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.