3.1.7 SimpliciTI应用层接口
1.1 smplStatus_t SMPL__Init(uint8_t (*callback)(linkID_t))
功能描述:该函数主要初始化通信系统和simpliciti的协议栈。完成的工作包括有:
A.直接调用驱动层函数MRFI_Init完成通讯硬件设备初始化,随机数种子初始化,物理层数据接收缓冲区初始化等工作。
B.调用网络层函数nwk_nwkInit注册用户接收数据处理函数并初始化连接表数据结构,初始化最大连接数,初始化下一个连接将使用到的接收和发送端口号,初始化下一个连接号;将中心节点地址设置为0,并从ROM中获取自身地址并搬移到RAM中;初始化设备类型,数据接收和发送的方式,初始化TRACE ID,将数据接收处理函数注册给nwk_frame.c 文件(而nwk_nwkInit则继续调用nwk_frameInit初始化本设备帧的固有数据结构并向下注册用户接收数据处理函数,nwk_frameInit注册用户数据处理函数的过程是根据预编译宏RX_POLLS来完成的,这个宏设置了用户程序对接收数据的处理方式。当其被置一,则表明用户程序将采用查询的方式来处理数据,底层用户数据处理函数注册被放弃。这种情况下接收到用户程序需要处理的数据时,该数据被保存在网络层的接收数据队列sInFrameQ中,等待应用程序来查询获取。反之,用户数据处理程序被注册给底层函数供中断调用处理。获取自身地址,并初始化nwk_frame.c文件的TID );初始化应用层接收和发送数据处理队列sInframeQ和sOutFrameQ,这两个数据队列在逻辑层次上刚刚高于物理层的数据接收缓冲区;同时nwk_nwkInit还将初始化网络层内置的一些应用的TID以及相应的默认信标;初始化广播用到的连接号和端口号。
C.如果不是end device则使通信系统处于接收状态
D.如果是end device 则开启地址过滤
E.调用nwk_join启动一次连接AP的过程。该过程通过广播地址使用JOIN端口发起一次向AP的加入请求。加入成功将获得AP的地址和新的连接信标。
1.2 输入参数:
uint8_t (*callback)(linkID_t)--用户数据处理函数的函数指针,用户数据处理函数只有在end device上才能生效
1.3 返回值:
SMPL_SUCCESS--初始化成功
SMPL_NO_JOIN--因为没有收到AP返回,加入AP失败
SMPL_NO_CHANNEL--频率信道扫描失败,这种情况只有跳频条件编译功能开关打开才会发生。
2.1 smplStatus_t SMPL_Link(linkID_t *lid)
功能描述:用广播地址发起一个连接请求,如果收到回复则成功建立起一个连接,同时会生成一个连接号供应用程序使用该连接。连接建立过程受到等待时间的限制,等待超时将返回连接失败。等待时间是在初始化系统时根据通信速率,自动计算获取的。该函数可以被重复多次条用以获得多个连接。这些连接可以基于同一个设备也可以建立在不同设备之间。
执行过程:首先从连接表中选取一个空连接(选取空链接的时候需要更新连接表的下一个连接号)
3.1.8 SimpliciTI接收数据处理机制
Simpliciti接收数据的最小单位为数据帧,因为其外接的射频收发芯片是按帧为单位进行数据收发的。在适当的配置之下,射频芯片接收到数据帧后将发生一个中断告之MCU,MCU对响应这个中断并处理接收数据。Simpliciti中断调用并处理这个数据帧结构非常复杂,异常庞大,它几乎将除了用户应用程序外的所有simpliciti内部协议的接收处理都放在了中断函数中。
Mrfi_SyncPinRxIsr:该函数由中断触发并调用,模拟物理层对数据进行接收。主要完成的工作是对帧完整性进行验证;对数据帧的校验和进行验证;根据自身地址和功能开关对地址进行过滤(地址过滤操作将允许广播地址通过);转换帧信号标识(RSSI,LQI转换为DB位计量单位的量)。
该函数涉及到的一个全局变量:mrfiIncomingPacket。这个变量专门用于对存放接收到的单帧数据。
nwk_QfindSlot:寻找一个空余数据帧空隙,将接收到的数据放入该数据帧。如果所有数据帧都满了,那么将最老的那个数据帧去掉。
该过程涉及到的全局变量是:sInFrameQ[],这个变量时由结构体frameInfo_t定义的。
MRFI_Receive:该函数实现将接收到的数据填充到刚刚找到的空隙中。这里有一个技巧,原代码设计时使用了结构体变量之间,直接赋值!
dispatchFrame:检测信息类型,并更具信息类型进行投递到相应的应用层处理函数。主要完成工作是:检测信息是否是自身的回声(这种情况一般来至extender的转发);根据获取到的端口判断是否调用内部网络层固有处理函数;根据网络层内部处理函数结果判断是否转发;根据端口判断是否存在相应的服务程序;
3.2.1 SimpliciTI的缺点
1.能够构建的网络相对较简单,网络容量小
2.不具备路由管理功能,每一次通讯都依靠RE进行侦听转发,比较浪费时间。这应该算是simpliciti最大的一个缺点了。
3.转发跳数限制在4跳,极大地限制了通信距离
4.每一个网络里边最大允许出现四个RE,这虽然可以减少数据发送过程带来的冲突,但是也使网络规模受到限制,传输距离受到限制。
5.设备分了三种类型,为安装带来麻烦
3.2.2 SimpliciTI的启迪
1.编写代码的时候每一个独立文件所独有的变量尽量使用static进行修饰,这样在设计功能类似的代码可以取一致的变量名。
2.在外部线程操作中断内可改变的变量时需要关闭中断。
3.中断内部可改变的变量需要用volatile定义。
4.学会使用assert功能
5.每一个应用线程独立的维护自己的TID
6.学会使用函数指针数组来完成对函数的调用
7.每一个文件内部的变量都是静态的,属于本文件的,这些变量的操作均借助于该文件内专用的操作函数来完成。(它的优点目前我还未能领悟)
8.学会使用memcpy,memset以及memcmp函数,将极大的简化代码
9.启用工程对项目进行管理的时候,通过不同的工程配置文件达到一个工程管理多个平台的目的。具体细节是,不同工程配置文件配置不同的包含路径,在工程的驱动层c文件中通过包含的方式包含底层驱动,由于不同配置不同包含路径导致配置变了以后自动包含了不同的驱动,从而实现一个工程管理多个平台。
10.用枚举定义所有函数的返回类型,并且包括所有可能出现的异常。
11. 只针对CC25xx/CC11xx无线射频的:SimpliciTI使用SmartRF Studio配置工具设置外部寄存器。 这个工具通过空中射频和控制寄器设置寄存器。 SimpliciTI使用空中RF设置但必须忽略大多数控制寄存器的设置方式。 控制设置只是影响功能,使他们不能被覆盖。 下表列出直接由软件控制得寄存器:
寄存器 |
评论 |
IOCFG0 |
GPIO的配置。 完全由软件控制。 |
IOCFG2 |
GPIO的配置。 完全由软件控制。 |
MCSM0 |
状态机的配置。 PO_TIMEOUT的值从SmartRFStudio的输出值中获得,所有其他字段由软件控制。 |
MCSM1 |
状态机的配置。 完全由软件控制。 |
PKTLEN |
包长度。 完全由软件控制。 |
PKTCTRL0 |
分组控制寄存器。 WHITE_DATA的值从SmartRFStudio的输出值中获得,所有其他字段由软件控制。 |
PATABLE0 |
SmartRFStudio 目前不输出这个值。 如果将来的修订版导出这个值,它将用来代替内置软件的默认设置。 |
CHANNR |
通道号。 该值是SmartRFStudio 输出值。 但是,这个值有可能在项目中定义了MRFI_CHAN而被覆盖。 |
表5 CC1100/CC2500 寄存器例外设置
12.SMPL_LinkListen()调用阻塞了相对长的一段时间,与此同时SMPL_Link()调用连续性执行。 阻塞的时间可以通过修改nwk_api.c文件中的宏定义。
13.接收数据帧顺序是相同的。 如果帧队列被填充,当新帧到达时,老帧将被丢弃,以腾出空间。
14.当一个应用程序调用了SMPL_Receive(),它从较早的帧收到指定链接ID的有效载荷。
15.当帧转发到存储和转发的客户,他们将按转发的顺序接收。
16.广播帧和NWK应用帧是不能代表客户存储和转发。
17.如果无线接入点本身的应用程序发送到轮询设备,在其他所有设备发送完后可以发送,而不是按顺序发送的。
18.无线接入点不会记住加入了设备的地址。 这意味着,无论信息来源是哪里,接入点都将重播帧。 (对于范围扩展器也是这样。)它是由对等应用程序决定的而不是流氓消息。 在使用的连接和链路令牌可以减轻设备来自非成员设备的干扰,帮助防止未经授权的连接,但它是没有保证。
19.用户应用帧在NWK层通过匹配目标端口和源地址的连接表条目来验证是否合法。 接收帧必须通过验证,否则将被丢弃。 否则就没有办法从输入帧队列中删除这些信息,因为不会有应用程序试图检索这些帧。
(注:此部分部分内容源自网上整理非原创。) |