SMC-RTOS之idle_task空闲任务

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33894122/article/details/81482250

idle_task

这个idle_task就是空闲任务,所谓空闲就是在CPU上没有其他thread时才会跑到的任务。
在系统初始化时,他是系统自动创建的任务,因为如果用户没有创建任何任务的话直接去启动系统,会发现无任务可调度,会崩溃。
另一个重要功能就是统计CPU的空闲时间,稍作处理就可以获得CPU的使用率。

接口介绍

  • 初始化
    这里面有个计算CPU使用率的逻辑就是用正常工作时1s内smc_idle_cnt_run自加到的数去除只有smc_idle_cnt_run自加时的smc_idle_cnt_max,得到的就是CPU空闲时间百分比,但是这个smc_idle_cnt_max是不知道的,这里有个小技巧来得到smc_idle_cnt_max,就是在开机运行任何任务前先把线程调度器给上锁,然后开一个100ms定时器,只让idle_task跑,100ms跑完会进入time_out处理函数,以后每1s也会进入time_out函数,所以在time_out函数汇总做了一个判断是否第一次time_out,第一次time_out需要改smc_idle_cnt_max,如果不是第一次就需要计算smc_cpu_usage了。
void smc_idle_thread_init(void)
{
smc_thread_init(&smc_thread_idle,
                idle_thread_entry,
                NULL,
                IDLE_THREAD_PRIORITY,
                smc_idle_thread_stack,
                SMC_IDLE_STACK_SIZE,
                40);
}

void idle_thread_entry(void *parameter)
{
/**
 * Using cpu usage for SMC-RTOS
 */
#ifdef SMC_USING_CPU_USAGE
    smc_cpu_usage_init();
#endif

    while (1) {
/**
 * Using cpu usage for SMC-RTOS
 */
#ifdef SMC_USING_CPU_USAGE
        smc_int32_t status;

        /* disable interrupt */
        status = smc_cpu_disable_interrupt();
        smc_idle_cnt_run++;
        /* enable interrupt */
        smc_cpu_enable_interrupt(status);
#endif
        if (smc_thread_idle_hook)
            smc_thread_idle_hook();
    }
}


static void smc_cpu_usage_init(void)
{
    /* Scheduler lock to establish the maximum value for the idle counter */
    smc_scheduler_lock();

    /* Create a timer for 100ms to establish the maximum value for the idle counter in 100ms */
    smc_timer_init(&smc_idle_timer,
                   SMC_TICKS_PER_SECOND / 10,
                   smc_idle_timeout,
                   NULL,
                   SMC_TIMER_PERIODIC);

    /* start timer */
    smc_timer_enable(&smc_idle_timer);
}

static void smc_idle_timeout(void *parameter)
{
    /**
     * For the first time, get the the maximum value(smc_idle_cnt_max) for the idle counter.
     */
    if (smc_idle_cnt_max == 0U) {
        smc_uint32_t tick = SMC_TICKS_PER_SECOND;

        smc_idle_cnt_max = smc_idle_cnt_run / 10U;

        /* Set timer timeout tick for 1 second */
        smc_timer_command(&smc_idle_timer,
                          SMC_TIMER_SET_TIMEOUT_TICK_IMMEDIATELY,
                          &tick);

        /* do scheduler */
        smc_scheduler_unlock();
    } else {
        smc_int8_t usage;

        /* Computes the cpu usage */
        usage         = (smc_int8_t)(100U - smc_idle_cnt_run / smc_idle_cnt_max);
        smc_cpu_usage = usage > 0 ? usage : 0;
    }
    /* Reset the idle counter for the next second */
    smc_idle_cnt_run = 0;
}
  • 获得CPU使用率 smc_cpu_usage
smc_uint8_t smc_get_cpu_usage(void)
{
    return smc_cpu_usage;
}

猜你喜欢

转载自blog.csdn.net/qq_33894122/article/details/81482250