SimpliciTI初步

一、搭建SimpliciTI环境

一个MCU和一个RF模块,这就是搭建SimpliciTI环境的硬件需求(TI的SoC也是在芯片内部集成了RF模块)。当然了,这个协议栈是有版权的,当你用作商业用途时需要向TI缴纳一定的费用,而用于学习时,TI也会要求你至少用他的RF芯片。

这里使用的是TI的eZ430-RF2500套件,板载MSP430F2274和CC2500射频芯片,使用芯片天线,传输距离并不远,如果离开一段距离或者有遮蔽物就会出现丢包,这个我们会在后面进行测试。电路图如下(点击看大图),2274和CC2500之间通过SPI和两个IO(中断方式)通信,一般网上卖的模块也会留出这些接口。如果对RF PCB设计没有信心,淘宝上有10块钱的CC2500模块,虽然是白菜价,但是PCB天线一般都是低于0dB的,通信距离可想而知。

TI官方的开发套件,$49。

淘宝上可以找到CC2500模块,价格在10无左右。

同时,此平台也对外开放一个USB调试接口(包括UART和SBW)。

接口定义

 

二、SimpliciTI协议栈结构与移植

SimpliciTI协议的一大特点就是简单,所以在极大简化开发过程的同时也带了很多限制,比如缺少完备的路由协议,最多4个RE(使通信距离受限),即使低功耗也是在ED关闭RF接收功能的前提下实现的(限制双向通信)。不过即使如此,也丝毫不影响它为无线网络通信带来的便利,你可以根据应用需求在ZigBee和SimpliciTI之间取舍。

想要使用它你需要下载协议栈代码,下面是及针对RF2500套件的演示代码:

http://www.ti.com/lit/zip/slac139

通用协议栈SimpliciTI-IAR1.1.1(最新版本为1.2.0)可以在TI官网上下载:

http://www.ti.com.cn/tool/cn/simpliciti

安装后在安装目录下可以找到代码和说明文档,建议看一下Developers Notes、Sample Application User’s Guide和API文档,如果需要涉及加密、调频等应用,这里还有相应的Application Note xxxxxxxxxxx。

SimpliciTI本身的软件分为3层,即BSP、MRFI和NWK:

BSP是一个轻量级板级支持包,包含了MCU、SPI(这个必须有)、LED和Button,简单吧,TI的意思是尽可能的减少协议栈本身的硬件内容,因此如果想要用串口或者ADC,就要自行解决,我们暂且将这些额外添加的硬件控制代码称为Driver吧。

MRFI是最小射频接口,主要是与BSP中的SPI对接以及射频芯片的控制代码。如果要移植协议栈,就需要更改与MCU定义、中断、IO和SPI相关的代码,不过只要你使用MSP430或CC系列SoC作为MCU可以直接在代码中找到相近的Board从而减少工作量。当然啦,如果你是高手或者兼有求知和耐心的美德,甚至可以自己写底层而只保留NWK和APP层,不过这不是我们现在的目的,至少目前不是。

NWK网络层负责数据收发队列,同时包含很多网络层应用,注意区分NWK Applications与用户的应用代码(Customer Applications)的区别,这些网络层应用是以端口作为标识的(如Ping是0x01,Link是0x02),相应的函数以nwk_作为前缀,而我们通常将用户代码称作应用层。SimpliciTI的端口(Port)与TCP/IP的端口神似(similar in spirit ^^),每个端口对应一种应用,用户也可以定义自己的网络层应用。网络层为用户提供了API函数,以SMPL为前缀,如SMPL_Link等,我们的工作就是利用这些API实现组网及无线通信。

 

三、建立第一个简单双向通信程序

1)配置工程

打开演示代码eZ430-RF2500 WirelessSensorMonitor中的Sensor_Demo_AP_as_Data_Hub工程,如果你使用的是eZ430-RF2500套件,直接修改其中的Application文件就好了,如果不是TI的官方套件,可以选择一个硬件组成相近的工程,修改MCU定义和按键、LED等配置,这里不再深究,以后可以专门开贴讨论。

Tips在下载程序时可能出现这个错误,具体描述为:

Fatal error: The Object file contains features not suported by the driver.   Session aborted!

Failed to load debugee: …

这是因为在新版本的IAR中同时使用了选项配置和命令行,Debugger的版本较旧不识别,只需要取消命令行即可。

打开工程后可以看到两种器件,AP(Access Point)和ED(End Device)。AP是组网的关键,负责网络的建立和维护,同时负责对外通信,有点类似于ZigBee中的协调器。网络中最多只能有一个AP,在某些模式下(如P2P)可以不需要AP,但是这样的网络需要固定参数而缺少灵活性。ED是终端设备,在TI的演示中负责入网后通过片上温度传感器采集自身的温度,并发送给AP,由AP将接收到的数据转换成字符串后通过串给上位机。

在左侧的WorkSpace栏选择AP或者ED进行选择编译。

