Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
PM电源管理
rt-thread低功耗休眠应用问题请教
发布于 2016-11-22 15:48:57 浏览:6730
订阅该版
本屌目前使用MKL15Z128跑rt-thread系统,需要实现低功耗模式。 当下简单的在idle线程中判断rt_timer_next_timeout_tick最快超时timer的tick数来休眠。 由于此MCU自带lowpower timer,所以支持休眠计数唤醒功能。 设计思想: 1.在idle线程中调用rt_timer_next_timeout_tick获取最快超时的tick,然后计算出能休眠的tick数。 2.然后配置lowpower timer进入预定的休眠时间后唤醒MCU。 3.唤醒后重新配置MCU时钟 注意点: 1.由于mcu休眠器件无法进行OS TICK,所以需要唤醒后补偿OS TICK. 2.由于一旦唤醒后补偿OS TICK就会导致用户任务可能ready。 3.任务一旦ready应该已经重新配置好时钟等寄存器内容。此时可以保证在任务前后时钟已经配置,可以先锁定调度器再休眠,配置好各项参数后再开锁。 遇到的问题: 计算rt_timer_next_timeout_tick的tick会突然变得很大,想不通为什么。 代码结构: ``` #define RT_TICK_PER_SECOND 200 rt_thread_idle_sethook(_system_sleep_entry); void rt_init_thread_entry(void* parameter) { while (1) { rt_kprintf("init thread "); rt_thread_delay(4 * RT_TICK_PER_SECOND); } } static void _system_sleep_entry(void) { rt_tick_t sleep_tick; sleep_tick = rt_timer_next_timeout_tick() - rt_tick_get(); if (sleep_tick > RT_TICK_PER_SECOND) { rt_kprintf("sleep %u's entry ", sleep_tick); /* Wait for debug console output finished. */ while (!(kLPSCI_TransmissionCompleteFlag & LPSCI_GetStatusFlags(UART0))) { } lptmr_int = 0; LPTMR_SetTimerPeriod(LPTMR0, (sleep_tick * 5) - 1U); LPTMR_StartTimer(LPTMR0); LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable); LLWU_EnableInternalModuleInterruptWakup(LLWU, 0, true); NVIC_EnableIRQ(LLWU_IRQn); rt_enter_critical(); SMC_PreEnterStopModes(); SMC_SetPowerModeVlps(SMC); SMC_PostExitStopModes(); /* Power mode change. */ SMC_SetPowerModeRun(SMC); while (kSMC_PowerStateRun != SMC_GetPowerModeState(SMC)) { } /* Wait for PLL lock. */ while (!(kMCG_Pll0LockFlag & CLOCK_GetStatusFlags())) { } CLOCK_SetPeeMode(); rt_tick_get(); rt_tick_set(rt_tick_get() + sleep_tick); rt_exit_critical(); rt_kprintf("sleep wakeup "); } } ``` ``` | / - RT - Thread Operating System / | 2.1.0 build Nov 16 2016 2006 - 2016 Copyright by rt-thread team init thread sleep 800's entry sleep wakeup sleep 4294967295's entry init thread sleep wakeup sleep 800's entry sleep wakeup sleep 4294967295's entry init thread sleep wakeup sleep 800's entry sleep wakeup sleep 4294967295's entry init thread sleep wakeup sleep 800's entry sleep wakeup sleep 4294967295's entry init thread sleep wakeup sleep 800's entry sleep wakeup sleep 4294967295's entry init thread sleep wakeup sleep 800's entry sleep wakeup sleep 4294967295's entry init thread sleep wakeup sleep 800's entry sleep wakeup sleep 4294967295's entry init thread sleep wakeup sleep 800's entry sleep wakeup sleep 4294967295's entry init thread sleep wakeup sleep 800's entry sleep wakeup sleep 4294967295's entry init thread ```
查看更多
8
个回答
默认排序
按发布时间排序
geniusgogo
认证专家
2016-11-22
这家伙很懒,什么也没写!
终于知道问题了,执行OS TICK补偿我是使用的rt_tick_set,这样虽然TICK计数器被更新了,但是没有触发时间片调度器,所以导致线程没有被及时的调度,从而出现rt_get_tick大于timer_timeout_tick的情况。 现在解决办法是补偿TICK后,等待下一次OS TICK 中断来触发时间片调度,更好的办法还需要进一步研究。
aozima
2016-11-22
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
学习了! 楼主V5!
geniusgogo
认证专家
2016-11-22
这家伙很懒,什么也没写!
关于OS tick补偿的办法,要达到产生N次调用rt_tick_increase的效果,如何实现更好?
bernard
2016-11-22
这家伙很懒,什么也没写!
对牛头哥的敬仰如同滔滔江水连绵不绝 [s:186]
geniusgogo
认证专家
2016-11-22
这家伙很懒,什么也没写!
目前仿照tick中断模拟N次调用。 ``` rt_tick_set(rt_tick_get() + sleep_tick); thread = rt_thread_self(); if (thread->remaining_tick <= sleep_tick) { /* change to initialized tick */ thread->remaining_tick = thread->init_tick; /* yield */ rt_thread_yield(); } else { thread->remaining_tick -= sleep_tick; } /* check timer */ rt_timer_check(); ```
grissiom
2016-11-23
这家伙很懒,什么也没写!
>本屌目前使用MKL15Z128跑rt-thread系统,需要实现低功耗模式。 >当下简单的在idle线程中判断rt_timer_next_timeout_tick最快超时timer的tick数来休眠。 >由于此MCU自带lowpower timer,所以支持休眠计数唤醒功能。 >设计思想: >1.在idle线程中调用rt_timer_next_timeout_tick获取最快超时的tick,然后计算出能休眠的tick数。 >2.然后配置lowpower timer进入预定的休眠时间后唤醒MCU。 >3.唤醒后重新配置MCU时钟 >注意点: >1.由于mcu休眠器件无法进行OS TICK,所以需要唤醒后补偿OS TICK. >2.由于一旦唤醒后补偿OS TICK就会导致用户任务可能ready。 >3.任务一旦ready应该已经重新配置好时钟等寄存器内容。此时可以保证在任务前后时钟已经配置,可以先锁定调度器再休眠,配置好各项参数后再开锁。 >遇到的问题: >计算rt_timer_next_timeout_tick的tick会突然变得很大,想不通为什么。 >代码结构: > > >``` > > >#define RT_TICK_PER_SECOND 200 > >rt_thread_idle_sethook(_system_sleep_entry); > >void rt_init_thread_entry(void* parameter) >{ > while (1) > { > rt_kprintf("init thread >"); > rt_thread_delay(4 * RT_TICK_PER_SECOND); > } >} > >static void _system_sleep_entry(void) >{ > rt_tick_t sleep_tick; > > sleep_tick = rt_timer_next_timeout_tick() - rt_tick_get(); > > if (sleep_tick > RT_TICK_PER_SECOND) > { > rt_kprintf("sleep %u's entry >", sleep_tick); > /* Wait for debug console output finished. */ > while (!(kLPSCI_TransmissionCompleteFlag & LPSCI_GetStatusFlags(UART0))) > { > } > > lptmr_int = 0; > LPTMR_SetTimerPeriod(LPTMR0, (sleep_tick * 5) - 1U); > LPTMR_StartTimer(LPTMR0); > > LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable); > LLWU_EnableInternalModuleInterruptWakup(LLWU, 0, true); > > NVIC_EnableIRQ(LLWU_IRQn); > > rt_enter_critical(); > > SMC_PreEnterStopModes(); > SMC_SetPowerModeVlps(SMC); > SMC_PostExitStopModes(); > > /* Power mode change. */ > SMC_SetPowerModeRun(SMC); > while (kSMC_PowerStateRun != SMC_GetPowerModeState(SMC)) > { > } > > /* Wait for PLL lock. */ > while (!(kMCG_Pll0LockFlag & CLOCK_GetStatusFlags())) > { > } > CLOCK_SetPeeMode(); > rt_tick_get(); > rt_tick_set(rt_tick_get() + sleep_tick); > > rt_exit_critical(); > rt_kprintf("sleep wakeup >"); > } >} > >``` --- 牛头哥太牛了~ 另外,rt_enter_critical(); 是不是得用禁用中断?否则有中断唤醒其他线程后,最近超时时间发生变更的可能~
geniusgogo
认证专家
2016-11-23
这家伙很懒,什么也没写!
>>本屌目前使用MKL15Z128跑rt-thread系统,需要实现低功耗模式。 >> >>牛头哥太牛了~ 另外,rt_enter_critical(); 是不是得用禁用中断?否则有中断唤醒其他线程后,最近超时时间发生变更的可能~ > >--- --- 已经考虑进去,任何唤醒源唤醒后最后都会进入MCU的wakeup中断,在wakeup中断里我做了lowpower的counter计算,再对OS TICK做补偿的。
撰写答案
登录
注册新账号
关注者
0
被浏览
6.7k
关于作者
geniusgogo
这家伙很懒,什么也没写!
提问
42
回答
157
被采纳
7
关注TA
发私信
相关问题
1
STM32F103的低功耗
2
最近用rtthread系统下AD采样并低功耗,中断响应不及时
3
关于RTT对低功耗的支持
4
RT-Thread怎么休眠实现低功耗。
5
RT-Thread V3.0支持的低功耗,OS会自行进入吗?
6
关于RTThread3.0低功耗休眠模式
7
RTT3.0的bsp包中哪些MCU自带低功耗定时器?
8
关于低功耗上次说针对L4出个BSP的,怎么迟迟不见呀
9
低功耗问题。
10
STM32L4低功耗
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
8
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
5
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部