2020-05-28 12:48 PM
My code here:
...
@ some code
...
end:
nop
b end
thread0:
mov32 r1, 0x4001100C @ GPIOC_CRH address
ldr r0, [r1]
orr r0, 0x8000 @ switch_on C15 only
str r0, [r1]
b end
nvic_systick:
push { lr }
@cpsid i
mov32 r1, 0x4001100C @ GPIOC_CRH address
ldr r0, [r1]
eor r0, 0xA000 @ toggle pin state on C13 & C15
str r0, [r1]
adr r2, thread0+1
@push { r2 } <<<<---- EVIL INSTRUCTION
pop { lr }
bx lr
Code works well, but i want to controller going to 'thread0' function after returning from interrupt.
GDB says:
(gdb) info all-registers
r0 0x0 0
r1 0xed04 60676
r2 0x1e1 481
r3 0x8a1e8883 -1977710461
r4 0xef5fffff -278921217
r5 0xfffbffee -262162
r6 0x21136d6a 554921322
r7 0x7a8191d 128456989
r8 0xf7efbf75 -135282827
r9 0xfffffffb -5
r10 0xca444668 -901495192
r11 0xc2378b49 -1036547255
r12 0xff5bbfdf -10764321
sp 0x20005000 0x20005000
lr 0xffffffff 0xffffffff
pc 0x1ce 0x1ce
xpsr 0x41000000 1090519040
msp 0x20005000 0x20005000
psp 0x9f48dd14 0x9f48dd14
primask 0x0 0 '\000'
basepri 0x0 0 '\000'
faultmask 0x0 0 '\000'
control 0x0 0 '\000'
(gdb)
Pay attention to xpsr register. Controller stay at thread mode and now pointing to instruction inside 'end' function.
After uncommenting 'evil line':
...
@ code
...
nvic_systick:
push { lr }
@cpsid i
mov32 r1, 0x4001100C @ GPIOC_CRH address
ldr r0, [r1]
eor r0, 0xA000 @ toggle pin state on C13 & C15
str r0, [r1]
adr r2, thread0+1
push { r2 } @ THAT LINE
pop { lr }
bx lr
Controller execute IRQ handler once and then stay at the 'end' loop.
In that case GDB say:
(gdb) info all-registers
r0 0x0 0
r1 0xe000ed04 -536810236
r2 0x1e1 481
r3 0x8a1e8883 -1977710461
r4 0xef5fffff -278921217
r5 0xfffbffee -262162
r6 0x21136d6a 554921322
r7 0x7a8191d 128456989
r8 0xf7efbf75 -135282827
r9 0xfffffffb -5
r10 0xca444668 -901495192
r11 0xc2378b49 -1036547255
r12 0xff5bbfdf -10764321
sp 0x20004fdc 0x20004fdc
lr 0x1e1 0x1e1
pc 0x1dc 0x1dc
xpsr 0x4100000f 1090519055
msp 0x20004fdc 0x20004fdc
psp 0x9f48dd14 0x9f48dd14
primask 0x0 0 '\000'
basepri 0x0 0 '\000'
faultmask 0x0 0 '\000'
control 0x0 0 '\000'
(gdb)
Here xpsr contains value of IPSR, and 0xf = Currently running SysTick_IRQ.
Question: how to return from interrupt successfully?
Solved! Go to Solution.
2020-06-01 12:39 AM
Now it works!
end:
nop
b end
thread0:
mov32 r1, 0x4001100C @ GPIOC_CRH address
ldr r0, [r1]
orr r0, 0x8000 @ switch_on C15 only
str r0, [r1]
b end
nvic_systick:
mov32 r1, 0x4001100C @ GPIOC_CRH address
ldr r0, [r1]
eor r0, 0xA000 @ toggle pin state on C13 & C15
str r0, [r1]
adr r0, thread0+1
str r0, [sp, #24]
bx lr
But maybe I did a fault? Does writing directly to stack is correct?
All values and addresses was found by reading stack from RAM.
2020-05-28 01:01 PM
>>Question: how to return from interrupt successfully?
BX LR back through the call-gate so it unstacks the interrupt context/tail chain mechanism..
LR contains a "magic" value, review TRM
2020-05-28 01:11 PM
In my case I use BX LR in both variants, but I need to return(from interrupt) to specific address
I have read, in official arm documentation, that controller use MSP or PSR on return from exception.
After debugging has clear what LR contains sequence 0xFFFFFFF9 and in that case on BX LR controller must use MSP
2020-05-28 01:22 PM
If you want to change the return address, you need to determine the stack, and then go into the stack frame to check/modify the LR within THAT
2020-05-30 12:17 PM
Ok!
Another question: Why after returning from interrupt we don't exiting from Handler Mode? I just pushed address to stack.
2020-06-01 12:39 AM
Now it works!
end:
nop
b end
thread0:
mov32 r1, 0x4001100C @ GPIOC_CRH address
ldr r0, [r1]
orr r0, 0x8000 @ switch_on C15 only
str r0, [r1]
b end
nvic_systick:
mov32 r1, 0x4001100C @ GPIOC_CRH address
ldr r0, [r1]
eor r0, 0xA000 @ toggle pin state on C13 & C15
str r0, [r1]
adr r0, thread0+1
str r0, [sp, #24]
bx lr
But maybe I did a fault? Does writing directly to stack is correct?
All values and addresses was found by reading stack from RAM.