第四部分 提高篇-第9章 CC2530基于GenericApp无线收发实验

实验设备
硬件:PC 机一台;ZB2530(底板、核心板、仿真器、USB 线) 一套
软件:win7 系统,IAR 8.20 集成开发环境

本实验是基于GenericApp无线收发,编者在第2讲也有讲过,当时也是用的TI提供的源码改编的,比较完善,而现在编者将带领大家编写较为简单的协议栈,实现个性化订制,下图为该实验的模型。

这里写图片描述

图9-1无线收发LED模型

打开工程:
基于GenericApp无线收发实验\Projects\zstack\Samples\GenericApp\CC2530DB。
 OSAL_Example.c

#include "ZComDef.h"
#include "hal_drivers.h"  //硬件驱动头文件
#include "OSAL.h"         //操作系统头文件
#include "OSAL_Tasks.h"   //操作系统任务头文件

#if defined ( MT_TASK )   //串口应用头文件
  #include "MT.h"
  #include "MT_TASK.h"
#endif

#include "nwk.h"          //网络层头文件
#include "APS.h"          //应用支持层头文件
#include "ZDApp.h"        //设备对象头文件

#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
  #include "ZDNwkMgr.h"
#endif

#if defined ( ZIGBEE_FRAGMENTATION )
  #include "aps_frag.h"
#endif
#include "Common.h"

// 任务注册
const pTaskEventHandlerFn tasksArr[] = {
  macEventLoop,           //MAC任务循环
  nwk_event_loop,         //网络层任务函数
  Hal_ProcessEvent,       //硬件层函数
#if defined( MT_TASK )
  MT_ProcessEvent,        //串口支持层定义
#endif
  APS_event_loop,         //应用支持层任务事件函数
#if defined ( ZIGBEE_FRAGMENTATION )
  APSF_ProcessEvent,
#endif
  ZDApp_event_loop,       //设备对象层函数
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
  ZDNwkMgr_event_loop,
#endif
  GenericApp_ProcessEvent //自己定义的任务处理函数
};

const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] );
uint16 *tasksEvents;

void osalInitTasks( void )//完成了任务ID的分配,以及所有任务的初始化
{
  uint8 taskID = 0;
  //分配内存空间
  tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
  osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));

  macTaskInit( taskID++ );//MAC层的任务ID号
  nwk_init( taskID++ );   //网络ID分配
  Hal_Init( taskID++ );   //硬件ID分配
#if defined( MT_TASK )
  MT_TaskInit( taskID++ );
#endif
  APS_Init( taskID++ );
#if defined ( ZIGBEE_FRAGMENTATION )
  APSF_Init( taskID++ );
#endif
  ZDApp_Init( taskID++ );
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
  ZDNwkMgr_Init( taskID++ );
#endif
  GenericApp_Init( taskID );//自己任务初始化函数
}

第 1-22 行包含一些相关函数的头文件,相对固定不用过多研究
第 24-41 行 tasksArr 数组里面存放所有任务的任务处理函数,如果操作系查询到了该任务的 ID那么就会调用对应的任务处理函数,该数组的顺序必须和 osalInitTasks 函数的初始化顺序相同。
第 43 行 tasksCnt 保存了任务的个数
第 44 行 tasksEvent 这是一个指针,指向了事件标的首地址
第 45-68 行完成了任务 ID 的分配,以及所有任务的初始化。GenericApp_Init( taskID );是自己任务初始化函数。我们程序初始化部分都可写在此函数中,具体详解在协调器程序中给出。

 协调器源码分析

#include "OSAL.h"
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"

#include "Common.h"
#include "DebugTrace.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"
#include "OSAL_Nv.h"

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;
    GENERICAPP_MAX_CLUSTERS,          //  byte  AppNumInClusters;
    (cId_t *)GenericApp_ClusterList   //  byte *pAppInClusterList;
};

endPointDesc_t GenericApp_epDesc;
byte GenericApp_TaskID;
byte GenericApp_TransID;

void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );
void GenericApp_SendTheMessage(void);

void GenericApp_Init( byte task_id )
{
    GenericApp_TaskID = task_id;//osal分配的任务ID随着用户添加任务的增多而改变
    GenericApp_TransID = 0;//消息发送ID(多消息时有顺序之分)

    //定义本设备用来通信的APS层端点描述符
    GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT;//应用程序的端口号
    GenericApp_epDesc.task_id = &GenericApp_TaskID;  //描述符的任务ID
    GenericApp_epDesc.simpleDesc                     //简单描述符
        = (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;
    GenericApp_epDesc.latencyReq = noLatencyReqs;    //延时策略
    afRegister( &GenericApp_epDesc );                //向AF层登记描述符
}

UINT16 GenericApp_ProcessEvent( byte 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;
            }
            osal_msg_deallocate( (uint8 *)MSGpkt );
            MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );
        }
        return (events ^ SYS_EVENT_MSG);
    }
    return 0;
}

void GenericApp_MessageMSGCB(afIncomingMSGPacket_t *pkt)
{
    unsigned char buf[3]; 

    switch ( pkt->clusterId )
    {
    case GENERICAPP_CLUSTERID:
        osal_memset(buf, 0 , 3);
        osal_memcpy(buf, pkt->cmd.Data, 2);

        if(buf[0]=='D' && buf[1]=='1')       
        {
            HalLedBlink(HAL_LED_1, 0, 50, 500);  
            GenericApp_SendTheMessage();
        }
        else
        {
            HalLedSet(HAL_LED_1, HAL_LED_MODE_ON);                   
        }
        break;
    }
}

