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

        } 

  • 相关阅读:
    使用 PyTorch 的计算机视觉简介 (4/6)
    Pandas数据分析23——pandas时间偏移和周期
    【算法】二叉树的存储与遍历模板
    【C语言】函数的系统化精讲(三)
    前端利器躬行记(9)——WebView中的页面调试方法
    【服务器搭建】教程四:域名怎样进行备案?快来看~
    java基础巩固3
    使用OAK-D相机跑ORB-SLAM3算法遇到的问题总结
    JUnit5的条件测试、嵌套测试、重复测试
    【考研数学】线性代数第五章 —— 特征值和特征向量(3,矩阵对角化理论)
  • 原文地址:https://blog.csdn.net/m0_54797575/article/details/133463077