Liteos-A任务调度之OsTaskStackInit函数 原创

落子摘星
发布于 2022-9-6 16:37
浏览
0收藏

       之前看过Liteos-a任务调度部分源码,本来想系统的记录一下学习的结果,但是奈何能力不足,又不甘心啥都不写,所以决定碎片化的记录一下学习到的东西。liteos-a是一个操作系统,所以看源码也需要了解基本的操作系统知识,本文不对这些基本知识进行多余的解释。如:

       <font color=blue>什么是任务?任务和线程有什么区别?任务或线程都有哪些状态?

       而任务调度这部分也涉及汇编语言,liteos-a是基于arm架构,所以用的是arm汇编,需要各位了解arm架构和汇编的一些知识。

       任务调度包含了任务的初始化,任务的切换,而任务切换包括保存当前任务,加载新任务,当新任务运行完或运行时被更高的任务打断时,就会再次进行任务切换,即保存当前任务,加载新任务。。。这都是后话,本文讲的是任务调度之前的任务栈的初始化,具体函数是OsTaskStackInit函数。

一、代码简单注释

参数:
UINT32 taskID —— 任务ID
UINT32 stackSize —— 任务栈大小
VOID *topStack —— 任务栈顶
BOOL initFlag —— 初始化标志位,用来判断是否需要栈的初始化
返回值:
(VOID *)taskContext —— 任务上下文指针
LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack, BOOL initFlag)
{
    if (initFlag == TRUE) {  //判断是否进行栈的初始化
        OsStackInit(topStack, stackSize);  //任务栈的初始化
    }
    TaskContext *taskContext = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext));  //声明任务上下文结构体指针,同时定位指针的位置

    /* initialize the task context */
#ifdef LOSCFG_GDB  //LOSCFG_GDB宏未定义,执行else
    taskContext->PC = (UINTPTR)OsTaskEntrySetupLoopFrame;
#else
    taskContext->PC = (UINTPTR)OsTaskEntry;  //任务切换时新任务的入口函数
#endif
    taskContext->LR = (UINTPTR)OsTaskExit;  /* LR should be kept, to distinguish it's THUMB or ARM instruction */
    taskContext->R0 = taskID;               /* R0 */

#ifdef LOSCFG_THUMB  //LOSCFG_THUMB宏未定义,执行else
    taskContext->regCPSR = PSR_MODE_SVC_THUMB; /* CPSR (Enable IRQ and FIQ interrupts, THUMNB-mode) */
#else
    taskContext->regCPSR = PSR_MODE_SVC_ARM;   /* CPSR (Enable IRQ and FIQ interrupts, ARM-mode) */
#endif

//FPU(浮点单元初始化)
#if !defined(LOSCFG_ARCH_FPU_DISABLE)
    /* 0xAAA0000000000000LL : float reg initialed magic word */
    for (UINT32 index = 0; index < FP_REGS_NUM; index++) {
        taskContext->D[index] = 0xAAA0000000000000LL + index; /* D0 - D31 */
    }
    taskContext->regFPSCR = 0;
    taskContext->regFPEXC = FP_EN;
#endif

    return (VOID *)taskContext;
}

二、任务栈和任务上下文的初始化

       上面的代码总共做了两件事,一个是任务栈的初始化,一个是任务上下文结构体的初始化,其中任务栈是包含任务上下文结构体的。

1.任务栈的初始化

       任务栈的初始化代码是:

VOID OsStackInit(VOID *stacktop, UINT32 stacksize)
{
    /* initialize the task stack, write magic num to stack top */
    (VOID)memset_s(stacktop, stacksize, (INT32)OS_STACK_INIT, stacksize);  //用OS_STACK_INIT(0xCACACACA)初始化栈空间
    *((UINTPTR *)stacktop) = OS_STACK_MAGIC_WORD;  //用OS_STACK_MAGIC_WORD(0xCCCCCCCC)初始化栈顶指针
}

       任务栈初始化完成后会有一行代码:

TaskContext *taskContext = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext));

       声明一个任务上下文结构体,并指向任务栈中的某一位置,空间分布大概是这样:
Liteos-A任务调度之OsTaskStackInit函数-鸿蒙开发者社区
       这个栈空间我是以栈底作为高地址,栈顶作为低地址,栈空间初始化完成了,下面就该初始化任务上下文结构体了。

2.任务上下文结构体初始化

       首先是任务上下文结构体代码:

/* The size of this structure must be smaller than or equal to the size specified by OS_TSK_STACK_ALIGN (16 bytes). */
typedef struct {
#if !defined(LOSCFG_ARCH_FPU_DISABLE)
    UINT64 D[FP_REGS_NUM]; /* D0-D31 */
    UINT32 regFPSCR;       /* FPSCR */
    UINT32 regFPEXC;       /* FPEXC */
#endif
    UINT32 R4;
    UINT32 R5;
    UINT32 R6;
    UINT32 R7;
    UINT32 R8;
    UINT32 R9;
    UINT32 R10;
    UINT32 R11;

    /* It has the same structure as IrqContext */
    UINT32 reserved2; /**< Multiplexing registers, used in interrupts and system calls but with different meanings */
    UINT32 reserved1; /**< Multiplexing registers, used in interrupts and system calls but with different meanings */
    UINT32 USP;       /**< User mode sp register */
    UINT32 ULR;       /**< User mode lr register */
    UINT32 R0;
    UINT32 R1;
    UINT32 R2;
    UINT32 R3;
    UINT32 R12;
    UINT32 LR;
    UINT32 PC;
    UINT32 regCPSR;
} TaskContext;

       结构体中包括ARM的R0~R12通用寄存器,PC、LR、CPSR以及32个64位浮点寄存器,还有FPSCR和FPEXC寄存器,这些都是ARM硬件上结构,还有reserved1、reserved2,这两个成员是保留的,USP和ULR是任务调度时非特权模式下要用到,这是后话。

       根据OsTaskStackInit函数的代码,在任务栈初始化时主要初始化了PC、LR、R0、CPSR、32个64位浮点寄存器、FPSR和FPEXC这几个任务上下文结构体成员,这是加载任务并成功运行所必须的,所以必须初始化。

       一个任务被创建并初始化后就可以参加调度了,创建任务和任务调度部分有机会的话会继续写,而任务栈的初始化现在就到此为止了,再写就不礼貌了。。

欢迎访问我的CSDN博客:请添加链接描述

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
2
收藏
回复
举报
回复
    相关推荐