使用AF_ACK_REQUEST时,会进入长休眠,所有事件不再自动唤醒,只有外部中断触发才能唤醒
HI,大家好!
1、使用的是协议栈版本为Z-Stack Mesh 1.0.0。
2、节点类型为endev类型,pollrate为500ms。
问题描述:
在终端设备发送无线数据时,为了确保数据被目标节点收到,在发送无线数据时,使用AF_ACK_REQUEST选项,当一定的时间内没收到发送成功的AF_DATA_CONFIRM_CMD事件,即继续重发数据。
现在发现在使用AF_ACK_REQUEST选项时,当发送失败我继续重发时,经常性的设备进入了PM3的长期休眠模式了,外部中断可以触发程序继续运行。如果使用AF_ACK_REQUEST选项时,发送成功,不会进入长休眠模式,如果不使用AF_ACK_REQUEST选项,也不会进入长休眠模式。
添加打印输出时发现,在休眠函数halSleep()里对休眠前的事件打印输出,发现taskID为1,event为0x20,也就是nwk层的事件NWK_DATABUF_SEND出现异常,异常表现为在进入休眠前,跑到了halSleep( uint32 osal_timeout )函数时,osal_timeout 的值为0,就是taskID为1,event为0x20的timeout时间为0,导致进入休眠时,休眠函数不设置唤醒定时器,从而一直休眠,在函数halSleep()里,有以下一段代码:
if(timeout != 0)
{
if (timeout > HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME ))
{
timeout -= HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME );
halSleepSetTimer(HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME ));
}
else
{
/* set sleep timer */
halSleepSetTimer(timeout);
timeout = 0;
}
/* set up sleep timer interrupt */
HAL_SLEEP_TIMER_CLEAR_INT();
HAL_SLEEP_TIMER_ENABLE_INT();
}
从代码可以看出,只有在osal_timeout不为0的情况下,才去设置唤醒定时器,如果为0则不设置唤醒定时器,导致了长休眠。
请问:
什么情况下,nwk层的事件NWK_DATABUF_SEND的timeout时间会变成0?在使用AF_ACK_REQUEST时有什么特别要注意的地方?每发一包数据,要先等AF_DATA_CONFIRM_CMD才能继续发送第二包数据吗?如果没等到AF_DATA_CONFIRM_CMD的情况下,继续发送,会出现异常吗?
在论坛里,有一个类似的问题的帖子,只是没人回复解答:http://www.deyisupport.com/question_answer/wireless_connectivity/zigbee/f/104/t/97270.aspx
望大神能指点一下去解决问题。
如果你的poll rate等于500ms的话,系统是不会进入PM3模式的,最多是PM2模式下。
NWK_DATABUF_SEND的timer是0,说明是没有数据需要发送的。
应用层发送数据的间隔是多少?
VV,你好!
在文件OSAL_Timers.c的函数osal_next_timeout()中,会找出当前定时器链表中,timeout时间最小的一个,我在调试的时候,就是NWK_DATABUF_SEND的timerout时间为0,然后这个时间传递到Hal_sleeep.c中的函数halSleep( uint32 osal_timeout ),函数halSleep( uint32 osal_timeout )在接收的参数为0时,不去设置唤醒定时器了,这样就一直不会唤醒了,在没有外部中断触发的情况下,就一直休眠了。
我应用层发送的数据时间间隔是3秒,如果我将时间缩短,就更容易出问题,所以这个AF_ACK_REQUEST选项,用起来会出现一些意料不到的问题。