• 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 ] ) ); 

        } 

  • 相关阅读:
    1314. 矩阵区域和-矩阵前缀和算法
    科技成果验收测试需注意哪些方面?
    Linux权限
    java基于springboot+vue的地铁公交交通线路查询系统
    python在容器内克隆拉取git私有仓库
    WPF --- 触摸屏下的两个问题
    项目五 OpenStack镜像管理与制作
    海带软件分享——日常办公学习软件分享(收藏)
    迅为iTOP-2K1000开发板龙芯中科国产64位Loognix系统工业核心主板
    Apache Paimon 的 Query Service 使用
  • 原文地址:https://blog.csdn.net/m0_54797575/article/details/133463077