概述
1、UCOSII的定时中断
(1)绝大多数的内核要求提供定时中断,以实现延时与超时控制等功能。这个定时中断叫做时钟节拍。
(2)时钟的中断子程序ISR和时钟节拍函数OSTimeTick()
该函数用于通知UCOSII
,发生了时钟的节拍中断。
2、UCOSII的5个关键的时钟函数
(1)OSTimeDly();
后面的4个函数可以根据需要进行配置使用
(2)OSTimeHMSM();
(3)OSTimeDlyResume();
(4)OSTimeGet();
(5)OSTimeSet();
3、关键的时钟延时函数的实现OSTimeDly()
(1)参数分析:
ticks:代表的是多少个时钟周期节拍
(2)实现过程:
把相应任务的就绪表中的位图的位置清零。
把需要执行的等待节拍进行处理。
最后进行任务调度,寻找下一个这个时刻最高优先级的任务。
(3)发出疑问?为什么我在OS_TCB的结构体当中的Ticks填写相应的数字的时候可以
实现把任务从就绪态变为等待的状态?
答案:OSTimeTick()这个函数
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;
}
OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */
OS_EXIT_CRITICAL();
OS_Sched(); /* Find next task to run! */
}
}
实现任务等待时间的关键的函数:
PS:我以后都会把对理解无关紧要的代码删除。
(1)当任务是处于运行的状态的时候。判断OS现在处于的是什么样的状态。
(2)所有的任务都是通过任务的链表链接到一起的,我们后面的一个while循环就是,从开始不断的遍历到最后的任务,也就是空闲任务。
(3)对延时的时间不断的减1,当延时的dlyTick减少到0的时候,对OS_TCB任务控制块的一些状态进行修改,并且重新的把任务添加回就绪表中。
PS:这个函数应该是放置到中断服务函数中的,整个时间片的不断的触发执行的。
void OSTimeTick (void)
{
OS_TCB *ptcb;
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
//此处为此任务运行的核心的代码:
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 */
if (ptcb->OSTCBDly == 0u) { /* Check for timeout */
if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
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;
}
}
}
ptcb = ptcb->OSTCBNext; /* Point at next TCB in TCB list */
OS_EXIT_CRITICAL();
}
}
}
OSTimeDlyHmSM
INT8U OSTimeDlyHMSM (INT8U hours, INT8U minutes, INT8U seconds, INT16U milli)
由于OSTimeDlyHMSM()的具体实现方法,用户不能结束延时调用OSTimeDlyHMSM()要求延时超过65535个节拍的任务。换句话说,如果时钟节拍的频率是100Hz,用户不能让调用OSTimeDlyHMSM(0,10,55,350)或更长延迟时间的任务结束延时。
4、恢复延时的任务:OSTimeDlyResume()
里面关键的操作就是把那个全局的时间计数器变量设置为0
INT8U OSTimeDlyResume (INT8U prio)
{
OS_TCB *ptcb;
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 */
}
ptcb->OSTCBDly = 0u; /* 清除任务计数器 */
if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
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;
}
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);
}
最后
以上就是酷酷篮球为你收集整理的UCOSII操作系统(五)--时间管理的全部内容,希望文章能够帮你解决UCOSII操作系统(五)--时间管理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复