当前位置:
文档之家› 如何实现ZigBee休眠与唤醒
如何实现ZigBee休眠与唤醒
2.获取下一次MAC定时器到期时间
3. halPwrMgtMode = (timeout == 0) ? HAL_SLEEP_DEEP : HAL_SLE EP_TIMER; //为PM2,PM3模式。 没有任务要执行就进入PM3深度睡眠,否则进入P M2睡眠,可以定时器唤醒。 4.唤醒
OSAL机制的ZigBee低功耗管理(CC2530)
extern pwrmgr_attribute_t
pwrmgr_attribute;
定义一个电源管理的全局变量。
/********************************************************************* * @brief 初始化电源管理函数,这个函数在OSAL.C里面的osal_init_system( )调用, 也就是在OSAL系统初始化的时候将电源管理模式调成了不会进入睡眠模式的状态。 */ void osal_pwrmgr_init( void ) { pwrmgr_attribute.pwrmgr_device = PWRMGR_ALWAYS_ON; //默认没有睡眠模式 pwrmgr_attribute.pwrmgr_task_state = 0; } //清零
2、为什么闪的频率那么高? zstack的睡眠机制就是在操作系统没事干的时候才睡眠,频 率高说明应用程序让操作系统不断做事。你想让它长时间睡 眠,那要做的就是不要不断地给操作系统事情做,找到分配 系统任务的地方。
要设置低功耗模式,先确认: 1.f8wConfig.cfg文件中DRFD_RCVC_ALWAYS_ON定义为FALSE 2.Options->C/C++Compiler->Defined symbols中添加预编译“POW ER_SAVING”; 重要函数void halSleep( uint16 osal_timeout ) 1.首先将osal_timeout转成以320US为单位
// 清零
//置位
#if defined( POWER_SAVING ) /* osal_pwrmgr_powerconserve 这个函数在OSAL循环中如果没有任何事件需要执行的话将被 调用,将设备进入 睡眠模式,不可以在其他地方调用该函数。需要打开POWER_SAVING的宏定 义。*/ void osal_pwrmgr_powerconserve( void ) { uint16 next;
void osal_start_system( void ) {
#if !defined ( ZBIT ) && !defined ( UBIT )
for(;;) // Forever Loop #endif {…… } #if defined( POWER_SAVING ) else // Complete pass through all task events with no activity { osal_pwrmgr_powerconserve(); // Put the pro cessor/system into sleep } #endif }
加红部分是一个宏定义,在OnBoard.h里面定义的。
#define OSAL_SET_CPU_INTO_SLEEP(timeout) halSleep(timeout);
halSleep(timeout)是在hal_sleep.c中定义的。
这里面涉及的就是关于CC2530的电源管理寄存器的一些操 作。具体可以看代码。
return ( INVALID_TASK ); if ( state == PWRMGR_CONSERVE ) {
pwrmgr_attribute.pபைடு நூலகம்rmgr_task_state &= ~(1 << task_id );
} else { pwrmgr_attribute.pwrmgr_task_state |= (1 << task_id); } return ( SUCCESS ); }
/********************************************************************* * @fn osal_pwrmgr_device
* @brief
设置电源管理设备属性。
* @param pwrmgr_device -选择PWRMGR_ALWAYS_ON的话将不会进入睡眠 模式,选择 PWRMGR_BATTERY将允许HAL管理CPU进入SLEEP LITE或者SLEEP DEEP状态。 */ void osal_pwrmgr_device( uint8 pwrmgr_device ) { pwrmgr_attribute.pwrmgr_device = pwrmgr_device;
0 1
选择PWRMGR_ALWAYS_ON的话将不会进入睡眠模式,选择PWRMGR_BATTERY 将允许HAL管理CPU进入SLEEP LITE或者SLEEP DEEP状态。
#define PWRMGR_CONSERVE 0 #define PWRMGR_HOLD 1
低功耗标志,主要用于osal_pwrmgr_task_state()这个函数中,用于标志每一任务是 否需要低功耗。
如何实现ZigBee休眠与唤醒
报告人:XXX 时 间:2013-3-28
ZigBee技术优势
发射功率仅为1mW,仅靠两节5 号电池就可维持长达6个月到2 年的工作时间。
低功耗
在实际的开发应用中,产品是否具有低功耗这一特性 将在很大程度上决定其整体性能。 目标
通过休眠定时器,实现传感器节点的休眠 /唤醒调度,使其低功耗运行,减少节 点能耗。
halIntState_t intState if ( pwrmgr_attribute.pwrmgr_device != PWRMGR_ALWAYS_ON ) // 首先检查是否支持低功 { 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 ); //将系统进入睡眠模式 } } } #endif /* POWER_SAVING */
}
/* 这个函数可以被每一个任务调用,用于设置这个任务是否支持低功耗运行,如果每一个任 务不支持低功耗将无法进入低功耗模式运行。*/ uint8 osal_pwrmgr_task_state( uint8 task_id, uint8 state ) {
if ( task_id >= tasksCnt )
/* HAL电源管理模式是设置电源管理状态的,默认状态是HAL_SLEEP_OFF。其余 设置均会关*闭系统时钟停止CPU。 * HAL_SLEEP_TIMER模式可以被睡眠定时器中断和IO中断以及复位唤起。 * HAL_SLEEP_DEEP模式可以被IO中断以及复位唤起。 */ #define HAL_SLEEP_OFF #define HAL_SLEEP_TIMER #define HAL_SLEEP_DEEP CC2530_PM0 CC2530_PM2 CC2530_PM3
如何去实现ZigBee休眠与唤醒?
CC2530有3种睡眠模式,pm2模式比较省功耗而且 可以被定时唤醒;pm3模式最省电但是只能被外部中断唤 醒。
1、sensordemo的sensor在入网以后,为什么灯在不断地闪? 其实,闪一次就是睡眠了一次:亮的时候睡过来,灭的时候睡 下去。具体代码在halSleep函数里。要做的,就是读懂这个机 制是怎么运作的。
#define CC2530_PM0
0
#define CC2530_PM1
#define CC2530_PM2 #define CC2530_PM3
1
2 3
#define MAX_SLEEP_TIME 最大睡眠时间是510000ms。
510000
总结
可以看到在OSAL中是使用睡眠定时器来控制睡眠时间的,在系统初 始化的时候是将电源控制结构体中的pwrmgr_device设备属性设置 为PWRMGR_ALWAYS_ON,这样默认就不进入休眠状态。必须在 应用层里面调用void osal_pwrmgr_device( uint8 pwrmgr_device ) 这个OSAL的API来设置使得OSAL能够进入休眠状态。 在用户任务中需要用的这样一个API——uint8 osal_pwrmgr_task_s tate( uint8 task_id, uint8 state )来设置这个任务是否支持休眠,如 果有一个任务不支持休眠的话,整个系统就将不会进入休眠模式。 这个在void osal_pwrmgr_powerconserve( void )中有相关的查询。 在OSAL的主循环中void osal_start_system( void )调用了osal_pwr mgr_powerconserve这个函数。
}
表示OSAL系统在检查完所有的任务事件之后发现没有事件需要处理,这样在POW ER_SAVING宏定义打开的情况下将调用osal_pwrmgr_powerconserve();函数,在 这函数中将会根据选择系统进入休眠。
退出休眠
当出现IO中断或者复位时候会退出休眠,或者在休眠定时器中断时候也将会退出休 眠。如果是IO中断或者休眠定时器中断退出之后将回到进入休眠的地方继续向下执 行,复位退出的话进入程序的初部分执行。
uint16 accumulated_sleep_time;