xPortPendSVHandler任务切换流程

__asm void xPortPendSVHandler( void )

{

    extern uxCriticalNesting;

    extern pxCurrentTCB;

    extern vTaskSwitchContext;

    PRESERVE8

    mrs r0, psp

    isb//指令同步命令,

    ldr r3, =pxCurrentTCB       /* Get the location of the current TCB. */

    ldr r2, [r3]//r2保存pxCurrentTCB的值,也是结构体topofstack的值,即栈顶的地址,

    stmdb r0!, {r4-r11}         /* Save the remaining registers. */进入中断会自动保存部分寄存器到//PSP

    str r0, [r2]                /* Save the new top of stack into the first member of the TCB. */

更新topofstack的值。

    stmdb sp!, {r3, r14}//接下来会用到r3和r14.

    mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY

    msr basepri, r0//禁止部分中断优先级低的中断

    dsb

    isb

    bl vTaskSwitchContext//进行跳转的任务切换函数,见解析一

    mov r0, #0

    msr basepri, r0//运行所有中断

    ldmia sp!, {r3, r14}

    ldr r1, [r3]//因为r3保存的是xCurrentTCB的地址。在任务切换函数中,xCurrentTCB的值变成了要切换任务的TCB。所以下面的栈就是要运行的任务栈

    ldr r0, [r1]                /* The first item in pxCurrentTCB is the task top of stack. */

    ldmia r0!, {r4-r11}         /* Pop the registers and the critical nesting count. */

    msr psp, r0//将top of stack赋给PSP

    isb

    bx r14//跳转到另一个任务。因为中断的硬件保存机制,所以即使另一个任务是被中断的,也可以继续保持运行。

    nop

}

解析一:
 

void vTaskSwitchContext( void )

{

假设调度器正常运行。(精简后)

        xYieldPending = pdFALSE;//允许礼让。

        /* Select a new task to run using either the generic C or port

        optimised asm code. */

        taskSELECT_HIGHEST_PRIORITY_TASK();解析二

        

}

解析二:

    #define taskSELECT_HIGHEST_PRIORITY_TASK()                                                      \

    {                                                                                               \

    UBaseType_t uxTopPriority;    

        /* Find the highest priority list that contains ready tasks. */                             

找到就绪列表中含有的任务中最高的优先级。

        portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority );   

根据找到的就绪列表中的其它任务,并将该任务的TCB赋值给pxCurrentTCB

        listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); 

xPortPendSVHandler任务切换流程_第1张图片

    } 

你可能感兴趣的:(Freertos,stm32,学习)