空闲任务是其他任务都没就绪时运行的任务,帮助统计任务记录空闲任务运行的次数OSIdleCtr。这个任务是程序必须使用的,不能用软件删除。
void OS_TaskIdle (void *p_arg)
{
p_arg = p_arg; //防止编译器报错,没有用到P_ARG变量
for (;;) { //任务都是一个死循环
OS_ENTER_CRITICAL(); //关闭中断
OSIdleCtr++; //每运行一次都会记录下
OS_EXIT_CRITICAL(); //开放中断
OSTaskIdleHook(); //每运行一次空闲任务调用的勾函数
}
}
统计函数每秒计算一次处理器单位时间内的被任务占用时间,可以通过 OS_TASK_STAT_EN 置一来打开。
#if OS_TASK_STAT_EN > 0u
void OS_TaskStat (void *p_arg)
{
#if OS_CRITICAL_METHOD == 3u
OS_CPU_SR cpu_sr = 0u;
#endif
p_arg = p_arg; //防止编译器报错
while (OSStatRdy == OS_FALSE) { //OS_TICKS_PER_SEC时钟节拍
OSTimeDly(2u * OS_TICKS_PER_SEC / 10u); //直到操作系统就绪才允许运行统计任务
}
OSIdleCtrMax /= 100uL; //OSIdleCtrMax空闲任务0.1s内运行次数的最大值,这个值是在 OSStatInit函数中确定的。该函数运行时其他任务还没有运行,cpu只运行空闲函数。这时候就可以计算出可以0.1s中最多跑多少个空闲任务。这里有疑问,每次调用统计任务这个值都被除1次。。。。。。好像不对啊。
if (OSIdleCtrMax == 0uL) {
OSCPUUsage = 0u; //如果这个最大值小于100统计错了,清零。
#if OS_TASK_SUSPEND_EN > 0u //如果启用挂起任务函数
(void)OSTaskSuspend(OS_PRIO_SELF); //把当前的统计任务挂起(退出统计任务)
#else
for (;;) { //如果没有启用
OSTimeDly(OS_TICKS_PER_SEC); //利用 OSTimeDly进行任务调度(退出统计任务)
}
#endif
}
for (;;) {
OS_ENTER_CRITICAL();
OSIdleCtrRun = OSIdleCtr; //获取上一秒内空闲任务的运行次数
OSIdleCtr = 0uL; //同时清空空闲任务计数器为下一次统计做准备 OS_EXIT_CRITICAL();
OSCPUUsage = (INT8U)(100uL - OSIdleCtrRun / OSIdleCtrMax);
OSTaskStatHook(); //调用勾函数
#if (OS_TASK_STAT_STK_CHK_EN > 0u) && (OS_TASK_CREATE_EXT_EN > 0u)
OS_TaskStatStkChk(); //检查每个任务的堆栈
#endif
OSTimeDly(OS_TICKS_PER_SEC / 10u); //积累下一次0.1秒的空闲任务运行值。
}
}