3.2 μC/OS-Ⅱ的时钟
☆时钟:任何操作系统都要提供一个周期性的信号源,以供系统处理诸如延时、超时等与时间有关的时间。
☆利用硬件定时器产生一个周期是毫秒级的周期性中断来实现系统时钟,最小时钟单位为时钟节拍。
☆OSTickISR():硬件定时器以时钟节拍为周期定时产生中断的中断服务程序。完成系统在每个时钟节拍时所需的工作。
代码如下:
void OSTickISR(void)
{
保存CPU寄存器;
调用OSIntEnter(); //记录中断嵌套层数
if(OSIntNesting == 1)
{
OSTCBCur -> OSTCBStkPtr = SP; //在任务TCB中保存堆栈指针
}
调用OSTimeTick(); //节拍处理
清除中断;
开中断;
调用OSIntExit(); //中断嵌套层数减1
恢复CPU寄存器;
中断返回;
}
☆时钟节拍服务函数:在时钟中断服务程序中调用的OSTimeTick()。
代码如下:
OSTimeTick()的任务:在每个时钟节拍了解每个任务的延时状态,使其中已经到了延时时限的非挂起任务进入就绪状态。
3.3 时间管理
☆任务的延时:
函数OSTimeDly(),使当前任务的运行延时一段时间并进行一次任务调度,以让出CPU的使用权。
代码如下:
void OSTimeDly()
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
if(ticks > 0)
{
OS_ENTER_CRITICAL();
if((OSRdyTbl[OSTCBCur -> OSTCBY] &= ~OSTBCur -> OSTCBitX) == 0)
{
OSRdyGrp &= ~OSTCBCur -> OSTCBBitY; //取消当前任务的就绪状态
}
OSTCBCur -> OSTCBDly = ticks; //延时节拍数存入任务控制块
OST_EXIT_CRITICAL();
OS_Sched(); //调用调度函数
}
}
参数ticks是以时钟节拍数为单位的延时时间的。
☆用时、分、秒为参数的任务的延时函数OSTimeDlyHMSM(),原型如下:
INT8U OSTimeDlyHMSM(
INT8U hours, //小时
INT8U minutes, //分
INT8U seconds, //秒
INT16U milli //毫秒
);
☆调用函数OSTimeDly()和OSTimeDlyHMSM()的任务,当规定的延时时间期满,或有其他任务通过函数OSTimeDlyResume()取消了延时时,它会立即进入就绪状态。
☆取消任务的延时:
函数OSTimeDlyResume()
INT8U OSTimeDlyResume(INT8U prio);
参数prio为被取消延时任务的优先级别。
OSTimeDlyResume()函数的源代码:
☆获取和设置系统时间:
函数OSTimeGet()获取OSTime的值,OSTime在应用程序调用OSStart()时被初始化为0,以后每发生1个时钟节拍,OSTime的值就加1。
原型:
INT8U OSTimeGet(void);
函数OSTimeSet()可以设置OSTime的值。
原型:
void OSTimeSet(INT32U ticks);
3.4 小结
1.在μC/OS-Ⅱ中,中断服务子程序运行结束之后,系统将会根据情况进行一次中断级的任务调度去运行优先级别最高的就绪任务,而并不一定要接续运行被中断的任务。
2.μC/OS-Ⅱ的中断允许嵌套,用全局变量OSIntNesting来记录嵌套数。
3.μC/OS-Ⅱ的中断服务程序的工作通常是由中断激活的一个任务来完成的。
4.在任务中可以设置临界区的方法来屏蔽中断。设置临界区的宏有三种方式来实现。
5.μC/OS-ⅡI的时钟通常是一个由硬件计数器定时产生周期性中断信号来实现的,每一次中断叫做一个节拍,其中断服务程序叫做节拍服务程序。
6.μC/OS-Ⅱ在每一个节拍服务里都要遍历系统中全部任务的任务控制块,把其中记录任务延时时间的成员OSTCBDly减1,并使延时时间到的任务进入就绪状态。
7.μC/OS-Ⅱ有10个函数提供了钩子函数,应用程序设计人员可以再钩子函数中编写写自己的代码。
8.μC/OS-Ⅱ进行时间管理的函数中,最重要的是延时函数OSTimeDly()和OSTimeDlyHMSM().
|