mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Nested Interrupt Problem - LPC2148 - Yagarto


Autor: Jansus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe leider mal wieder Schwierigkeiten, die ich nicht alleine lösen 
kann.
Ich arbeite mit einem LPC2148 unter Eclipse mit GNU-ARM-Compiler.
Ich möchte Nested Interrupts enablen. Ich habe die dazu nötigen
Assemblerroutinen in mein Projekt eingebunden. Funktioniert prinzipiell
alles.
Leider landet mein µC bei der Befehlszeile "MSR CPSR_c, #0x1F" im
Aborthandler. Ich habe allerdings im ARM Instruction Set gelesen, dass
es möglich ist direkt HEX-Zahlen mit MSR zu verschieben. Das wird ja 
auch von vielen so genutzt. Was mir aber sehr zu denken gibt ist die 
Tatsache, dass mein Code nach dem # grün
eingefärbt wird, was ja bei vielen IDEs bedeutet, dass es als Kommentar 
gesehen wird. Dementsprechend lade ich dann ja nix in CPSR_c rein und 
somit wäre der Absturz gerechtfertigt.
Ich finde nur leider nirgends einen anderen Ansatz wie ich 0x1F direkt 
ins PSR bekomme.
Weiß jemand eine Lösung für mein Problem?
Bin für alle Tipps und Tricks dankbar!

Mfg
Jansus

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit dem Stand an präsentierter Information wird das nix. Und daher 
bringt auch eine Wiederholung der Frage nichts.

Autor: Jansus (Gast)
Datum:
Angehängte Dateien:
  • crt.s (4,42 KB, 200 Downloads)

Bewertung
0 lesenswert
nicht lesenswert
Hmm, ja war schon bisschen mager. Sorry!

Was ist denn alles von nöten, um was sagen zu können?

Hier das Assembler-File, mein Startup-File ist im Anhang:

.section .text ,"ax"
.arm


.global  nested_irq_enable
.global  nested_irq_disable

.func nested_irq_enable
nested_irq_enable:                       /* Nested Interrupts Entry*/
                STMFD   SP!, {R0}       /* stelle ein Register zur 
Verfügung*/
                MOV     R0,  LR         /* sichere darin die 
Returnadresse*/
                MRS     LR,  SPSR       /* sichere SPSR_irq über 
LR_irq*/
                STMFD   SP!, {LR}       /* auf dem IRQ Stack*/
                MSR     CPSR_c, #0x1F   /* Modewechsel IRQ - SYS, 
Freigabe IRQ*/
                STMFD   SP!, {LR}       /* Sichere LR_sys auf dem User 
Stack*/
                BX      R0              /* Return zur IRQ-ISR*/
.endfunc

.func nested_irq_disable
nested_irq_disable:                      /* Nested Interrupts Exit*/
                MOV     R0,  LR         /* sichere Returnadresse in 
Register*/
                LDMFD   SP!, {LR}       /* stelle LR_sys vom User Stack 
wieder her*/
                MSR     CPSR_c, #0x92   /* Modewechsel SYS - IRQ, 
Sperrung IRQ*/
                LDMFD   SP!, {LR}       /* Wiederherstellung*/
                MSR     SPSR_cxsf, LR   /* des SPSR_irq*/
                MOV     LR,  R0         /* lade Rücksprungadresse*/
                LDMFD   SP!, {R0}       /* stelle R0 wieder her*/
                BX      LR              /* Return zur IRQ-ISR*/
.endfunc

Autor: Martin Thomas (mthomas) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein GNU-Port der NXP-Beispielsammlung ist möglicherweise hilfreich. 
Download von 
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm...
von Interesse dürfte v.a. der Code in Startup.S sein.

Ansonsten wie Andreas Kaiser schon schrieb: zu wenig Information. Am 
Besten Minimalbeispiel erstellen, das das Fehlverhalten demonstriert. 
Mit allen notwendigen Dateien (linker-script, makefile, Quellcode) 
irgendwo auf einen Server legen oder als Attachment zu einem 
Forenbeitrag hier.

Martin Thomas

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In crt.s kann ich keine Initialisierung vom Sys/Usr Modus erkennen. Der 
Code läuft also im SVC-Modus. Wenn der Handler dann in den Sys-Modus 
wechselt ist kein gültiger Stack vorhanden.

PS: Code ist als Anhang lesbarer, alternativ als avrasm taggen. Der 
Umbruch stört halt sehr.

Autor: Jansus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In meinem Programm wird per Interrupt folgende Funktion aufgerufen:

void extint0(void) {
  EXTINT = 0x00000001;
  nested_irq_enable();
  extintcounter++;    // hochzählen
  nested_irq_disable();
  VICVectAddr = 0;
}


Hier die Funktion nested_irq_enable (so hier im Forum gefunden):

nested_irq_enable:                       /* Nested Interrupts Entry*/
                STMFD   SP!, {R0}       /* stelle ein Register zur 
Verfügung*/
                MOV     R0,  LR         /* sichere darin die 
Returnadresse*/
                MRS     LR,  SPSR       /* sichere SPSR_irq über 
LR_irq*/
                STMFD   SP!, {LR}       /* auf dem IRQ Stack*/
                MSR     CPSR_c, #0x1F   /* Modewechsel IRQ - SYS, 
