您的位置:首页 > 编程语言

STM32 eCos 启动代码分析(二)上下文切换

2011-11-30 14:24 826 查看
最近一直忙于工作,现在空一点继续写这个议题。(本文原创转载请注明出处 http://blog.csdn.net/rickleaf

stm32既然属于cortexm3体系结构,那么它的线程上下文切换必然要采用cortexm3的方式

打开

packages\hal\cortexm\arch\current\src\context.S

//==========================================================================
// Context switch
//
// R0 contains a pointer to the SP of the thread to load, R1 contains
// a pointer to the SP of the current thread.

.globl  hal_thread_switch_context
.thumb
.thumb_func
.type   hal_thread_switch_context, %function
hal_thread_switch_context:

push    {r0-r12,lr}             // Push all savable register
mov     r2,#2                   // Set state type == thread
mrs     r3,basepri              // Get priority base register
mov     r4,sp                   // Get SP (for info only)
push    {r2-r4}                 // Push them

str     sp,[r1]                 // Save SP

// Fall through

//--------------------------------------------------------------------------
// Load context
//
// This is used to load a thread context, abandoning the current one. This
// function is also the second half of hal_thread_switch_context.

.globl  hal_thread_load_context
.thumb
.thumb_func
.type   hal_thread_load_context, %function
hal_thread_load_context:

ldr     sp,[r0]                 // Load SP
pop     {r2-r4}                 // Pop type, basepri and SP (discarded)
msr     basepri,r3              // Set BASEPRI
pop     {r0-r12,pc}             // Pop all register and return

//==========================================================================

我们可以看到与ARM9的上下文切换相比,cortexm体系机构更为简洁。

在eCos的cortexm移植中:

R2保存当前任务的状态,比如R2=2来表示由thread进入上下文切换。

R3表示线程优先级

R4表示栈的状态

然后我们再浏览一下ARM9的上下文切换函数

packages\hal\arm\arch\current\src\context.S

// ----------------------------------------------------------------------------
//  hal_thread_switch_context
//  Switch thread contexts
//  R0 = address of sp of next thread to execute
//  R1 = address of sp save location of current thread

// Need to save/restore R4..R12, R13 (sp), R14 (lr)

// Note: this is a little wasteful since r0..r3 don't need to be saved.
// They are saved here though so that the information can match the
// HAL_SavedRegisters

FUNC_START_ARM(hal_thread_switch_context, r2)
mov     ip,sp
sub     sp,sp,#(ARMREG_SIZE - armreg_lr - 4) // skip svc_sp, svc_lr, vector, cpsr, and pc
stmfd   sp!,{ip,lr}
stmfd   sp!,{r0-r10,fp,ip}
mrs     r2,cpsr
str     r2,[sp,#armreg_cpsr]
str     sp,[r1]                 // return new stack pointer
#ifdef __thumb__
b       hal_thread_load_context_ARM // skip mode switch stuff
#endif

# Now load the destination thread by dropping through
# to hal_thread_load_context

// ----------------------------------------------------------------------------
//  hal_thread_load_context
//  Load thread context
//  R0 = address of sp of next thread to execute
//  Note that this function is also the second half of
//  hal_thread_switch_context and is simply dropped into from it.

FUNC_START_ARM(hal_thread_load_context, r2)
ldr     fp,[r0]                 // get context to restore
mrs     r0,cpsr                 // disable IRQ's
orr     r0,r0,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE
msr     cpsr,r0
ldr     r0,[fp,#armreg_cpsr]
msr     spsr,r0
ldmfd   fp,{r0-r10,fp,ip,sp,lr}
#ifdef __thumb__
mrs     r1,spsr                 // r1 is scratch
// [r0 holds initial thread arg]
msr     cpsr,r1                 // hopefully no mode switch here!
bx      lr
#else
movs    pc,lr                   // also restores saved PSR
#endif


ARM9中如果要保存连续的寄存器不能像cortexm这样才有push和pop,需要使用下面的两条指令完整类似的功能。

stmfd

ldmfd

简单的理解一下底层的上下文保存方法更让我们方便理解两个不同体系结构是如何与操作系统接口的。

笔者将在后面的文章中通过介绍eCos的ticker继续深入的了解cortexm体系结构如何使用eCos
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: