- 上章节系统所有延时,与前后台无差别,体现不出RTOS的优势;
- RTOS的优势就是榨干系统性能,永远不让CPU闲着; 因此任务需要延时就不能让CPU空等,至此加入阻塞延时概念;
- 阻塞延时:即任务需要延时的时候,任务放弃CPU的使用 权,CPU可以去干其它事,当任务延时时间到,重新获取CPU使用权,任务继续运行,充分利用CPU的资源,而不是干等;
- 空闲任务:系统初始化时创建的优先级最低的任务,只是对空闲全局变量计数;实际应用中,可以利用这种特性在空闲任务中让CPU进入低功耗模式或者睡眠状态;
- 例程:
/* ************************************************************************************************************************ * 空闲任务堆栈大小、起始地址 ************************************************************************************************************************ */ CPU_STK OSCfg_IdleTaskStk[OS_CFG_IDLE_TASK_STK_SIZE]; //空闲任务堆栈起始地址 CPU_STK *const OSCfg_IdleTaskStkBasePtr = (CPU_STK *)&OSCfg_IdleTaskStk[0]; //空闲任务堆栈大小 CPU_STK const OSCfg_IdleTaskStkSize = (CPU_STK_SIZE)OS_CFG_IDLE_TASK_STK_SIZE; /********************************************************* * 函数名: void OSSched(void); * 描述 :任务调度 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :内部调用 **********************************************************/ void OSSched(void) { #if 0 //两个任务简单的交替运行 if(OSTCBCurPtr == OSRdyList[0].HeadPtr) { OSTCBHighRdyPtr = OSRdyList[1].HeadPtr; } else { OSTCBHighRdyPtr = OSRdyList[0].HeadPtr; } #endif //如果当前任务是空闲任务,那就尝试执行其它任务,看他们的延时时间是否结束 //如果任务的延时时间均无到期,那就返回继续执行空闲任务 if(OSTCBCurPtr == &OSIdleTaskTCB) { if(OSRdyList[0].HeadPtr->TaskDelayTicks == 0) //判断任务0延时是否到达 { OSTCBHighRdyPtr = OSRdyList[0].HeadPtr; //到达,下个任务指向任务0 } else if(OSRdyList[1].HeadPtr->TaskDelayTicks == 0) { OSTCBHighRdyPtr = OSRdyList[1].HeadPtr; //同上 } else { return ; //任务延时都没有到达,返回继续执行空闲任务 } } //如果当前任务非空闲任务,检查另外任务,如果不在延时中,就切换到该任务 //否则,判断下当前任务是否进入延时状态,是的话切换到空闲任务,不是不做任何切换 else { if(OSTCBCurPtr == OSRdyList[0].HeadPtr) //判断当前任务是否为任务0 { if(OSRdyList[1].HeadPtr->TaskDelayTicks ==0) //判断任务1延时是否到达 { OSTCBHighRdyPtr = OSRdyList[1].HeadPtr; //到过,下一个任务切换任务1 } else if(OSTCBCurPtr->TaskDelayTicks != 0) //判断当前任务是否到达延时状态 { OSTCBHighRdyPtr = &OSIdleTaskTCB; //是,切换回空闲任务 } else { return ; //返回,保持当前运行状态 } } else if(OSTCBCurPtr == OSRdyList[1].HeadPtr) //判断当前任务是否为任务1 { if(OSRdyList[0].HeadPtr->TaskDelayTicks ==0) //判断任务0延时是否到达 { OSTCBHighRdyPtr = OSRdyList[0].HeadPtr; //到过,下一个任务切换任务0 } else if(OSTCBCurPtr->TaskDelayTicks != 0) //判断当前任务是否到达延时状态 { OSTCBHighRdyPtr = &OSIdleTaskTCB; //是,切换回空闲任务 } else { return ; //返回,保持当前运行状态 } } } OS_TASK_SW(); //触发PendSV异常 } /********************************************************* * 函数名: OS_IdleTask(void *p_arg); * 描述 :空闲任务 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :内部调用 **********************************************************/ void OS_IdleTask(void *p_arg) { p_arg = p_arg; //空闲任务什么都不做; 只是对全局变量OSIdleTaskCtr++操作 for(;;) { OSIdleTaskCtr++; } } /********************************************************* * 函数名:OS_IdleTaskInit(OS_ERR *p_err); * 描述 :空闲任务初始化,放在系统初始化中 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :内部调用 **********************************************************/ void OS_IdleTaskInit(OS_ERR *p_err) { //初始化空闲任务计数器,设置为0 OSIdleTaskCtr = (OS_IDLE_CTR)0; //创建空闲任务 OSTaskCreate( (OS_TCB *)&OSIdleTaskTCB, (OS_TASK_PTR )OS_IdleTask, (void *)0, (CPU_STK *)OSCfg_IdleTaskStkBasePtr, (CPU_STK_SIZE)OSCfg_IdleTaskStkSize, (OS_ERR *)p_err ); }
- 实验现象:
- 总结:阻塞任务与空闲任务配合,榨干系统性能,永远不让CPU闲着;达到实时;
【13】从0到1教你写uC/OS-III————>阻塞延时与空闲任务
最新推荐文章于 2024-03-05 20:10:49 发布