Chinaunix首页 | 论坛 | 博客
  • 博客访问: 261131
  • 博文数量: 65
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 375
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-29 21:49
个人简介

Flowers_World

文章分类

全部博文(65)

文章存档

2017年(7)

2016年(38)

2015年(14)

2014年(6)

我的朋友

分类: 嵌入式

2016-03-01 14:39:01

摘要 :

    本文讲述了Contiki之Rime协议栈的Rime地址rimeaddr_t相关细节,包括地址格式、地址相关操作rimeaddr_copy和rimeaddr_cmp、两个全局变量rimeaddr_node_addr和rimeaddr_null。


一、概述

    无论哪个协议栈,都得解决一个根本问题,如何标识不同的设备,即编址。如计算机网络中,用端口号标识同一台主机不同的进程,用IP地址标识不同的主机,用MAC唯一标识网卡。同样,Rime协议栈也需对不同节点进行标识,其用联合体rimeaddr_t进行描述。rimeaddr_t定义如下(在rimeaddr.h文件):

  1. typedef union
  2. {
  3.   unsigned char u8[RIMEADDR_SIZE];
  4. } rimeaddr_t;

    Rime协议栈的节点地址格式为%d.%d.%d...,默认长度为2,即%d.%d 。可以通过配置RIMEADDR_CONF_SIZE大小来配置节点地址长度,如contiki-2.5\platform\cc2530dk\contiki-conf.h中将RIMEADDR_CONF_SIZE 设为8。源代码如下:

  1. #ifdef RIMEADDR_CONF_SIZE
  2.   #define RIMEADDR_SIZE RIMEADDR_CONF_SIZE
  3. #else
  4.   #define RIMEADDR_SIZE 2
  5. #endif


二、相关操作

    对Rime地址rimeaddr_t操作很简单,拷贝eaddr_copy(也可以直接理解成赋值),判断两地址是否相等rimeaddr_cmp,重设当前节点Rime地址rimeaddr_node_addr的rimeaddr_set_node_addr。

2.1 rimeaddr_copy

rimeaddr_copy拷贝将Rime地址从src拷贝到dest,源码如下: 

  1. void rimeaddr_copy(rimeaddr_t *dest, const rimeaddr_t *src)
  2. {
  3.   u8_t i;
  4.   for(i = 0; i < RIMEADDR_SIZE; i++)
  5.   {
  6.     dest->u8[i] = src->u8[i];
  7.   }
  8. }

2.2 rimeaddr_cmp

rimeaddr_cmp用于判断两个Rime地址是不是相同,相同返回非0,不相同则返回0。源码如下:

  1. int rimeaddr_cmp(const rimeaddr_t *addr1, const rimeaddr_t *addr2)
  2. {
  3.   u8_t i;
  4.   for(i = 0; i < RIMEADDR_SIZE; i++)
  5.   {
  6.     if(addr1->u8[i] != addr2->u8[i])
  7.     {
  8.       return 0;
  9.     }
  10.   }
  11.   return 1;
  12. }

2.3 rimeaddr_set_node_addr

rimeaddr_set_node_addr用于设置当前节点Rime地址rimeaddr_node_addr,源码如下: 

  1. void rimeaddr_set_node_addr(rimeaddr_t *t)
  2. {
  3.   rimeaddr_copy(&rimeaddr_node_addr, t);
  4. }


三、几个全局变量

3.1 rimeaddr_node_addr

    节点的Rime地址,可以通过rimeaddr_set_node_addr()函数改变当前节点的Rime地址,即rimeaddr_node_addr。源代码如下: 

  1. rimeaddr_t rimeaddr_node_addr;

  2. void rimeaddr_set_node_addr(rimeaddr_t *t)
  3. {
  4.   rimeaddr_copy(&rimeaddr_node_addr, t);
  5. }

3.2 rimeaddr_null

    先来看下咱们熟悉的TCP/IP协议栈0.0.0.0地址,其表示整个网络,用于帮助路由表中无法查询的包(即路由表没有指明特定到达条目的主机和目的网络),路由表中无法查询的包都送到全零网络的路由中去[2]。在一些老的软件中,0.0.0.0作为广播地址使用[3]。

    Rime的零地址貌似跟TCP/IP协议栈不同,路由表使用零地址表明该项未使用,没有配置地址的节点默认为零地址。但配置地址的节点如果设成零地址,在与其他节点通信时将会有问题。这点我也没看懂,待后续源码分析求证。另,建立连接时(如rucb_open),发送方sender的地址被设成rimeaddr_null了。rimeaddr_null注释及定义如下:

  1. /*This variable contains the null Rime address. The null address is used in route tables to indicate that the table entry is unused. Nodes with no configured address has the null address. Nodes with their node address set to the null address will have problems communicating with other nodes.*/
  2. const rimeaddr_t rimeaddr_null;

    如果Rime地址长度为2,则rimeaddr_null为0.0;若Rime地址长度为8,则rimeaddr_null为0.0.0.0.0.0.0.0。源码如下: 

  1. #if RIMEADDR_SIZE == 2
  2.   const rimeaddr_t rimeaddr_null = { { 0, 0 } };
  3. #else
  4.   #if RIMEADDR_SIZE == 8
  5.     const rimeaddr_t rimeaddr_null = { { 0, 0, 0, 0, 0, 0, 0, 0 } };
  6.   #endif
  7. #endif

    这显然有个问题,如果在配置Rime地址长度RIMEADDR_CONF_SIZE时,既不是2也不是8(当然,如果不配置则默认为2),那么rimeaddr_null则没有初始化,即rimeaddr_null是一个弱符号,对该符号的处理依赖于编译连接器。


参考资料:

[1] Adam Dunkels论文《Poster Abstract: Rime - A Lightweight Layered Communication Stack for Sensor Networks》

[2] 博文《》

[3] 博文《0.0.0.0的IP是什么地址

阅读(558) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~