zstack学习笔记2--点对点通信1

来源:互联网 发布:网络贸易 编辑:程序博客网 时间:2024/06/05 02:57

1 实验说明 

     学习zstack协议栈时,最简单的实验莫过于点对点的实验。而本篇将介绍的点对点实验有只是实现了一个最简单功能:当终端节点加入协调器创建的网络时,其网络状态将发生改变。当终端节点的网络状态改变时,终端节点发送一个数据(AF无线的方式)给协调器节点。协调器节点收到数据后,进行解析,如收到的数据为“LED”则将其板载的LED2置为闪烁状态。

2 协调器节点代码

/********************************************************************* * INCLUDES */#include "OSAL.h"#include "AF.h"#include "ZDApp.h"#include "ZDObject.h"#include "ZDProfile.h"#include "Coordinator.h"#include "DebugTrace.h"   #include <string.h>#if !defined( WIN32 )#include "OnBoard.h"#endif   /* HAL */#include "hal_lcd.h"#include "hal_led.h"#include "hal_key.h"#include "hal_uart.h"
     此处为若干的头文件定义,没什么特别的,无需交代什么。
/********************************************************************* * GLOBAL VARIABLES */// This list should be filled with Application specific Cluster IDs.const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS] ={  GENERICAPP_CLUSTERID};const SimpleDescriptionFormat_t GenericApp_SimpleDesc ={  GENERICAPP_ENDPOINT,              //  int Endpoint;  GENERICAPP_PROFID,                //  uint16 AppProfId[2];  GENERICAPP_DEVICEID,              //  uint16 AppDeviceId[2];  GENERICAPP_DEVICE_VERSION,        //  int   AppDevVer:4;  GENERICAPP_FLAGS,                 //  int   AppFlags:4;  GENERICAPP_MAX_CLUSTERS,          //  byte  AppNumInClusters;  (cId_t *)GenericApp_ClusterList,  //  byte *pAppInClusterList;  0,          //  byte  AppNumInClusters;  (cId_t *)NULL   //  byte *pAppInClusterList;};// This is the Endpoint/Interface description.  It is defined here, but// filled-in in GenericApp_Init().  Another way to go would be to fill// in the structure here and make it a "const" (in code space).  The// way it's defined in this sample app it is define in RAM.endPointDesc_t GenericApp_epDesc;/********************************************************************* * EXTERNAL VARIABLES *//********************************************************************* * EXTERNAL FUNCTIONS *//********************************************************************* * LOCAL VARIABLES */byte GenericApp_TaskID;   // Task ID for internal task/event processing                          // This variable will be received when                          // GenericApp_Init() is called.devStates_t GenericApp_NwkState;byte GenericApp_TransID;  // This is the unique message ID (counter)afAddrType_t GenericApp_DstAddr;unsigned char uartbuf[128];
     以上为各种变量的定义。

/********************************************************************* * LOCAL FUNCTIONS */static void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );//static void GenericApp_SendTheMessage( void );static void rxCB(uint8 port,uint8 event);
     以上为各个函数的定义。
