CC2431定位分析

一、盲节点想参考节点广播信息

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;     //接收数据为0

  blastCnt = BLINDNODE_BLAST_COUNT;//发送次数为8

  state = eBnBlastOut;

  //定时重发

  osal_start_timerEx(BlindNode_TaskID,BLINDNODE_BLAST_EVT,                BLINDNODE_BLAST_DELAY );

}

二、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

      {

  //不是最后一次广播,正常接着广播-->8

        stat = AF_DataRequest( &dstAddr, (endPointDesc_t *)&epDesc,

                                LOCATION_RSSI_BLAST, 0, NULL,

                               &transId, AF_SKIP_ROUTING, 1 );

        delay = BLINDNODE_BLAST_DELAY;

      }

   //如果失败了,广播次数+1

      if ( stat != afStatus_SUCCESS )

      {

        blastCnt++;

      }

   //再次触发事件BLINDNODE_BLAST_EVT,

      osal_start_timerEx(BlindNode_TaskID, BLINDNODE_BLAST_EVT, delay );

    }

    return ( events ^ BLINDNODE_BLAST_EVT );

  }

函数说明:

在处理BLINDNODE_BLAST_EVT事件时主要完成盲节点对参考节点的八次广播。在处理过程中分为了三种可能①广播完成②最后一次广播③以上两种情况的非,姑且把这种情况起名为正常情况。

要完成8次广播,前七次完全相同,即为正常情况。

当最后一次广播的时候,广播信息的ID和前七次不同:LOCATION_XY_RSSI_REQUEST。当参考节点接收到含有该信息的簇ID后,将返回RSSI值。

广播完成,广播完成后将blast状态设置为关闭,并调用了finishCollection()进行接收来自参考节点的RSSI值。-----该函数稍后分析,先梳理参考节点数据流程。

三、参考节点接收blast信息

说明:在上面的梳理过程我们可以知道,blast信息共发送了8次,其中前七次使用相同的簇IDLOCATION_RSSI_BLAST,而第八次使用的簇ID则是LOCATION_XY_RSSI_REQUEST。可以看出肯定在参考节点进行了不同的处理。

3.1IDLOCATION_RSSI_BLAST

case LOCATION_RSSI_BLAST:

  addBlast( pkt->srcAddr.addr.shortAddr, pkt->LinkQuality );

break;

static void addBlast( uint16 addr, byte rssi )

{

  blastAcc_t *ptr = blastPtr;

  //进行地址匹配

  while ( ptr )

  {

    if ( ptr->addr == addr )

    {

      break;

    }

    ptr = ptr->next;

  }

 

  if ( ptr )//匹配成功

  {

    ptr->acc += rssi;//添加RSSI

    ptr->cnt++;//增加次数

  }

  else//增加列表项,添加信息

  {

    ptr = (blastAcc_t *)osal_mem_alloc( sizeof( blastAcc_t ) );

    if ( ptr )

    {

      ptr->next = blastPtr;

      blastPtr = ptr;

      ptr->addr = addr;

      ptr->acc = rssi;

      ptr->cnt = 1;

    }

  }

}

又上面的代码可以看出,八次blast的前七次只是为了提取RSSI值,参考节点将RSSI值累加到ptr->acc。 

3.2  LOCATION_XY_RSSI_REQUEST

 case LOCATION_XY_RSSI_REQUEST:

    rssiRsp( pkt );

 break;

static void rssiRsp( afIncomingMSGPacket_t *pkt )

{

  blastAcc_t *ptr = blastPtr;

  blastAcc_t *prev = NULL;

  byte options, radius;

  while ( ptr )

  {

    if ( ptr->addr == pkt->srcAddr.addr.shortAddr )

    {

      break;

    }

    prev = ptr;

    ptr = ptr->next;

  }

  if ( ptr )

  {

    //RSSI的平均值

    rspMsg[LOCATION_XY_RSSI_RSSI_IDX] =(ptr->acc + pkt->LinkQuality) /   (ptr->cnt + 1);

    if ( prev )

    {

      prev->next = ptr->next;

    }

    else

    {

      blastPtr = ptr->next;

    }

    osal_mem_free( ptr );

    options = AF_SKIP_ROUTING;

    radius = 1;

  }

  else

  {

  //没有匹配到,返回本次RSSI

    rspMsg[LOCATION_XY_RSSI_RSSI_IDX] = pkt->LinkQuality;

    options = AF_TX_OPTIONS_NONE;

    radius = AF_DEFAULT_RADIUS;

  }

  pkt->srcAddr.addrMode = afAddr16Bit;

  //向盲节点发送RSSI

  (void)AF_DataRequest( &pkt->srcAddr, (endPointDesc_t *)&epDesc,

              LOCATION_XY_RSSI_RESPONSE,LOCATION_XY_RSSI_LEN,

                                        rspMsg, &transId, options, radius );

}

 
CC2431定位分析 - 屠猪客 - 屠猪客博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值