/*
*********************************************************************************************************
*                                                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原理与实践任务控制与时间的解析的更多相关文章

  1. 嵌入式实时操作系统μCOS原理与实践+事件部分代码

    //事件等待表的初始化函数:pevent表示事件控制块的指针#if (OS_EVENT_EN)void  OS_EventWaitListInit (OS_EVENT *pevent){    INT ...

  2. 嵌入式实时操作系统Nucleus PLUS综述

    近些年来,随着嵌入式系统飞速的发展.嵌入式实时操作系统广泛地应用在制造工业.过程控制.通讯.仪器仪表.汽车.船舶.航空航天.军事.装备.消费类产 品等方面. Nucleus PLUS 是为实时嵌入式应 ...

  3. 嵌入式实时操作系统VxWorks入门――开发环境构建[转]

    VxWorks 操作系统是美国WindRiver公司于1983年设计开发的一种嵌入式实时操作系统(RTOS),它以其良好的可靠性和卓越的实时性被广泛地应用在通 信.军事.航空.航天等高精尖技术及实时性 ...

  4. 嵌入式实时程序设计中C/C++代码的优化

    1 引言 计算机技术和信息技术的高速发展的今天,计算机和计算机技术大量应用在人们的日常生活中,嵌入式计算机也得到了广泛的应用.嵌入式计算机是指完成一种或多种特定功能的计算机系统,是软硬件的紧密结合体. ...

  5. vxworks 实时操作系统

    VxWorks 是美国 Wind River System 公司( 以下简称风河公司 ,即 WRS 公司)推出的一个实时操作系统.Tornado 是WRS 公司推出的一套实时操作系统开发环境,类似Mi ...

  6. QNX 实时操作系统(Quick Unix)

    Gordon Bell和Dan Dodge在1980年成立了Quantum Software Systems公司,他们根据大学时代的一些设想写出了一个能在IBM PC上运行的名叫QUNIX(Quick ...

  7. VxWorks Fuzzing 之道:VxWorks 工控实时操作系统漏洞挖掘调试与利用揭秘

    转载:freebuf 0×00 前言 关于VxWorks,这里引用44CON议题<攻击 VxWorks:从石器时代到星际>探究 一文章中的介绍: VxWorks 是世界上使用最广泛的一种在 ...

  8. Atitit.软件兼容性原理与实践 v5 qa2.docx

    Atitit.软件兼容性原理与实践   v5 qa2.docx 1. Keyword2 2. 提升兼容性的原则2 2.1. What 与how 分离2 2.2. 老人老办法,新人新办法,只新增,少修改 ...

  9. Atitit.软件兼容性原理与实践 v3 q326.docx

    Atitit.软件兼容性原理与实践 v3 q326.docx 1. 架构兼容性1 2. Api兼容性1 2.1. 新api  vs  修改旧的api1 3. Web方面的兼容性(js,html)1 3 ...

随机推荐

  1. Linux Linux程序练习八

    题目:自己动手实现一个守护进程,当控制台窗口关闭时还可以在后台运行.每隔一秒钟向my.log文件中插入一条记录,记录格式如下:yyyy-mm-dd hh:mi:se 记录内容,其中yyyy为年,mm为 ...

  2. JS insertAdajcentHTML 方法简介

    修改节点的内容除了常用的innerHTML和innerText之外,还有insertAdjacentHTML和insertAdjacentText方法,可以在指定的地方插入内容.insertAdjac ...

  3. 面试准备(三) Java 异常类层次结构

    在Java中,异常分为受检查的异常,与运行时异常. 两者都在异常类层次结构中.这类容易出选择题 考试你是否掌握了异常类并清楚哪些异常类必须捕获 下面的图展示了Java异常类的继承关系. 图1 粉红色的 ...

  4. matlab如何读取未知行数,带头文件和字段名的txt文件

    文件格式是这样的 20120108 50024 X235RZB30801 01 15 2361 2362 2363 2364 2365 2366 2367 2368 2369 236A 236B 23 ...

  5. 实践2.4 ELF文件格式分析

    实践2.4 ELF文件格式分析 1.ELF文件头 查看/usr/include/elf.h文件: #define EI_NIDENT (16) typedef struct { unsigned ch ...

  6. 信息安全系统设计基础实验四 20135210&20135218

    北京电子科技学院(BESTI) 实     验    报     告 课程:信息安全系统设计基础          班级:   1352 姓名:程涵,姬梦馨 学号:20135210,20135218 ...

  7. java个人总结

    20145230<Java程序设计>课程总结 每周读书笔记链接汇总 20145230<java程序设计>第0周学习总结:http://www.cnblogs.com/kobe2 ...

  8. 学习笔记——Maven实战(四)基于Maven的持续集成实践

    Martin的<持续集成> 相信很多读者和我一样,最早接触到持续集成的概念是来自Martin的著名文章<持续集成>,该文最早发布于2000年9月,之后在2006年进行了一次修订 ...

  9. WIN7下USB多点触摸,一次发多个数据包的延迟问题,重要!

    这个问题很常见, 花了差不多一个星期时间来解决.硬件相关的东西太多坑了,而且这些坑不像代码那样可见.   使用混合模式,每次最多报告2个点.如果是5点则需要上报三次. 问题就来了,atmel的CTP最 ...

  10. angular实现了一个简单demo,angular-weibo-favorites

    前面必须说一段 帮客户做了一个过渡期的项目,唯一的要求就是速度,我只是会点儿基础的php,于是就用tp帮客户做了这个项目.最近和客户架构沟通,后期想把项目重新做一下,就用现在最流行的技术,暂时想的使用 ...