TICKLESS模式下最大低功耗的时间只能是349tick的原因分析

TICKLESS模式下最大低功耗的时间只能是349tick的原因分析

原因

  • 开启TICKLESS模式后,在PreSleepProcessingPostSleepProcessing中打印ulExpectedIdleTime变量,即空闲时间.输出如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-amV8h9iH-1684999895390)(TICKLESS.assets/image-20230523161450180.png)]

  • 代码如下
void PreSleepProcessing(uint32_t *ulExpectedIdleTime)
{
    log_i("ulExpectedIdleTime %lu", *ulExpectedIdleTime);
}

void PostSleepProcessing(uint32_t *ulExpectedIdleTime)
{

}

分析

  • 为什么是349tick进入一次空闲线程?
  • 分析FREERTOS源码,在portTASK_FUNCTION函数中调用接口,写入空闲时间值
  • 在赋值后打印变量
if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
{
    vTaskSuspendAll();
    {
        configASSERT( xNextTaskUnblockTime >= xTickCount );
        xExpectedIdleTime = prvGetExpectedIdleTime();
//这里打印一下时间
printf("xExpectedIdleTime = %lu", 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();
}

输出如下

xExpectedIdleTime = FFFF FD23
I/NO_TAG          [ms:0000000732] ulExpectedIdleTime 349
  • 空闲执行时间没问题,传入函数后有问题.

  • 进入vPortSuppressTicksAndSleep分析,找到如下代码

/* Make sure the SysTick reload value does not overflow the counter. */
/*确保 SysTick 重载值不会溢出计数器。*/
if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
{
    xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
}

查找变量xMaximumPossibleSuppressedTicks赋值

/* The systick is a 24-bit counter. */
#define portMAX_24_BIT_NUMBER				( 0xffffffUL )
/* 48MHZ / 1000hz调度频率 */
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
/*xMaximumPossibleSuppressedTicks = 0xffffffU / 48000 ≈ 349 */
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;

结论

  • 当线程全部阻塞时,空闲线程时间实际预计的解除阻塞时间 - 当前运行时间.
  • 但是在进入TICKLESS后,为了确保 SysTick 重载值不会溢出计数器.所以限制了TICKLESS的低功耗休眠时间.
  • 所以进入TICKLESS的最大时间为0XFFFFFF / (系统时钟 / 调度频率),在本机中为349.

是否使用TICKLESS模式

方案1:使用TICKLESS模式

  • 按照tickless模式,每个最大固定时间会唤醒一次,进行systick的溢出处理.
  • 处理完成后再次进入睡眠模式.
  • 测量进入低功耗的电流与唤醒去处理的电流.是否差别较大.
  • 如果差别不大可以接受,用TICKLESS去调度既可

方案2:不使用TICKLESS模式

  • 使用空闲钩子函数,进入低功耗.
  • 退出低功耗由RTC的定时器唤醒.然后处理事件.结束后再次进入空闲线程.进入低功耗.
  • 问题点:systick无法计算恢复,影响调度
  • 计数值无法按照正常低功耗时间增加

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jxrOjp0l-1684999895390)(TICKLESS.assets/image-20230523201043183.png)]

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值