飞比”Zigbee论坛CC2530开发板学习教程 下载本文

SERIALAPP_MAX_CLUSTERS, (cId_t *)SerialApp_ClusterList, SERIALAPP_MAX_CLUSTERS, (cId_t *)SerialApp_ClusterList, FALSE );

}

此处发起绑定请求,等待其他节点应答,而如果有一个节点也按了Joystick右键,同样发出了绑定请求,则本节点收到一个End_Device_Bind_rsp的信息,并在

SerialApp_ProcessZDOMsgs函数中进行了处理,如下代码:

/********************************************************************* * @fn SerialApp_ProcessZDOMsgs()

*

* @brief Process response messages

*

* @param none

*

* @return none

*/

static void SerialApp_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 );

}

break;

...

}

}

至此,中国小伙已经成功加美国MM为好友了~

接下来的事,大家想必都知道了。。。

看看他们是怎么发送信息,怎么接收信息的吧?

1. “串口终端1”的数据,如何被“节点1”所接收,并且发送出去的?

串口数据是由哪层来负责的呢?--HAL。。。恩,猜对了。但这个肯定不是靠猜的,其中的过程就不讲了。让我们从主循环(osal_start_system)的Hal_ProcessPoll函数找下去(用source insight的同学可以用ctrl +),Hal_ProcessPoll ==> HalUARTPoll ==>

HalUARTPollDMA

这个HalUARTPollDMA函数里最后有这样一句话:dmaCfg.uartCB(HAL_UART_DMA-1,

evt); 对dmaCfg.uartCB这个函数进行了调用,ctrl / 搜索这个dmaCfg.uartCB,发现SerialApp_Init函数有两句话:

uartConfig.callBackFunc = SerialApp_CallBack;

HalUARTOpen (SERIAL_APP_PORT, &uartConfig);

此处将dmaCfg.uartCB这个函数注册成为SerialApp_CallBack,也就是说

SerialApp_CallBack函数每次循环中被调用一次,对串口的内容进行查询,如果DMA中接收到了数据,则调用HalUARTRead,将DMA数据读至数据buffer并通过AF_DataRequest函数发送出去,注意:送出去的信息的CLUSTERID(信息簇ID)号为

SERIALAPP_CLUSTERID1。

总结一下这个过程:串口数据==>DMA接收==>主循环中通过SerialApp_CallBack查询==>从DMA获取并发送到空中。

2. 节点2在收到空中的信号后,如何传递给与其相连的串口终端?

节点2从空中捕获到信号后,在应用层上首先收到信息的就是SerialApp_ProcessEvent这个函数了,它收到一个AF_INCOMING_MSG_CMD的事件,并通知

SerialApp_ProcessMSGCmd,执行以下代码

switch ( pkt->clusterId )

{

// A message with a serial data block to be transmitted on the serial port.

case SERIALAPP_CLUSTERID1:

... ...

// 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;

}

... ...

这样就将从空中获取到的信息,传给了串口终端2--美国MM,第一句话终于传到美国了~至于后面的事情嘛,我们就不关注了,看小伙自己的造化了~~~

另外,此例程中还有一种模式,就是这个中国小伙可以按条件搜索(Joystick左键,profileID与clusterID相同者响应),但这种条件找出的MM都比较有个性--只接受你的信息,但不给你发。想想也是,明显没诚意嘛~ 这种模式的细节,本教程不再涉及,有兴趣的读者可自行了解。

声明一点,要真想泡美国MM,只用我们所谈的Zigbee是暂时搞不定的,它最大的传

输距离能有几公里就相当不易了,不过隔壁办公室的MM,倒是可以考虑送她一个~~~

[四]网络结构及协议解析

本例程的重点是串口的应用,其中涉及的组网及绑定等网络层细节,暂不详细阐述,将在后续的“奥特曼Zigbee读书日记”中进行深入分析。

[五]扩展思考

1. DMA方式与ISR方式的UART传输,有什么区别?分别如何实现?

2. ZDO_CB_MSG与AF_INCOMING_MSG_CMD等事件的产生机制?

3. 如何完成“多对一”或者“一对多”的通信?

4. 绑定表的存储位置与生命周期?

由于我们极力倡导“开源Zigbee”,有网友对我们的CC2530开发板项目有所误解,认为我们的开发板是用freakz而不用TI提供的ZStack。实则不然,ZStack是由Zigbee组织认证通过的“Golden unit”Zigbee平台,或者叫Zigbee中的“明星工程”。而且TI公司免费提供了一整套的开发平台及代码。我们没有理由拒绝这么优秀的平台,选择freakz作为补充,只是为了深入到协议层的学习,了解更多的“为什么”。

一个有效的学习过程,应该是由浅入深,由表面到本质。我们将ZStack的学习定位为了解“是什么”和“怎么样”的过程。从上一篇SerialApp的讲解开始,到本篇的GenericApp和后面的SampleApp, TransmitApp与SimpleApp我们都会以了解例程功能,操作与基本原理为主,深入的学习将在“奥特曼Zigbee读书日记”中进行铺开。

[注:本文源自“飞比”Zigbee论坛,为尊重劳动者成果,如需转载请保留此行,并通知作者]

其实这几个例程实现了不同的功能,方便了开发者在此基本功能上进行二次开发,以缩短项目周期,一定程序上减轻了Zigbee开发的复杂度。让我们一起来一一进行分析:

例4、ZStack的“Hello, world!”例程――GenericApp

注:本例程位于C:\Texas Instruments\ZStack-CC2530-2.3.0-1.4.0\Projects\zstack\ Samples\GenericApp\CC2530DB目录下,IAR工程文件为GenericApp.eww

[一]程序功能

本例程在启动后,自动组织建立一个Zigbee网络(我们以一个协调器和终端节点组成的简单网络进行讲解),网络中的设备间通过“绑定”与“按条件搜索”两种方式,建立连接。成功之后互相发送“Hello, world!”字符信息

[二]操作说明

打开上述的工程文件,分别选择“Coordinator”与“Enddevice”两种设备进行编译、下载至两个FB2530EB板中,详细过程前文已有描述,不再重复。按Reset键后,屏幕显示如下:

如果显示信息如上图所示,则表示网络初始化成功。

此时,按下Enddevice的摇杆(Joystick)右键进行绑定申请,然后立即按下Coordinator的Joystick右键进行绑定确认。此时,两个节点的红色LED灯--LED1,同时点亮,表示绑定成功,可以开始通信。

注:绑定也可以由Coordinator发起,由Enddevice响应。

在成功建立连接后,Enddevice与Coordinator均将每5秒钟向对方发送一次“Hello World”字符串。

与前文SerialApp例程相似,建立连接的方式除了“绑定”外,还有“条件搜索”的方式。按Enddevice的摇杆(Joystick)左键发送“条件搜索”请求――即按规定的ProfileID,支持的Cluster等信息进行匹配设备查找,收到此请求后,Coordinator

将会显示如下

此信息表明Coordinator已经接收到搜索请求,并且返回了响应信息。随后,Enddevice