stack协议栈SampleApp小解(1)
这篇文章觉得有用,特地转载
看了好几遍TI的zstack协议栈的SampleApp示例,终于看到点端倪了。
示例程序路径:X:\Texas Instruments\ZStack-CC2530-2.2.2-1.3.0\Projects\zstack\Samples\SampleApp\CC2530DB\SampleApp.eww
做的是第一个最简单的DemoEB的Workspace。
先说下这个实验的功能:
UP键:向组内其他节点发送闪烁命令。
Right键:添加(移除)闪烁组,这个控制是否接受闪烁命令。
下面分析下流程:
首先,ZStack的OSAL工作机制,暂不先分析,假设已经了解该原理。
第一:闪烁组的确定
这个还没有看,先不说,看了在加上。
第二:发送闪烁命令
按下Up键之后,在SampleApp_ProcessEvent这个事件处理系统中,会识别到一个KEY_CHANGE事件,进入事件处理函数SampleApp_HandleKeys。
代码如下:
if ( keys & HAL_KEY_SW_1 )
{
SampleApp_SendFlashMessage( SAMPLEAPP_FLASH_DURATION );
}
if ( keys & HAL_KEY_SW_2 )
{
aps_Group_t *grp;
grp = aps_FindGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP );
if ( grp )
{
aps_RemoveGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP );
}
else
{
aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group );
}
}
在SampleApp_HandleKeys函数,有两个传入参数,主要使用第二个keys,指出了按下的是哪个按键。不同的按键有不同的反应,对应有不同的处理程序。发送闪烁命令时,按下的是Up键,键值对应的为HAL_KEY_SW_1,因此进入发送闪烁的处理函数SampleApp_SendFlashMessage( SAMPLEAPP_FLASH_DURATION );中来。此处的SAMPLEAPP_FLASH_DURATION参数是宏定义的一个闪烁持续时间。
void SampleApp_SendFlashMessage( uint16 flashTime )
{
uint8 buffer[3];
buffer[0] = (uint8)(SampleAppFlashCounter++);
buffer[1] = LO_UINT16( flashTime );
buffer[2] = HI_UINT16( flashTime );
if ( AF_DataRequest( &SampleApp_Flash_DstAddr,
&SampleApp_epDesc,
SAMPLEAPP_FLASH_CLUSTERID,
3,
buffer,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}
在上述函数中,首先将闪烁时间flashtime转换成16位数,分别是左移八位与0xFF相与,求出高八位,然后与0xFF相与,求出低八位。
在AF_DataRequest中,指出了数据发送的几个参数,主要的有前五个,分别是:目的地址,源节点,闪烁组簇,数据长度,数据缓冲区。
第三:接收端,接收无线信号
接收端触发AF_INCOMING_MSG_CMD时间,进入SampleApp_MessageMSGCB( MSGpkt );事件处理函数中。
函数代码如下:
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
uint16 flashTime;
switch ( pkt->clusterId )
{
case SAMPLEAPP_PERIODIC_CLUSTERID:
break;
case SAMPLEAPP_FLASH_CLUSTERID:
flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
break;
}
}
上述函数,查询收到包的clusterid属性,闪烁的就是HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
第四:脱离于加入闪烁组
具体操作,就是按下按键Right,从而选择是否屏蔽Up键的闪烁命令。
同样,类似于第二部分,此处进入的还是KEY_CHANGE事件,SampleApp_HandleKeys函数,不同的是,此次的传输参数为Keys的值为HAL_KEY_SW_2,进入另一个处理中。
if ( keys & HAL_KEY_SW_2 )
{
aps_Group_t *grp;
grp = aps_FindGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP );
if ( grp )
{
aps_RemoveGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP );
}
else
{
aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group );
}
上述代码,首先查询,当前节点是否在闪烁组中,如果在,就将其移除,如果不在,就将其加入。这两个函数的具体实现,没有找到代码。
此网络中,只有终端节点,并不能运行起来,必须有协调器节点,来创建闪烁组。终端节点,可以中途加入闪烁组,之后,协调器节点在退出之后,原有网络还可以继续运行。
但是,协调器节点一旦退出网络,在重新启动,就无法进入网络,即无法接受闪烁命令。但是终端节点可以中途退出网络,然后再加入,都可以继续工作。这是为什么呢?
还有一个不明白的是,网络是在什么时候,创建的?尚未找到代码。