/*
********************************************************************************************************** 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 stacksHANDLE 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