昨天我们说了系统节拍,经过一步步的分析,了解了任务运行的基础,是怎么来的。今天就继续谈谈“时间管理”这个话题,系统节拍驱动任务的运行,时间管理就是对任务的运行时间进行管理的一种内核机制。那么下面就简单介绍几个常用的时间管理函数。
1.OSTimeDly函数,它位于os_time.c文件中,这个文件还有其他很多的时间管理函数,以下的函数都位于这个文件。
看了上面的参数是不是还是毫无感觉,那我们看看源码,注明:注释不是自己写的,是秉火团队写的。我们需要做的不光是学会使用这些别人提供的好内容,更要学会程序的设计思想(大学嵌入式老师讲的),所以每次看待问题,我都会提醒自己,这段代码的背后究竟是什么?别人这么设计的目的的是什么?这种设计的局限又是什么?吹了点牛,说了这么多题外的废话,就是提醒自己不要太肤浅,要多思考。。。还是从一步开始:读程序;简单的说就是停止当前任务的执行(任务为等待态),延时一段时间再继续运行,那为什么程序会有这么多if呢?因为计算机需要对未知的状态做提前的分析和预处理,以对各种情况作出反映,就像人一样,如果对某种状况毫无准备,将会措手不及;逻辑还是很清楚的,(1)如果使能了安全检测,在中断中调用此函数,调度器被锁,dly为0,opt超出范围,插入节拍列表出现错误的这几种情况,将不会进行延时处理;(2)否则,进入临界区,把任务状态变为等待态,将任务插到节拍列表(如果插入不出现错误的话),然后将任务拿出就绪列表,最后退出临界区。
void OSTimeDly (OS_TICK dly, //延时的时钟节拍数 OS_OPT opt, //选项 OS_ERR *p_err) //返回错误类型 { CPU_SR_ALLOC(); //使用到临界段(在关/开中断时)时必需该宏,该宏声明和定义一个局部变 //量,用于保存关中断前的 CPU 状态寄存器 SR(临界段关中断只需保存SR) //,开中断时将该值还原。 #ifdef OS_SAFETY_CRITICAL //如果使能(默认禁用)了安全检测 if (p_err == (OS_ERR *)0) { //如果错误类型实参为空 OS_SAFETY_CRITICAL_EXCEPTION(); //执行安全检测异常函数 return; //返回,不执行延时操作 } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u //如果使能(默认使能)了中断中非法调用检测 if (OSIntNestingCtr > (OS_NESTING_CTR)0u) { //如果该延时函数是在中断中被调用 *p_err = OS_ERR_TIME_DLY_ISR; //错误类型为“在中断函数中延时” return; //返回,不执行延时操作 } #endif /* 当调度器被锁时任务不能延时 */ if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0u) { //如果调度器被锁 *p_err = OS_ERR_SCHED_LOCKED; //错误类型为“调度器被锁” return; //返回,不执行延时操作 } switch (opt) { //根据延时选项参数 opt 分类操作 case OS_OPT_TIME_DLY: //如果选择相对时间(从现在起延时多长时间) case OS_OPT_TIME_TIMEOUT: //如果选择超时(实际同上) case OS_OPT_TIME_PERIODIC: //如果选择周期性延时 if (dly == (OS_TICK)0u) { //如果参数 dly 为0(0意味不延时) *p_err = OS_ERR_TIME_ZERO_DLY; //错误类型为“0延时” return; //返回,不执行延时操作 } break; case OS_OPT_TIME_MATCH: //如果选择绝对时间(匹配系统开始运行(OSStart())后的时钟节拍数) break; default: //如果选项超出范围 *p_err = OS_ERR_OPT_INVALID; //错误类型为“选项非法” return; //返回,不执行延时操作 } OS_CRITICAL_ENTER(); //进入临界段 OSTCBCurPtr->TaskState = OS_TASK_STATE_DLY; //修改当前任务的任务状态为延时状态 OS_TickListInsert(OSTCBCurPtr, //将当前任务插入到节拍列表 dly, opt, p_err); if (*p_err != OS_ERR_NONE) { //如果当前任务插入节拍列表时出现错误 OS_CRITICAL_EXIT_NO_SCHED(); //退出临界段(无调度) return; //返回,不执行延时操作 } OS_RdyListRemove(OSTCBCurPtr); //从就绪列表移除当前任务 OS_CRITICAL_EXIT_NO_SCHED(); //退出临界段(无调度) OSSched(); //任务切换 *p_err = OS_ERR_NONE; //错误类型为“无错误” }
2.OSTimeDlyHMSM()函数与上一个函数功能类似,具体看手册,再打出来就重复造轮子了,我们造一遍,而且知道怎么造,就没必要重复了;
3.OSTimeDlyResume()用于结束其他任务的延时。还是那句话,使用之前,多看手册;
4.OSTimeGet()函数用于获取当前的时钟节拍计数值,OSTimeSet()函数用于设置当前的时钟节拍计数值。
具体使用就自己区操作了,今天就先到这里啦!!!