LiteOS学习第五篇——任务切换

来源:互联网 发布:木马编程 编辑:程序博客网 时间:2024/05/22 08:12

系统有两个任务切换函数

VOID osSchedule(VOID)

VOID LOS_Schedule(VOID)


两个函数最终切换调用的是用汇编编写的osTaskSchedule()函数,在移植的时候要根据不同的内核来修改

在COTEX-M3函数内核中用的是pendsv中断来切换任务。


osTaskSchedule
    LDR     R0, =OS_NVIC_INT_CTRL
    LDR     R1, =OS_NVIC_PENDSVSET
    STR     R1, [R0]
    BX      LR


这个函数就是直接操作寄存器触发pendsv异常

PendSV_Handler
    MRS     R12, PRIMASK
    CPSID   I


    LDR     R2, =g_pfnTskSwitchHook
    LDR     R2, [R2]
    CBZ     R2, TaskSwitch
    PUSH    {R12, LR}
    BLX     R2
    POP     {R12, LR}


异常直接调用TaskSwitch函数


TaskSwitch
    MRS     R0, PSP


    STMFD   R0!, {R4-R12}
    VSTMDB  R0!, {D8-D15}


    LDR     R5, =g_stLosTask
    LDR     R6, [R5]
    STR     R0, [R6]




    LDRH    R7, [R6 , #4]
    MOV     R8,#OS_TASK_STATUS_RUNNING
    BIC     R7, R7, R8
    STRH    R7, [R6 , #4]




    LDR     R0, =g_stLosTask
    LDR     R0, [R0, #4]
    STR     R0, [R5]




    LDRH    R7, [R0 , #4]
    MOV     R8,  #OS_TASK_STATUS_RUNNING
    ORR     R7, R7, R8
    STRH    R7,  [R0 , #4]


    LDR     R1,   [R0]
    VLDMIA  R1!, {D8-D15}
    LDMFD   R1!, {R4-R12}
    MSR     PSP,  R1


    MSR     PRIMASK, R12
    BX      LR



任务切换函数就是通过操作全局变量g_stLosTask,吧当前任务的寄存器入栈,其实就是存在任务控制块中pStackPointer指向的内存里面。然后把最新的就绪任务弹出来。这样就实现了任务切换。

typedef struct tagTaskCB
{
    VOID                        *pStackPointer;             /**< Task stack pointer                 */
    UINT16                      usTaskStatus;
    UINT16                      usPriority;
    UINT32                      uwStackSize;                /**< Task stack size                 */
    UINT32                      uwTopOfStack;               /**< Task stack top               */
    UINT32                      uwTaskID;                  /**< Task ID                     */
    TSK_ENTRY_FUNC              pfnTaskEntry;               /**< Task entrance function               */
    VOID                        *pTaskSem;                  /**< Task-held semaphore           */
    VOID                        *pThreadJoin;               /**< pthread adaption            */
    VOID                        *pThreadJoinRetval;         /**< pthread adaption            */
    VOID                        *pTaskMux;                  /**< Task-held mutex           */
    UINT32                      auwArgs[4];                 /**< Parameter, of which the maximum number is 4          */
    CHAR                        *pcTaskName;                /**< Task name                     */
    LOS_DL_LIST                 stPendList;
    LOS_DL_LIST                 stTimerList;
    UINT32                      uwIdxRollNum;
    EVENT_CB_S                  uwEvent;
    UINT32                      uwEventMask;                /**< Event mask               */
    UINT32                      uwEventMode;                /**< Event mode               */
    VOID                        *puwMsg;                    /**< Memory allocated to queues          */
} LOS_TASK_CB;

0 0
原创粉丝点击