Forum: Mikrocontroller und Digitale Elektronik LPC2378 und TN-Kernel


von Peter (Gast)


Lesenswert?

Hallo,
Ich habe den TNKernel ein wenig abgeändert, so dass ich Interrupts über 
den VIC leiten kann (Im Original muß man ja alles in eine riesige ISR 
packen).
Leider läuft es nur, wenn der Compiler (IAR) ARM Instructions erzeugt. 
Im Thumb Modus stürzt er ab. Ich nehme an, es liegt an einer geänderten 
Assembler-Funktion:
1
tn_cpu_irq_isr:
2
3
     sub    lr, lr, #4              ; Set lr to the actual return address
4
     stmfd  sp!, {r0-r12, lr}       ; save all registers
5
6
     ldr    r2, =tn_int_counter
7
     ldr    r3, [r2]                ; interrupt_counter -> r3
8
     add    r0, r3,#1               ; interrupt_counter++
9
     str    r0, [r2]
10
11
     //LDR     R0,=tn_cpu_irq_handler
12
     LDR     R0,=tn_tick_int_processing
13
     MOV     LR, PC
14
     BX      R0
15
16
     ; interrupt_counter--
17
18
     ldr    r2, =tn_int_counter
19
     ldr    r1, [r2]
20
     sub    r3, r1,#1
21
     str    r3, [r2]
22
     cmp    r3, #0x00               ; if it is nested int - return
23
     bne    exit_irq_int            ; return from int
24
     ldr    r0, =tn_context_switch_request  ; see if we need to do a context switch
25
     ldr    r1, [R0]
26
     cmp    r1, #0                  ; if 0 - return
27
     beq    exit_irq_int
28
     mov    r1, #0                  ; else - clear req flag and  goto context switch
29
     str    r1, [r0]
30
     b      tn_int_ctx_switch
31
32
exit_irq_int:
33
34
     // Clear timer 0 interrupt
35
     ldr  r0, =1
36
     ldr  r3, =T0IR
37
     str  r0, [r3]
38
39
     // Acknowledge VIC
40
     ldr  r0, =0
41
     ldr  r3, =VICVECTADDR
42
     str  r0, [r3]
43
44
     ldmfd  sp!, {r0-r12, pc}^      ; exit
45
46
  ;---------------------------------------------------------------------------
47
48
tn_int_ctx_switch:
49
50
  ; Our target - get all registers of interrrupted task, saved in IRQ's stack
51
  ; and save them in the interrupted task's stack
52
53
54
     mrs    r0, spsr                  ; Get interrupted task's CPRS
55
     stmfd  sp!, {r0}                 ; Save it in the IRQ stack
56
     add    sp, sp, #4                ; Restore stack ptr after CPSR saving
57
     ldmfd  sp!, {r0-r12, lr}         ; Put all saved registers from IRQ
58
                                      ;   stack back to registers
59
     mov    r1, sp                    ; r1 <-  IRQ's SP
60
     sub    r1,r1,#4
61
     msr    cpsr_c, #(NOINT | SVCMODE) ; Change to SVC mode; INT are disabled
62
63
   ; Now - in SVC mode; in r1 - IRQ's SP
64
65
     ldr    r0, [r1], #-14*4    ; r0 <- task's lr (instead pc)+ rewind stack ptr
66
     stmfd  sp!, {r0}
67
     stmfd  sp!, {r2-r12, lr}   ; Save registers in interrupted task's
68
                                ;  stack,except CPSR,r0,r1
69
     ldr    r0, [r1],#2*4       ; Get interrupted task's CPSR (pos 0(-15))
70
     ldr    r2, [r1],#-4        ; Get valid r1 to save (pos 2(-13))
71
     ldr    r1, [r1]            ; Get valid r0 to save (pos 1(-14))
72
     stmfd  sp!, {r0-r2}        ; Save r0, r1, and CPSR
73
74
  ; Registers has been saved. Now - switch context
75
76
     ldr    r0, =tn_curr_run_task
77
     ldr    r0, [r0]
78
     str    sp, [r0]               ; SP <- curr task
79
80
     ldr    r0, =tn_next_task_to_run
81
     ldr    r2, [r0]
82
     ldr    r0, =tn_curr_run_task
83
     str    r2, [r0]
84
     ldr    sp, [r2]
85
86
  ; Return
87
88
     // Clear timer 0 interrupt
89
     ldr  r0, =1
90
     ldr  r3, =T0IR
91
     str  r0, [r3]
92
93
     // Acknowledge VIC
94
     ldr  r0, =0
95
     ldr  r3, =VICVECTADDR
96
     str  r0, [r3]
97
98
     ldmfd  sp!, {r0}                  ; Get CPSR
99
     msr    spsr_cxsf, r0              ; SPSR <- CPSR
100
     ldmfd  sp!, {r0-r12, lr, pc}^     ; Restore all registers, CPSR also

Die Funktion wird beim VIC als ISR für Timer 0 angemeldet und macht die 
Context Switches. Sie ruft eine C-Funktion auf (tn_tick_int_processing), 
die dann ja Thumb Code wäre. Ich habe schon versucht, 
tn_tick_int_processing als __arm zu deklarieren, hat aber leider nichts 
geholfen.
Hat jemand eine Idee?

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.