TobudOs提供两种低功耗模式第一种是当任务进入空闲任务是会进行休眠
直接开启宏定义就能使用了无需提供任何接口
#define TOS_CFG_PWR_MGR_EN 1u
空闲任务
__STATIC__ void knl_idle_entry(void *arg)
{
arg = arg; // make compiler happy
while (K_TRUE) {
#if TOS_CFG_OBJ_DYNAMIC_CREATE_EN > 0u//处理动态分配释放的内存
task_free_all();
#endif
#if TOS_CFG_PWR_MGR_EN > 0u
pm_power_manager();//低功耗管理
#endif
}
}
__KNL__ void pm_power_manager(void)
{
if (pm_idle_pwr_mgr_mode_is_sleep()) {
pm_cpu_sleep_mode_enter();
}
#if TOS_CFG_TICKLESS_EN > 0u
else if (pm_idle_pwr_mgr_mode_is_tickless()) {
tickless_proc();
}
#endif
}
在进入睡眠模式不就会就会因为滴答定时器而被唤醒,因此不会节省特别多的能耗.
第二种低功耗模式需要开启宏定义以及提供能够在低功耗模式下工作的闹钟以便恢复后修改系统时间,还可以额外提供pm设备(进入低功耗前想要进行额外处理的外设).
#define TOS_CFG_TICKLESS_EN 0u // 配置Tickless 低功耗模块开关
__API__ k_err_t tos_pm_cpu_lpwr_mode_set(k_cpu_lpwr_mode_t cpu_lpwr_mode)//设置系统在进入低功耗模式后处于什么模式
参数如下:
typedef enum k_cpu_low_power_mode_en {
TOS_LOW_POWER_MODE_NONE = 0, /* if set to NONE, disable low power mode */
TOS_LOW_POWER_MODE_SLEEP, /* wakeup source: systick/tim/rtc */
TOS_LOW_POWER_MODE_STOP, /* wakeup source: rtc wakeup/alarm */
TOS_LOW_POWER_MODE_STANDBY, /* wakeup source: rtc alarm */
__LOW_POWER_MODE_DUMMY,
} k_cpu_lpwr_mode_t;
tos_tickless_wkup_alarm_install(TOS_LOW_POWER_MODE_SLEEP, &alarm);//设置具体模式用的什么闹钟
typedef struct k_tickless_wakeup_alarm_st {
int (*init)(void);
int (*setup)(k_time_t millisecond);
int (*dismiss)(void);
k_time_t (*max_delay)(void); /* in millisecond */
} k_tickless_wkup_alarm_t;
__API__ k_err_t tos_tickless_wkup_alarm_init(k_cpu_lpwr_mode_t mode)//调用我们给的初始化闹钟函数
再使用tickless模式时,我们首先需用调用tos_tickless_wkup_alarm_install()安装闹钟,然后再初始化闹钟tos_tickless_wkup_alarm_init,最后设置要进入的休眠模式tos_pm_cpu_lpwr_mode_set();
实例:
k_time_t delay(void)//闹钟最大延时时长ms单位
{
return 1000;
}
int init()
{
MX_TIM6_Init();
}
int setup (k_time_t millisecond)
{
__HAL_TIM_SET_AUTORELOAD(&htim6,millisecond);
__HAL_TIM_SET_COUNTER(&htim6,0);
HAL_TIM_Base_Start_IT(&htim6);
}
int dismiss (void)
{
HAL_TIM_Base_Stop_IT(&htim6);
}
int tos_bsp_tickless_setup(void)//没啥用,再tos_knl_init()初始化时调用,不知道为啥没加定义需要自己添加不然编译不过
{
printf("钩子函数\n");
}
void task1_handler(void* arg)
{
k_tickless_wkup_alarm_t alarm;
alarm.init=init;
alarm.dismiss=dismiss;
alarm.max_delay=delay;
alarm.setup=setup;
tos_tickless_wkup_alarm_install(TOS_LOW_POWER_MODE_SLEEP, &alarm);
tos_tickless_wkup_alarm_init(TOS_LOW_POWER_MODE_SLEEP);
tos_pm_cpu_lpwr_mode_set(TOS_LOW_POWER_MODE_SLEEP);
while(1)
{
tos_task_delay(500);
printf("task1 running %llu\n",tos_systick_get());
}
}
最后空闲函数中添加一句打印看看效果:进入空闲模式后进休眠了没有循环打印
__STATIC__ void knl_idle_entry(void *arg)
{
arg = arg; // make compiler happy
while (K_TRUE) {
printf("进入低功耗模式 %llu\n",tos_systick_get());
#if TOS_CFG_OBJ_DYNAMIC_CREATE_EN > 0u
task_free_all();
#endif
#if TOS_CFG_PWR_MGR_EN > 0u
pm_power_manager();
#endif
}
}