查看: 6461|回复: 4

谈谈SerialApp

[复制链接]
Vigi_Lin 发表于 2012-7-27 10:53:53 | 显示全部楼层 |阅读模式
   粗略的看了下这个程序,发现这个程序有一个EP(终端),每个终端有两个簇(SERIALAPP_CLUSTERID1、SERIALAPP_CLUSTERID2),可以在以下代码中定义
// This list should be filled with Application specific Cluster IDs.
const cId_t SerialApp_ClusterList[SERIALAPP_MAX_CLUSTERS] =
{
  SERIALAPP_CLUSTERID1,
  SERIALAPP_CLUSTERID2
};
其中SERIALAPP_CLUSTERID1是负责数据的传输的,而SERIALAPP_CLUSTERID2则负责传输的反馈。在以下函数中可以看出
/*********************************************************************
* @fn      SerialApp_ProcessMSGCmd
*
* @brief   Data message processor callback. This function processes
*          any incoming data - probably from other devices. Based
*          on the cluster ID, perform the intended action.
*
* @param   pkt - pointer to the incoming message packet
*
* @return  TRUE if the 'pkt' parameter is being used and will be freed later,
*          FALSE otherwise.
*/
void SerialApp_ProcessMSGCmd( afIncomingMSGPacket_t *pkt )
{
  uint8 stat;
  uint8 seqnb;
  uint8 delay;

  switch ( pkt->clusterId )
  {
  // A message with a serial data block to be transmitted on the serial port.
  case SERIALAPP_CLUSTERID1:        // 处理数据
    // Store the address for sending and retrying.
    osal_memcpy(&SerialApp_RxAddr, &(pkt->srcAddr), sizeof( afAddrType_t ));  // 保存来信地址

    seqnb = pkt->cmd.Data[0];  // 保存计数(来自发送端,来用检验)

    // Keep message if not a repeat packet
    if ( (seqnb > SerialApp_RxSeq) ||                    // Normal, 是否是最新的数据
        ((seqnb < 0x80 ) && ( SerialApp_RxSeq > 0x80)) ) // Wrap-around,
    {
#ifndef   GEC_EP
      // Transmit the data on the serial port.
      if ( HalUARTWrite( SERIAL_APP_PORT, pkt->cmd.Data+1, (pkt->cmd.DataLength-1) ) )
      {
        // Save for next incoming message
        SerialApp_RxSeq = seqnb;   // 保存计数
        stat = OTA_SUCCESS;
      }
      else
      {
        stat = OTA_SER_BUSY;
      }
#else                   // 添加部分代码,实现数据回传显示到串口,没办法串口只有一个
    if (afStatus_SUCCESS != AF_DataRequest(&SerialApp_RxAddr,
                                           (endPointDesc_t *)&SerialApp_epDesc,
                                            SERIALAPP_CLUSTERID1,
                                            SerialApp_TxLen+1, SerialApp_TxBuf,
                                            &SerialApp_MsgID, 0, AF_DEFAULT_RADIUS))
    {
      osal_set_event(SerialApp_TaskID, SERIALAPP_SEND_EVT);
    }
#endif
    }
    else
    {
      stat = OTA_DUP_MSG;
    }

    // Select approproiate OTA flow-control delay.
    delay = (stat == OTA_SER_BUSY) ? SERIALAPP_NAK_DELAY : SERIALAPP_ACK_DELAY; // UART忙则延时16ms,否则延时1ms

    // Build & send OTA response message.
    SerialApp_RspBuf[0] = stat;   // 接收状态
    SerialApp_RspBuf[1] = seqnb;  // 计数
    SerialApp_RspBuf[2] = LO_UINT16( delay );
    SerialApp_RspBuf[3] = HI_UINT16( delay );
    osal_set_event( SerialApp_TaskID, SERIALAPP_RESP_EVT );  // 发送反馈信息
    osal_stop_timerEx(SerialApp_TaskID, SERIALAPP_RESP_EVT);  // 停止反馈定时器
    break;

  // A response to a received serial data block.
  case SERIALAPP_CLUSTERID2:    // 处理反馈
    if ((pkt->cmd.Data[1] == SerialApp_TxSeq) &&   // 反馈回来的是刚才发的
       ((pkt->cmd.Data[0] == OTA_SUCCESS) || (pkt->cmd.Data[0] == OTA_DUP_MSG)))  // 成功或者过期
    {
      SerialApp_TxLen = 0;    // 准备下一次发送
      osal_stop_timerEx(SerialApp_TaskID, SERIALAPP_SEND_EVT);  // 无需重发,关闭定时器
    }
    else   // 需要重发
    {
      // Re-start timeout according to delay sent from other device.
      delay = BUILD_UINT16( pkt->cmd.Data[2], pkt->cmd.Data[3] );    // 延时发送
      osal_start_timerEx( SerialApp_TaskID, SERIALAPP_SEND_EVT, delay );  //
    }
    break;

    default:
      break;
  }
}

总结一下以上的代码,当SERIALAPP_CLUSTERID1收到数据的时候,将会检验这个数据包是否是新的,由于逻辑有点复杂,下面用伪代码描述
if (新数据包)

   if (UART发送成功)
   {
        反馈成功信息;
     }
    else  否则反馈UART忙;

else 反馈此包过期;

同样,对于SERIALAPP_CLUSTERID2的信息处理也可以这样描述
if (刚才发送的包 && (成功 || 过期))
{
   关闭定时器,注备下一次的发送,也就是说没有收到确认信息,不会进行下一次的发送
}
else
{
  给我延时重发去
}
outman 发表于 2012-7-28 08:02:04 | 显示全部楼层
审核晚了,感谢楼主的共享,已经为您增加了威望值,并提升为vip会员,多谢对飞比的支持!
lizheng86312 发表于 2012-8-29 12:10:38 | 显示全部楼层
学到东西了。顶。。。
佩天门 发表于 2012-10-13 15:50:31 | 显示全部楼层
感谢您的分享
星夜 发表于 2013-1-4 17:03:21 | 显示全部楼层
谢谢楼主的分享
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表