活到老,学到老!
分类: 嵌入式
2014-04-17 12:25:56
摘要:
本文讲述了Rime协议栈单跳单播的头部,包括ruc(runicast)、uc(unicast)、broadcast、abc,并用图直观表示。
一、Rime协议栈头部格式
1.1 概述
Rime协议栈为了能适用不同的网络协议(network protocols),这就需要解决头部格式兼容问题。很容易想到的方法是定义一个统一的头部格式,但缺点几乎是致命的,头部太大且扩展性差。
图1 不同网络协议的头部格式
巧妙的是,Rime干脆不定义任何头部格式,而是将所有头部字段抽象为类型和长度(结构体packetbuf_attrlist )。将头部各字段组织成数组attributes[],部份源代码如下:
这样的思想很常见,如:HTTP报文整个报文段内容是普通ASCII文本,头部各个字段靠空格或者回车换行符隔开,而Rime头部是用长度来隔开。
1.2 数据包缓冲属性类型
Contiki将数据包缓冲属性类型(packet buffer attribute type)组织成枚举类型变量,如下:
每个枚举元素都是一个常量(枚举型是预处理指令#define的替代),若第一个枚举元素没有赋值,则默认为0,随后元素以1递增。所以在本例,PACKETBUF_ATTR_NONE为0,PACKETBUF_ATTR_MAX为28。
1.3 runicast头部
在contiki/core/net/rime/runicast.c文件定义了该数组,源代码如下:
RUNICAST_ATTRIBUTES分析见本文第二部分,PACKETBUF_ATTR_LAST分析见本文第四部分。所有宏展开,理清变量间关系,最后得到runicast头部示意图见本文第五部分。
PS:第二、三、四部分系分析过程,无非就是一些宏展开,没多大阅读价值,建立直接看第五部分结论。
二、RUNICAST_ATTRIBUTES
宏RUNICAST_ATTRIBUTES展开如下:
2.1 PACKETBUF_ATTR_PACKET_TYPE
PACKETBUF_ATTR_PACKET_TYPE是上述枚举类型的元素,其值为15,PACKETBUF_ATTR_BIT由#define定义,其值为1。
2.2 PACKETBUF_ATTR_PACKET_ID
PACKETBUF_ATTR_PACKET_ID是上述枚举类型的元素,其值为14。PACKETBUF_ATTR_BIT 、RUNICAST_PACKET_ID_BITS皆由#define定义,其值分别为1、2,两者乘积为2。源码如下:
2.3 STUNICAST_ATTRIBUTES
宏STUNICAST_ATTRIBUTES一步步展开如下:
2.3.1 PACKETBUF_ADDR_RECEIVER
PACKETBUF_ADDR_RECEIVER是上述枚举类型的元素,其值为26。宏PACKETBUF_ADDRSIZE 展开如下:
Rime地址长度RIMEADDR_SIZE默认为2,sizeof(rimeaddr_t)为2,所以PACKETBUF_ADDRSIZE为16。可见packetbuf_attrlist成员变量长度len是以bit为单位。
2.3.2 BROADCAST_ATTRIBUTES
见本文第三部分。
三、BROADCAST_ATTRIBUTES
BROADCAST_ATTRIBUTES宏展开如下:
3.1 PACKETBUF_ADDR_SENDER
PACKETBUF_ADDR_SENDER是上述枚举类型的元素,其值为25,宏PACKETBUF_ADDRSIZE 展开如下:
Rime地址长度RIMEADDR_SIZE默认为2,sizeof(rimeaddr_t)为2,所以PACKETBUF_ADDRSIZE为16。
3.2 ABC_ATTRIBUTES
宏ABC_ATTRIBUTES展开如下:
四、PACKETBUF_ATTR_LAST
宏PACKETBUF_ATTR_LAST 展开如下:
PACKETBUF_ATTR_NONE是上述枚举类型的元素,其值为0。
五、总结
5.1 runicast头部
runicast的attributes数组定义源代码如下:
结合上述分析,runicast头部示意图如下:
图2 runicast头部示意图
5.2 unicast头部
unicast的attributes数组定义源代码如下:
结合上述分析,runicast头部示意图如下:
图3 unicast头部示意图
5.3 broadcast
的attributes数组定义源代码如下:
结合上述分析,broadcast头部示意图如下:
图4 broadcast头部示意图
5.4 abc
abc的attributes数组定义源代码如下:
结合上述分析,abc头部示意图如下:
图5 abc头部示意图
5.5 其他问题
如果你细心的话,你会发现rucb、stuc、abc是没有头部的。我的理解是这样的,rucb块传输层,直接把应用程序数据交给下层ruc,无须增加头部。Rime协议栈将可靠传输层分成两层stuc与ruc,只须加一次头部。abc层的数据直接发送出去,也无须增加头部(abc类似于物理层的功能)。
本文所有头部示意图源文件 Rime单跳单播头部.rar
参考资料:
[1] Adam Dunkels,Fredrik Osterlind,Zhitao He. An Adaptive Communication Architecture for Wireless Sensor Networks[J]