1 中断
1.1 相关概念
裸机的中断和μC/OS-II的中断大体相同,但也有不同的地方。具体为以下几个方面:
- 中断服务子程序运行结束后,系统将会根据情况进行一次任务调度去运行优先级别最高的就绪任务,而不一定要继续运行被中断的任务。这里的情况需要满足以下三个条件:
- 中断嵌套层数为0
- 调度器未锁定
- 最高级别的就绪任务不是被中断的任务
- 由上述可知,我们需要记录中断嵌套层数,因此需要在运行中断服务函数代码前,对中断嵌套层数计数器+1;退出中断服务函数前,,对中断嵌套层数计数器-1,并执行一次任务调度,具体实现方法如下:
void IRQHandler (void)
{
OSIntEnter (); //中断嵌套层数计数器+1
//中断服务函数代码
OSIntExit (); //中断嵌套层数计数器-1,任务调度
}
1.2 中断相关API
μC/OS-II中与中断相关的函数分布比较散但是不多,如有需要,可以自行从μC/OS-II内核文件从查找。以下列出函数声明以供查阅。
#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();}
#define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);}
void OSIntEnter (void)
void OSIntExit (void)
2 时钟
2.1 相关概念
任何操作系统都要提供一个周期性的信号源,以供系统处理诸如延时、超时等与时间有关的事件,这个周期性的信号源叫做时钟。μC/OS-II用硬件定时器产生一个周期性中断,该中断服务函数为OSTickISR(),在该函数中,调用OSTimeTIck()函数完成系统在每个时钟节拍时需要做的工作:
- 给计数器OSTime+1
- 所有任务控制块中,把存放任务延时的OSTCBDly变量(不等于0)-1
- 使到了延时期限的非挂起任务进入就绪状态
- 另外,提供了一个钩子函数OSTimeTickHook()供用户插入自己的工作。μC/OS-II在一些系统函数中提供了钩子函数,使得用户能够实现某些功能,函数名称xxxxHook()。但是对于初学者来说,比较少使用这些钩子函数,如有需要可以查阅相关资料,看看哪些系统函数拥有钩子函数,并加以使用。
2.2 时钟相关API
一般来说,用户不直接调用时钟相关的API,相关函数实现的功能在2.1中已经叙述,如需要源码可以通过函数名在μC/OS-II内核文件中查找,此处不再赘述。
3 时间管理
3.1 相关概念
μC/OS-II规定:除了空闲任务以外的所有任务,必须在任务中合适的位置调用系统提供的函数OSTimeDly(ticks)或OSTimeDlyHMSM(hours,minutes,seconds,milli),使当前任务的运行延时(暂停)一段时间并进行一次任务调度,以让出CPU的使用权。系统延时函数的延时原理我们不深究,需要关注的是以下几点:
- 当某个任务调用了系统延时函数,该任务就会被挂起,并执行一次任务调度
- 当规定的延时时间期满,任务进入就绪状态
- 当其他任务通过调用OSTimeDlyResume()函数取消了延时,任务进入就绪状态,并执行一次任务调度
3.2 时间管理相关API
μC/OS-II中与时间管理相关的函数定义在os_time.c文件中,函数声明在ucos_ii.h文件中,以下列出函数声明以供查阅。
void OSTimeDly (INT32U ticks);
INT8U OSTimeDlyHMSM (INT8U hours,
INT8U minutes,
INT8U seconds,
INT16U ms);
INT8U OSTimeDlyResume (INT8U prio);
INT32U OSTimeGet (void);
void OSTimeSet (INT32U ticks);