堆栈使用测量

关于堆栈的统计,他的应用主要是确保任务堆栈不会栈溢出,而导致影响其他任务或内核资源,但是有为了对资源的良好利用,进而引出了堆栈测量

堆栈统计的方法,大致是把堆栈初始化全部为0,遍历找出为0的,就是未使用的空间;当然,这种方法需要这个任务运行长时间进而运行完所有的情况,因为可能在某个情况下,它开辟了空间,这么统计的就不准确了

    info->stackFree = 0;
    stackEnd = task->stackBase;
    while ((*stackEnd++ == 0) && (stackEnd <= task->stackBase + task->stackSize / sizeof(tTaskStack)))
    {
        info->stackFree++;
    }
    // 转换成字节数
    info->stackFree *= sizeof(tTaskStack);

在tTaskGetInfo新增以上内容,逻辑是从栈顶往下遍历出0的数量—也需要保证遍历范围不超过栈的大小,最后乘上单位即可,这里的单位也就是定义栈的数据类型

CPU使用百分比测量

采用的方法是先执行一段程序,时间自定义,单独运行这个代码块获取到计数,定义为Max;后面通过实际运行同样获取到计数,定义为Cnt;大致可以算出来百分比=100 * (1 - Cnt/Max);这里执行特殊代码块就是空闲任务

static float cpuUsage;                      // cpu使用率统计
static uint32_t enableCpuUsageStat;         // 是否使能cpu统计
static void initCpuUsageStat (void)
{
    idleCount = 0;
    idleMaxCount = 0;
    cpuUsage = 0;
    enableCpuUsageStat = 0;
}
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;
    }
}
static void cpuUsageSyncWithSysTick (void)
{
    // 等待与时钟节拍同步
    while (enableCpuUsageStat == 0)
    {
        ;;
    }
}
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);
    }
}

这其中最重要的是checkCpuUsage函数,功能是检查CPU使用率,然后通过调用tCpuUsageGet即可查询使用率;首先是与空闲任务的同步,这步是提高精度然后就是分为了两种情况,一种是只执行空闲任务,一种是都执行;最后计算即可

需要注意的是,必须要在滴答定时器中添加以下内容

    // 节拍计数增加
    tickCount++;
    // 检查cpu使用率
    checkCpuUsage();