Freigabe IRQ*/
                STMFD   SP!, {LR}       /* Sichere LR_sys auf dem User 
Stack*/
                BX      R0              /* Return zur IRQ-ISR*/

In der Zeile MSR CPSR_c, #0x1F hängt sich mein Controller auf.

Autor: Jansus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dumme Frage: Was ist der SVC-Modus? Und wie kann ich die einzelnen Modi 
im Startup initialisieren?

P.S.: Der nächste Code folgt ordentlich. Verprochen!

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Apropos aufhängen: Debugging per JTAG ist ganz nett, aber manchmal sind 
LEDs als Statusanzeige hilfreicher. Speziell dann, wenn nicht sicher 
ist, ob das Problem genau da liegt wo es angezeigt wird, oder man 
möglicherweise von einer Interferenz zwischen Debugger und System 
geleimt wird.

An dem MSR kann ich nämlich kein Problem erkennen. Aber dieser Befehl 
ermöglicht weitere Interrupts (eben das nesting), was den Schluss 
nahelegt, dass eher dort das Problem liegt.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
=> "Setup a stack for each mode".

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Dumme Frage: Was ist der SVC-Modus?

Manual Not Read Error.
RTFM.

Autor: Jansus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm, da hast Du mich erwischt! Hab das Manual schon gelesen. Nur nach 
den 3xx Seiten weiß ich auch nimmer alles. Supervisor Mode, oder?

Ich habe also für den User Mode den Stack initialisiert.
MSR     CPSR_c, #ARM_MODE_USER|I_BIT|F_BIT /* Interrupts disabled */
ldr     SP, __stack_usr_end

Keine Sorge, den dafür nötigen Rest habe ich auch erledigt.

Leider funktionieren jetzt überhaupt keine Interrupts mehr. Ich dachte 
mit den Zeilen hier hätte ich Interrupts angeschaltet.

[avrasm]MRS    r0, CPSR
BIC   r0, r0, #I_BIT | F_BIT     /* Enable FIQ and IRQ interrupt */
MRS   CPSR, r0
[/arvasm]

Ist das jetzt nutzlos geworden?
Wäre es auch denkbar, dass ich gleich bei der Initialisierung die 
Interrupts enable, also I_BIT und F_BIT nicht setzte? Oder ist es 
sinnvoller wie in den Beispielen von Martin Thomas das erst im laufenden 
Betrieb zu machen?

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zwei Möglichkeiten hattest du. Eine richtige, eine falsche...
Im User-Mode kannst du die Interrupts nicht kontrollieren. Keine Rechte.

Ich pflege Interrupts erst einzuschalten, wenn die Initialisierung durch 
ist. Vermeidet Überraschungen. Die meisten anderen scheinen es ebenso zu 
halten.

Autor: Jansus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gibt's eigentlich einen Trick um zu verhindern, dass sich OpenOCD in 90% 
aller Startversuche aufhängt?

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kenne ich so nicht.

Autor: Jansus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dass es sich ständig aufhängt?

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja.

Autor: Jansus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry. Meinte GDB. Wenn ich es starte, hängt sich entweder Eclipse auf, 
oder es kommt die Fehlermeldung "Stack is not available". Ziemlich 
frustrierend...

Autor: Jansus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In einem Anflug von Funktion konnte ich mal wieder debuggen. Und siehe 
da, es klappt ohne Absturz!

Und wiedereinmal kann ich nur sagen: Vielen Dank! Echt klasse!
Hoffentlich komme ich bei zukünftigen Problemen mal selbst drauf.

Gibt es eigentlich noch mehr Tücken, die sich im Startup verstecken?

Wegen dem ständigen Aufhängen. Ich verwende diesen Befehlssatz 
(vielleicht ist das dran schuld?):

target remote localhost:3333
monitor reset
monitor sleep 500
monitor poll
monitor soft_reset_halt
monitor arm7_9 sw_bkpts enable
monitor mww 0xE01FC040 0x0002
monitor mdw 0xE01FC040
break main
load
continue

Autor: Jansus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, habe alles neu installiert und jetzt klappt's.

Ich habe nun folgendes Rätsel:
Wenn ich einen Breakpoint an den Anfang meiner Interruptroutine setze, 
erlebe ich den Einsprung und anschließend läuft mein Programm auch 
völlig normal weiter.
Wenn ich den Breakpoint nun weglasse, den Interrupt auslöse und dann im 
Debugger nachsehe, wo ich gelandet bin, stelle ich fest, dass ich im 
PAbortHandler stecke.

Das kann doch irgendwie nicht sein, oder?

Wenn es mal wieder so ein Anfängererror (vgl. Manual) sein sollte, sagt 
mir das bitte, aber irgendwie bin ich ratlos.

Habe bisher nur C16x programmiert und solche Erlebnisse waren da 
irgendwie nicht an der Tagesordnung.

Bin wie immer für alle Ratschläge dankbar!

Autor: Jansus (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Zur Ergänzung:

Linkerskript im Anhang.
Debugge im RAM. Flash ist leer.

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.