www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik interrupteinstellung lpc2378


Autor: Steffen H. (mcst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
ich bin ARM-Neuling und hab so meine Probleme.
ich will auf einem LPC2378 den CAN über interrupt laufen lassen, die
Beiträge hier im Forum haben mir leider noch nicht weiterhelfen können.
Meine Initialisierung sieht wie folgt aus :
...
CAN1IER = CAN2IER = 0x01; // Enable receive interrupts
...
VICVectAddr23 = HandlerAddr //HandlerAddris Pointer auf function
VICVectCntl23 = 0x01;
VICIntEnable = 1 << 23;  /* Enable Interrupt */
...


nun dacht ich, es muss noch das I-Flag im CPSR vom ARM-Kern deaktiviert
werden daher steht in meinem Startup-File:
/* Stack Sizes */
.set  UND_STACK_SIZE, 0x00000004 /* stack for "undefined instruction" interrupts is 4 bytes*/
.set  ABT_STACK_SIZE, 0x00000004/* stack for "abort" interrupts is 4 bytes*/
.set  FIQ_STACK_SIZE, 0x00000004/* stack for "FIQ" interrupts  is 4 bytes*/
.set  IRQ_STACK_SIZE, 0X00000080/* stack for "IRQ" normal interrupts is 4 bytes*/
.set  SVC_STACK_SIZE, 0x00000004/* stack for "SVC" supervisor mode is 4 bytes*/


/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs (program status registers) */
.set  MODE_USR, 0x10 /* Normal User Mode */
.set  MODE_FIQ, 0x11 /* FIQ Processing Fast Interrupts Mode */
.set  MODE_IRQ, 0x12 /* IRQ Processing Standard Interrupts Mode */
.set  MODE_SVC, 0x13 /* Supervisor Processing Software Interrupts Mode*/
.set  MODE_ABT, 0x17 /* Abort Processing memory Faults Mode*/
.set  MODE_UND, 0x1B /* Undefined Processing Undefined Instructions Mode*/
.set  MODE_SYS, 0x1F /* System Running Priviledged Operating System Tasks  Mode*/

.set  I_BIT, 0x80 /* when I bit is set, IRQ is disabled (program status registers) */
.set  F_BIT, 0x40 /* when F bit is set, FIQ is disabled (program status registers) */

[....]

/* Setup a stack for each mode - note that this only sets up a usable stack for User mode.   Also each mode is setup with interrupts initially disabled. */

      ldr   r0, =_stack_end
      msr   CPSR_c, #MODE_UND|I_BIT|F_BIT   /* Undefined Instruction Mode  */
      mov   sp, r0
      sub   r0, r0, #UND_STACK_SIZE
      msr   CPSR_c, #MODE_ABT|I_BIT|F_BIT  /* Abort Mode */
      mov   sp, r0
      sub   r0, r0, #ABT_STACK_SIZE
      msr   CPSR_c, #MODE_FIQ|I_BIT|F_BIT   /* FIQ Mode */
      mov   sp, r0
     sub   r0, r0, #FIQ_STACK_SIZE
      msr   CPSR_c, #MODE_IRQ|I_BIT|F_BIT   /* IRQ Mode */
      mov   sp, r0
      sub   r0, r0, #IRQ_STACK_SIZE
      msr   CPSR_c, #MODE_SVC|I_BIT|F_BIT  /* Supervisor Mode */
      mov   sp, r0
      sub   r0, r0, #SVC_STACK_SIZE
      msr   CPSR_c, #MODE_SYS|F_BIT  /* User Mode */
      mov   sp, r0

Problem ist nun: wenn mein Interrupt kommt bleibt der µC stehen
die Interrupt-Routine wird nicht ausgeführt.
Auf VICVectAddr23 steht 0x01B0, genau an dieser Speicheradresse befindet
sich laut Mapfile die Routine.
ich denke nun das ich mit den Bit's im CPSR irgend was falsch mache.

und noch eine Frage: wenn ein Interrupt am ARM anleigt wechselt er dann 
in den IRQ-Mode? und such sich die entsprechende Adresse der 
Interruproutien selber aus dem register?

Sollte der ARM lieber in einem anderem Modus laufen? momentan ist der 
System mode eingestellt.

hoffe auf eure Hilfe ich bin am verzweifeln!!!

Autor: Microman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

poste doch mal dein komplettes Startupfile, damit man sehen kann wie es 
bei einem IRQ darin abläuft und ob die Adresse auch aus dem VICVectAddr 
abgeholt und angesprungen wird. Es ist wichtig was an der Stelle der 
IRQ-Exception steht.

Gruß Microman

Autor: Steffen H. (mcst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK hier der Startupcode:
/* Stack Sizes */
.set  UND_STACK_SIZE, 0x00000080    /* stack for "undefined instruction" interrupts is 4 bytes  */
.set  ABT_STACK_SIZE, 0x00000080    /* stack for "abort" interrupts is 4 bytes                  */
.set  FIQ_STACK_SIZE, 0x00000080    /* stack for "FIQ" interrupts  is 4 bytes               */
.set  IRQ_STACK_SIZE, 0X00000200    /* stack for "IRQ" normal interrupts is 4 bytes          */
.set  SVC_STACK_SIZE, 0x00000080    /* stack for "SVC" supervisor mode is 4 bytes          */

/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs (program status registers) */
.set  MODE_USR, 0x10                /* Normal User Mode                     */
.set  MODE_FIQ, 0x11                /* FIQ Processing Fast Interrupts Mode             */
.set  MODE_IRQ, 0x12                /* IRQ Processing Standard Interrupts Mode           */
.set  MODE_SVC, 0x13                /* Supervisor Processing Software Interrupts Mode       */
.set  MODE_ABT, 0x17                /* Abort Processing memory Faults Mode             */
.set  MODE_UND, 0x1B                /* Undefined Processing Undefined Instructions Mode     */
.set  MODE_SYS, 0x1F                /* System Running Priviledged Operating System Tasks  Mode  */

.set  I_BIT, 0x80                   /* when I bit is set, IRQ is disabled (program status registers) */
.set  F_BIT, 0x40                   /* when F bit is set, FIQ is disabled (program status registers) */

.text
.arm

.global  Reset_Handler
.global _startup
.func   _startup

.section .startup, "ax"

_startup:

# Exception Vectors

_vectors:       ldr     PC, Reset_Addr         
                ldr     PC, Undef_Addr
                ldr     PC, SWI_Addr
                ldr     PC, PAbt_Addr
                ldr     PC, DAbt_Addr
                nop              /* Reserved Vector (holds Philips ISP checksum) */
                //ldr     PC, [PC,#-0xFF0]  /* see page 71 of "Insiders Guide to the Philips ARM7-Based Microcontrollers" by Trevor Martin  */
                ldr     PC, [PC, #-0x0120]  // Vector from VicVectAddr
                ldr     PC, FIQ_Addr

Reset_Addr:     .word   Reset_Handler    /* defined in this module below  */
Undef_Addr:     .word   UNDEF_Routine    /* defined in main.c  */
SWI_Addr:       .word   SWI_Routine      /* defined in main.c  */
PAbt_Addr:      .word   UNDEF_Routine    /* defined in main.c  */
DAbt_Addr:      .word   UNDEF_Routine    /* defined in main.c  */
IRQ_Addr:       .word   IRQ_Routine      /* defined in main.c  */
FIQ_Addr:       .word   FIQ_Routine      /* defined in main.c  */
                .word   0          /* rounds the vectors and ISR addresses to 64 bytes total  */

# Reset Handler

Reset_Handler:  

        .extern TargetResetInit
                 ldr     SP, =_stack_end    @ temporary stack at Stack_Top
                 LDR R0, =TargetResetInit
                 MOV LR, PC
                 BX R0
        
        /* Setup a stack for each mode - note that this only sets up a usable stack
        for User mode.   Also each mode is setup with interrupts initially disabled. */


          ldr   r0, =_stack_end
//Enter Undefined Instruction Mode and set its Stack Pointer
          msr   CPSR_c, #MODE_UND|I_BIT|F_BIT
          mov   sp, r0
          sub   r0, r0, #UND_STACK_SIZE

//Enter Abort Mode and set its Stack Pointer
          msr   CPSR_c, #MODE_ABT|I_BIT|F_BIT
          mov   sp, r0
          sub   r0, r0, #ABT_STACK_SIZE

//Enter FIQ Mode and set its Stack Pointer
          msr   CPSR_c, #MODE_FIQ|I_BIT|F_BIT
          mov   sp, r0  
           sub   r0, r0, #FIQ_STACK_SIZE

//Enter IRQ Mode and set its Stack Pointer
          msr   CPSR_c, #MODE_IRQ|I_BIT|F_BIT
          mov   sp, r0
          sub   r0, r0, #IRQ_STACK_SIZE

//Enter Supervisor Mode and set its Stack Pointer
          msr   CPSR_c, #MODE_SVC|I_BIT|F_BIT
          mov   sp, r0
          SUB   sl, sp, #SVC_STACK_SIZE
          //sub   r0, r0, #SVC_STACK_SIZE

//Enter User Mode and set its Stack Pointer
        //  msr   CPSR_c, #MODE_SYS|I_BIT|F_BIT
        //  mov   sp, r0

      
// copy .data section (Copy from ROM to RAM)
                ldr     R1, =_etext
                ldr     R2, =_data
                ldr     R3, =_edata
LoopRel:       cmp     R2, R3
                ldrlo   R0, [R1], #4
                strlo   R0, [R2], #4
                blo     LoopRel

// Clear .bss section (Zero init)
                mov     R0, #0
                ldr     R1, =_bss_start
                ldr     R2, =_bss_end
LoopZI:      cmp     R1, R2
                strlo   R0, [R1], #4
                blo     LoopZI

        /* Enter the C code  */
                b       main
.endfunc
.end


Die I-Bit’s lasen ich damit es keine Probleme bei der Initialisierung 
gibt. In meiner Main-Funktion enable ich dann die Interrupts über 
Assembler:
#define IRQ_MASK 0x00000080
static inline unsigned asm_get_cpsr(void)
{
  unsigned long retval;
  asm volatile (" mrs  %0, cpsr" : "=r" (retval) : /* no inputs */  );
  return retval;
}
static inline void asm_set_cpsr(unsigned val)
{
  asm volatile (" msr  cpsr, %0" : /* no outputs */ : "r" (val)  );
}
unsigned enableIRQ(void)
{
  unsigned _cpsr;

  _cpsr = asm_get_cpsr();
  asm_set_cpsr(_cpsr & ~IRQ_MASK);
  return _cpsr;
}
Der Interrupt am ARM-Kern bewirkt auch das er zum richtigen Exception 
Vector an Stelle 0x0018 springt, also zu der Zeile:
"ldr     PC, [PC, #-0x0120]  "ab hier denk ich läuft es schief.
Ziel ist ja dem Kern die Adresse der Interrupt-Routine mitzuteilen die 
im VicVectAddr (0xFFFFFF00) steht. Die Aktion [PC, #-0x0120] springt 
aber meiner Meinung falsch oder?
PC ist an dieser Stelle 0x18(befehlsanfang)+0x02 also 0x20
0x20-0x0120 ist bei mir 0xFFFFFEFF müsste man nicht 0x011F abziehen?
0x20-0x011F = 0xFFFFFF00

PS:
meine Interrupt-Routine habe ich so deklariert:
void CAN_Handler(void)
{...
return;
}
void CAN_Handler(void)  __attribute__ ((interrupt ("IRQ")));
...
VICVectAddr23 = (unsigned long) CAN_Handler

und danke für den Einsatz!

Autor: Steffen H. (mcst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zusatz:
laut Disassembly versteht der gcc Assambler anscheinend die Zeile
PC, [PC, #-0x0120] nicht! Allerdingst macht mein Debugger auch Blödsinn 
wenn er asm-befegle bekommt

Autor: Wilhelm F. (ferkes-willem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Steffen H.:

Hab mir mal das UM zum LPC2378 geladen. Seltsam, bei NXP kann ich es 
nicht herunter laden, sondern bei Keil.

VICAddress ist 0xFFFF FF00. Da im ARM-Mode, muß die Adresse von 
0x18+8=0x20 aus um 0x120 zurück gerechnet werden.
Der Befehl ldr PC, [PC, #-0x0120] spricht generell einen 4k Addressraum 
an, sieht damit korrekt aus.

Ich hoffe, du hast generell aber das richtige Startup-File, und nicht zu 
viel darin manipuliert (weil da auch die deaktivierte Zeile eines 
anderen Controllers mit anderem VIC-Vektor drin ist).

War da nicht noch was mit dem Default-Vektor???

Autor: Steffen H. (mcst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie meinst du das mit 0x18+8=0x20?
steht die 8 für 0x08 also für 8 Byte?

Wie du sagts sieht alles korrekt aus, aber wenn der µC in den IRQ-mode 
geht springt er noch richtig zum Exception Vector aber von da aus macht 
er nur noch Mist.

Weis auch nicht wie mir ein Default-Vektor weiterhelfen könnt.

Autor: Wilhelm F. (ferkes-willem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Steffen H.:

>wie meinst du das mit 0x18+8=0x20?
>steht die 8 für 0x08 also für 8 Byte?

Ja, das scheint auch richtig so.

>Wie du sagts sieht alles korrekt aus, aber wenn der µC in den
>IRQ-mode geht springt er noch richtig zum Exception Vector aber
>von da aus macht er nur noch Mist.

An dieser Stelle soll das Register PC mit dem Inhalt der VICAddress 
geladen werden. In deinem Fall sollte da der Inhalt von VICVectAddr23 
(CAN_Handler) drin stehen.

Hat schon jemals ein anderer IRQ mal funktioniert?

>Weis auch nicht wie mir ein Default-Vektor weiterhelfen könnt.

OK, habs schon gesehen, im LPC23xx gibt es wohl keinen nicht 
vektorisierten IRQ. Hat sich damit erledigt.

Ganz oben fand ich noch:
>VICVectCntl23 = 0x01;
Ist das so in Ordnung?
Hast du das richtige Registerfile (z.B. LPC2378.h) eingebunden?
Nicht, das die Registeradressen total nicht stimmen!
Im User Manual LPC2378 fand ich kein Register VICVectCntl23 !

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.