void GenericApp_SendTheMessage(void)
{
    byte SendData[3]="D1";

    afAddrType_t devDstAddr;
    devDstAddr.addrMode=(afAddrMode_t)Addr16Bit;
    devDstAddr.endPoint=GENERICAPP_ENDPOINT;
    devDstAddr.addr.shortAddr=0xFFFF; 

    AF_DataRequest(&devDstAddr,
        &GenericApp_epDesc,
        GENERICAPP_CLUSTERID,
        2,
        SendData,
        &GenericApp_TransID,
        AF_DISCV_ROUTE,
        AF_DEFAULT_RADIUS);
}

第 1-19 行包含一些相关函数的头文件
第 21-24 行GENERICAPP_CLUSTERID 为簇 ID 列表,消息发送和接收需要用的,如果定义多个簇 ID 就在这里增加,以前的实验我们已增加过了,这里只提一下。
第 26-37 行简单描述符的定义,定义终端号、终端支持的设备 ID、设备描述的版本、终端支持的输入簇数目等信息,格式相对固定。
第 39 行 endPointDesc_t GenericApp_epDesc; //简单描述符。
第 40 行 byte GenericApp_TaskID; //osal 分配的任务 ID 随着用户添加任务的增多而改变。
第 41 行 byte GenericApp_TransID; //消息发送 ID(多消息时有顺序之分)
第 46-58 行 GenericApp_Init 函数,程序初始化部分都可写在此函数
第 60-83 行事件处理函数。
第 85-106 行接收数据。
第 108-125 行发送数据。
以上代码是在 TI GenericApp 例程复制过来的,我们对 GenericApp.c 中的代码进行了裁剪,帮助大家更容易掌握 GenericApp,同时我们把协调器和终端的代码独立开,让初学者不易混淆。 明白了其中的原理后,再去看其它程序那就是小菜一碟了。至于终端只有三个地方不同,我们讲不同处即可,大部分一样。相信学到现在的水平,应该完全可以看懂了
 终端源码分析

 #include "OSAL.h"
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"

#include "Common.h"
#include "DebugTrace.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"

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;
  GENERICAPP_MAX_CLUSTERS,          //  byte  AppNumInClusters;
  (cId_t *)GenericApp_ClusterList   //  byte *pAppInClusterList;
};

endPointDesc_t GenericApp_epDesc;
byte GenericApp_TaskID;
byte GenericApp_TransID;
devStates_t GenericApp_NwkState;

void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );
void GenericApp_SendTheMessage( void );

void GenericApp_Init( byte task_id )
{   
    GenericApp_TaskID = task_id;
    GenericApp_NwkState=DEV_INIT;
    GenericApp_TransID = 0;

    GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT;
    GenericApp_epDesc.task_id = &GenericApp_TaskID;
    GenericApp_epDesc.simpleDesc
        = (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;

    GenericApp_epDesc.latencyReq = noLatencyReqs;
    afRegister( &GenericApp_epDesc ); 
}

UINT16 GenericApp_ProcessEvent( byte 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;
            case ZDO_STATE_CHANGE:
                GenericApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
                if(GenericApp_NwkState == DEV_END_DEVICE)
                {
                    GenericApp_SendTheMessage();
                }
                break;
            default:
                break;
            }
            osal_msg_deallocate( (uint8 *)MSGpkt );
            MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );
        }

        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
    }
    return 0;
}
void GenericApp_MessageMSGCB(afIncomingMSGPacket_t *pkt)
{
    unsigned char buf[3]; 

    switch ( pkt->clusterId )
    {
    case GENERICAPP_CLUSTERID:
        osal_memset(buf, 0 , 3);
        osal_memcpy(buf, pkt->cmd.Data, 2);
        if(buf[0]=='D' && buf[1]=='1')       
        {
            HalLedBlink(HAL_LED_1, 0, 50, 500);                                   
        }
        else
        {
            HalLedSet(HAL_LED_1,HAL_LED_MODE_ON);                   
        }
        break;
    }
}

void GenericApp_SendTheMessage(void)
{
    byte SendData[3]="D1";

    afAddrType_t devDstAddr;
    devDstAddr.addrMode=(afAddrMode_t)Addr16Bit;
    devDstAddr.endPoint=GENERICAPP_ENDPOINT;
    devDstAddr.addr.shortAddr=0x0000; 

    AF_DataRequest(&devDstAddr,
        &GenericApp_epDesc,
        GENERICAPP_CLUSTERID,
        2,
        SendData,
        &GenericApp_TransID,
        AF_DISCV_ROUTE,
        AF_DEFAULT_RADIUS);
}

 实验现象
1)选择 CoodinatorEB-Pro, 下载到开发板 A;作为协调器;
2)选择 EndDeviceEB-Pro, 下载到开发板 B;作为终端设备
3)给两块开发板上电,协调器组网,终端联网成功后发“D1”, 协调器收到数据“D1”后Led1 闪烁;同时也发“D1”给终端,终端收到后 Led1 也闪烁。

本章参考代码

点击进入

猜你喜欢

转载自blog.csdn.net/u013162035/article/details/80984368