• 嵌入式实时操作系统μCOS原理与实践任务控制与时间的解析


    /*
    *********************************************************************************************************
    *                                                uC/OS-II
    *                                          The Real-Time Kernel  RTOS
    *

    *********************************************************************************************************
    */
    /*
    * 嵌入式实时操作系统μCOS原理与实践
    * 王小波
    * 2016于青岛大学
    */
    #include "includes.h"

    /*
    *********************************************************************************************************
    *                                               CONSTANTS
    *********************************************************************************************************
    */
    //堆栈大小
    #define  TASK_STK_SIZE               512       /* Size of each task's stacks (# of WORDs)            */
    //开始的堆栈指针优先级
    #define TaskStart_Prio    1
    //任务1的优先级
    #define Task1_Prio        2

    //任务堆栈 二维数组
    OS_STK  TaskStk[OS_MAX_TASKS][TASK_STK_SIZE];        //Tasks stacks
    HANDLE mainhandle;        //主线程句柄
    CONTEXT Context;        //主线程切换上下文
    BOOLEAN FlagEn = 1;        //增加一个全局变量,做为是否时钟调度的标志

    //任务开始函数的声明
    void TaskStart(void * pParam) ;
    //void Task1(void * pParam) ;                            /*Function  prototypes of tasks    

    /*$PAGE*/
    /*
    *********************************************************************************************************
    *                                                MAIN
    *********************************************************************************************************
    */
    //主方法的入口
    int main(int argc, char **argv)
    {
        int p[2],Experiment;  //定义变量
        p[0]=0;
        p[1]=100;
        //初始化vc环境
        VCInit();    @@@:
    @@@:
        //初始化vc环境
        void VCInit(void)
        {
            HANDLE cp,ct; //进程巨变
            Context.ContextFlags = CONTEXT_CONTROL;
            cp = GetCurrentProcess();    //得到当前进程句柄
            ct = GetCurrentThread();    //得到当前线程伪句柄
            DuplicateHandle(cp, ct, cp, &mainhandle, 0, TRUE, 2);    //伪句柄转换,得到线程真句柄
                
        }
    //显示以下的内容并与操作
        printf("0.没有用户任务 ");
        printf("1.第一个例子,一个用户任务 ");
        printf("2.第二个例子,两个任务共享CPU交替运行 ");
        printf("3.第三个例子,任务的挂起和恢复 ");
        printf("4.第四个例子,信号量管理 ");
        printf("5.第五个例子,互斥信号量管理 ");
        printf("6.第六个例子,事件标志组 ");
        printf("7.第七个例子,消息邮箱 ");
        printf("8.第八个例子,消息队列 ");
        printf("9.第九个例子,内存管理 ");
        
        printf("请输入序号选择例子: ");
        scanf("%d",&Experiment);
        //对你输入的变量进行判断
        if ((Experiment<0)||(Experiment>10))
        {
            printf("无效的输入!");
            return(1);     
        }
         //初始化OS(操作系统)的相关变量
        OSInit();        @@@:                        
    @@@:
        //初始化OS的相关变量
        void  OSInit (void)
        {
            //钩子函数---空函数  啥也不做
            OSInitHookBegin();                                           /* Call port specific initialization code   */
            //初始化全局变量
            OS_InitMisc();                                               /* Initialize miscellaneous variables       */
            //初始化就绪任务
            OS_InitRdyList();                                            /* Initialize the Ready List                */
            //初始化任务控制块
            OS_InitTCBList();                                            /* Initialize the free list of OS_TCBs      */
            //事件控制块的初始化
            OS_InitEventList();                                          /* Initialize the free list of OS_EVENTs    */

        #if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)
            //初始化事件标志
            OS_FlagInit();                                               /* Initialize the event flag structures     */
        #endif
            
        #if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u)
            //初始化内存
            OS_MemInit();                                                /* Initialize the memory manager            */
        #endif

        #if (OS_Q_EN > 0u) && (OS_MAX_QS > 0u)
            //初始化队列
            OS_QInit();                                                  /* Initialize the message queue structures  */
        #endif
            //初始化空闲任务
            OS_InitTaskIdle();                                           /* Create the Idle Task                     */
        #if OS_TASK_STAT_EN > 0u
           //初始化统计任务
            OS_InitTaskStat();                                           /* Create the Statistic Task                */
        #endif

        #if OS_TMR_EN > 0u
            OSTmr_Init();                                                /* Initialize the Timer Manager             */
        #endif
            //初始化钩子函数
            OSInitHookEnd();                                             /* Call port specific init. code            */

        #if OS_DEBUG_EN > 0u
            //初始化调式函数
            OSDebugInit();
        #endif
        }

        @@@:
        #if OS_VERSION > 203
        void OSInitHookBegin (void)
        {
        }
        #endif        

        //初始化全局变量
        static  void  OS_InitMisc (void)
        {
        #if OS_TIME_GET_SET_EN > 0u
            OSTime                    = 0uL;                       /* Clear the 32-bit system clock            */
        #endif
            //中断嵌套
            OSIntNesting              = 0u;                        /* Clear the interrupt nesting counter      */
            //调度锁
            OSLockNesting             = 0u;                        /* Clear the scheduling lock counter        */
            //任务计数
            OSTaskCtr                 = 0u;                        /* Clear the number of tasks                */
            //是否运行状态
            OSRunning                 = OS_FALSE;                  /* Indicate that multitasking not started   */
            //任务切换次数
            OSCtxSwCtr                = 0u;                        /* Clear the context switch counter         */
            //空闲计数
            OSIdleCtr                 = 0uL;                       /* Clear the 32-bit idle counter            */

        #if OS_TASK_STAT_EN > 0u
            OSIdleCtrRun              = 0uL;
            OSIdleCtrMax              = 0uL;
            OSStatRdy                 = OS_FALSE;                  /* Statistic task is not ready              */
        #endif

        #ifdef OS_SAFETY_CRITICAL_IEC61508
            OSSafetyCriticalStartFlag = OS_FALSE;                  /* Still allow creation of objects          */
        #endif
        }

        //初始化就绪任务
        static  void  OS_InitRdyList (void)
        {
            INT8U  i;

            //初始化就绪组
            OSRdyGrp      = 0u;                                    /* Clear the ready list                     */
            for (i = 0u; i < OS_RDY_TBL_SIZE; i++) {
            OSRdyTbl[i] = 0u;
            }
            //当前优先级
            OSPrioCur     = 0u;
            //指向最高优先级的任务
            OSPrioHighRdy = 0u;
            //强制转化为os系统块
            OSTCBHighRdy  = (OS_TCB *)0;
            OSTCBCur      = (OS_TCB *)0;
        }

        //初始化任务控制块链表
        static  void  OS_InitTCBList (void)
        {
            INT8U    ix;
            INT8U    ix_next;
            OS_TCB  *ptcb1;
            OS_TCB  *ptcb2;
            
            //先清空任务控制块
            OS_MemClr((INT8U *)&OSTCBTbl[0],     sizeof(OSTCBTbl));      /* Clear all the TCBs                 */
            //清空任务优先表
            OS_MemClr((INT8U *)&OSTCBPrioTbl[0], sizeof(OSTCBPrioTbl));  /* Clear the priority table           */
           //在初始化任务控制块
            for (ix = 0u; ix < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1u); ix++) {    /* Init. list of free TCBs     */
            ix_next =  ix + 1u;
            ptcb1   = &OSTCBTbl[ix];
            ptcb2   = &OSTCBTbl[ix_next];
            ptcb1->OSTCBNext = ptcb2;
                //是否给任务控制块名
        #if OS_TASK_NAME_EN > 0u
            ptcb1->OSTCBTaskName = (INT8U *)(void *)"?";             /* Unknown name                       */
        #endif
            }
            ptcb1                   = &OSTCBTbl[ix];
            ptcb1->OSTCBNext        = (OS_TCB *)0;                       /* Last OS_TCB                        */
        #if OS_TASK_NAME_EN > 0u
            ptcb1->OSTCBTaskName    = (INT8U *)(void *)"?";              /* Unknown name                       */
        #endif
            //给最后一个任务控制块指向NULL
             OSTCBList               = (OS_TCB *)0;                       /* TCB lists initializations          */
            //给空闲任务控制块链表指向任务控制块的首地址
             OSTCBFreeList          = &OSTCBTbl[0];
        }

        //给事件表做一个清空
        void  OS_MemClr (INT8U  *pdest,
                 INT16U  size)
        {
            while (size > 0u) {
            *pdest++ = (INT8U)0;
            size--;
            }
        }

        //进行任务调度
        void  OS_Sched (void)
        {
        #if OS_CRITICAL_METHOD == 3u                           /* Allocate storage for CPU status register     */
            OS_CPU_SR  cpu_sr = 0u;
        #endif
            //进入临界区
            OS_ENTER_CRITICAL();
            //是否在存在中断
            if (OSIntNesting == 0u) {                          /* Schedule only if all ISRs done and ...       */
            //是否有调度锁
                if (OSLockNesting == 0u) {                     /* ... scheduler is not locked                  */
                //进行任务新的调度
                    OS_SchedNew();
                    //取出任务优先级表的最高优先级任务
                OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
                //判断是否当前运行的任务
                    if (OSPrioHighRdy != OSPrioCur) {          /* No Ctx Sw if current task is highest rdy     */
        #if OS_TASK_PROFILE_EN > 0u
                        //进行切换任务控制的计数++
                OSTCBHighRdy->OSTCBCtxSwCtr++;         /* Inc. # of context switches to this task      */
        #endif            //切换任务数+1    
                OSCtxSwCtr++;                          /* Increment context switch counter             */
                        //进行一次任务的切换
                        OS_TASK_SW();                          /* Perform a context switch                     */
                }
            }
            }
            OS_EXIT_CRITICAL();
        }

        //进行任务调度
        static  void  OS_SchedNew (void)
        {
        //判断最低优先级是否小于63
        #if OS_LOWEST_PRIO <= 63u                        /* See if we support up to 64 tasks                   */
            INT8U   y;
            
            //得到优先级最高三位
            //查询任务就绪表是否有高的优先级
            y             = OSUnMapTbl[OSRdyGrp];
            //获取任务的最高优先级
            OSPrioHighRdy = (INT8U)((y << 3u) + OSUnMapTbl[OSRdyTbl[y]]);
        #else                                            /* We support up to 256 tasks                         */
            //否则就是256个任务
            INT8U     y;
            OS_PRIO  *ptbl;


            if ((OSRdyGrp & 0xFFu) != 0u) {
            y = OSUnMapTbl[OSRdyGrp & 0xFFu];
            } else {
            y = OSUnMapTbl[(OS_PRIO)(OSRdyGrp >> 8u) & 0xFFu] + 8u;
            }
            ptbl = &OSRdyTbl[y];
            if ((*ptbl & 0xFFu) != 0u) {
            OSPrioHighRdy = (INT8U)((y << 4u) + OSUnMapTbl[(*ptbl & 0xFFu)]);
            } else {
            OSPrioHighRdy = (INT8U)((y << 4u) + OSUnMapTbl[(OS_PRIO)(*ptbl >> 8u) & 0xFFu] + 8u);
            }
        #endif
        }

        //进行任务的切换
        void OSCtxSw(void)
        {
        //在c中执行汇编代码
            _asm{
                lea     eax, nextstart    ;任务切换回来后从nextstart开始
                push eax
                pushfd                ;标志寄存器的值
                pushad                ;保存EAX -- EDI        
                mov ebx, [OSTCBCur]
                mov [ebx], esp        ;把堆栈入口的地址保存到当前TCB结构中
            }
            //钩子函数
            OSTaskSwHook();
            //初始化当前变量
            OSTCBCur = OSTCBHighRdy;    
            OSPrioCur = OSPrioHighRdy;
            
            _asm{
                mov ebx, [OSTCBCur]
                mov esp, [ebx]        ;得到OSTCBHighRdy的esp
                
                popad                ;恢复所有通用寄存器,共8个
                popfd                ;恢复标志寄存器
                ret                    ;跳转到指定任务运行
            }
        nextstart:            //任务切换回来的运行地址
                return;
        }

        //初始化空闲任务
        void  OS_TaskIdle (void *p_arg)
        {
        #if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
            OS_CPU_SR  cpu_sr = 0u;
        #endif


            //参数的赋值-目的就是防止编译器警告
            p_arg = p_arg;                               /* Prevent compiler warning for not using 'p_arg'     */
            for (;;) {
            OS_ENTER_CRITICAL();//进入临界区
            OSIdleCtr++;        //空闲任务数++
            OS_EXIT_CRITICAL(); //离开临界区
            OSTaskIdleHook();   //钩子函数                  /* Call user definable HOOK                           */
            }
        }


        //任务控制块的初始化
        INT8U  OS_TCBInit (INT8U    prio,//优先级
                   OS_STK  *ptos,//栈点
                   OS_STK  *pbos,//栈底
                   INT16U   id,//进程id
                   INT32U   stk_size,//堆栈大小
                   void    *pext,//参数
                   INT16U   opt)//选择项
        {
            OS_TCB    *ptcb;
        #if OS_CRITICAL_METHOD == 3u                               /* Allocate storage for CPU status register */
            OS_CPU_SR  cpu_sr = 0u;
        #endif
        #if OS_TASK_REG_TBL_SIZE > 0u
            INT8U      i;
        #endif

            //移植代码
            OS_ENTER_CRITICAL();
            //获取空闲链表的首部
            ptcb = OSTCBFreeList;                                  /* Get a free TCB from the free TCB list    */
            //null
            if (ptcb != (OS_TCB *)0) {
            //指向下一个链表头
                OSTCBFreeList            = ptcb->OSTCBNext;        /* Update pointer to free TCB list          */
            OS_EXIT_CRITICAL();
            ptcb->OSTCBStkPtr        = ptos;                   /* Load Stack pointer in TCB                */
            ptcb->OSTCBPrio          = prio;                   /* Load task priority into TCB              */
            ptcb->OSTCBStat          = OS_STAT_RDY;            /* Task is ready to run                     */
            ptcb->OSTCBStatPend      = OS_STAT_PEND_OK;        /* Clear pend status                        */
            ptcb->OSTCBDly           = 0u;                     /* Task is not delayed                      */
        //扩展的功能
        #if OS_TASK_CREATE_EXT_EN > 0u
            ptcb->OSTCBExtPtr        = pext;                   /* Store pointer to TCB extension           */
            ptcb->OSTCBStkSize       = stk_size;               /* Store stack size                         */
            ptcb->OSTCBStkBottom     = pbos;                   /* Store pointer to bottom of stack         */
            ptcb->OSTCBOpt           = opt;                    /* Store task options                       */
            ptcb->OSTCBId            = id;                     /* Store task ID                            */
        //防止编译器警告
        #else
            pext                     = pext;                   /* Prevent compiler warning if not used     */
            stk_size                 = stk_size;
            pbos                     = pbos;
            opt                      = opt;
            id                       = id;
        #endif
        //容许删除
        #if OS_TASK_DEL_EN > 0u
            ptcb->OSTCBDelReq        = OS_ERR_NONE;
        #endif
        //最高任务数0
        #if OS_LOWEST_PRIO <= 63u                                         /* Pre-compute X, Y                  */
            ptcb->OSTCBY             = (INT8U)(prio >> 3u);
            ptcb->OSTCBX             = (INT8U)(prio & 0x07u);
        //以后
        #else                                                             /* Pre-compute X, Y                  */
            ptcb->OSTCBY             = (INT8U)((INT8U)(prio >> 4u) & 0xFFu);
            ptcb->OSTCBX             = (INT8U) (prio & 0x0Fu);
        #endif
                //查表                                                            /* Pre-compute BitX and BitY         */
            ptcb->OSTCBBitY          = (OS_PRIO)(1uL << ptcb->OSTCBY);
            ptcb->OSTCBBitX          = (OS_PRIO)(1uL << ptcb->OSTCBX);
        //事件
        #if (OS_EVENT_EN)
            ptcb->OSTCBEventPtr      = (OS_EVENT  *)0;         /* Task is not pending on an  event         */
        #if (OS_EVENT_MULTI_EN > 0u)
            ptcb->OSTCBEventMultiPtr = (OS_EVENT **)0;         /* Task is not pending on any events        */
        #endif
        #endif

        #if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u) && (OS_TASK_DEL_EN > 0u)
            ptcb->OSTCBFlagNode  = (OS_FLAG_NODE *)0;          /* Task is not pending on an event flag     */
        #endif

        #if (OS_MBOX_EN > 0u) || ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u))
            ptcb->OSTCBMsg       = (void *)0;                  /* No message received                      */
        #endif

        #if OS_TASK_PROFILE_EN > 0u
            ptcb->OSTCBCtxSwCtr    = 0uL;                      /* Initialize profiling variables           */
            ptcb->OSTCBCyclesStart = 0uL;
            ptcb->OSTCBCyclesTot   = 0uL;
            ptcb->OSTCBStkBase     = (OS_STK *)0;
            ptcb->OSTCBStkUsed     = 0uL;
        #endif

        #if OS_TASK_NAME_EN > 0u
            ptcb->OSTCBTaskName    = (INT8U *)(void *)"?";
        #endif
        //初始化任务控制块就绪表
        #if OS_TASK_REG_TBL_SIZE > 0u                              /* Initialize the task variables            */
            for (i = 0u; i < OS_TASK_REG_TBL_SIZE; i++) {
                ptcb->OSTCBRegTbl[i] = 0u;
            }
        #endif
                //钩子函数
            OSTCBInitHook(ptcb);
                //空函数
            OSTaskCreateHook(ptcb);                            /* Call user defined hook                   */
                //全局变量
            OS_ENTER_CRITICAL();
                //以上从空闲表拿出来但没放到就绪链表里去
            OSTCBPrioTbl[prio] = ptcb;
            ptcb->OSTCBNext    = OSTCBList;                    /* Link into TCB chain                      */
            ptcb->OSTCBPrev    = (OS_TCB *)0;
            if (OSTCBList != (OS_TCB *)0) {
                OSTCBList->OSTCBPrev = ptcb;
            }
                //设置就绪表和就绪组--
            OSTCBList               = ptcb;
            OSRdyGrp               |= ptcb->OSTCBBitY;         /* Make task ready to run                   */
            OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
            //任务控制块的切换数++
                OSTaskCtr++;                                       /* Increment the #tasks counter             */
            OS_EXIT_CRITICAL();
            return (OS_ERR_NONE);
            }
            OS_EXIT_CRITICAL();
            return (OS_ERR_TASK_NO_MORE_TCB);
        }

        //初始化空闲任务
        static  void  OS_InitTaskIdle (void)
        {
        #if OS_TASK_NAME_EN > 0u
            INT8U  err;
        #endif

        //以下是任务的扩展功能
        #if OS_TASK_CREATE_EXT_EN > 0u
            #if OS_STK_GROWTH == 1u
            (void)OSTaskCreateExt(OS_TaskIdle,
                      (void *)0,                                 /* No arguments passed to OS_TaskIdle() */
                      &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1u],/* Set Top-Of-Stack                     */
                      OS_TASK_IDLE_PRIO,                         /* Lowest priority level                */
                      OS_TASK_IDLE_ID,
                      &OSTaskIdleStk[0],                         /* Set Bottom-Of-Stack                  */
                      OS_TASK_IDLE_STK_SIZE,
                      (void *)0,                                 /* No TCB extension                     */
                      OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack  */
            #else
            (void)OSTaskCreateExt(OS_TaskIdle,
                      (void *)0,                                 /* No arguments passed to OS_TaskIdle() */
                      &OSTaskIdleStk[0],                         /* Set Top-Of-Stack                     */
                      OS_TASK_IDLE_PRIO,                         /* Lowest priority level                */
                      OS_TASK_IDLE_ID,
                      &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1u],/* Set Bottom-Of-Stack                  */
                      OS_TASK_IDLE_STK_SIZE,
                      (void *)0,                                 /* No TCB extension                     */
                      OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack  */
            #endif
        #else
            //以下是否创建任务的一般功能--创建空闲任务
            #if OS_STK_GROWTH == 1u
            (void)OSTaskCreate(OS_TaskIdle,
                       (void *)0,
                       &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1u],
                       OS_TASK_IDLE_PRIO);
            #else
            (void)OSTaskCreate(OS_TaskIdle,
                       (void *)0,
                       &OSTaskIdleStk[0],
                       OS_TASK_IDLE_PRIO);
            #endif
        #endif

        #if OS_TASK_NAME_EN > 0u
            OSTaskNameSet(OS_TASK_IDLE_PRIO, (INT8U *)(void *)"uC/OS-II Idle", &err);
        #endif
        }

        //任务调度锁
        #if OS_SCHED_LOCK_EN > 0u
        void  OSSchedLock (void)
        {
        #if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
            OS_CPU_SR  cpu_sr = 0u;
        #endif


        //判断是否有任务在运行
            if (OSRunning == OS_TRUE) {                  /* Make sure multitasking is running                  */
            OS_ENTER_CRITICAL();
            //保证没有中断发生
                if (OSIntNesting == 0u) {                /* Can't call from an ISR                             */
                //保证调度锁小于最大值
                    if (OSLockNesting < 255u) {          /* Prevent OSLockNesting from wrapping back to 0      */
                //调度锁加1
                        OSLockNesting++;                 /* Increment lock nesting level                       */
                }
            }
            OS_EXIT_CRITICAL();
            }
        }

        //给任务解锁
        #if OS_SCHED_LOCK_EN > 0u
        void  OSSchedUnlock (void)
        {
        #if OS_CRITICAL_METHOD == 3u                               /* Allocate storage for CPU status register */
            OS_CPU_SR  cpu_sr = 0u;
        #endif


            //判断是否有任务在运行
            if (OSRunning == OS_TRUE) {                            /* Make sure multitasking is running        */
            OS_ENTER_CRITICAL();
                //是否调度锁大于0
            if (OSLockNesting > 0u) {                          /* Do not decrement if already 0            */
                OSLockNesting--;                               /* Decrement lock nesting level             */
                if (OSLockNesting == 0u) {                     /* See if scheduler is enabled and ...      */
                   //没有中断发生
                        if (OSIntNesting == 0u) {                  /* ... not in an ISR                        */
                    OS_EXIT_CRITICAL();
                    //进行一次任务的调度
                            OS_Sched();                            /* See if a HPT is ready                    */
                } else {
                    OS_EXIT_CRITICAL();
                }
                } else {
                OS_EXIT_CRITICAL();
                }
            } else {
                OS_EXIT_CRITICAL();
            }
            }
        }
        #endif


        OSTaskCreate(TaskStart, 0, &TaskStk[1][TASK_STK_SIZE-1], TaskStart_Prio);//看到12级
        switch(Experiment)
        {
            printf("011112");
            case 1://一个任务运行
                printf("0000000");
                OSTaskCreate(FirstTask, 0, &TaskStk[5][TASK_STK_SIZE-1], 5);
                break;
            case 2://两个任务共享CPU
                OSTaskCreate(E2_task1, 0, &TaskStk[5][TASK_STK_SIZE-1], 5);
                OSTaskCreate(E2_task2, 0, &TaskStk[6][TASK_STK_SIZE-1], 6);
                break;
            case 3://任务的挂起和恢复
                OSTaskCreate(E3_task0, 0, &TaskStk[5][TASK_STK_SIZE-1], 5);
                OSTaskCreate(E3_task1, 0, &TaskStk[6][TASK_STK_SIZE-1], 6);
                OSTaskCreate(E3_task2, 0, &TaskStk[7][TASK_STK_SIZE-1], 7);
                break;
            case 4://信号量管理例程
                OSTaskCreate(UserTaskSemA, 0, &TaskStk[5][TASK_STK_SIZE-1], 7);
                OSTaskCreate(UserTaskSemB, 0, &TaskStk[6][TASK_STK_SIZE-1], 6);
                OSTaskCreate(UserTaskSemC, 0, &TaskStk[7][TASK_STK_SIZE-1], 5);
                break;
            case 5://互斥信号量管理例程
                OSTaskCreate(TaskMutex1, 0, &TaskStk[6][TASK_STK_SIZE-1], 6);
                OSTaskCreate(TaskMutex2, 0, &TaskStk[7][TASK_STK_SIZE-1], 50);
                OSTaskCreate(TaskPrint, 0, &TaskStk[8][TASK_STK_SIZE-1], 30);
                break;
            case 6://时间标志组管理例程
                OSTaskCreate(TaskDataProcess, 0, &TaskStk[5][TASK_STK_SIZE-1],5);
                OSTaskCreate(TaskIO1, 0, &TaskStk[6][TASK_STK_SIZE-1], 6);
                OSTaskCreate(TaskIO2, 0, &TaskStk[7][TASK_STK_SIZE-1], 7);
                OSTaskCreate(TaskIO3, 0, &TaskStk[8][TASK_STK_SIZE-1], 8);
                OSTaskCreate(TaskIO4, 0, &TaskStk[9][TASK_STK_SIZE-1], 9);
                break;
            case 7://消息邮箱
                OSTaskCreate(TaskMessageSen, 0, &TaskStk[6][TASK_STK_SIZE-1], 6);
                OSTaskCreate(TaskMessageRec, 0, &TaskStk[7][TASK_STK_SIZE-1], 7);
                break;
            case 8://消息队列
                 OSTaskCreate(TaskQSen, 0, &TaskStk[7][TASK_STK_SIZE-1], 5);
                 OSTaskCreate(TaskQRec, 0, &TaskStk[8][TASK_STK_SIZE-1], 6);
                 OSTaskCreate(TaskQRec, 0, &TaskStk[9][TASK_STK_SIZE-1], 7);
                break;
            case 9://内存管理
                 OSTaskCreate(TaskM, 0, &TaskStk[8][TASK_STK_SIZE-1], 6);
                break;
            default:           
                ;
        }

        @@@
    @@@
        //初始化创建任务的函数;
        #if OS_TASK_CREATE_EN > 0u
        INT8U  OSTaskCreate (void   (*task)(void *p_arg),
                     void    *p_arg,
                     OS_STK  *ptos,
                     INT8U    prio)
        {
            OS_STK    *psp;
            INT8U      err;
        #if OS_CRITICAL_METHOD == 3u                 /* Allocate storage for CPU status register               */
            OS_CPU_SR  cpu_sr = 0u;
        #endif



        #ifdef OS_SAFETY_CRITICAL_IEC61508
            if (OSSafetyCriticalStartFlag == OS_TRUE) {
            OS_SAFETY_CRITICAL_EXCEPTION();
            }
        #endif
        //检查优先级是否有效--首先是0
        #if OS_ARG_CHK_EN > 0u
            if (prio > OS_LOWEST_PRIO) {             /* Make sure priority is within allowable range           */
            return (OS_ERR_PRIO_INVALID);
            }
        #endif
            OS_ENTER_CRITICAL();
            //若是在嵌套中断函数时调用时-是不容许的
            if (OSIntNesting > 0u) {                 /* Make sure we don't create the task from within an ISR  */
            OS_EXIT_CRITICAL();
            return (OS_ERR_TASK_CREATE_ISR);
            }
            //查看任务优先级表的是否被占用 是 就执行以下代码
            if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority  */
                //不知是哪个tcb--就先用书包占用
            OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ...  */
            //bit                                     /* ... the same thing until task is created.              */
            OS_EXIT_CRITICAL();
            //任务堆栈的初始化
                psp = OSTaskStkInit(task, p_arg, ptos, 0u);             /* Initialize the task's stack         */
                //任务控制块的初始化
            err = OS_TCBInit(prio, psp, (OS_STK *)0, 0u, 0u, (void *)0, 0u);
                //若多任务已经启动就调用一次任务调度
                if (err == OS_ERR_NONE) {
                    //若多任务的启用
                if (OSRunning == OS_TRUE) {      /* Find highest priority task if multitasking has started */
                OS_Sched();//任务调度
                }
            } else {//no_tcb
                OS_ENTER_CRITICAL();
                    //错误不能创建任务--把刚把书包的站的位置重新给优先级指针表的对应为清0
                OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others                 */
                OS_EXIT_CRITICAL();
            }
            return (err);
            }
            OS_EXIT_CRITICAL();
            return (OS_ERR_PRIO_EXIST);//返回优先级被占用的信息
        }
        #endif
        //初始化堆栈
        OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
        {
            INT32U *stk;                            //console 下寄存器为32位宽


            opt    = opt;                           /* 'opt' is not used, prevent warning                      */
            stk    = (INT32U *)ptos;                /* Load stack pointer                                      */
            *--stk = (INT32U)pdata;         /* Simulate call to function with argument                 */                                    
            //cs
            *--stk = (INT32U)0X00000000;    
            //ip
            *--stk = (INT32U)task;          /* Put pointer to task   on top of stack                   */
            *--stk = (INT32U)0x00000202;                /* EFL = 0X00000202                                                */
            *--stk = (INT32U)0xAAAAAAAA;                /* EAX = 0xAAAAAAAA                                              */
            *--stk = (INT32U)0xCCCCCCCC;                /* ECX = 0xCCCCCCCC                                             */
            *--stk = (INT32U)0xDDDDDDDD;                /* EDX = 0xDDDDDDDD                                             */
            *--stk = (INT32U)0xBBBBBBBB;                /* EBX = 0xBBBBBBBB                                             */
            *--stk = (INT32U)0x00000000;                /* ESP = 0x00000000  esp可以任意,因为                                           */
            *--stk = (INT32U)0x11111111;                /* EBP = 0x11111111                                             */
            *--stk = (INT32U)0x22222222;                /* ESI = 0x22222222                                             */
            *--stk = (INT32U)0x33333333;                /* EDI = 0x33333333                                             */
                         
            return ((OS_STK *)stk);
        }


        //实现任务的删除
        #if OS_TASK_DEL_EN > 0u
        INT8U  OSTaskDel (INT8U prio)
        {
        #if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)
            OS_FLAG_NODE *pnode;
        #endif
            OS_TCB       *ptcb;
        #if OS_CRITICAL_METHOD == 3u                            /* Allocate storage for CPU status register    */
            OS_CPU_SR     cpu_sr = 0u;
        #endif


            //在中断中
            if (OSIntNesting > 0u) {                            /* See if trying to delete from ISR            */
            return (OS_ERR_TASK_DEL_ISR);
            }
            //空闲任务
            if (prio == OS_TASK_IDLE_PRIO) {                    /* Not allowed to delete idle task             */
            return (OS_ERR_TASK_DEL_IDLE);
            }
            //优先级
        #if OS_ARG_CHK_EN > 0u
            if (prio >= OS_LOWEST_PRIO) {                       /* Task priority valid ?                       */
            if (prio != OS_PRIO_SELF) {
                return (OS_ERR_PRIO_INVALID);
            }
            }
        #endif

        /*$PAGE*/
            OS_ENTER_CRITICAL();
            if (prio == OS_PRIO_SELF) {                         /* See if requesting to delete self            */
            prio = OSTCBCur->OSTCBPrio;                     /* Set priority to delete to current           */
            }
            //检查优先级是否存在
            ptcb = OSTCBPrioTbl[prio];
            if (ptcb == (OS_TCB *)0) {                          /* Task to delete must exist                   */
            OS_EXIT_CRITICAL();
            return (OS_ERR_TASK_NOT_EXIST);
            }
            //表示优先级在表中被保留
            if (ptcb == OS_TCB_RESERVED) {                      /* Must not be assigned to Mutex               */
            OS_EXIT_CRITICAL();
            return (OS_ERR_TASK_DEL);
            }
            //修改就绪表和就绪组的 标志-对就绪组和就绪表进行删除
            OSRdyTbl[ptcb->OSTCBY] &= (OS_PRIO)~ptcb->OSTCBBitX;
            if (OSRdyTbl[ptcb->OSTCBY] == 0u) {                             /* Make task not ready                         */
            OSRdyGrp           &= (OS_PRIO)~ptcb->OSTCBBitY;
            }

        #if (OS_EVENT_EN)
            //被删除的任务是否还在等待事件的发生。是,就将从事件等待队列中删除掉,已经删除了就不需要等待了
            if (ptcb->OSTCBEventPtr != (OS_EVENT *)0) {
            OS_EventTaskRemove(ptcb, ptcb->OSTCBEventPtr);  /* Remove this task from any event   wait list */
            }
        #if (OS_EVENT_MULTI_EN > 0u)//os容许等待多个事件
            if (ptcb->OSTCBEventMultiPtr != (OS_EVENT **)0) {   /* Remove this task from any events' wait lists*/
            OS_EventTaskRemoveMulti(ptcb, ptcb->OSTCBEventMultiPtr);
            }
        #endif
        #endif

        #if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)
            pnode = ptcb->OSTCBFlagNode;
            if (pnode != (OS_FLAG_NODE *)0) {                   /* If task is waiting on event flag            */
            OS_FlagUnlink(pnode);                           /* Remove from wait list                       */
            }
        #endif
            //延时
            ptcb->OSTCBDly      = 0u;                           /* Prevent OSTimeTick() from updating          */
            ptcb->OSTCBStat     = OS_STAT_RDY;                  /* Prevent task from being resumed             */
            ptcb->OSTCBStatPend = OS_STAT_PEND_OK;
           //强行调度器上一次锁  保证不发生任务调度
            if (OSLockNesting < 255u) {                         /* Make sure we don't context switch           */
            OSLockNesting++;
            }
            OS_EXIT_CRITICAL();                                 /* Enabling INT. ignores next instruc.         */
            //空闲函数  
            OS_Dummy();                                         /* ... Dummy ensures that INTs will be         */
            OS_ENTER_CRITICAL();                                /* ... disabled HERE!                          */
            if (OSLockNesting > 0u) {                           /* Remove context switch lock                  */
            OSLockNesting--;
            }
            OSTaskDelHook(ptcb);                                /* Call user defined hook                      */
            //任务数减一
            OSTaskCtr--;                                        /* One less task being managed                 */
            //把优先级任务表不指向任务块了
            OSTCBPrioTbl[prio] = (OS_TCB *)0;                   /* Clear old priority entry                    */
           //对就绪链表 和空闲链表操作--也就是从就绪表中把摘下tcb,插进空闲链表
            if (ptcb->OSTCBPrev == (OS_TCB *)0) {               /* Remove from TCB chain                       */
            ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
            OSTCBList                  = ptcb->OSTCBNext;
            } else {
            ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
            ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
            }
            ptcb->OSTCBNext     = OSTCBFreeList;                /* Return TCB to free TCB list                 */
            OSTCBFreeList       = ptcb;
        #if OS_TASK_NAME_EN > 0u
            ptcb->OSTCBTaskName = (INT8U *)(void *)"?";
        #endif
            OS_EXIT_CRITICAL();
            //判断是否在多任务
            if (OSRunning == OS_TRUE) {
               //进行一次任务调度
                OS_Sched();                                     /* Find new highest priority task              */
            }
            return (OS_ERR_NONE);
        }
        #endif


        //请求自己的删除任务
        //a) notify a task to delete itself.
        //b) to see if a task requested that the current task delete itself.
        /*$PAGE*/
        #if OS_TASK_DEL_EN > 0u
        INT8U  OSTaskDelReq (INT8U prio)
        {
            INT8U      stat;
            OS_TCB    *ptcb;
        #if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
            OS_CPU_SR  cpu_sr = 0u;
        #endif

        //各种判断--
            if (prio == OS_TASK_IDLE_PRIO) {                            /* Not allowed to delete idle task     */
            return (OS_ERR_TASK_DEL_IDLE);
            }
        #if OS_ARG_CHK_EN > 0u
            if (prio >= OS_LOWEST_PRIO) {                               /* Task priority valid ?               */
            if (prio != OS_PRIO_SELF) {
                return (OS_ERR_PRIO_INVALID);
            }
            }
        #endif
            //如果删除的是自己
            if (prio == OS_PRIO_SELF) {                                 /* See if a task is requesting to ...  */
            OS_ENTER_CRITICAL();                                    /* ... this task to delete itself      */
            //就将自己的任务打上标记
                stat = OSTCBCur->OSTCBDelReq;                           /* Return request status to caller     */
            OS_EXIT_CRITICAL();
            return (stat);
            }
            OS_ENTER_CRITICAL();
            //若是请求删除其他任务
            ptcb = OSTCBPrioTbl[prio];
            if (ptcb == (OS_TCB *)0) {                                  /* Task to delete must exist           */
            OS_EXIT_CRITICAL();
            return (OS_ERR_TASK_NOT_EXIST);                         /* Task must already be deleted        */
            }
            if (ptcb == OS_TCB_RESERVED) {                              /* Must NOT be assigned to a Mutex     */
            OS_EXIT_CRITICAL();
            return (OS_ERR_TASK_DEL);
            }
            //设置请求删除任务的标志
            ptcb->OSTCBDelReq = OS_ERR_TASK_DEL_REQ;                    /* Set flag indicating task to be DEL. */
            OS_EXIT_CRITICAL();
            return (OS_ERR_NONE);
        }
        #endif


        //任务挂起
        #if OS_TASK_SUSPEND_EN > 0u
        INT8U  OSTaskSuspend (INT8U prio)
        {
            BOOLEAN    self;
            OS_TCB    *ptcb;
            INT8U      y;
        #if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
            OS_CPU_SR  cpu_sr = 0u;
        #endif


        //检查
        #if OS_ARG_CHK_EN > 0u
            if (prio == OS_TASK_IDLE_PRIO) {                            /* Not allowed to suspend idle task    */
            return (OS_ERR_TASK_SUSPEND_IDLE);
            }
            if (prio >= OS_LOWEST_PRIO) {                               /* Task priority valid ?               */
            if (prio != OS_PRIO_SELF) {
                return (OS_ERR_PRIO_INVALID);
            }
            }
        #endif
            OS_ENTER_CRITICAL();
            if (prio == OS_PRIO_SELF) {                                 /* See if suspend SELF                 */
            //获取自己的优先级
                prio = OSTCBCur->OSTCBPrio;
            self = OS_TRUE;
                //当前任务
            } else if (prio == OSTCBCur->OSTCBPrio) {                   /* See if suspending self              */
            self = OS_TRUE;
            } else {
            self = OS_FALSE;                                        /* No suspending another task          */
            }
            ptcb = OSTCBPrioTbl[prio];
            //被挂起的任务不存在?
            if (ptcb == (OS_TCB *)0) {                                  /* Task to suspend must exist          */
            OS_EXIT_CRITICAL();
            return (OS_ERR_TASK_SUSPEND_PRIO);
            }
            //创建任务时--书包占位置 OS_TCB_RESERVED为1
            if (ptcb == OS_TCB_RESERVED) {                              /* See if assigned to Mutex            */
            OS_EXIT_CRITICAL();
            return (OS_ERR_TASK_NOT_EXIST);
            }
            //以下代码实现就绪组 和 就绪表取消就绪标志
            y            = ptcb->OSTCBY;
            OSRdyTbl[y] &= (OS_PRIO)~ptcb->OSTCBBitX;                   /* Make task not ready                 */
            if (OSRdyTbl[y] == 0u) {
            OSRdyGrp &= (OS_PRIO)~ptcb->OSTCBBitY;
            }//4
            //标志任务被挂起了
            ptcb->OSTCBStat |= OS_STAT_SUSPEND;                         /* Status of task is 'SUSPENDED'       */
            OS_EXIT_CRITICAL();
            //若挂起的是自己
            if (self == OS_TRUE) {                                      /* Context switch only if SELF         */
            OS_Sched(); //任务调度                                            /* Find new highest priority task      */
            }
            return (OS_ERR_NONE);
        }
        #endif

        //恢复被挂起的函数
        #if OS_TASK_SUSPEND_EN > 0u
        INT8U  OSTaskResume (INT8U prio)
        {
            OS_TCB    *ptcb;
        #if OS_CRITICAL_METHOD == 3u                                  /* Storage for CPU status register       */
            OS_CPU_SR  cpu_sr = 0u;
        #endif



        #if OS_ARG_CHK_EN > 0u
            if (prio >= OS_LOWEST_PRIO) {                             /* Make sure task priority is valid      */
            return (OS_ERR_PRIO_INVALID);
            }
        #endif
            OS_ENTER_CRITICAL();
            ptcb = OSTCBPrioTbl[prio];
             /* Task to suspend must exist            */
            if (ptcb == (OS_TCB *)0) {                                /* Task to suspend must exist            */
            OS_EXIT_CRITICAL();
            return (OS_ERR_TASK_RESUME_PRIO);
            }
            //判断控制块是否被保留
            if (ptcb == OS_TCB_RESERVED) {                            /* See if assigned to Mutex              */
            OS_EXIT_CRITICAL();
            return (OS_ERR_TASK_NOT_EXIST);
            }
            if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != OS_STAT_RDY) { /* Task must be suspended                */
               //任务必须是被挂起的才可以被恢复
                ptcb->OSTCBStat &= (INT8U)~(INT8U)OS_STAT_SUSPEND;    /* Remove suspension                     */
            //移除挂起标志
                if (ptcb->OSTCBStat == OS_STAT_RDY) {                 /* See if task is now ready              */
                if (ptcb->OSTCBDly == 0u) {
                //设置就绪表和就绪组 使任务就绪
                        OSRdyGrp               |= ptcb->OSTCBBitY;    /* Yes, Make task ready to run           */
                OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
                OS_EXIT_CRITICAL();
                if (OSRunning == OS_TRUE) {
                    OS_Sched();                               /* Find new highest priority task        */
                }
                } else {
                OS_EXIT_CRITICAL();
                }
            } else {                                              /* Must be pending on event              */
                OS_EXIT_CRITICAL();
            }
            return (OS_ERR_NONE);
            }
            OS_EXIT_CRITICAL();
            return (OS_ERR_TASK_NOT_SUSPENDED);
        }
        #endif

        //时钟中断
        void  OSTimeTick (void)
        {
            OS_TCB    *ptcb;
            BOOLEAN    step;
            OSTimeTickHook();                                      /*调用用户钩子函数,默认是空函数                     */

        #if OS_TIME_GET_SET_EN > 0u
            OS_ENTER_CRITICAL();                                   /* Update the 32-bit tick counter               */
            OSTime++; //调度计数+1
            OS_EXIT_CRITICAL();
        #endif
            //成立表示已经启动多任务
            if (OSRunning == OS_TRUE) {
        #if OS_TICK_STEP_EN > 0u
            switch (OSTickStepState) {                         /* Determine whether we need to process a tick  */
                case OS_TICK_STEP_DIS:                         /* Yes, stepping is disabled                    */
                 step = OS_TRUE;
                 break;

                case OS_TICK_STEP_WAIT:                        /* No,  waiting for uC/OS-View to set ...       */
                 step = OS_FALSE;                          /*      .. OSTickStepState to OS_TICK_STEP_ONCE */
                 break;

                case OS_TICK_STEP_ONCE:                        /* Yes, process tick once and wait for next ... */
                 step            = OS_TRUE;                /*      ... step command from uC/OS-View        */
                 OSTickStepState = OS_TICK_STEP_WAIT;
                 break;

                default:                                       /* Invalid case, correct situation              */
                 step            = OS_TRUE;
                 OSTickStepState = OS_TICK_STEP_DIS;
                 break;
            }
            if (step == OS_FALSE) {                            /* Return if waiting for step command           */
                return;
            }
        #endif
                 /* Point at first TCB in TCB list */
            ptcb = OSTCBList;                                  /* Point at first TCB in TCB list               */
            while (ptcb->OSTCBPrio != OS_TASK_IDLE_PRIO) {     /* Go through all TCBs in TCB list              */
                OS_ENTER_CRITICAL();
                if (ptcb->OSTCBDly != 0u) {                    /* No, Delayed or waiting for event with TO     */
                ptcb->OSTCBDly--;                          /* Decrement nbr of ticks to end of delay       */
                        //Check for timeout
                        if (ptcb->OSTCBDly == 0u) {                /* Check for timeout                            */
                            //若有任务等待一事件的发生
                    if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
                                // Clear status flag  
                                ptcb->OSTCBStat  &= (INT8U)~(INT8U)OS_STAT_PEND_ANY;          /* Yes, Clear status flag   */
                    ptcb->OSTCBStatPend = OS_STAT_PEND_TO;                 /* Indicate PEND timeout    */
                    } else {
                    ptcb->OSTCBStatPend = OS_STAT_PEND_OK;
                    }
                            //如果任务不是被挂起的
                    if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {  /* Is task suspended?       */
                    OSRdyGrp               |= ptcb->OSTCBBitY;             /* No,  Make ready          */
                    OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
                    }
                }
                }
                    // Point at next TCB in TCB list
                ptcb = ptcb->OSTCBNext;                        /* Point at next TCB in TCB list                */
                OS_EXIT_CRITICAL();
            }
            }
        }


        //实现结束中断操作--OSIntNesting-1,找到优先级最高的任务来运行
        void  OSIntExit (void)
        {
        #if OS_CRITICAL_METHOD == 3u                               /* Allocate storage for CPU status register */
            OS_CPU_SR  cpu_sr = 0u;
        #endif
            //是否在运行阶段
            if (OSRunning == OS_TRUE) {
            OS_ENTER_CRITICAL();
                //是否在函数嵌套
            if (OSIntNesting > 0u) {                           /* Prevent OSIntNesting from wrapping       */
                OSIntNesting--;
            }
            if (OSIntNesting == 0u) {                          /* Reschedule only if all ISRs complete ... */
                //调度锁
                    if (OSLockNesting == 0u) {                     /* ... and not locked.                      */
                OS_SchedNew();//find hight
                //获取优先级的任务优先级表
                        OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
                if (OSPrioHighRdy != OSPrioCur) {          /* No Ctx Sw if current task is highest rdy */
        #if OS_TASK_PROFILE_EN > 0u
                    //给任务切换数++
                            OSTCBHighRdy->OSTCBCtxSwCtr++;         /* Inc. # of context switches to this task  */
        #endif                //切换任务计数++
                    OSCtxSwCtr++;                          /* Keep track of the number of ctx switches */
                   //实现任务的切换
                            OSIntCtxSw(); //                         /* Perform interrupt level ctx switch       */
                }
                }
            }
            OS_EXIT_CRITICAL();
            }
        }


        //实现中断级的任务切换
        void OSIntCtxSw(void)
        {
            OS_STK *sp;
            OSTaskSwHook();
            
            sp = (OS_STK *)Context.Esp;    //得到主线程当前堆栈指针
            //在堆栈中保存相应寄存器。
            *--sp = Context.Eip;    //先保存eip
            *--sp = Context.EFlags;    //保存efl
            *--sp = Context.Eax;
            *--sp = Context.Ecx;
            *--sp = Context.Edx;
            *--sp = Context.Ebx;
            *--sp = Context.Esp;    //此时保存的esp是错误的,但OSTCBCur保存了正确的
            *--sp = Context.Ebp;
            *--sp = Context.Esi;
            *--sp = Context.Edi;    
            OSTCBCur->OSTCBStkPtr = (OS_STK *)sp;    //保存当前esp
            
            OSTCBCur = OSTCBHighRdy;        //得到当前就绪最高优先级任务的tcb
            OSPrioCur = OSPrioHighRdy;        //得到当前就绪任务最高优先级
            sp = OSTCBHighRdy->OSTCBStkPtr;    //得到重新执行的任务的堆栈指针
            
            
            //恢复所有处理器的寄存器
            Context.Edi = *sp++;
            Context.Esi = *sp++;
            Context.Ebp = *sp++;
            Context.Esp = *sp++;        //此时上下文中得到的esp是不正确的
            Context.Ebx = *sp++;
            Context.Edx = *sp++;
            Context.Ecx = *sp++;
            Context.Eax = *sp++;
            Context.EFlags = *sp++;
            Context.Eip = *sp++;
            
            Context.Esp = (unsigned long)sp;        //得到正确的esp
            
            SetThreadContext(mainhandle, &Context);    //保存主线程上下文
        }

        //多任务的开启
        void  OSStart (void)
        {    
            //若os的多任务还未启动
            if (OSRunning == OS_FALSE) {
                //Find highest priority's task priority number
                OS_SchedNew();                               /* Find highest priority's task priority number   */
            //OSPrioHighRdy变量在OS_SchedNew已经被设置
                OSPrioCur     = OSPrioHighRdy;
            OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run    */
            OSTCBCur      = OSTCBHighRdy;
            OSStartHighRdy();                            /* Execute target specific code to start task     */
            }
        }

        //启动高优先级任务
        void OSStartHighRdy(void)
        {
            OSTaskSwHook();
            OSRunning = TRUE;  //全局变量 表示启动了多任务
            _asm{
                mov ebx, [OSTCBCur]    ;OSTCBCur结构的第一个参数就是esp
                mov esp, [ebx]        ;恢复堆栈

                popad        ;恢复所有通用寄存器,共8个
                popfd        ;恢复标志寄存器
                ret            ;ret 指令相当于pop eip 但保护模式下不容许使用eip
                ;永远都不返回
            }
        }

        //进入中断服务程序
        void  OSIntEnter (void)
        {
            if (OSRunning == OS_TRUE) {
            if (OSIntNesting < 255u) {
                    //增加中断服务程序ISR嵌套层数
                OSIntNesting++;                      /* Increment ISR nesting level                        */
            }
            }
        }


        //任务延时函数  若是100表示在100个时间片后 把该任务就绪;
        void  OSTimeDly (INT32U ticks)
        {
            //从就绪态到阻塞态
            INT8U      y;
        #if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
            OS_CPU_SR  cpu_sr = 0u;
        #endif

            //中断服务程序不能延时
            if (OSIntNesting > 0u) {                     /* See if trying to call from an ISR                  */
            return;
            }
            //调度器上锁不能延时-因为延时后就要进行调度;
            if (OSLockNesting > 0u) {                    /* See if called with scheduler locked                */
            return;
            }
            //若延时时间延时才回进行延时
            if (ticks > 0u) {                            /* 0 means no delay!                                  */
            OS_ENTER_CRITICAL();
            //在就绪组和就绪表中取消当前任务的就绪标志;
                y            =  OSTCBCur->OSTCBY;        /* Delay current task                                 */
            OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX;
            if (OSRdyTbl[y] == 0u) {
                OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY;
            }
                //加载给任务控制块OSTCBDly赋值延时时间
            OSTCBCur->OSTCBDly = ticks;              /* Load ticks in TCB                                  */
            OS_EXIT_CRITICAL();
                //进行一次任务调度
                OS_Sched();                              /* Find next task to run!                             */
            }
        }

        //任务延时以小时 分 秒
        #if OS_TIME_DLY_HMSM_EN > 0u
        INT8U  OSTimeDlyHMSM (INT8U   hours,
                      INT8U   minutes,
                      INT8U   seconds,
                      INT16U  ms)
        {
            INT32U ticks;

            //中断服务程序不能延时
            if (OSIntNesting > 0u) {                     /* See if trying to call from an ISR                  */
            return (OS_ERR_TIME_DLY_ISR);
            }
            //调度器枷锁不能延时
            if (OSLockNesting > 0u) {                    /* See if called with scheduler locked                */
            return (OS_ERR_SCHED_LOCKED);
            }
            //进行参数的检查
        #if OS_ARG_CHK_EN > 0u
            if (hours == 0u) {
            if (minutes == 0u) {
                if (seconds == 0u) {
                if (ms == 0u) {
                    return (OS_ERR_TIME_ZERO_DLY);
                }
                }
            }
            }
            //无效分钟数
            if (minutes > 59u) {
            return (OS_ERR_TIME_INVALID_MINUTES);    /* Validate arguments to be within range              */
            }
            if (seconds > 59u) {
            return (OS_ERR_TIME_INVALID_SECONDS);
            }
            if (ms > 999u) {
            return (OS_ERR_TIME_INVALID_MS);
            }
        #endif
                                 /* Compute the total number of clock ticks required.. */
                                 /* .. (rounded to the nearest tick)                   */
           //计算这些时间需要多少个时间片
            ticks = ((INT32U)hours * 3600uL + (INT32U)minutes * 60uL + (INT32U)seconds) * OS_TICKS_PER_SEC
              + OS_TICKS_PER_SEC * ((INT32U)ms + 500uL / OS_TICKS_PER_SEC) / 1000uL;
            OSTimeDly(ticks);
            return (OS_ERR_NONE);
        }
        #endif

        //获取时间
        #if OS_TIME_GET_SET_EN > 0u
        INT32U  OSTimeGet (void)
        {
            INT32U     ticks;
        #if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
            OS_CPU_SR  cpu_sr = 0u;
        #endif



            OS_ENTER_CRITICAL();
            ticks = OSTime;
            OS_EXIT_CRITICAL();
            return (ticks);
        }

        //设置时间
        #if OS_TIME_GET_SET_EN > 0u
        void  OSTimeSet (INT32U ticks)
        {
        #if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
            OS_CPU_SR  cpu_sr = 0u;
        #endif



            OS_ENTER_CRITICAL();
            OSTime = ticks;
            OS_EXIT_CRITICAL();
        }
        #endif


        //延时恢复函数--也就是说延时没结束的时候--直接调用此函数就得以恢复
        #if OS_TIME_DLY_RESUME_EN > 0u
        INT8U  OSTimeDlyResume (INT8U prio)
        {
            OS_TCB    *ptcb;
        #if OS_CRITICAL_METHOD == 3u                                   /* Storage for CPU status register      */
            OS_CPU_SR  cpu_sr = 0u;
        #endif

            //各种参数检查
            if (prio >= OS_LOWEST_PRIO) {
            return (OS_ERR_PRIO_INVALID);
            }
            OS_ENTER_CRITICAL();
            ptcb = OSTCBPrioTbl[prio];                                 /* Make sure that task exist            */
            if (ptcb == (OS_TCB *)0) {
            OS_EXIT_CRITICAL();
            return (OS_ERR_TASK_NOT_EXIST);                        /* The task does not exist              */
            }
            //查看优先级是否被保留
            if (ptcb == OS_TCB_RESERVED) {
            OS_EXIT_CRITICAL();
            return (OS_ERR_TASK_NOT_EXIST);                        /* The task does not exist              */
            }
            //本函数是否被延时
            if (ptcb->OSTCBDly == 0u) {                                /* See if task is delayed               */
            OS_EXIT_CRITICAL();
            return (OS_ERR_TIME_NOT_DLY);                          /* Indicate that task was not delayed   */
            }
            //延时时间被强行设置为0
            ptcb->OSTCBDly = 0u;                                       /* Clear the time delay                 */
            //如果任务在等待事件的发生;不让等待事件
            if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
            //取反--清0
                ptcb->OSTCBStat     &= ~OS_STAT_PEND_ANY;              /* Yes, Clear status flag               */
            ptcb->OSTCBStatPend  =  OS_STAT_PEND_TO;               /* Indicate PEND timeout                */
            } else {
                //取消了延时
            ptcb->OSTCBStatPend  =  OS_STAT_PEND_OK;//结束的原因 ,是时间结束了
            }
            //如果任务不是被挂起的-那么被挂起的任务一定要使用OSTaskResum来恢复
            if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {  /* Is task suspended?                   */
            //若没被挂起-设置就绪组合就绪表的标志-进行事件调度;
                OSRdyGrp               |= ptcb->OSTCBBitY;             /* No,  Make ready                      */
            OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
            OS_EXIT_CRITICAL();
                //进行一次任务调度
            OS_Sched();                                            /* See if this is new highest priority  */
            } else {
                //任务是被挂起 不能使用本函数恢复;
            OS_EXIT_CRITICAL();                                    /* Task may be suspended                */
            }
            return (OS_ERR_NONE);
        }
        #endif
                                       

  • 相关阅读:
    HTTP协议相关知识点
    收集—— css实现垂直居中
    Nginx、lls、Apache三种服务器的日志格式及其字段含义
    XXE
    不安全的url跳转问题
    SSRF
    暴力破解
    跨站脚本xss
    CSRF跨站请求伪造
    RCE
  • 原文地址:https://www.cnblogs.com/wxb20/p/6107145.html
Copyright © 2020-2023  润新知