[ASM] How to terminate IRQ on STM32 or why microcontroller don't update IPSR?
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 lrCode 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 lrController 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?