和网络相关的设置可以在几个配置文件中修改,其中smpl_config_AP.dat和smpl_config_ED.dat文件定义了设备类型、最大连接数、发送和接收帧队列长度等内容,smpl_nwk_config.dat文件则定义了基本的网络参数如网络和应用层负载长度、最大跳数等,这些配置可以在不同的应用中灵活选择,这里我们采用默认配置。

 

2AP节点

首先,通过BSP_Init函数初始化BSP,然后初始化需要的外围设备如串口、定时器、AD等,这里的串口函数并不包含在SimpliciTI中,而是以virtual_com_cmds.c文件的形式添加到工程中,甚至加入printf和scanf。

在设备初始化完成后,需要初始化SimpliciTI网络,AP中对应的函数为:

SMPL_Init(sCB);

这里的sCB是一个回调函数,本例中用来在接收到帧时区分是入网还是数据,并分别处理,它会在CC2500 RX接收中断后调用。想要研究协议结构的童鞋可以一路Go to definition找到函数调用的地方,现在我们只需定义该函数而无须理会调用机制。

回调函数的原型如下,当lid为0时,表示有设备入网,此时sJoinSem++,在主函数的sJoinSem子过程中进行处理,建立连接并为其分配LinkID。如果lid不为零则表示该设备已经入网并分配了LinkID,这个数据帧被作为通信数据在主函数的sPeerFrameSem子过程中通过SMPL_Recieve函数接收。

至此整个初始化工作完成,然后AP进入while(1)循环,这个循环中包含几个子过程,这里我们只需要sJoinSem和sPeerFrameSem两个过程。

sJoinSem过程内容如下:

一旦进入这个过程(有设备入网),软件将持续通过SMPL_LinkListen函数监听ED发起的链接,在链接建立后会为该链接分配一个LinkID,以后数据收发就考这个LinkID作为标识。该函数的实参就是一个用来存放LinkID的数组。sNumCurrentPeers是当前连接设备计数器,这里要注意的是在处理完入网帧后,需要减少sJoinSem的值,而sJoinSem是一个公共变量,同时受回调函数的控制。sCB是一个在中断中执行的函数,所以要通过BSP_ENTER_CRITICAL_SECTION进行临界保护,参数intState其实是一个unsigned short型变量,在主函数中定义,用于保存相关寄存器,在退出临界状态时恢复。

对接收到的通信数据的处理则要靠sPeerFrameSem:

 

SMPL_Receive函数读取接收到的数据帧,将APP_PAYLOAD分离出来保存在msg数组中,len作为实参保存msg的长度,最后通过USCI0_SendDataString发送给上位机。

其中USCI0_PutChar这个函数需要自己写,如果是带有USCI模块的430可以使用我的SED430-RF2500中的UART.c,若是USART模块的430则参见SED430中的串口文件。传送门上面已经给出。

那么如果要给ED发数据怎么办呢,依然只要一个函数即可:

定义一个msg数组,写入要发送的数据,然后:

SMPL_Send(lid, msg, len);

lid是要目的设备的LinkID,len是要发送数据的长度,这里len和接收函数不同是形参,注意不要超过最大负载长度哦。

这就是AP的部分,可以完成入网,数据接收发送功能,另外还有一些跳频和信号强度检测的功能,可以自己研究一下。

 

3ED节点

修改代码之前,需要给ED设置一个32位地址,这个地址相当于TCP/IP中的IP地址,由于SimpliciTI没有MAC层,所以设备就要靠这个地址识别数据包是不是发给自己的。网络中每一个设备的地址都应当是唯一的,否则会发生冲突。可以在对应设备的.dat配置文件中修改这条语句:

-DTHIS_DEVICE_ADDRESS=”{0x7A, 0x56, 0x34, 0x12}”

若不想一个一个设置,可以参考范例共给出的产生随机地址的方法,通过ADC或者VLO采集一个真随机数(虽然是真随机数不过不知道是什么分布的),换算成地址并写入Flash。

ED和AP的设备初始化过程一样,初始化完成后,开始检测是否存在网络并,直到检测到AP建立的网络并入网。__bis_SR_register函数的作用是休眠并等待TA中断,如果不想采用这种方式,也可以通过__delay_cycles函数或自己编写Delay函数实现延时。

如果ED不需要接收数据,SMPL_Init时可以不要回调函数:SMPL_Init(0)。如果需要接收数据,则应当开启RX:

SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);

ED的回调函数中只处理数据帧而没有入网帧,其形式如下:

ED在加入网络后还不能直接和AP通信,首先需要建立一个连接(Link):

连接建立好以后,AP的LinkID被保存在LID_AP变量中,因为我们只需要和一个固定的AP通信,所以不需要数组来保存多个LinkID。

至此,ED已经可以和AP自由的交换数据了,在sPeerFrameSem子过程中,我们将接收到的数据发还给AP并翻转一个LED。

搞定,可以编译运行了。

设置Show build messages显示全部消息,编译……

 

可以看到软件占用资源情况,想要运行这个协议栈,还要跑一些自己的程序,至少要有10KB的Flash和1KB的RAM,不过比起ZigBee那样的重量级协议,已经非常节省了。

未经允许不得转载:TacuLee » SimpliciTI初步

赞 (0)

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址