📄 os_stat.c
字号:
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* STATISTICS TASK
*
* Description: This task is internal to uC/OS-III and is used to compute some statistics about the multitasking
* environment. Specifically, OS_StatTask() computes the CPU usage. CPU usage is determined by:
*
* OSStatTaskCtr
* OSStatTaskCPUUsage = 100 * (1 - ------------------) (units are in %)
* OSStatTaskCtrMax
*
* Arguments : p_arg this pointer is not used at this time.
*
* Returns : none
*
* Note(s) : 1) This task runs at a priority level higher than the idle task.
*
* 2) You can disable this task by setting the configuration #define OS_CFG_STAT_TASK_EN to 0.
*
* 3) You MUST have at least a delay of 2/10 seconds to allow for the system to establish the maximum value
* for the idle counter.
*
* 4) This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_StatTask (void *p_arg)
{
#if OS_CFG_DBG_EN > 0u
#if OS_CFG_TASK_PROFILE_EN > 0u
OS_CPU_USAGE usage;
OS_CYCLES cycles_total;
#endif
OS_TCB *p_tcb;
#endif
OS_ERR err;
OS_TICK dly;
CPU_TS ts_start;
CPU_TS ts_end;
CPU_SR_ALLOC();
p_arg = p_arg; /* Prevent compiler warning for not using 'p_arg' */
while (OSStatTaskRdy != DEF_TRUE) {
OSTimeDly(2u * OSCfg_StatTaskRate_Hz, /* Wait until statistic task is ready */
OS_OPT_TIME_DLY,
&err);
}
OSStatReset(&err); /* Reset statistics */
dly = (OS_TICK)0; /* Compute statistic task sleep delay */
if (OSCfg_TickRate_Hz > OSCfg_StatTaskRate_Hz) {
dly = (OS_TICK)(OSCfg_TickRate_Hz / OSCfg_StatTaskRate_Hz);
}
if (dly == (OS_TICK)0) {
dly = (OS_TICK)(OSCfg_TickRate_Hz / (OS_RATE_HZ)10);
}
while (DEF_ON) {
ts_start = OS_TS_GET();
#ifdef CPU_CFG_INT_DIS_MEAS_EN
OSIntDisTimeMax = CPU_IntDisMeasMaxGet();
#endif
CPU_CRITICAL_ENTER(); /* ----------------- OVERALL CPU USAGE ------------------ */
OSStatTaskCtrRun = OSStatTaskCtr; /* Obtain the of the stat counter for the past .1 second */
OSStatTaskCtr = (OS_TICK)0; /* Reset the stat counter for the next .1 second */
CPU_CRITICAL_EXIT();
if (OSStatTaskCtrMax > OSStatTaskCtrRun) {
if (OSStatTaskCtrMax > (OS_TICK)0) {
OSStatTaskCPUUsage = (OS_CPU_USAGE)((OS_TICK)100u - 100u * OSStatTaskCtrRun / OSStatTaskCtrMax);
} else {
OSStatTaskCPUUsage = (OS_CPU_USAGE)100;
}
} else {
OSStatTaskCPUUsage = (OS_CPU_USAGE)100;
}
OSStatTaskHook(); /* Invoke user definable hook */
#if OS_CFG_DBG_EN > 0u
#if OS_CFG_TASK_PROFILE_EN > 0u
cycles_total = (OS_CYCLES)0;
p_tcb = OSTaskDbgListPtr;
while (p_tcb != (OS_TCB *)0) { /* ----------------- TOTAL CYCLES COUNT ----------------- */
OS_CRITICAL_ENTER();
p_tcb->CyclesTotalPrev = p_tcb->CyclesTotal; /* Save accumulated # cycles into a temp variable */
p_tcb->CyclesTotal = (OS_CYCLES)0; /* Reset total cycles for task for next run */
OS_CRITICAL_EXIT();
cycles_total += p_tcb->CyclesTotalPrev;/* Perform sum of all task # cycles */
p_tcb = p_tcb->DbgNextPtr;
}
#endif
#if OS_CFG_TASK_PROFILE_EN > 0u
cycles_total /= 100u; /* ------------- INDIVIDUAL TASK CPU USAGE -------------- */
#endif
p_tcb = OSTaskDbgListPtr;
while (p_tcb != (OS_TCB *)0) {
#if OS_CFG_TASK_PROFILE_EN > 0u /* Compute execution time of each task */
if (cycles_total > (OS_CYCLES)0) {
usage = (OS_CPU_USAGE)(p_tcb->CyclesTotalPrev / cycles_total);
if (usage > 100u) {
usage = 100u;
}
} else {
usage = 0u;
}
p_tcb->CPUUsage = usage;
#endif
#if OS_CFG_STAT_TASK_STK_CHK_EN > 0u
OSTaskStkChk( p_tcb, /* Compute stack usage of active tasks only */
&p_tcb->StkFree,
&p_tcb->StkUsed,
&err);
#endif
p_tcb = p_tcb->DbgNextPtr;
}
#endif
if (OSStatResetFlag == DEF_TRUE) { /* Check if need to reset statistics */
OSStatResetFlag = DEF_FALSE;
OSStatReset(&err);
}
ts_end = OS_TS_GET() - ts_start; /* Measure execution time of statistic task */
if (ts_end > OSStatTaskTimeMax) {
OSStatTaskTimeMax = ts_end;
}
OSTimeDly(dly,
OS_OPT_TIME_DLY,
&err);
}
}
/*$PAGE*/
/*
************************************************************************************************************************
* INITIALIZE THE STATISTICS
*
* Description: This function is called by OSInit() to initialize the statistic task.
*
* Argument(s): p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_STK_INVALID If you specified a NULL stack pointer during configuration
* OS_ERR_STK_SIZE_INVALID If you didn't specify a large enough stack.
* OS_ERR_PRIO_INVALID If you specified a priority for the statistic task equal to or
* lower (i.e. higher number) than the idle task.
* OS_ERR_xxx An error code returned by OSTaskCreate()
*
* Returns : none
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_StatTaskInit (OS_ERR *p_err)
{
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
OSStatTaskCtr = (OS_TICK)0;
OSStatTaskCtrRun = (OS_TICK)0;
OSStatTaskCtrMax = (OS_TICK)0;
OSStatTaskRdy = OS_STATE_NOT_RDY; /* Statistic task is not ready */
OSStatResetFlag = DEF_FALSE;
/* ---------------- CREATE THE STAT TASK ---------------- */
if (OSCfg_StatTaskStkBasePtr == (CPU_STK*)0) {
*p_err = OS_ERR_STK_INVALID;
return;
}
if (OSCfg_StatTaskStkSize < OSCfg_StkSizeMin) {
*p_err = OS_ERR_STK_SIZE_INVALID;
return;
}
if (OSCfg_StatTaskPrio >= (OS_CFG_PRIO_MAX - 1u)) {
*p_err = OS_ERR_PRIO_INVALID;
return;
}
OSTaskCreate((OS_TCB *)&OSStatTaskTCB,
(CPU_CHAR *)((void *)"uC/OS-III Stat Task"),
(OS_TASK_PTR )OS_StatTask,
(void *)0,
(OS_PRIO )OSCfg_StatTaskPrio,
(CPU_STK *)OSCfg_StatTaskStkBasePtr,
(CPU_STK_SIZE)OSCfg_StatTaskStkLimit,
(CPU_STK_SIZE)OSCfg_StatTaskStkSize,
(OS_MSG_QTY )0,
(OS_TICK )0,
(void *)0,
(OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
(OS_ERR *)p_err);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -