Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
PM电源管理
RT-Thread怎么休眠实现低功耗。
发布于 2017-09-01 11:23:13 浏览:6832
订阅该版
HI各位大神,我目前有一个案子是电池供电的,需要实现低功耗。 选用的主控芯片是EFM32LG系列的,有低功耗定时器,我想用一个嵌入式的操作系统,我对RT-Thread也不太了解,不知道RT-Thread有没有实现空闲时休眠,在定时任务时间到达时唤醒,还有外部中断可以打断休眠再进行正常的任务调度?
查看更多
11
个回答
默认排序
按发布时间排序
geniusgogo
认证专家
2017-09-01
这家伙很懒,什么也没写!
可以参考bsp里面nrf52832和samd21的实现方法。
mmyer
2017-09-01
这家伙很懒,什么也没写!
>可以参考bsp里面nrf52832和samd21的实现方法。 --- 好的,我先研究一下。
mmyer
2017-09-04
这家伙很懒,什么也没写!
>可以参考bsp里面nrf52832和samd21的实现方法。 --- 大神你好,我看了nrf52832的代码,在idle task的钩子函数里调用_sleep_ongo( uint32_t sleep_tick )实现休眠,唤醒之后用_wakeup_tick_adjust恢复系统tick,但是如果休眠中被外部中断唤醒该怎么处理,我没找到相应的代码。是不是说外部中断唤醒也是在这里处理了? 还有一种情况,就是timer_list为空的情况下,rt_timer_next_timeout_tick返回了RT_TICK_MAX,更好的处理方式是让处理器deep sleep,等待外部中断的唤醒。感觉RTT针对低功耗这块还需要加入一些标准API去处理。
mmyer
2017-09-05
这家伙很懒,什么也没写!
>可以参考bsp里面nrf52832和samd21的实现方法。 --- 大神,我参考了NRF52838的方法,做了尝试,结果遇到了和你去年一样的问题, [http://www.rt-thread.org/phpBB3/post25105.html](http://www.rt-thread.org/phpBB3/post25105.html) 补偿了sleep得到一个很大的值,按照你的提示一想,确实没有补偿timer_list里面的每个remaining_tick,请问是怎么解决的?
mmyer
2017-09-06
这家伙很懒,什么也没写!
结合NRF和FREERTOS的例子,现在已经可以休眠了,但是休眠好像影响了TICK的长度,rt_thread_delay()的延时在使能休眠的情况下明显长很多,不知何故,具体的原因还要查查。以下是我的代码,系统时钟和休眠时钟用的都是RTC: ``` static void _wakeup_tick_adjust(uint32_t diff) { uint32_t level; level = rt_hw_interrupt_disable(); rt_tick_set(rt_tick_get() + diff); if (rt_thread_self() != RT_NULL) { struct rt_thread *thread; /* check time slice */ thread = rt_thread_self(); if (thread->remaining_tick <= diff) { /* change to initialized tick */ thread->remaining_tick = thread->init_tick; /* yield */ rt_thread_yield(); } else { thread->remaining_tick -= diff; } /* check timer */ rt_timer_check(); } rt_hw_interrupt_enable(level); } static void _sleep_ongo( uint32_t idle_tick ) { unsigned long cnt_before_sleep, cnt_afer_sleep; unsigned long rtc_load_value, gone_tick; bool rtcFlag; // CORE_DECLARE_IRQ_STATE; /* Make sure the SysTick reload value does not overflow the counter. */ if ( idle_tick > TIMER_CAPACITY / CNT_PER_ONT_TICK ) { idle_tick = TIMER_CAPACITY / CNT_PER_ONT_TICK; } /* Calculate the reload value required to wait idle_tick * tick periods. */ rtc_load_value = (CNT_PER_ONT_TICK * idle_tick)&0xfffffe; if (rtc_load_value > timer_compensation) { /* Compensate for the fact that the RTC is going to be stopped * momentarily. */ rtc_load_value -= timer_compensation; } /* Stop the RTC momentarily. The time the RTC is stopped for is accounted * for as best it can be, but using the tickless mode will inevitably result * in some tiny drift of the time maintained by the kernel with respect to * calendar time. The count is latched before stopping the timer as stopping * the timer appears to clear the count. */ cnt_before_sleep = RTC_CounterGet(); RTC_Enable(false); /* If this function is re-entered before one complete tick period then the * reload value might be set to take into account a partial time slice. So * we adjust the count before sleep to take this into account. * * Just reading the count would be wrong, as it assumes that we are * counting up to a full ticks worth. */ cnt_before_sleep += (CNT_PER_ONT_TICK - RTC_CompareGet(0)); /* Enter a critical section but don't use the taskENTER_CRITICAL() * method as that will mask interrupts that should exit sleep mode. */ //CORE_ENTER_CRITICAL(); rt_enter_critical(); #if 0 /* If a context switch is pending or a task is waiting for the scheduler * to be unsuspended then abandon the low power entry. */ if (eTaskConfirmSleepModeStatus() == eAbortSleep) { /* Restart tick and count up to whatever was left of the current time * slice. */ RTC_CompareSet(0, (CNT_PER_ONT_TICK - cnt_before_sleep)); RTC_Enable(true); /* Re-enable interrupts */ CORE_EXIT_CRITICAL(); } else #endif { /* Adjust the reload value to take into account that the current time * slice is already partially complete. */ rtc_load_value -= cnt_before_sleep; RTC_CompareSet(0, rtc_load_value); RTC_IntClear(_RTC_IFC_MASK); //RTC_IntEnable(RTC_IF_COMP0); /* Restart the counter */ RTC_Enable(true); /* Sleep until something happens. save cpu status before sleep,restore when wakeup*/ EMU_EnterEM2(RT_TRUE); /* Stop the RTC and save the counter value since stopping the RTC clears * the counter. Again, the time the SysTick is stopped for is * accounted for as best it can be, but using the tickless mode will * inevitably result in some tiny drift of the time maintained by the * kernel with respect to calendar time. */ cnt_afer_sleep = RTC_CounterGet(); RTC_Enable(false); rtcFlag = (RTC_IntGet() & RTC_IF_COMP0) != 0; /* Re-enable interrupts */ //CORE_EXIT_CRITICAL(); if (rtcFlag) { /* The tick interrupt handler will already have pended the tick * processing in the kernel. As the pending tick will be * processed as soon as this function exits, the tick value * maintained by the tick is stepped forward by one less than the * time spent waiting. */ gone_tick = idle_tick - 1UL; } else { /* Some other interrupt than the RTC ended the sleep, now we need to * calculate how much time has passed since the last tick. */ cnt_afer_sleep += cnt_before_sleep; /* Calculate how many complete ticks have passed since the last tick */ gone_tick = cnt_afer_sleep / CNT_PER_ONT_TICK; /* The reload value is set to whatever fraction of a single tick * period remains. */ cnt_afer_sleep -= (gone_tick * CNT_PER_ONT_TICK); rtc_load_value = CNT_PER_ONT_TICK - cnt_afer_sleep; RTC_IntClear(_RTC_IFC_MASK); /* Reset the RTC compare value to trigger at the configured tick rate */ RTC_CompareSet(0, rtc_load_value); } /* Start the counter */ RTC_Enable(true); /* The tick forward by the number of tick periods that * remained in a low power state. */ _wakeup_tick_adjust(gone_tick); rt_exit_critical(); } } void rt_hw_system_powersave(void) { uint32_t idle_tick; idle_tick = rt_timer_next_timeout_tick() - rt_tick_get(); if ( idle_tick >= EXPECTED_IDLE_TIME_BEFORE_SLEEP) { // rt_kprintf("sleep entry:%u ", rt_tick_get()); _sleep_ongo( idle_tick ); } } ```
belen
2018-01-10
这家伙很懒,什么也没写!
问题解决了吗?我想是电池供电,用的STM32L4的,但不知道如何处理这低功耗问题。
mcubuilder
2018-01-10
这家伙很懒,什么也没写!
慢慢来,咱们这个用的人还是没那么多,前途是光明的,道路是曲折的:$
bernard
2018-01-10
这家伙很懒,什么也没写!
周末深圳沙龙有低功耗的主题,不知道是否有视频,有视频的话,可能会有更多的信息和帮助吧
mmyer
2018-01-13
这家伙很懒,什么也没写!
>问题解决了吗?我想是电池供电,用的STM32L4的,但不知道如何处理这低功耗问题。 ... --- 可以休眠,但是休眠后发现tick的时间变长了
mmyer
2018-01-22
这家伙很懒,什么也没写!
希望官方能出一个低功耗的教程
撰写答案
登录
注册新账号
关注者
0
被浏览
6.8k
关于作者
mmyer
这家伙很懒,什么也没写!
提问
7
回答
22
被采纳
0
关注TA
发私信
相关问题
1
STM32F103的低功耗
2
最近用rtthread系统下AD采样并低功耗,中断响应不及时
3
rt-thread低功耗休眠应用问题请教
4
关于RTT对低功耗的支持
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
TinyUSB Demo运行教程
2
RT-Thread学习大礼包一键带走!
3
freemodbus从机调试说明
4
【1024】瑞萨 RA 系列 BSP 制作与适配最新版本的 Keil 、 RSC、固件,较新的 FSP
5
基于 RT-Thread 星火一号开发板的俄罗斯方块
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
ART-Pi
FinSH
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
rt-smart
FAL
ESP8266
I2C_IIC
WIZnet_W5500
ota在线升级
UART
cubemx
PWM
flash
packages_软件包
freemodbus
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
用户名由3_15位
10
个答案
1
次被采纳
KunYi
4
个答案
1
次被采纳
踩姑娘的小蘑菇
2
个答案
1
次被采纳
bernard
1
个答案
1
次被采纳
rv666
1
个答案
1
次被采纳
本月文章贡献
出出啊
1
篇文章
2
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
4
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部