Freertos低功耗管理

2024-01-09

空闲任务中的低功耗Tickless处理:

在整个系统运行得过程中,其中大部分时间都是在执行空闲任务的,空闲任务之所以执行,因为在系统中的其他任务处于阻塞或者被挂起时才会执行,因此可以将空闲任务的执行时间转换成低功耗模式,在其他任务解除阻塞而准备运行的时候让MCU退出相应的低功耗模式。 难点在于 如何计算MCU进入低功耗模式的时间

在Freertos中已经解决了这个问题,源码:

        #if ( configUSE_TICKLESS_IDLE != 0 )
            {
                TickType_t xExpectedIdleTime;

                /* 计算进入低功耗的时长,不一定准确,会受到任务调度器的影响 */
                xExpectedIdleTime = prvGetExpectedIdleTime();
                
                  /*如果计算的是时长大于两个时钟节拍,则进去低功耗模式 */
                if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
                {
                    vTaskSuspendAll();
                    {
                  
                        configASSERT( xNextTaskUnblockTime >= xTickCount );
                         /* 重新计算进入低功耗的时长 */
                        xExpectedIdleTime = prvGetExpectedIdleTime();

                        /* 如果不想进入低功耗模式,将此宏置0. */
                        configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING(xExpectedIdleTime);

                        if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
                        {
                            traceLOW_POWER_IDLE_BEGIN();
                            /* 这个宏是将单片机进入低功耗模式的. */
                            portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime );
                            traceLOW_POWER_IDLE_END();
                        }
                        else
                        {
                            mtCOVERAGE_TEST_MARKER();
                        }
                    }
                    ( void ) xTaskResumeAll();
                }
                else
                {
                    mtCOVERAGE_TEST_MARKER();
                }
            }

从以上代码可以看出,首先判断进入低功耗模式的时长,当大于两个时钟节拍的时候,进入低功耗模式,进入之后在计算低功耗时长。

低功耗函数:

configPRE_SLEEP_PROCESSING(x)

此函数用于进入低功耗模式前需要执行的事务,如关闭外设时钟等

configPOSR_SLEEP_PROCESSING(x)
在系统退出相应低功耗模式后执行的事务,如开启外设时钟

void freertos_demo(void)
{
    
    xTaskCreate((TaskFunction_t )start_task,            /* 任务函数 */
                (const char*    )"start_task",          /* 任务名称 */
                (uint16_t       )START_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )START_TASK_PRIO,       /* 任务优先级 */
                (TaskHandle_t*  )&StartTask_Handler);   /* 任务句柄 */
    vTaskStartScheduler();
}

/**
 * @brief       start_task
 * @param       pvParameters : 传入参数(未用到)
 * @retval      无
 */
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           /* 进入临界区 */
    /* 创建任务1 */
    xTaskCreate((TaskFunction_t )task1,
                (const char*    )"task1",
                (uint16_t       )TASK1_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK1_PRIO,
                (TaskHandle_t*  )&Task1Task_Handler);
    vTaskDelete(StartTask_Handler); /* 删除开始任务 */
    taskEXIT_CRITICAL();            /* 退出临界区 */
}

/**
 * @brief       task1
 * @param       pvParameters : 传入参数(未用到)
 * @retval      无
 */
void task1(void *pvParameters)
{
    while(1)
    {
        LED0(1);
        delay_ms(3000); /* CPU忙延时,期间不会进入低功耗模式 */
        LED0(0);
		vTaskDelay(3000);   /* 阻塞延时,期间会进入低功耗模式 */
    }
}



void PRE_SLEEP_PROCESSING()
{
    /* 关闭部分外设时钟,仅作演示 */
    __HAL_RCC_GPIOA_CLK_DISABLE();
    __HAL_RCC_GPIOB_CLK_DISABLE();
    __HAL_RCC_GPIOC_CLK_DISABLE();
    __HAL_RCC_GPIOD_CLK_DISABLE();
    __HAL_RCC_GPIOE_CLK_DISABLE();
    __HAL_RCC_GPIOF_CLK_DISABLE();
    __HAL_RCC_GPIOG_CLK_DISABLE();
}

/**
 * @brief       POST_SLEEP_PROCESSING
 * @param       无
 * @retval      无
 */
void POST_SLEEP_PROCESSING(void)
{
    /* 重新打开部分外设时钟,仅作演示 */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();
    __HAL_RCC_GPIOE_CLK_ENABLE();
    __HAL_RCC_GPIOF_CLK_ENABLE();
    __HAL_RCC_GPIOG_CLK_ENABLE();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Freertos低功耗管理 的相关文章

  • 2024年一套超详细Java面试精华资料,让进大厂少走弯路

    在座的诸位有没有是自学Java的 有的话评论区给我扣个1看看 但凡自学过的同学都知道有多难 虽说现在互联网非常发达 不明白的上网一搜就有很多资料 不过大多质量不高 而且非常碎片化 实在很难梳理成一个可持续成长的体系 所以有了这篇文章 我结合

随机推荐