Forum: Mikrocontroller und Digitale Elektronik LPC2000 nested Interrupts /Realview: wie kann ich die Functions nested_irq_enable in C-code aufrufen


von Benoit (Gast)


Lesenswert?

Hallo, liebe Mikrocontroller-Gemeinde,

Der ARM RealView-Kompiler verhindert konsequent, in Inline Assembly die 
physikalischen Register zu benutzen.
Von Hitex gibt es ein Beispiel, in dem per Inline Assembly ein Makro zum
Freigeben und Sperren der Nested Interrupts in den Source Code eingefügt
wird:
Die ursprünglichen Makros sehen folgendermaßen aus:

// Macros for Interrupt Nesting
#define IENABLE                      /* Nested Interrupts Entry */   \
  __asm { MRS     LR, SPSR      }    /* Copy SPSR_irq to LR     */   \
  __asm { STMFD   SP!, {LR}     }    /* Save SPSR_irq           */   \
  __asm { MSR     CPSR_c, #0x1F }    /* Enable IRQ (Sys Mode)   */   \
  __asm { STMFD   SP!, {LR}     }    /* Save LR                 */   \

#define IDISABLE                      /* Nested Interrupts Exit */   \
  __asm { LDMFD   SP!, {LR}     }     /* Restore LR             */   \
  __asm { MSR     CPSR_c, #0x92 }     /* Disable IRQ (IRQ Mode) */   \
  __asm { LDMFD   SP!, {LR}     }     /* Restore SPSR_irq to LR */   \
  __asm { MSR     SPSR_cxsf, LR }     /* Copy LR to SPSR_irq    */   \

Ich habe eine Lösung in diesem forum gefunden und sieht folgendermassen 
aus:

nested_irq_enable                       ; Nested Interrupts Freigabe:
                STMFD   SP!, {R0}       ; sichere R0 auf IRQ Stack
                MOV     R0,  LR         ; Returnadr: LR_irq != LR_sys
                MRS     LR,  SPSR       ; sichere SPSR_irq mit Hilfe
                STMFD   SP!, {LR}       ; von LR_irq auf dem IRQ Stack
                MSR     CPSR_c, #0x1F   ; Freigabe IRQ, Mode-Wechsel
                STMFD   SP!, {LR}       ; Sichere LR_sys auf User Stack
                BX      R0              ; zurück zur aufrufenden Stelle

nested_irq_disable                      ; Nested Interrupts Ende:
                MOV     R0,  LR         ; Returnadr: LR_irq != LR_sys
                LDMFD   SP!, {LR}       ; stelle LR_sys wieder her
                MSR     CPSR_c, #0x92   ; sperre IRQ, Mode-Wechsel
                LDMFD   SP!, {LR}       ; regeneriere SPSR_irq mit Hilfe
                MSR     SPSR_cxsf, LR   ; von LR_irq vom IRQ Stack
                MOV     LR,  R0         ; lade Rücksprungadresse
                LDMFD   SP!, {R0}       ; stelle R0 wieder her
                BX      LR              ; zurück zur aufrufenden Stelle
======================================================================== 
==
Kann mir jemand sagen wie kann ich die nested_irq_enable-Funktion und 
nested_irq_disable-Funktion in C-code aufrufen?
Ich bitte euch um ein kleines Beispielcode.

Danke im Voraus.

von (prx) A. K. (prx)


Lesenswert?

Ein anderer Ansatz, nested IRQs zuzulassen, besteht in einem zentralen 
Wrapper um die Vektoren. Also nicht im IRQ-Einsprung gleich zum Vektor 
weiterspringen, sondern zu ein bischen Assembler-Code, der die 
Verwaltung der Register und des VIC vornimmt und seinerseits den Vektor 
aufruft. Das hat zusätzlich den Charme, dass die eigentlichen 
Interrupt-Handler ganz normale C-Funktion sein dürfen und auch die 
abschliessende Quittierung beim VIC schon erledigt wird.

In manchen Startups ist so etwas schon drin (z.B. Crossworks).

Wenn man das richtig macht, dann dürfen bei dieser Methode die Handler 
auch Thumb-Funktionen sein.

von Benoit (Gast)


Lesenswert?

Danke A.K. für deine Antwort, aber ich komme trotzdem nicht weiter. 
Liegt irgendwo ein Beispielcode für das andere Ansatz ?

von Benoit (Gast)


Lesenswert?

Niemand hat eine Idee wie kann ich die  nested_irq_enable-Funktion und
nested_irq_disable-Funktion in C-code aufrufen?
Ich bitte euch um ein kleines Beispielcode.

Danke im Voraus.

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.