This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

怎么获得收到的应答帧

如上图,每发一个数据,都会有会复(那个短的,左边有空格的)

这个回复的接收在什么地方啊?

 

  • 函数rxStartIsr中,有一段Process ACKs.

  • Hi Aries Lord,

    嗯,看过了,但看到macTxComPleteCallback(status)就跟不下去了,我想看看 当收到应答 或  收不到应答   时是怎么向上层传递的,以及数据是怎么重发的,这些流程能看到么?

  • ACK不对上层开放,只是底层用于CSMA回退计算用,还有就是终端节点可以从ACK中判断是否继续RX_ON还是休眠

  • Hi Aries Lord,

    我想这样:终端发送数据,只要判断发送数据时是否到第一个节点(应该是父节点吧)就可以了,那有什么好方法么?

    现在看到正常发送,然后关闭协调器后(只有一个终端和协调器),macTxAckNotReceivedCallback会调用8或7次

     

    AF_dataRequest函数中加入AF_ACK_REQUEST,成功发送数据时,也进不了AF_DATA_CONFIRM_CMD事件,是不是AF_ACK_REQUEST不这样用?

     

    我现在想,只能在macTxAckNotReceivedCallback函数中记录这个函数的调用次数来判断这一次是否发送失败

     

     

  • Hi Aries Lord

    纠正下我的实验现象

    现在看到正常发送,然后关闭协调器后(只有一个终端和协调器),macTxAckNotReceivedCallback会调用7次

    后来几次macTxAckNotReceivedCallback会调用24次,加串口显示,可以看到,他把原来的数据也重发了,每4次是一个数据,也就说,重发了6组数据

  • AF_DataRequest只要返回了ZSuccess,那么必然导致AF_DATA_CONFIRM触发。
  • Hi Aries Lord

    但是我在AF_DATA_CONFIRM下加串口输出,只有输出过一次,以后发送数据没有输出过(终端发给协调器)

     

    终端调用AF_DataRequest函数,当协调器关闭后,这个函数返回值是ZSuccess啊,只有到下次再发时才是失败,加AF_ACK_REQUEST也是如此,这样,当协调器关闭后的第一次发数据就会丢了啊,终端这边也不知道

    我这边想把丢的数据暂存起来,下次一起发,有什么好的建议么?

  • 你好,

    对于应用层来说,调用一次AF_DataRequest,算是一次发送,所以只返回一次AF_DATA_CONFIRM。

    对于底层来说,当7次发送都失败的时候,给应用层发失败 Confirm数据,7次里面只要有一次成功,就给应用发成功 Confirm了。

  • Hi VV,

    AF_DATA_CONFIRM事件中,我加入串口输出函数,看到只有在入网时会触发一次这个事件

    当发送数据时,不会触发这个事件,发送函数加入AF_ACK_REQUEST也不触发

    是不是你说的AF_DATA_CONFIRM不是事件标志?

  • Hi VV,

    现在知道了,我以前都是在ZDApp.c中的ZDAPP_ProcessOSALMsg()函数中的case AF_DATA_CONFIRM_CMD中加的串口输出,结果,无论怎样,只有在入网时输出一次,以后怎么也不会收到

    现在我在SampleApp_ProcessEvent()函数中加入case AF_DATA_CONFIRM_CMD: afDataConfirm = (afDataConfirm_t *)MSGpkt;然后判断afDataConfirm的值就可以了

    是我以前没注意,才弄了这么久…

  • Hi VV,

    我现在SampleApp_ProcessEvent()函数中加入case AF_DATA_CONFIRM_CMD: 中输出值,结果单播数据后,输出的值时间延迟很晚,发完数据后,应答可能10s或者更长,很多时候还会在下一次数据发送之前才收到这次数据的应答,

    请问怎么快点在应用层收到?

  • 你的数据是发给谁的?End device吗? end device 来拿数据的poll rate多少?

    如果是终端设备的话,要等节点来请求数据,data Request以后,把MAC发过来,你的应用层才会有AF_DATA_CONFIRM_CMD

  • Hi VV,

    发给协调器的,终端发给协调器

    end device 的poll rate都改成0了,接收器常开

    end device发完数据后强制休眠,我现在把应答的判断放在afDataConfirm函数中了,在该函数中对status值判断,为00表示成功,不为0表示失败

     

    另一个问题: 我这个是强制休眠的,可能会影响底层部分内容,当end device 向协调器发数据一段时间后,我通过单击按键(按键事件里会调用ZDOInitDevice(0))重新入网,结果看抓包:这个函数没有反应,没抓到任何包(没有Becon Request),这可能是哪方面出问题呢?

  • Hi VV,

    找到调用ZDOInitDevice(0)后,抓包抓不到Becon Request的线索了

    在ZDO_NetworkDiscoveryConfirmCB(uint8 ResultCount, networkDesc_t *NetworkList)  这个函数里面,传进了来的参数ResultCount是0,

    难道NLME_NetworkDisvoceryRequest()没有找到网络,协调器就在旁边啊,重启end device后,end device就能找到网络,运行一会后,按键调用ZDOInitDevice(0)就找不到,这是怎么回事呢???

  • 看下你的devState状态值

  • Hi VV,

    devState的状态值是未知的,不是devStates_t结构中的定义的

    是不是给devState赋个值(如DEV_INIT)就可以了呢???

    这种情况是那一部分出问题导致的啊???

  • Hi VV,

    我上次说的 ”devState的状态值是未知的,不是devStates_t结构中的定义的……“ 这个不对,弄错了

    实验情况是:

    起初devState是DEV_END_DEVICE,后来调用ZDOInitDevice(0)后,devState变为DEV_NWK_DISC,在ZDO_NetworkDiscoveryConfirmCB(uint8 ResultCount, networkDesc_t *NetworkList)  这个函数里面,传进了来的参数ResultCount此时是0

    请问:是什么导致的呢,我知道调用AF_DataRequest()函数后,若还没收到应答,就强制休眠或调用发送函数就会出现这种情况,问题是怎么恢复呢???

  • 问下你用的协议栈是哪个?我这边 ZStatus_t ZDO_NetworkDiscoveryConfirmCB(uint8 status)跟你那边不一样么.

  • Hi VV,

    我现在用的是zstack-2.3.0的

    这问题是强制休眠引起的,不休眠的话,程序很正常

    现在我在做改成用协议栈中原来的休眠函数,不再用强制休眠的了,程序基本改好了,不过还存在两个问题:

    <1>上电不入网的话,电流在11mA左右,(注:我已经限制入网次数为3次)

    <2>如果入网后,再掉网或在网,此时电流在300uA,此时只有按下按键产生一次中断,才会降低最低60uA

    也就是说,终端上电后,如一次网,产生一次中断才正常

    那刚上电时,这些引起电流大的原因可能是哪里呢???

     

  • Hi VV,

    这些情况找到原因了,

    <1>上电不入网的话,电流在11mA左右,是因为OSAL_PwrMgr.c中OSAL_pwrmgr_init()中pwrmgr_attribute.pwrmgr_device我没有初始化为PWRMGR_BATTERY的缘故

    <2>如果入网后,再掉网或在网,此时电流在300uA,此时只有按下按键产生一次中断,才会降低最低60uA

        这个的原因和上面的相似,还是引脚初始化上,只有中断产生一次,那引脚才配置的

    <3>终端,入协调器A后,关闭协调器A,终端掉网后,打开协调器B,不能再入协调器B的网络

         我搜的时候看到你们的回答是  擦出FLASH或离开网络

        我调用NLME_InitNV出错,(不知道这个是不是擦出函数),离开网络函数,看了下,貌似也不能用,因为在掉网状态下,而且离开网络函数貌似还会软重启,我的程序不能 重启

    后来我发现:在ZDApp.c中的ZDO_NetworkDiscoveryConfirmCB()函数中,屏蔽掉一下内容就可以了,就是入网过程中不校验协调器的物理地址,分享下

                  if(nwk_ExtPANIDValid(ZDO_UseExtendPANID) == true)

                  {

                       if(OSAL_ExtAddrEqual(ZDO_UseExtendedPANID,pNwkDesc->extenedPANID) == false)

                           continue;

                  }

     

     

  • 关于第三个问题,原因在于节点保存了之前加过网的ExtendPANID,所以即便搜索到其他网络,如果这个新的网络的ExtendPANID和原先的不一样,就不会选择加入。

    你可以通过重新一次的入网来做,

    // Set the NV startup option to force a "new" join.
          zgWriteStartupOptions( ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE );