码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-11-27 23:21:37      阅读:262      评论:0      收藏:0      [点我收藏+]

标签:assign   不能   oss   priority   sel   push   处理   创建   system   

/*
*********************************************************************************************************
*                                                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.没有用户任务\n");
    printf("1.第一个例子,一个用户任务\n");
    printf("2.第二个例子,两个任务共享CPU交替运行\n");
    printf("3.第三个例子,任务的挂起和恢复\n");
    printf("4.第四个例子,信号量管理\n");
    printf("5.第五个例子,互斥信号量管理\n");
    printf("6.第六个例子,事件标志组\n");
    printf("7.第七个例子,消息邮箱\n");
    printf("8.第八个例子,消息队列\n");
    printf("9.第九个例子,内存管理\n");
    
    printf("请输入序号选择例子:\n");
    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
                                   

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

标签:assign   不能   oss   priority   sel   push   处理   创建   system   

原文地址:http://www.cnblogs.com/wxb20/p/6107145.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!