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

来源:互联网 发布:怎么在淘宝做代理 编辑:程序博客网 时间:2024/06/06 09:16

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

原创粉丝点击