您的位置:首页 > 其它

contiki netstack数据收发结构

2015-09-07 18:47 561 查看
 

摘要

本文介绍了contiki netstack的MAC层以下数据收发层次结构,并讨论如何移植新的无线器件做为contiki的无线收发器。

正文

contiki netstack的数据收发层级



 





Radio:主要完成物理层无线数据的收发和控制
Framer: 完成对数据帧的打包和解析
RDC: radio duty cycling, 周期性访问radio,主要为了减少功耗
MAC: 数据链路层
Netstack: 网络协议栈

contiki内各层级的配置与用处

contiki可以在contiki-conf.h中进行配置

#define NETSTACK_CONF_NETWORK rime_driver //使用rime协议栈
#define NETSTACK_CONF_MAC nullmac_driver //不使用mac层协议
#define NETSTACK_CONF_RDC contikimac_driver //使用contikimac rdc
#define NETSTACK_CONF_FRAMER framer_nrf24 //使用nrf24的frame结构
#define NETSTACK_CONF_RADIO nrf24_radio_driver //使用nrf24做为无线器件


NETSTACK_CONF_RADIO

定义contiki netstack使用的无线通信器件,这一层的驱动一般只完成物理层上的收发控制。其定义的原型在radio.h中:

struct radio_driver {
int (* init)(void);
/** Prepare the radio with a packet to be sent. */
int (* prepare)(const void *payload, unsigned short payload_len);
/** Send the packet that has previously been prepared. */
int (* transmit)(unsigned short transmit_len);
/** Prepare & transmit a packet. */
int (* send)(const void *payload, unsigned short payload_len);
/** Read a received packet into a buffer. */
int (* read)(void *buf, unsigned short buf_len);
/** Perform a Clear-Channel Assessment (CCA) to find out if there is
a packet in the air or not. */
int (* channel_clear)(void);
/** Check if the radio driver is currently receiving a packet */
int (* receiving_packet)(void);
/** Check if the radio driver has just received a packet */
int (* pending_packet)(void);
/** Turn the radio on. */
int (* on)(void);
/** Turn the radio off. */
int (* off)(void);
};


NETSTACK_CONF_FRAMER

定义使用radio driver的frame格式,这一层完成对数据帧的解析和打包,原型定义在framer.h中

struct framer {
int (* create)(void);
int (* parse)(void);
};


NETSTACK_CONF_RDC

radio duty cycling, RDC层,从radio层获取数据,并通过framer解析。RDC将要发送的数据通过parser打包并通过radio层发送。RDC提供无线传感的省电duty cycling。contiki提供了以下的rdc mac协议:

sicslowmac_driver
contikimac_driver
cxmac_driver
lpp_driver
nullrdc_driver
其中nullrdc_driver不做任何duty cycling动作。

NETSTACK_CONF_MAC

MAC层主要是完成,防碰撞的协议,contiki提供以下的MAC协议:

csma_driver
nullmac_driver
其中nullmac_driver不做任何防碰撞,直接转发数据

针对nrf24l01,NETSTACK收发各层级的移植

RDC层/MAC层/NETSTACK层的代码contiki提供,如果没有特殊的需求不用做修改和添加,主要的移植工作集中在Framer和radio层.

framer层,完成数据发送前的封包和接收后的解析,在nrf24l01同步等的framer结构都在nrf24l01的硬件中处理,因此定义的framer结构只与地址和payload有关

数据frame结构:



 





create frame时,RDC将MAC层要发送的数据加上dst addr和src addr后送到radio。

parser frame时,从中解析出dst addr和src addr,然后将actual payload送到MAC层。

按照上述做法实现

 

const struct framer framer_nrf24 = {
create, parse
};


driver层

不用考虑任何数据链路层和网络层的内容,只做很单纯的收发动作,因此按照struct radio_driver的要求实现各个API即可:

const struct radio_driver nrf24_radio_driver =
{
nrf24_radio_init,
nrf24_radio_prepare,
nrf24_radio_transmit,
nrf24_radio_send,
nrf24_radio_read,
nrf24_radio_channel_clear,
nrf24_radio_receiving_packet,
nrf24_radio_pending_packet,
nrf24_radio_on,
nrf24_radio_off,
};


由于nrf24l01没有广播地址的概念,因此将nrf24l01的pipe0做为点对点数据, pipe1做为广播数据。也就是将所有节点的pipe0地址设置为自己独有的,所以节点的pipe1的地址设置为相同的,这样针对pipe1地址发送数据,所有节点都能收到,则实现了广播



 





nrf24l01按照自己的pipe地址设置选择和接收数据,因此nrf24l01只知道自己的地址是什么,不知道发送者是谁,所以实际nrf24l01要通过RF发送的数据需要包含src address。因此将frame数据去掉dst进行发送:





nrf24l01将dst address设置入硬件寄存器,nrf24l01会自动将数据发送到指定的地址。

从发送的数据格式可以看出nrf24l01通过RF收到的数据也是没有dst addr的,但nrf24l01只收自己地址的数据,所以dst addr也就知道是什么,因此nrf24l01收到数据后,根据收到数据的pipe,为数据加上dst addr然后送到RDC层,再由frame来解包。

RDC层直接使用contikimac

MAC层使用nullmac,因为nrf24l01自已后碰撞和可靠接收的硬件机制因此MAC层不用再做动作,直接转发到NETSTACK层即可

NETSTACK用什么,看具体情况,可以选择uip也可用rime等等。

关于nrf24l01一个packet的长度

nrf24l01能发送的净payload为32byte,为了适应在contiki,要从其中分出3~5个byte放src addr,在我的移植中定义为4,因此nrf24l01发送一个包最长为28byte

结束语

本文从contiki收发数据的层级介绍了contiki netstack的数据收发层级。并简单介绍了nrf24l01作为contiki radio的移植方法。nrf24l01要以28byte作为净数据来做为contiki的radio是否可行,还需要进一步探讨。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: