第 0 节:zstack与MT层
zstack是TI的zigbee协议栈.基于IEEE 802.15.4基础上,一种低速,低功耗,短距离通信协议.和蓝牙4.0,wifi,THREAD,6LowPAN一起构成物联网的基础连接.
MT层是zstack的一个调试层,全称是monitior and test layer,只是TI为了方便开发调试,添加的一个调试接口.自然,既然是调试,就会涉及到跟协议栈的各个层通信与接口,因此,MT是一个熟悉zstack的好工具.zstack各层通过串口与MT层通信,通过上位机Z-TOOLS参与调试.
第 1 节:各个层的功能集
MT层有system,AF,NWK,ZDO,UTIL,APP,MAC等功能集.其中,MAC功能集是针对TI-MAC协议栈使用的,他是一个802.15.4点对点式的通信协议栈.其余的各个功能集需要在IAR预编译处设置,如MT_ZDO_FUNC,MT_NWK_FUNC,如图1-1就能在Z-TOOLS中显示 出对应的功能集.如图1-2所示.
图1-1 图1-2
第 2 节:system层的功能集
由第一节的说明可知,对于有多个功能集的MT层,这篇博文只从分析说明system层,掘出有用的金!
( 1 ).MT_SYS_RESET_REQ---系统重启请求
用这个命令系统重启,会有一个参数--TYPE,即是软重启还是硬重启.在硬重启中,使用了HAL_DISABLE_INTERRUPTS()关闭中断,然后调用HAL_SYSTEM_RESET()通过重启看门狗达到重启设备的效果,代码如下所示.
从这个操作中,我们了解到,
对于我们手动重启设备,可以使用HAL_SYSTEM_RESET()函数实现!
-
#define SystemReset() \
-
{
-
HAL_DISABLE_INTERRUPTS(); \
-
HAL_SYSTEM_RESET(); \
-
}
//系统重启,通过看门狗的重启实现
-
#define HAL_SYSTEM_RESET() st( HAL_DISABLE_INTERRUPTS(); WDCTL = WD_RESET1; WDCTL = WD_RESET2; for(;;); )
另一种是使用软重启,软重启在文档中说对于cc2531之类的设备比较有用,是直接跳转到重启的向量表中执行,不会断开跟usb host的连接,具体没使用过.
( 2 ).MT_SYS_PING---查看设备是否在线与支持的功能集
ping 在网络中常用来常看目的主机是否连通和网络状况等信息.在zstack MT功能集中,它除了查看是否在线,还有一个功能是查看他打开的功能集,如SYS,nwk,zdo等.在MT.h中设置了各个功能集的宏,如图1-3
图 1-3
在ping的返回值中就包含了打开的功能集的值.
( 3 ).MT_SYS_NV_item-intit/read/write/delete---nv操作功能集
这个函数功能集主要是设置读取nv,
使用osal层的函数,如osal_nv_read(),osal_nv_write(),osal_nv_item_init().其中多次调用一个中间函数,
zgSetItem(),这个函数用以从NV中的一个条目复制信息到一块内存中.
( 4 ).MT_SYS_OSAL_START/STOP_TIMER---设置/停止一个定时器
这个命令中,主要是使用了
osal_start_timerEx()来设置一个时间,在时间到后,执行某个动作.
( 5 ).MT_SYS_RANDOM---产生随机数
这个命令产生一个16位的随机数,他使用的是板子的随机数函数,
Onboard_rand(),这个函数在
Onboard.c文档中.
( 6 ).MT_SYS_STACK_TUNE---设置发射模块
在这个命令的实现中,可以看出这个函数有两种功能,第一,设置发射功率,第二,设置空闲时的收发器的状态.如下代码所示
-
case STK_TX_PWR://设置发射功率
-
rtrn = ZMacSetReq(ZMacPhyTransmitPowerSigned, pBuf);
-
break;
-
-
case STK_RX_ON_IDLE://调整空闲时的收发器状态
-
if ((*pBuf != TRUE) && (*pBuf != FALSE))
-
{
-
(void)ZMacGetReq(ZMacRxOnIdle, &rtrn);
-
}
-
else
-
{
-
rtrn = ZMacSetReq(ZMacRxOnIdle, pBuf);
-
}
在这个函数实现中,发现
ZMacSetReq()可以用来设置MAC层的PIB信息库,从而设置MAC层的一些属性.
ZMacGetReq()则可以用来获取MAC层的一些属性.
( 7 ).MT_SYS_SET_TIME---设置系统的时间
这个函数的实现还是很有用的,可以接入系统的时间,从而就可以做一些用户习惯等的数据分析了,这对于大数据而言,是很重要的.来让我们看看这个函数.
-
void MT_SysSetUtcTime(uint8 *pBuf)
-
{
-
uint8 cmdId;
-
uint8 retStat;
-
UTCTime utcSecs;
-
-
/* Parse header */
-
cmdId = pBuf[MT_RPC_POS_CMD1];
-
pBuf += MT_RPC_FRAME_HDR_SZ;
-
-
utcSecs = osal_build_uint32( pBuf, 4 );
-
if ( utcSecs == 0 )
-
{
-
UTCTimeStruct utc;
-
-
/* Skip past UTC time */
-
pBuf += 4;
-
-
/* Get time and date parameters */
-
utc.hour = *pBuf++;
-
utc.minutes = *pBuf++;
-
utc.seconds = *pBuf++;
-
utc.month = (*pBuf++) - 1;
-
utc.day = (*pBuf++) - 1;
-
utc.year = osal_build_uint16 ( pBuf );
-
-
if ((utc.hour < 24) && (utc.minutes < 60) && (utc.seconds < 60) &&
-
(utc.month < 12) && (utc.day < 31) && (utc.year > 1999) && (utc.year < 2136))
-
{
-
/* Got past the course filter, now check for leap year */
-
if ((utc.month != 1) || (utc.day < (IsLeapYear( utc.year ) ? 29 : 28)))
-
{
-
/* Numbers look reasonable, convert to UTC */
-
utcSecs = osal_ConvertUTCSecs( &utc );
-
}
-
}
-
}
-
-
if ( utcSecs == 0 )
-
{
-
/* Bad parameter(s) */
-
retStat = ZInvalidParameter;
-
}
-
else
-
{
-
/* Parameters accepted, set the time */
-
osal_setClock( utcSecs );
-
retStat = ZSuccess;
-
}
-
-
/* Build and send back the response */
-
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS),
-
cmdId, 1, &retStat);
-
}
这个我贴了个原生态的函数实现,首先了解到一个时间结构体
UTCTimeStruct ,通过对这个结构体成员的赋值就能传一个时间给系统了.然后看到有一个
IsLeapYear()的判断函数,这个函数的功能是判断是否是闰年,怎么样,该有的都有了吧!之后使用
osal_ConvertUTCSecs()函数将时间结构体转换成从2000年0时0分0秒以来的秒数,不为其他,只是下面
osal_setClock()设置时间函数需要这个秒数作为参数.
( 8 ).MT_SYS_SET_TX_POWER---设置发送功率
这个功能主要使用的是一个设置调整发射功率的函数
macRadioSetTxPower(),在第6个功能
ZMacSetReq()中设置发射功率时,其实底层也是调用了
macRadioSetTxPower().
阅读(7237) | 评论(1) | 转发(1) |