1 CPU使用百分比测量
1.1 需求概述

1.2 设计原理

1.3 设计实现
特殊代码块:

统计使用百分比:

相关代码如下:
// 空闲任务计数与最大计数
uint32_t idleCount;
uint32_t idleMaxCount;
static void initCpuUsageStat (void);
static void checkCpuUsage (void);
static void cpuUsageSyncWithSysTick (void);
static float cpuUsage; // cpu使用率统计
static uint32_t enableCpuUsageStat; // 是否使能cpu统计
/**********************************************************************************************************
** Function name : initCpuUsageStat
** Descriptions : 初始化cpu统计
** parameters : 无
** Returned value : 无
***********************************************************************************************************/
static void initCpuUsageStat (void)
{
idleCount = 0;
idleMaxCount = 0;
cpuUsage = 0;
enableCpuUsageStat = 0;
}
/**********************************************************************************************************
** Function name : checkCpuUsage
** Descriptions : 检查cpu使用率
** parameters : 无
** Returned value : 无
***********************************************************************************************************/
static void checkCpuUsage (void)
{
// 与空闲任务的cpu统计同步
if (enableCpuUsageStat == 0)
{
enableCpuUsageStat = 1;
tickCount = 0;
return;
}
if (tickCount == TICKS_PER_SEC)
{
// 统计最初1s内的最大计数值
idleMaxCount = idleCount;
idleCount = 0;
// 计数完毕,开启调度器,允许切换到其它任务
tTaskSchedEnable();
}
else if (tickCount % TICKS_PER_SEC == 0)
{
// 之后每隔1s统计一次,同时计算cpu利用率
cpuUsage = 100 - (idleCount * 100.0 / idleMaxCount);
idleCount = 0;
}
}
/**********************************************************************************************************
** Function name : tTaskSystemTickHandler
** Descriptions : 系统时钟节拍处理。
** parameters : 无
** Returned value : 无
***********************************************************************************************************/
void tTaskSystemTickHandler (void)
{
tNode * node;
// 进入临界区,以保护在整个任务调度与切换期间,不会因为发生中断导致currentTask和nextTask可能更改
uint32_t status = tTaskEnterCritical();
// 检查所有任务的delayTicks数,如果不0的话,减1。
for (node = tTaskDelayedList.headNode.nextNode; node != &(tTaskDelayedList.headNode); node = node->nextNode)
{
tTask * task = tNodeParent(node, tTask, delayNode);
if (--task->delayTicks == 0)
{
// 如果任务还处于等待事件的状态,则将其从事件等待队列中唤醒
if (task->waitEvent)
{
// 此时,消息为空,等待结果为超时
tEventRemoveTask(task, (void *)0, tErrorTimeout);
}
// 将任务从延时队列中移除
tTimeTaskWakeUp(task);
// 将任务恢复到就绪状态
tTaskSchedRdy(task);
}
}
// 检查下当前任务的时间片是否已经到了
if (--currentTask->slice == 0)
{
// 如果当前任务中还有其它任务的话,那么切换到下一个任务
// 方法是将当前任务从队列的头部移除,插入到尾部
// 这样后面执行tTaskSched()时就会从头部取出新的任务取出新的任务作为当前任务运行
if (tListCount(&taskTable[currentTask->prio]) > 0)
{
tListRemoveFirst(&taskTable[currentTask->prio]);
tListAddLast(&taskTable[currentTask->prio], &(currentTask->linkNode));
// 重置计数器
currentTask->slice = TINYOS_SLICE_MAX;
}
}
// 节拍计数增加
tickCount++;
// 检查cpu使用率
checkCpuUsage();
// 退出临界区
tTaskExitCritical(status);
// 通知定时器模块节拍事件
tTimerModuleTickNotify();
// 这个过程中可能有任务延时完毕(delayTicks = 0),进行一次调度。
tTaskSched();
}
/**********************************************************************************************************
** Function name : cpuUsageSyncWithSysTick
** Descriptions : 为检查cpu使用率与系统时钟节拍同步
** parameters : 无
** Returned value : 无
***********************************************************************************************************/
static void cpuUsageSyncWithSysTick (void)
{
// 等待与时钟节拍同步
while (enableCpuUsageStat == 0)
{
;;
}
}
/**********************************************************************************************************
** Function name : cpuUsageSyncWithSysTick
** Descriptions : 为检查cpu使用率与系统时钟节拍同步
** parameters : 无
** Returned value : 无
***********************************************************************************************************/
float tCpuUsageGet (void)
{
float usage = 0;
uint32_t status = tTaskEnterCritical();
usage = cpuUsage;
tTaskExitCritical(status);
return usage;
}
// 用于空闲任务的任务结构和堆栈空间
tTask tTaskIdle;
tTaskStack idleTaskEnv[TINYOS_IDLETASK_STACK_SIZE];
void idleTaskEntry (void * param) {
// 禁止调度,防止后面在创建任务时切换到其它任务中去
tTaskSchedDisable();
// 初始化App相关配置
tInitApp();
// 初始化定时器任务
tTimerInitTask();
// 启动系统时钟节拍
tSetSysTickPeriod(TINYOS_SYSTICK_MS);
// 等待与时钟同步
cpuUsageSyncWithSysTick();
for (;;)
{
uint32_t status = tTaskEnterCritical();
idleCount++;
tTaskExitCritical(status);
}
}
int main ()
{
// 优先初始化tinyOS的核心功能
tTaskSchedInit();
// 初始化延时队列
tTaskDelayedInit();
// 初始化定时器模块
tTimerModuleInit();
// 初始化时钟节拍
tTimeTickInit();
// 初始化cpu统计
initCpuUsageStat();
// 创建空闲任务
tTaskInit(&tTaskIdle, idleTaskEntry, (void *)0, TINYOS_PRO_COUNT - 1, idleTaskEnv, TINYOS_IDLETASK_STACK_SIZE);
// 这里,不再指定先运行哪个任务,而是自动查找最高优先级的任务运行
nextTask = tTaskHighestReady();
// 切换到nextTask, 这个函数永远不会返回
tTaskRunFirst();
return 0;
}
参考资料:
1160

被折叠的 条评论
为什么被折叠?



