contiki netstack數據收發結構

 

摘要

本文介紹了contiki netstack的MAC層如下數據收發層次結構,並討論如何移植新的無線器件作爲contiki的無線收發器。網絡

正文

contiki netstack的數據收發層級

 

image

  • Radio:主要完成物理層無線數據的收發和控制
  • Framer: 完成對數據幀的打包和解析
  • RDC: radio duty cycling, 週期性訪問radio,主要爲了減小功耗
  • MAC: 數據鏈路層
  • Netstack: 網絡協議棧

contiki內各層級的配置與用處

contiki能夠在contiki-conf.h中進行配置ui

#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_RADIOspa

定義contiki netstack使用的無線通訊器件,這一層的驅動通常只完成物理層上的收發控制。其定義的原型在radio.h中:.net

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_FRAMERcode

定義使用radio driver的frame格式,這一層完成對數據幀的解析和打包,原型定義在framer.h中orm

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

NETSTACK_CONF_RDCip

radio duty cycling, RDC層,從radio層獲取數據,並經過framer解析。RDC將要發送的數據經過parser打包並經過radio層發送。RDC提供無線傳感的省電duty cycling。contiki提供瞭如下的rdc mac協議:get

  • 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結構:

 

image

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地址發送數據,全部節點都能收到,則實現了廣播

 

image

nrf24l01按照本身的pipe地址設置選擇和接收數據,所以nrf24l01只知道本身的地址是什麼,不知道發送者是誰,因此實際nrf24l01要經過RF發送的數據須要包含src address。所以將frame數據去掉dst進行發送:

image

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是否可行,還須要進一步探討。

相關文章
相關標籤/搜索