CC2431 代码分析-CC2431狂轰滥炸

Posted Position闲谈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CC2431 代码分析-CC2431狂轰滥炸相关的知识,希望对你有一定的参考价值。

CC2431 code review : CC2431 狂轰滥炸

在上一篇中的最后我们分析到CC2431 开始喊出第一声,这里我们逐步分析从第一声到后面的狂轰滥炸!

上代码

/*********************************************************************
 * @fn      startBlast
 *
 * @brief   Start a sequence of blasts and calculate position.
 *
 * @param   none
 *
 * @return  none
 */
static void startBlast( void )
{
  uint8 idx;
  afAddrType_t dstAddr;
  dstAddr.addrMode = afAddrBroadcast;
  dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR_DEVALL;
  dstAddr.endPoint = LOCATION_REFNODE_ENDPOINT;

  if ((ZDO_Config_Node_Descriptor.CapabilityFlags & CAPINFO_RCVR_ON_IDLE) == 0)
  {
    // Turn the receiver on while idle - temporarily.
    idx = true;
    ZMacSetReq( ZMacRxOnIdle, &idx );
  }
  SampleApp_Sleep( FALSE );

  for ( idx = 0; idx < BLINDNODE_MAX_REF_NODES; idx++ )
  {
    refNodes[idx].addr = INVALID_NODE_ADDR;
  }

  (void)AF_DataRequest( &dstAddr, (endPointDesc_t *)&epDesc,
                         LOCATION_RSSI_BLAST, 0,
                         NULL, &transId,
                         AF_SKIP_ROUTING, 1 );
  rspCnt = 0;
  blastCnt = BLINDNODE_BLAST_COUNT;
  state = eBnBlastOut;
  osal_start_timerEx( BlindNode_TaskID, BLINDNODE_BLAST_EVT, BLINDNODE_BLAST_DELAY );
}

 

上面函数主要内容

a.  dstAddr 这个结构体

  通过赋值,我们可以看出这个地址是一个广播地址,就是向网络中的所有节点都发送信息。还有一个需要注意的事项就是Endpoint,这个先留意是 LOCATION_REFNODE_ENDPOINT,其实这个就指明了虽然我是广播信息,但是需要REFNODE,也就是参考节点处理。(任何节点都可能收到信息,但是只有参考节点需要处理)。

b.  if ((ZDO_Config_Node_Descriptor.CapabilityFlags & CAPINFO_RCVR_ON_IDLE) == 0)

  这个里面调用MAC层的函数,我们暂时可以认为它没有执行。(其实也就是接收器控制)

  后面的 SampleApp_Sleep( FALSE );其实也很好理解,不要睡眠进入低功耗模式,你喊出一嗓子后,参考节点会回信息给你,如果睡眠下去怎么接收信息(虽然等到醒来可以接收,但是会导致延时,代码这里就一气呵成,等定完位再可以休眠)。

c 清理地址

  for ( idx = 0; idx < BLINDNODE_MAX_REF_NODES; idx++ )
  {
    refNodes[idx].addr = INVALID_NODE_ADDR;
  }

因为现在还不知道喊出一嗓子后有没有节点会回应,所以把保存地址的数组先清理掉,等接收到信息后把对应的地址都在放进去。

d 喊一嗓子 函数

  (void)AF_DataRequest( &dstAddr, (endPointDesc_t *)&epDesc,
                         LOCATION_RSSI_BLAST, 0,
                         NULL, &transId,
                         AF_SKIP_ROUTING, 1 );

AF_DataRequest 函数就是一个无线发送函数,这个需要有两点注意的是

1. LOCATION_RSSI_BLAST --这个表明了这个是什么事,接收到这条信息的节点,也就是参考节点会根据它进行具体处理,我们后续会继续看这个问题。

2.  AF_SKIP_ROUTING -- 这个是AF_DataRequest 的一个参数,表明发出的信息不能被路由,我们知道在Zigbee 网络中信息是可以被路由到很远的地方,通过这个参数控制该信息是不能被路由的,传一步就停了。 为何有这样的考虑呢? 其实也很简单,当盲节点喊出一嗓子,旁边的节点收到信息后根据距离不同RSSI值不同。但是如果路由了,那么喊出这一嗓子的就不是盲节点了。再举个例子,军训站成一排,第一个人报数,教官通过声音就知道第一个人大概离自己有多远;第二个人听到第一个人报数后再喊一嗓子,对于教官来说无法通过第二个人的声音判断出第一个人在哪里,所以没必要通过连续报数获得第一个人的位置,所以也不需要路由。

 rspCnt = 0;
  blastCnt = BLINDNODE_BLAST_COUNT;
  state = eBnBlastOut;

全部变量的设定,rspCnt 是统计收到回应的个数,刚刚发出去信息当时没有收到,先清零,后面收到信息会有累加

        blastCnt 这个是表明CC2431 一次要喊多少次,刚刚才是第一嗓子,真正要喊 BLINDNODE_BLAST_COUNT, 其实这也是一个可以优化的参数,因为我们后面可以看出,其实在参考节点手打盲节点的信息后,将多次的RSSI会求均值然后发回到CC2431 中,再我们看来,次数越多,均值也就也接近真实稳定的值。

         state = eBnBlastOut; 之前我们遇到过这个state,当时是idle状态,目前状态是eBnBlastOut,也是就是喊出去了,后面还会多次修改。

 osal_start_timerEx( BlindNode_TaskID, BLINDNODE_BLAST_EVT, BLINDNODE_BLAST_DELAY );

函数的最后一句,定时执行一个事件BLINDNODE_BLAST_EVT,我们也可以猜出来,通过这个事件会进一步狂轰滥炸。

 

2 BLINDNODE_BLAST_EVT 狂轰滥炸

 if ( events & BLINDNODE_BLAST_EVT )
  {
    if ( blastCnt == 0 )
    {
      state = eBnBlastOff;
      finishCollection();
    }
    else
    {
      afAddrType_t dstAddr;
      uint8 stat, delay;

      dstAddr.addrMode = afAddrBroadcast;
      dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR_DEVALL;
      dstAddr.endPoint = LOCATION_REFNODE_ENDPOINT;

      if ( --blastCnt == 0 )
      {
        stat = AF_DataRequest( &dstAddr, (endPointDesc_t *)&epDesc,
                                LOCATION_XY_RSSI_REQUEST, 0, NULL,
                               &transId, AF_SKIP_ROUTING, 1 );

        state = eBnBlastIn;
        delay = config.timeout;
      }
      else
      {
        stat = AF_DataRequest( &dstAddr, (endPointDesc_t *)&epDesc,
                                LOCATION_RSSI_BLAST, 0, NULL,
                               &transId, AF_SKIP_ROUTING, 1 );
        delay = BLINDNODE_BLAST_DELAY;
      }
      if ( stat != afStatus_SUCCESS )
      {
        blastCnt++;
      }
      osal_start_timerEx( BlindNode_TaskID, BLINDNODE_BLAST_EVT, delay );
    }

    return ( events ^ BLINDNODE_BLAST_EVT );
  }

  

 

以上是关于CC2431 代码分析-CC2431狂轰滥炸的主要内容,如果未能解决你的问题,请参考以下文章

POJ_2431 Expedition 数据结构

POJ2431&BUCU5945——丛林探险(中文版)——题解

poj 2431 优先队列,贪心

POJ - 2431 Expedition(贪心+优先队列)

POJ 2431

POJ 2431 Expedition(探险)