一、任务状态
????????任务在内核中有五种状态,对应运行状态、等待状态、就绪状态、睡眠状态、中断状态。需要把任务交给操作系统的函数为OSTaskCreate()或OSTaskCreateExt()。任务一旦创建就进入就绪状态,任务可以在多任务运行开始之前建立,也可以被一个运行中的务动态建立。如果一个任务是被另一个任务建立的,而这个任务的优先级高于建立它的那个任务,则这个刚刚建立的任务将立即得到CPU的控制权。一个任务可以通过调用OSTaskDel()返回到睡眠态,或通过调用该函数让另一个任务进入睡眠态。剩下的任务状态转化可以以下图的方式进行转换。
?在UCOSii中也可以根据任务的优先级计算出任务的在就绪任务组中的位与任务就绪控制块的位,如图,在OSRdyTbl中如果有一个就绪的任务,则对应的OSRdyGrp对应的位也应该被置为1。比如优先级为32的任务对应二进制为00100100可以得出该任务在位图的位置,4*4。
?二、任务切换
????????为实现任务切换,OSTCBHighRdy必须指向优先级最高的那个任务控制块OS_TCB,这是通过将以OSPrioHighRdy为下标的OSTCBPrioTbl[]数组中的那个元素赋给OSTCBHighRdy来实现的。接着,统计计数器OSCtxSwCtr加1,以跟踪任务切换次数。最后宏调用OS_TASK_SW(即OSCtxSw)来完成实际上的任务切换。任务级调度函数OSSched中的所有代码都属于临界段代码。任务级切换和中断级切换最后都是调用PendSV来完成。
三、中断处理
UCOSii中的中断服务子程序执行流程如下:
? ? ? ? 1、保存所有CPU的寄存器。
? ? ? ? 2、调用OSIntEnter进入中断或者执行OSIntNesting自加一。
? ? ? ? 3、执行用户代码做中断服务。
? ? ? ? 4、执行OSIntExit退出中断。
? ? ?? ?5、恢复所有CPU寄存器。
? ? ? ? 6、执行中断返回指令。
在中断返回后对被中断了的任务说来,1、如果没有高优先级的任务被中断服务子程序激活而进入就绪态,OSIntExit()只占用很短的运行时间。进而,在这种情况下,CPU寄存器只是简单地恢复并执行中断返回指令。
2、如果中断服务子程序使一个高优先级的任务进入了就绪态,则OSIntExit()将占用较长的运行时间,因为这时要做任务切换。
四、时钟节拍
????????μC/OS需要用户提供周期性信号源,用于实现时间延时和确认超时。节拍率应在每秒10次到100次之间,或者说10到100Hz。时钟节拍率越高,系统的额外负荷就越重。时钟节拍的实际频率取决于用户应用程序的精度。时钟节拍源可以是专门的硬件定时器,也可以是来自50/60Hz交流电源的信号。
????????用户必须在多任务系统启动以后再开启时钟节拍器,也就是在调用OSStart()之后。换句话说,在调用OSStart()之后做的第一件事是初始化定时器中断。
|