/********************************************************************* * @fn      GenericApp_Init * * @brief   Initialization function for the Generic App Task. *          This is called during initialization and should contain *          any application specific initialization (ie. hardware *          initialization/setup, table initialization, power up *          notificaiton ... ). * * @param   task_id - the ID assigned by OSAL.  This ID should be *                    used to send messages and set timers. * * @return  none */void GenericApp_Init( uint8 task_id ){  halUARTCfg_t uartConfig;  GenericApp_TaskID = task_id;  GenericApp_TransID = 0;  // Fill out the endpoint description.  GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT;  GenericApp_epDesc.task_id = &GenericApp_TaskID;  GenericApp_epDesc.simpleDesc            = (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;  GenericApp_epDesc.latencyReq = noLatencyReqs;  // Register the endpoint description with the AF  afRegister( &GenericApp_epDesc );    uartConfig.configured = TRUE;  uartConfig.baudRate = HAL_UART_BR_115200;  uartConfig.flowControl = FALSE;  uartConfig.callBackFunc = rxCB;  HalUARTOpen(0,&uartConfig);}
      Generic App Task初始化函数。

/********************************************************************* * @fn      GenericApp_ProcessEvent * * @brief   Generic Application Task event processor.  This function *          is called to process all events for the task.  Events *          include timers, messages and any other user defined events. * * @param   task_id  - The OSAL assigned task ID. * @param   events - events to process.  This is a bit map and can *                   contain more than one event. * * @return  none */uint16 GenericApp_ProcessEvent( uint8 task_id, uint16 events ){  afIncomingMSGPacket_t *MSGpkt;  if ( events & SYS_EVENT_MSG )  {    MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );    while ( MSGpkt )    {      switch ( MSGpkt->hdr.event )      {        case AF_INCOMING_MSG_CMD:          GenericApp_MessageMSGCB( MSGpkt );          break;        default:          break;      }      // Release the memory      osal_msg_deallocate( (uint8 *)MSGpkt );      // Next      MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );    }    // return unprocessed events    return (events ^ SYS_EVENT_MSG);  }  // Discard unknown events  return 0;}
      Generic Application的事件处理函数。在系统的消息队列中如果收到了接收到无线数据包的消息,则程序将跳转到case AF_INCOMING_MSG_CMD:即调用GenericApp_MessageMSGCB()函数对收到的消息进行处理。

/********************************************************************* * LOCAL FUNCTIONS *//********************************************************************* * @fn      GenericApp_MessageMSGCB * * @brief   Data message processor callback.  This function processes *          any incoming data - probably from other devices.  So, based *          on cluster ID, perform the intended action. * * @param   none * * @return  none */static void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ){  unsigned char buffer[4] = " ";  switch ( pkt->clusterId )  {    case GENERICAPP_CLUSTERID:      osal_memcpy(buffer,pkt->cmd.Data,3);      if(buffer[0] == 'L' && buffer[1] == 'E' && buffer[2] == 'D')      {        HalLedBlink(HAL_LED_2,0,50,2000);      }      else      {        HalLedSet(HAL_LED_2,HAL_LED_MODE_ON);      }      break;  }}
      GenericApp_MessageMSGCB()函数对收到的消息进行处理为:判断收到的数据是否为“LED”。如果收到的是“LED”则将LED2进行闪烁,如果收到的数据不是“LED”则将LED2置为长亮。

/********************************************************************* * @fn      rxCB * * @brief    * * @param   port  - * @param   event - * * @return   */static void rxCB(uint8 port,uint8 event){  HalUARTRead(0,uartbuf,16);  if(osal_memcmp(uartbuf,"www.wlwmaker.com",16))  {    HalUARTWrite(0,uartbuf,16);    HalUARTWrite(0,"\n",1);  }    return ;}
      这段代码在本例程中其实没起到作用,rxCB()函数为串口的回调函数。用于串口收到数据后进行的处理工作。至此,协调器的程序到此结束。

3 终端节点代码

const SimpleDescriptionFormat_t GenericApp_SimpleDesc ={  GENERICAPP_ENDPOINT,              //  int Endpoint;  GENERICAPP_PROFID,                //  uint16 AppProfId[2];  GENERICAPP_DEVICEID,              //  uint16 AppDeviceId[2];  GENERICAPP_DEVICE_VERSION,        //  int   AppDevVer:4;  GENERICAPP_FLAGS,                 //  int   AppFlags:4;  0,          //  byte  AppNumInClusters;  (cId_t *)NULL,   //  byte *pAppInClusterList;  GENERICAPP_MAX_CLUSTERS,          //  byte  AppNumInClusters;  (cId_t *)GenericApp_ClusterList  //  byte *pAppInClusterList;};
      终端节点的这部分代码与协调器有区别,输入、输出命令簇的设定正好相反。

afAddrType_t GenericApp_DstAddr;unsigned char uartbuf[128];
      这两句代码在终端节点中去掉。关于串口的操作部分也去掉。

  halUARTCfg_t uartConfig;  uartConfig.configured = TRUE;  uartConfig.baudRate = HAL_UART_BR_115200;  uartConfig.flowControl = FALSE;  uartConfig.callBackFunc = rxCB;  HalUARTOpen(0,&uartConfig);


uint16 GenericApp_ProcessEvent( uint8 task_id, uint16 events ){  afIncomingMSGPacket_t *MSGpkt;  if ( events & SYS_EVENT_MSG )  {    MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );    while ( MSGpkt )    {      switch ( MSGpkt->hdr.event )      {        case ZDO_STATE_CHANGE:          GenericApp_NwkState = (devStates_t)(MSGpkt->hdr.status);          if (GenericApp_NwkState == DEV_END_DEVICE)          {            GenericApp_SendTheMessage();          }          break;        default:          break;      }      // Release the memory      osal_msg_deallocate( (uint8 *)MSGpkt );      // Next      MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );    }    // return unprocessed events    return (events ^ SYS_EVENT_MSG);  }  // Discard unknown events  return 0;}
      终端节点的事件处理函数与协调器不同,代码如上,在该代码中不涉及无线接收数据包,相反在其网络状态发生变化时发送数据包。调用的函数为GenericApp_SendTheMessage(),其代码为:

/********************************************************************* * @fn      GenericApp_SendTheMessage * * @brief   Send "the" message. * * @param   none * * @return  none */static void GenericApp_SendTheMessage( void ){  char theMessageData[4] = "LED";  afAddrType_t my_DstAddr;  my_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;  my_DstAddr.endPoint = GENERICAPP_ENDPOINT;  my_DstAddr.addr.shortAddr = 0x0000;  if ( AF_DataRequest( &my_DstAddr, &GenericApp_epDesc,                       GENERICAPP_CLUSTERID,                       (byte)osal_strlen( theMessageData ) + 1,                       (byte *)&theMessageData,                       &GenericApp_TransID,                       AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )  {    // Successfully requested to be sent.    HalLedBlink(HAL_LED_2,0,50,1000);  }  else  {    // Error occurred in request to send.  }}

By:霜月孤鸟

2016.1.2

0 0