UCOS中的OSStatInit()函数

ucos启动之后,会创建两个任务,空闲任务和统计任务(若是配置了的话),咱们常常会在代码里看到OSStatInit(),其实这个函数使用的时候要当心了。
做者原著中提到,OSStatInit()要在创建的第一个,而且只有一个任务的时候调用,因此会常常见到下面的结构:
int main(void)
{
OSInit();


OSStart();
}

void AppTask(void *pdata)
{

}

这样作是由于统计任务计算CPU利用率的须要。函数

之因此说,调用这个函数要注意,主要缘由就是由于在OSStatInit()中调用OSTimeDly发生了任务的调度,而这一点特别容易被忽略掉。学习

 

----------------------------------------------------------------------.net

----------------------------------------------------------------------get

void OSStatInit (void)

#if OS_TASK_STAT_EN > 0
void OSStatInit (void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif


OSTimeDly(2);
OS_ENTER_CRITICAL();
OSIdleCtr = 0L;
OS_EXIT_CRITICAL();
OSTimeDly(OS_TICKS_PER_SEC / 10);
OS_ENTER_CRITICAL();
OSIdleCtrMax = OSIdleCtr;
OSStatRdy = TRUE;
OS_EXIT_CRITICAL();
}
#endif

在OSStatInit一开始延迟时间为2时钟节拍里:第一在就绪表中删除掉当前任务的就绪标志,这个当前任务也就是调用OSStatInt()的用户编写的TaskStart()任务,这是用户建立的优先级最高的任务;第二令OSTCBDly =ticks也就是这个任务要延迟ticks所表明的时间;第三,调用 OS_Sched(),进行一次任务调度,在任务调度里找出优先级最高的任务,并进行任务切换,切换到如今的具备最高优先级的任务,使其运行。此时在任务调度的时候,TaskStart()任务又从新处于就绪状态,此时程序从OSTimeDly(2)中返回,接着执行下面的程序。执行完OSIdleCtr= 0L; 后,又进入一个延时程序OSTimeDly(OS_TICKS_PER_SEC / 10);,本程序是又延迟了100毫秒,在这100毫秒中,TaskStart()任务处于等待状态,所以在这100毫秒中执行的是Idle任务。Idle任务会不断给OSIdelCtr计数,从而100毫秒后OSIdelCtr记录的就是100毫秒内被增长的最大次数(在这一秒中没有其它任务高于Idle任务,因此结果是最大的)。100毫秒延迟结束后。TaskStart()任务从新就绪,得到cpu使用权,就执行OSIdleCtrMax= OSIdleCtr; OSStatRdy = TRUE;此后程序结束。

OSStatInit一开始延迟时间为2时钟节拍,用于保持与系统时钟的同步,由于延迟以后调用的第一个语句为“OSIdelCtr=0”,基本不用花费系统时间,而后就进入第二个语句OSTimeDly(OS_TICKS_PER_SEC);至关于再次延迟1s;在这延迟的一秒中,Idle任务会不断给OSIdelCtr计数,从而1s后OSIdelCtr记录的就是1s内被增长的最大次数(在这一秒中没有其它任务高于Idle任务,因此结果是最大的)。

在创建其余任务以前,必须调用OSStatInit()来肯定用户的PC有多快。在一开始,OSStatInit()就将自身延时了两个时钟节拍,这样它就能够与时钟节拍中断同步。所以,OSStatInit()必须在时钟节拍启动以后调用;不然,用户的应用程序就会崩溃。当µC/OS-II调用OSStatInit()时,一个32位的计数器OSIdleCtr被清为0,并产生另外一个延时,这个延时使OSStatInit()挂起。此时,uCOS-II没有别的任务能够执行,它只能执行空闲任务(µC/OS-II的内部任务)。空闲任务是一个无线的循环,它不断的递增OSIdleCtr。1秒之后,uCOS-II从新开始OSStatInit(),而且将OSIdleCtr保存在OSIdleMax中。因此OSIdleMax是OSIdleCtr所能达到的最大值。而当用户再增长其余应用代码时,空闲任务就不会占用那样多的CPU时间。若是用户程序每秒抚慰一次OSIdleCtr()那么OSIdleCtr不可能达到那样多的记数。CPU利用率的计算由µC/OS-II中的OSStatTask()函数来完成,这个任务每秒执行一次。而当OSStatRdy置为TRUE表示µC/OS-II将统计CPU的利用率。

OSStatInit()将返回到TaskStart()。全部任务能够都由TaskStart()中创建,因为TaskStart()的优先级为0(最高),新任务创建后不进行任务调度。当全部任务都创建完成后,TaskStart()将进入无限循环之中。

嵌入式应用时,用户必须在第一个任务中打开时钟节拍中断。

void ARMStartTimer(void)
{
//autoreload and start m
rTCON = 0x9;
}同步


学习统计任务的过程当中,要十分注意统计任务初始化函数OSStatInit和OSTaksStat之间时间延迟的区别和应用!
OSStatInit一开始延迟时间为2时钟节拍,用于保持与系统时钟的同步,由于延迟以后调用的第一个语句为“OSIdelCtr=0”,基本不用花费系统时间,而后就进入第二个语句OSTimeDly(OS_TICKS_PER_SEC);至关于再次延迟1s;在这延迟的一秒中,Idle任务会不断给OSIdelCtr计数,从而1s后OSIdelCtr记录的就是1s内被增长的最大次数(在这一秒中没有其它任务高于Idle任务,因此结果是最大的)。it

OSTaskStat则不一样,它一开始就直接延迟2s(注意不是2时钟节拍),而2s>>2时钟节拍,所以在OSStatInit中进行时钟同步和最大值记录过程当中,OSTaskStat一直处于休眠状态,不会影响到前面的操做。配置

相关文章
相关标签/搜索