Monday, May 4, 2009

stmdb, ldmdb, stmfd etc...

It seems that I am getting quite close to my first working context switch right now. As recommended for RTOS:es on Cortex-M3, my context switches actually takes place in the PendSV handler which looks like this:

    .global    CM3_handler_pendsv
.thumb_func
.extern current_pcb
.extern new_pcb
CM3_handler_pendsv:
mrs r12, PSP @ Get PSP for current process.
stmfd r12!, {r4-r11} @ Save remaining registers.
ldr r0, =current_pcb @ r0 = &current_pcb.
ldr r0, [r0] @ r0 = current_pcb
str r12, [r0, 8] @ Update SP in PCB.
ldr r0, =new_pcb @ r0 = &new_pcb
ldr r0, [r0] @ r0 = new_pcb
ldr r12, [r0, 8] @ r12 = SP for new process.
ldmfd r12!, {r4-r11} @ Restore r4-r11 for new process.
msr PSP, r12 @ Update SP for new process.
ldr lr, =0xfffffffd @ Use process stack when returning.
bx lr @ Return to new process.



Make sure to use the proper variants of the stm and ldm instructions.The fd suffix stands for full descending which means that the stack pointer decreases before data is written to the stack using it. Therefore, the stack is always full ie. the stack pointer always points at valid data. When reading from the stack, the stack pointer increases after the reading operation.

No comments:

Post a Comment