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

最近一直忙于工作,现在空一点继续写这个议题。(本文原创转载请注明出处 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

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值