通信例程之GenericApp
来源:互联网 发布:淘宝卖医疗器械手续, 编辑:程序博客网 时间:2024/06/03 16:33
首先来看看 TI 究竟有哪些例子: 可以看出其例子是非常丰富的。
GenericApp(设备互相绑定传送信息-hellow world),Location(定位),SampleApp(设备发送和接收LED灯信息),SimpleApp(温度和灯开关,和智能家居结合使用的,have Pro
1、GenericApp
这个实验是两个模块相互绑定后可以对传数据,模块绑定之后,两个模块之间相互传输字符串”Hello World”。
实验说明:首先启动一个网络协调器,协调器如果建立网络成功后,会在 LCD 上显示该节点为协调者同时显示网络 ID号。然后打开一个终端节点或路由器的电源,此时节点会自动加入网络。加入网络成功后,节点会显示自己的节点类型、网络地址和父节点的网络地址。
节点加入网络成功后,首先把主机模块的摇杆往右拔一下,然后把要绑定模块的 RIGHT按一下,如果两边的 LED4 都熄灭或是点亮后马上熄灭,表示绑定成功。绑定成功后,两个节点就开始相互定时发送数据,并在对方的LCD屏上显示出来,发送的数据为”Hello World”。此时如果把相互绑定模块中的 left 按一下,可以发送 Match Description Request命令,对方则显示 Match Description Request信息。(以上无线龙手册提供)
2 关键函数分析:
我开始没搞清楚,功能是个啥 大约浏览了下,这个例子似乎还与设备的 所以还决定看看程序来判断这个例子的功能。 绑定有关系,在key control 描述中发现
//***************** Key control**************************//
SW2: initiates end device binding //–初始化中断设备绑定
SW4: initiates a match description request //–初始化一个匹配描述请求
2.1 按建处理程序中发现:
if ( keys & HAL_KEY_SW_2 )
{
HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
// Initiate an End Device Bind Request for the mandatory endpoi
nt
dstAddr.addrMode = Addr16Bit;
dstAddr.addr.shortAddr = 0x0000; // Coordinator
ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(),
GenericApp_epDesc.endPoint,
GENERICAPP_PROFID,
GENERICAPP_MAX_CLUSTERS, (cId_t *)Generic
App_ClusterList,
GENERICAPP_MAX_CLUSTERS, (cId_t *)Generic
App_ClusterList,
FALSE );
}
很明显这里按键 2(右键)是发送绑定请求的命令。
if ( keys & HAL_KEY_SW_4 )
{
HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
// Initiate a Match Deion Request (Service Discovery)
dstAddr.addrMode = AddrBroadcast;
dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR,
GENERICAPP_PROFID,
GENERICAPP_MAX_CLUSTERS, (cId_t *)GenericApp_
ClusterList,
GENERICAPP_MAX_CLUSTERS, (cId_t *)GenericApp_
ClusterList,
FALSE );
}
显然按键 4(左)是初始化一个匹配描述符请求,也就是发现服务,或者叫自动寻求匹配设备。
2.2 在发送数据发现:
void GenericApp_SendTheMessage( void )
{
char theMessageData[] = “Hello World”;
if ( AF_DataRequest( &GenericApp_DstAddr, &GenericApp_epDesc,
GENERICAPP_CLUSTERID,
(byte)osal_strlen( theMessageData ) + 1,
(byte *)&theMessageData,
&GenericApp_TransID,
AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatu
s_SUCCESS )
{
// Successfully requested to be sent.
}
else
{
// Error occurred in request to send.
}
}
这里发送了”Hello World”字符串。如果更改这里,是可以在接收端看到变化的。 这里调用了 AF_DataRequest 函数,该函数为 AF层请求发送数据函数。
afStatus_t AF_DataRequest( afAddrType_t *dstAddr, endPointDesc_t *srcEP,
uint16 cID, uint16 len, uint8 *buf, uint8 *transID,
uint8 options, uint8 radius )
我想最关心的就是几个参数:
1、目标地址:&GenericApp_DstAddr
typedef struct
{
union
{
uint16 shortAddr;
} addr;
afAddrMode_t addrMode;
byte endPoint;
} afAddrType_t;//–里面定义了目标地址模式、地址、EP三个参数
2、端点描述符:&GenericApp_epDesc
typedef struct
{
byte endPoint;
byte *task_id; // Pointer to location of the Application task ID.
SimpleDescriptionFormat_t *simpleDesc;
afNetworkLatencyReq_t latencyReq;
} endPointDesc_t;
3、串 ID
4、发送数据
数据长度:(byte)osal_strlen( theMessageData ) + 1,
数据载荷: (byte *)&theMessageData,
5、发送 ID:&GenericApp_TransID
6、选项:AF_DISCV_ROUTE
7、发送半径:AF_DEFAULT_RADIUS
#define AF_DEFAULT_RADIUS DEF_NWK_RADIUS
网络路由深度,初始化为: #define DEF_NWK_RADIUS 10
2.3 接收处理函数发现 :
void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ) ///接收处理函数
{
switch ( pkt->clusterId )
{
case GENERICAPP_CLUSTERID:
// “the” message
// HalLcdWriteScreen( (char*)pkt->cmd.Da
Print8(HAL_LCD_LINE_2,10,” “, 1);
Print8(HAL_LCD_LINE_3,10,” “, 1);
Print8(HAL_LCD_LINE_2,10,(INT8U*)pkt->cmd.Da
Print8(HAL_LCD_LINE_3,16, “WXL Welcome”, 1);
break;
#endif
}
}
接收数据处理函数里居然要通过液晶显示,本人这里的液晶暂时没有移植过来,因为暂时还不具备那个实力,怪不得看不到发送数据的状况!这里本人就自作聪明的把以前 SampleApp 例子里面的一句话加过来了:
void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ) //–修改的哦
{
switch ( pkt->clusterId )
{
case GENERICAPP_CLUSTERID:
// “the” message
HalLedBlink( HAL_LED_4, 4, 50, (500) );
HalLcdWriteScreen( (char*)pkt->cmd.Da
#elif defined( WIN32 )
WPRINTSTR( pkt->cmd.Da
#endif
break;
}
}
麽想到啊,这么一加居然就有反应了!其实这里很简单的了,就是接收到数据后闪烁 4 下灯,间隔 0.5S。因为从:GenericApp_ProcessEvent中有周期性发送函数
2.4 周期性发送函数
if ( events & GENERICAPP_SEND_MSG_EVT )
{
// Send “the” message
GenericApp_SendTheMessage(); //–发送信息
// Setup to send message again
osal_start_timerEx( GenericApp_TaskID,
GENERICAPP_SEND_MSG_EVT,
GENERICAPP_SEND_MSG_TIMEOUT );
// return unprocessed events
return (events ^ GENERICAPP_SEND_MSG_EVT);
}
这里可以看出,这个例子很明显仅仅是个发送周期信息的例子。所以 LED4 就周期性的闪烁 4 下,当然是协调器发送,路由器闪烁,路由器发送,协调器闪烁。 该事件是一个用户事件,不在系统事件内。可以看到调用了发送函数 GenericApp_SendTheMessage();,之后又调用了osal_start_timerEx函数触发定时发送数据,所以是一个周期发送。 发送了,不一定对方一定能收到,这里只有匹配描述符的才能接收这个信息。
2.5 再来看看ZDO 响应函数:
void GenericApp_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg )
{
switch ( inMsg->clusterID )
{
case End_Device_Bind_rsp: //–绑定
if ( ZDO_ParseBindRsp( inMsg ) == ZSuccess )
{
// Light LED
HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );
}
else
{
// Flash LED to show failure
HalLedSet ( HAL_LED_4, HAL_LED_MODE_FLASH );
}
#endif
break;
case Match_Desc_rsp: //–描述符匹配
{
ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( inMsg );
if ( pRsp )
{
if ( pRsp->status == ZSuccess && pRsp->cnt )
{
GenericApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
GenericApp_DstAddr.addr.shortAddr = pRsp->nwkAddr;
// Take the first endpoint, Can be changed to search through endpoints
GenericApp_DstAddr.endPoint = pRsp->epList[0];
// Light LED
HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );
}
osal_mem_free( pRsp );
}
}
break;
}
}
这里两类事件,主要是针对两种按键操作的响应处理:绑定响应和描述符匹配响应。 可以看到,当绑定成功 G灯点亮,失败 G灯闪烁。 描述符匹配成功 G灯点亮。此时液晶上也会有显示。
3. 事件处理函数:
UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events )
{
afIncomingMSGPacket_t *MSGpkt;
afDataConfirm_t *afDataConfirm;
// Da
byte sentEP;
ZStatus_t sentStatus;
byte sentTransID; // This should match the value sent
if ( events & SYS_EVENT_MSG )
{
MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );
while ( MSGpkt )
{
switch ( MSGpkt->hdr.event )
{
case ZDO_CB_MSG:
GenericApp_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
break;
case KEY_CHANGE:
GenericApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
break;
case AF_DA
// This message is received as a confirmation of a da
// The status is of ZStatus_t type [defined in ZComDef.h]
// The message fields are defined in AF.h
afDataConfirm = (afDataConfirm_t *)MSGpkt;
sentEP = afDataConfirm->endpoint;
sentStatus = afDataConfirm->hdr.status;
sentTransID = afDataConfirm->transID;
(void)sentEP;
(void)sentTransID;
// Act
if ( sentStatus != ZSuccess )
{
// The da
}
break;
case AF_INCOMING_MSG_CMD:
GenericApp_MessageMSGCB( MSGpkt );
break;
case ZDO_STATE_CHANGE:
GenericApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
if ( (GenericApp_NwkState == DEV_ZB_COORD)
|| (GenericApp_NwkState == DEV_ROUTER)
|| (GenericApp_NwkState == DEV_END_DEVICE) )
{
// Start sending “the” message in a regular interval.
osal_start_timerEx( GenericApp_TaskID,
GENERICAPP_SEND_MSG_EVT,
GENERICAPP_SEND_MSG_TIMEOUT );
}
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);
}
// Send a message out - This event is generated by a timer
// (setup in GenericApp_Init()).
if ( events & GENERICAPP_SEND_MSG_EVT )
{
// Send “the” message
GenericApp_SendTheMessage();
// Setup to send message again
osal_start_timerEx( GenericApp_TaskID,
GENERICAPP_SEND_MSG_EVT,
GENERICAPP_SEND_MSG_TIMEOUT );
// return unprocessed events
return (events ^ GENERICAPP_SEND_MSG_EVT);
}
// Discard unknown events
return 0;
}
3.1 网络状态改变
case ZDO_STATE_CHANGE:
GenericApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
if ( (GenericApp_NwkState == DEV_ZB_COORD)
|| (GenericApp_NwkState == DEV_ROUTER)
|| (GenericApp_NwkState == DEV_END_DEVICE) )
{
// Start sending “the” message in a regular interval.
osal_start_timerEx( GenericApp_TaskID,
GENERICAPP_SEND_MSG_EVT,
GENERICAPP_SEND_MSG_TIMEOUT );
}
break;
一旦网络设备类型确定,就表示加入网络成功。那么就调用了 osal_start_timerEx 函数定期(GENERICAPP_SEND_MSG_TIMEOUT)触发发送事件,这里也是周期发送(GENERICAPP_SEND_MSG_EVT)
3.2 ZDO 响应事件
case ZDO_CB_MSG:
GenericApp_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
break;
这里主要是对键盘事件操作后的一个 ZDO层的响应。
3.3 接收信息处理
case AF_INCOMING_MSG_CMD:
GenericApp_MessageMSGCB( MSGpkt );
break;
调用了 GenericApp_MessageMSGCB函数。
总的来说:例子很明显仅仅是个发送周期信息的例子。所以 LED4 就周期性的闪烁 4 下,当然是协调器发送,路由器闪烁,路由器发送,协调器闪烁(这个是在我改过后的情况)。 这例子里体现了绑定的概念,应该说是从基本功能上很齐全的一个例子,而且在 ZSTACK 上实现无线网络数传,没有任何多余的功能。所以该例子是一个典型的 ZSTACK 模板,也就是为用户提供了一个通用模板可以通过这个建立自己的应用。关于如何在这个例子上建立、修改成自己的工程和应用项目详细见文档: Create New Application For The CC2430DB_F8W-2005-0033_.pdf
我们来看看没有修改的函数演示现象
- 通信例程之GenericApp
- zigbee学习笔记---通信例程之GenericApp
- zigbee学习笔记3-通信例程之GenericApp
- Zstack之例程GenericApp分析笔记1
- Zstack之例程GenericApp分析笔记2
- TI协议栈例程GenericApp SampleApp SimpleAp 区别
- TI协议栈例程GenericApp SampleApp SimpleAp 区别
- Linux基础之tcp socket 简单通信例程
- MTK网络通信例程
- MTK网络通信例程
- 例程 关于串口通信
- c++ socket通信例程
- C#_SOCKET通信例程
- VC实现串口通信例程
- VC实现串口通信例程
- VC实现串口通信例程
- VC实现串口通信例程
- atmega8 例程:USART串口通信
- linux中的信号2——进程如何处理信号?
- PHP微信公众号开发常用功能
- 内存崩溃delete和deleteLater
- python核心编程(一)
- oracel环境变量配置
- 通信例程之GenericApp
- java-封装
- [Easy]C++ 第二期 7道
- 联合权值 【图论】【数学优化】Codevs3728
- Cudnn v5.1与V 6.0的特性
- 深入分析Java ClassLoader原理
- 怎么创建一个ramdisk块设备
- android 实时采播录音播放或发送出去
- C语言内存分布图