一些参考 :
http://wjf88223.blog.163.com/blog/static/351680012011731105424480/
http://blog.csdn.net/tanqiuwei/article/details/7640913
这片文章总结一下学习ZStack自带例子的过程。这些例子位于ZStack的安装目录中,如:
D:\Texas Instruments\ZStack-CC2530-2.5.1a\Projects\zstack\Samples
此外,安装路径下有自带的帮助文档,位于:
D:\Texas Instruments\ZStack-CC2530-2.5.1a\Documents
这些文档对于学习ZStack很有帮助。
在这里总结一些预备知识。来源是自带文档《Z-Stack Developer’s Guide》
f8wconfig.cfg
共享的配置文件,可以配置channel,PAN ID(即网络ID)f8wCoord.cfg
协调器的配置文件f8wEnddev.cfg
终端设备的配置文件f8wRouter.cfg
路由器的配置文件地址分配策略:
MAX_DEPTH
定义了网络的深度depth,协调器的depth是0, 它的子节点的depth是1,以此类推。MAX_CHILDREN
定义了一个router节点的子节点个数的最大值。MAX_ROUTERS
定义了一个coordinator或router所拥有的router的最大个数,MAX_CHILDREN – MAX_ROUTERS
则表示拥有的终端节点的个数。Z-Stack中的地址:
发送数据使用函数AF_DataRequest()
, 参考《Z-Stack API》,函数原型为:
afStatus_t AF_DataRequest(
afAddrType_t *dstAddr, // 目的地址
endPointDesc_t *srcEP, // 源地址
uint16 cID, // Cluster ID ,the message’s cluster ID is likea message ID and is unique with in
the profile.
uint16 len, // 要发送的数据的长度
uint8 *buf, // 指向发送数据的地址
uint8 *transID, //transaction sequence number pointer. This number will be incremented by
this function if the message is buffered to be sent.
uint8 options,
uint8 radius // 跳数 : Maximum number of hops
);
其中afAddrType_t
用来表示一个设备的网络地址。
typedef enum
{
afAddrNotPresent = AddrNotPresent, // ? indiret , binding table...
afAddr16Bit = Addr16Bit, // 用于单播
afAddr64Bit = Addr64Bit,
afAddrGroup = AddrGroup, // 用于多播
afAddrBroadcast = AddrBroadcast // 用于广播
} afAddrMode_t;
typedef struct
{
union
{
uint16 shortAddr; // 上面提到的16bit的网络地址
ZLongAddr_t extAddr;
} addr;
afAddrMode_t addrMode; // 用单播、广播或多播
uint8 endPoint;
uint16 panId; // used for the INTER_PAN feature
} afAddrType_t;
其中addrMode
用来做什么呢? ZigBee中的网络包可以单播、多播、广播,addrMode用于不同的模式。
一些与地址相关的API
Todo:
Bind…
Routing…
binding table, routing table, neighbor table…
实验的主要过程:一个协调器,一个终端节点。
按键:
有两种方法让两个设备进行沟通:
建立联系后,终端节点并会不断的发送信息Hello World
给协调器,协调器收到后会将信息显示到LCD上。
device binding:
设备向coordinator发送binding请求(通过函数ZDApp_SendEndDeviceBindReq()
),然后coordinator会维护一个binding table,这个表用来记录有联系的设备。
device discovery:
call ZDP_MatchDescReq
This call will build and send an Match Descripton Request. Use this function to search for devices/applications that
match something in the input/output cluster list ofan application.
终端节点加入网络后,会周期性的发送信息给协调器,这是通过定时器timer实现的。
当有相应时间发生时会调用GenericApp_ProcessEvent
,该函数判断时间类型中如果指定了GENERICAPP_SEND_MSG_EVT
时,就调用GenericApp_SendTheMessage
发送信息给协调器。然后使用定时器周期性地发送该消息。
uint16 GenericApp_ProcessEvent( uint8 task_id, uint16 events )
{
...
// 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);
}
...
}
/* 终端节点和中控通信加密 */
-DSECURE=1
/* 默认加密密钥,保证各设备一致 */
-DDEFAULT_KEY="{0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0D}"
/* 告诉中控,我会休眠,中控知道后会将消息放入队列 */
-DRFD_RCVC_ALWAYS_ON=FALSE
/* 想中控查询数据的时间间隔,单位毫秒 */
-DPOLL_RATE=3000
/* Define the default PAN ID.
*
* Setting this to a value other than 0xFFFF causes
* ZDO_COORD to use this value as its PAN ID and
* Routers and end devices to join PAN with this ID
*/
-DZDAPP_CONFIG_PAN_ID=0x1C9E // PAN ID, 即网络ID。终端设备会加入PAN ID为0x1c9e的网络
对于终端节点来说,GenericApp_ProcessEvent
为主要代码。此外,终端节点通常需要注重休眠的细节,需要着重设计(省电)。
对于协调器(或叫中控)来说,功能通常比较复杂。不过代码框架是不变的,代码框架见OSAL的分析。只不过是添加一些任务。