转:ZigBeeZ-StackCC2530实现低功耗运⾏的配置简介
设备⽀持低功耗运⾏是ZigBee⽹络的⼀⼤特点,该特性借助CC2530芯⽚能够很好地体现出来。CC2530芯⽚有五种运⾏模式,分别为主动模式、空闲模式、PM1、PM2和PM3。主动模式是⼀般运⾏模式;空闲模式除了CPU内核停⽌运⾏外,其他和主动模式⼀样;PM1、
PM2、PM3是低功耗运⾏模式,CC2530通过关闭不必要的部分和调整系统时钟来达到低功耗的效果。
PM1:稳压器的数字部分开启,32 MHzXOSC和 16 MHz RCOSC都不运⾏。32 kHz RCOSC或32 kHz XOSC运⾏。复位、外部中断或睡眠定时器溢出时系统将转到主动模式。
PM2:稳压器的数字内核关闭。32 MHzXOSC和 16 MHz RCOSC都不运⾏。32kHz RCOSC或32 kHz XOSC运⾏。复位、外部中断或睡眠定时器过期时系统将转到主动模式。
PM3:稳压器的数字内核关闭。所有的振荡器都不运⾏。复位或外部中断时系统将转到主动模式。
⼏种运⾏模式的对⽐如下表所⽰:
PM2模式⼜叫LITE SLEEP模式,其功耗在毫安级别,多⽤于需要定时唤醒的场合,⽐如周期性地唤醒传感器来进⾏数据的采集。
timeout on t2 timerPM3模式⼜叫做DEEP SLEEP模式,在⼏种运⾏模式中功耗最低,在微安级别,多⽤于远程遥控场合,⽐如使⽤CC2530做⼀个远程遥控器,在没有按键按下时,可使其进⼊PM3模式以减少电能消耗。
Z-STACK提供了两种低功耗运⾏模式,PM2和PM3。PM2模式可被睡眠定时器,外部中断和复位唤醒,PM3模式可被外部中断和复位唤醒。
在Z-Stack的使⽤⽂档中得知为了使设备能够进⼊睡眠模式,必须满⾜以下的条件:
1、通过添加预编译项POWER_SAVING来使能睡眠模式
2、ZDO节点描述符指定“在空闲时发送功能是关闭的”,通过在f8wConfig.cfg⽂件中将RFD_RCVC_ALWAYS_ON设置为FALSE来实现。
3、所有的Z-Stack任务⽀持powersaving
4、Z-Stack的各个任务没有预定的活动事件
5、MAC没有预定的活动事件
在进⾏设置之前,我们先来了解⼀下Z-Stack进⼊睡眠模式的流程。
⼀、Z-Stack进⼊睡眠模式的流程分析
在main函数的最后,程序进⼊osal_start_system函数开始进⾏轮询机制,在osal_start_system函数的最后,程序通过判断宏来确定是否进⾏电源管理,如下所⽰:
#if defined( POWER_SAVING )
else  // Complete pass through all task events with no activity?
{
osal_pwrmgr_powerconserve();  // Put the processor/system into sleep
}
#endif
[color=rgb(51, 102, 153) !important]复制代码
可以看出如果我们在预编译时定义了宏POWER_SAVING,且满⾜else条件,程序就会调函数osal_pwrmgr_powerconserve,与else对应的if的条件是if (idx< tasksCnt) ,分析可知if是⽤来判断当前
系统有没有要执⾏的任务,也就是说,要进⼊电源管理,还必须满⾜系统当前没有正在执⾏的任务或者将要执⾏的任务。
进⼊osal_pwrmgr_powerconserve函数后⾸先要进⾏两次判断,第⼀次判断设备是否为电池设备:pwrmgr_attribute.pwrmgr_device
!=PWRMGR_ALWAYS_ON其中PWRMGR_ALWAYS_ON宏在OSAL_PwrMgr.h定义,使⽤电池供电的设备⽤宏PWRMGR_BATTERY来表⽰。
/* With PWRMGR_ALWAYS_ON selection, there is no power savings and the
* device is most likely on mains power. The PWRMGR_BATTERY selection allows
* the HAL sleep manager to enter SLEEP LITE state or SLEEP DEEP state.
*/
#define PWRMGR_ALWAYS_ON  0
#define PWRMGR_BATTERY    1
[color=rgb(51, 102, 153) !important]复制代码
第⼆次判断是判断是否所有的任务都⽀持power saving:
if ( pwrmgr_attribute.pwrmgr_task_state == 0 )
确认这两个条件都满⾜后先关闭中断HAL_ENTER_CRITICAL_SECTION( intState );然后获取下⼀次任务截⽌的时间,next =
osal_next_timeout(); 然后再使能中断HAL_EXIT_CRITICAL_SECTION(intState );在获取下⼀次任务截⽌时间时关闭中断是为了不影响时间的获取,获取⼀个准确的时间,最后调⽤宏OSAL_SET_CPU_INTO_SLEEP( next );追踪发现该宏实际上是调⽤了函数halSleep,该函数在⽂件hal_sleep.c中,在hal_sleep函数中,⾸先来获取Z-Stack下⼀次任务截⽌时间和MAC任务下⼀次截⽌时间的最⼩值,使⽤语句如下:
if (timeout == 0)//Z-Stack下⼀次任务截⽌时间为0,即没有预定的Z-Stack任务
{
timeout = MAC_PwrNextTimeout();//获取MAC下⼀次任务的截⽌时间
}
Else //有预定的Z-Stack任务
{
/* get next MAC timer expiration */
macTimeout = MAC_PwrNextTimeout();/获取MAC下⼀次任务的截⽌时间
/* get lesser of two timeouts */
//获取Z-Stack下⼀次任务截⽌时间和MAC任务下⼀次截⽌时间的最⼩值
if ((macTimeout != 0) && (macTimeout < timeout))
{
timeout = macTimeout; //将最⼩的值作为休眠时间
}
}
[color=rgb(51, 102, 153) !important]复制代码
获取timeout后,接着通过判断timeout来决定是进⼊PM2还是PM3模式,halPwrMgtMode = (timeout == 0) ? HAL_SLEEP_DEEP :
HAL_SLEEP_TIMER; 如果timeout为0,及Z-Stack和MAC都没有预定的任务,则系统进⼊PM3模式,如果不为0就进⼊PM2模式。
电源管理理念通常被电池供电的设备采纳,⽽为了维护⽹络的完整性、稳定性,协调器和路由器⼀般不采⽤电池供电,也就是说只有终端设备经常使⽤电池供电,所以在使⽤时尽量不要对协调器和路由器开启POWER_SAVING选项。
了解完⼤致过程后接下来介绍⼀下在Z-Stack中开启PM2、PM3的⽅法。
⼆、Z-Stack开启PM2、PM3的⽅法
第⼀步:添加预编译项POWER_SAVING。
右键⼯程名称,选择Options->C/C++Compiler/Preprocessor选项,在Defined Symbols框⾥添加POWER_SAVING。
第⼆步:修改f8wConfig.cfg⽂件。
到-DRFD_RCVC_ALWAYS_ON将值改为-DRFD_RCVC_ALWAYS_ON=FALSE
将-DPOLL_RATE=1000改为-DPOLL_RATE=0
将-DQUEUED_POLL_RATE=0改为-DQUEUED_POLL_RATE=0
将-DRESPONSE_POLL_RATE=100改为-DRESPONSE_POLL_RATE=0
下⾯对以上设置进⾏说明。
Z-Stack⼯程中的ENDDEVICE默认情况下是不使⽤电源管理的,因此⾃动轮询消息机制是打开的。在⼯程中有三个轮询选项,每⼀个都有⼀个定时延时时间,因此每个轮询都会影响到睡眠机制,定时的时间延迟不能使设备进⼊PM3模式,这在⼀定程度上了增加了电能的消耗。这三个轮询选项的描述分别如下:
1、Data Request Polling,周期性地向⽗节点发送数据请求来轮询消息队列。轮询的时间间隔由NLME_SetPollRate函数或者zgPollRate设定,如果先前是被禁⽌的,那么在调⽤NLME_SetPollRate函数时就会⽴即开始轮询。
2、Queued Data Polling,在收到数据指⽰后,就会向⽗节点请求消息,这个时间间隔可以通过函数NLME_SetQueuedPollRate或者zgQueuedPollRate参数来设定。
3、Response DataPolling,在收到数据确认指⽰后,就会向⽗节点请求响应消息,这个时间间隔可以由NLME_SetResponsePollRate 函数或者是zgResponsePollRate参数来设定。
上述的三个参数和函数都是仅终端设备可⽤,在ZStack中,默认地使⽤指定参数值的⽅法来设置轮询时间,在ZGlobals.c中可以看到:
// Polling values
uint16 zgPollRate= POLL_RATE;
uint16zgQueuedPollRate = QUEUED_POLL_RATE;
uint16zgResponsePollRate = RESPONSE_POLL_RATE;
uint16 zgRejoinPollRate =REJOIN_POLL_RATE;
⽽POLL_RATE、QUEUED_POLL_RATE、RESPONSE_POLL_RATE三个参数则在⽂件f8wConfig.cfg被设置,如上所述。对于上述三个参数,如果只是使⽤默认的设置,则只能进⼊PM2模式,要想能够进⼊PM3模式,就必须将上述三个参数的值设置为0.
在f8wConfig.cfg⽂件的最后还有⼀个轮询的参数——重新加⼊参数,就是在加⼊⽹络不成功的时候会在设定的时间到后重新请求加⼊⽹络,-DREJOIN_POLL_RATE。如果想在只有终端节点没有协调器的情况下做低功耗的实验,可以将这个参数设置为0,这样设备就不会每440毫秒(默认值为440)进⼊PM2模式⼀次了。
第三步:配置存在轮询的程序,也就是有预定活动的任务。
上⾯提到过预定活动的任务会使系统只能进⼊PM2模式,这些预定的互动包括Z-Stack和MAC的,⽽在Z-Stack中凡是使⽤到函数
osal_start_timerEx的地⽅都会产⽣预定的任务活动。在Z-Stack中,有两个地⽅会⽤到osal_start_timerEx函数,⼀个是使⽤轮询法来扫描按键时,另⼀个是在应⽤层中⼀些⽤户⾃定义的定时任务,所以要想使设备能够进⼊PM3模式,就要屏蔽掉这两处。第⼀是将按键的机制改为中断⽅式,
在InitBoard函数的else分⽀中将OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;改为OnboardKeyIntEnable= HAL_KEY_INTERRUPT_ENABLE;然后将应⽤层中所有使⽤到osal_start_timerEx函数的地⽅都屏蔽掉就⾏了。
第四步:
上⾯提到在进⼊osal_pwrmgr_powerconserve函数后会对电源管理属性进⾏两次判断,以确定设备为电池供电设备,同时所有的任务⽀持powersaving,这部分的设置在函数osal_pwrmgr_init中完成,将函数修改为如下即可:
void osal_pwrmgr_init( void )
{
//pwrmgr_attribute.pwrmgr_device = PWRMGR_ALWAYS_ON; // Default to no power //conservation.
pwrmgr_attribute.pwrmgr_device = PWRMGR_BATTERY;
pwrmgr_attribute.pwrmgr_task_state = 0;            // Cleared.  All set to conserve

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。