Chinaunix首页 | 论坛 | 博客
  • 博客访问: 76475
  • 博文数量: 12
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 82
  • 用 户 组: 普通用户
  • 注册时间: 2013-04-29 15:07
文章分类

全部博文(12)

文章存档

2016年(5)

2015年(7)

我的朋友

分类: 嵌入式

2015-04-28 12:53:28

第 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()函数实现!

点击(此处)折叠或打开

  1. #define SystemReset() \
  2. {
  3.   HAL_DISABLE_INTERRUPTS(); \
  4.   HAL_SYSTEM_RESET(); \
  5. }

       //系统重启,通过看门狗的重启实现

  1. #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---设置发射模块
                       在这个命令的实现中,可以看出这个函数有两种功能,第一,设置发射功率,第二,设置空闲时的收发器的状态.如下代码所示            

点击(此处)折叠或打开

  1. case STK_TX_PWR://设置发射功率
  2.     rtrn = ZMacSetReq(ZMacPhyTransmitPowerSigned, pBuf);
  3.     break;

  4. case STK_RX_ON_IDLE://调整空闲时的收发器状态
  5.     if ((*pBuf != TRUE) && (*pBuf != FALSE))
  6.     {
  7.       (void)ZMacGetReq(ZMacRxOnIdle, &rtrn);
  8.     }
  9.     else
  10.     {
  11.       rtrn = ZMacSetReq(ZMacRxOnIdle, pBuf);
  12.     }
                    在这个函数实现中,发现ZMacSetReq()可以用来设置MAC层的PIB信息库,从而设置MAC层的一些属性.ZMacGetReq()则可以用来获取MAC层的一些属性.
                ( 7 ).MT_SYS_SET_TIME---设置系统的时间
                       这个函数的实现还是很有用的,可以接入系统的时间,从而就可以做一些用户习惯等的数据分析了,这对于大数据而言,是很重要的.来让我们看看这个函数.            

点击(此处)折叠或打开

  1. void MT_SysSetUtcTime(uint8 *pBuf)
  2. {
  3.   uint8 cmdId;
  4.   uint8 retStat;
  5.   UTCTime utcSecs;

  6.   /* Parse header */
  7.   cmdId = pBuf[MT_RPC_POS_CMD1];
  8.   pBuf += MT_RPC_FRAME_HDR_SZ;

  9.   utcSecs = osal_build_uint32( pBuf, 4 );
  10.   if ( utcSecs == 0 )
  11.   {
  12.     UTCTimeStruct utc;

  13.     /* Skip past UTC time */
  14.     pBuf += 4;

  15.     /* Get time and date parameters */
  16.     utc.hour = *pBuf++;
  17.     utc.minutes = *pBuf++;
  18.     utc.seconds = *pBuf++;
  19.     utc.month = (*pBuf++) - 1;
  20.     utc.day = (*pBuf++) - 1;
  21.     utc.year = osal_build_uint16 ( pBuf );

  22.     if ((utc.hour < 24) && (utc.minutes < 60) && (utc.seconds < 60) &&
  23.         (utc.month < 12) && (utc.day < 31) && (utc.year > 1999) && (utc.year < 2136))
  24.     {
  25.       /* Got past the course filter, now check for leap year */
  26.       if ((utc.month != 1) || (utc.day < (IsLeapYear( utc.year ) ? 29 : 28)))
  27.       {
  28.         /* Numbers look reasonable, convert to UTC */
  29.         utcSecs = osal_ConvertUTCSecs( &utc );
  30.       }
  31.     }
  32.   }

  33.   if ( utcSecs == 0 )
  34.   {
  35.     /* Bad parameter(s) */
  36.     retStat = ZInvalidParameter;
  37.   }
  38.   else
  39.   {
  40.     /* Parameters accepted, set the time */
  41.     osal_setClock( utcSecs );
  42.     retStat = ZSuccess;
  43.   }

  44.   /* Build and send back the response */
  45.   MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS),
  46.                                  cmdId, 1, &retStat);
  47. }
                这个我贴了个原生态的函数实现,首先了解到一个时间结构体 UTCTimeStruct ,通过对这个结构体成员的赋值就能传一个时间给系统了.然后看到有一个IsLeapYear()的判断函数,这个函数的功能是判断是否是闰年,怎么样,该有的都有了吧!之后使用osal_ConvertUTCSecs()函数将时间结构体转换成从2000年0时0分0秒以来的秒数,不为其他,只是下面osal_setClock()设置时间函数需要这个秒数作为参数.
                ( 8 ).MT_SYS_SET_TX_POWER---设置发送功率
                       这个功能主要使用的是一个设置调整发射功率的函数macRadioSetTxPower(),在第6个功能ZMacSetReq()中设置发射功率时,其实底层也是调用了macRadioSetTxPower().

                        

                    
阅读(7116) | 评论(1) | 转发(1) |
给主人留下些什么吧!~~

凡艾2015-04-29 09:36:09

大牛很厉害,学习了不少!