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

Flowers_World

文章分类

全部博文(65)

文章存档

2017年(7)

2016年(38)

2015年(14)

2014年(6)

我的朋友

分类: 嵌入式

2016-07-14 13:48:20

0.前言
    由于Contiki在linux环境下开发,为了深入学习Contiki所以从【Instant Contiki 安装笔记——SDCC和CC2530】博文之后陆续开始学习linux,学习linux则借助树莓派平台,没想到一学就学就学上瘾了,写了20多篇树莓派的学习笔记从小白变为了低级菜鸟——【树莓派学习笔记——索引博文】。今天回到Contiki整理些IPV6的相关资料,今天说说IPv6地址。

1.MAC48地址变为IPv6地址
    在IPV6中有一种称为无状态自动配置的机制使用EUI-64地址来自动配置IPV6地址,EUI-64格式即扩展唯一标识符,相当于MAC-48地址。所谓无状态自动配置是指在网络中没有DHCP服务器的情况下,允许节点自行配置IPV6地址的机制。
    【工作原理】
    自动将48bit的以太网MAC地址扩展成64bit,再挂在一个64bit的前缀后面,组成一个IPV6地址,步骤共有三步。
    【第一步】将48位的MAC地址从中间分开,插入一个固定数值FFFE(16进制)。
    【第二步】将第7个比特位反转,如果原来是0就变为1,如果原来是1就变为0 。
    【第三步】加上64位的网络前缀这就是一个完整的IPV6地址
    【反转原因】
           在MAC地址中,第7比特为1表示本地管理,为0表示全球管理。
      在EUI-64格式中,第7位为1表示全球唯一,为0表示本地唯一。

    【具体例子】——【】

图1 IPv6和EUI-64地址变化
    【1】原MAC48地址为39-A7-94-07-CB-D0,从中间断开插入FF-FE,变为39-A7-94--FF-FE-07-CB-D0。
    【2】第7个比特反转(从左往右数),变为3B-A7-94-FF-FE-07-CB-D0
    【3】加入网络前缀,若前缀为链路本地地址则网络前缀为FE-80-00-00-00-00.
            IPV6地址最终为FE-80-00-00-00-00-00-00-3B-A7-94-FF-FE-07-CB-D0
            可简写为FE80::3BA7:94FF:FE07:CBD0

2. IEEE 802.15.4地址变为IPv6地址
    CC2530符合IEEE802.15.4标准,在出厂时便有一个IEEE地址,IEEE802.15.4地址共有8字节(IEEE802.15.4分为长地址8字节和短地址2字节)。由于CC2530的IEEE地址共有8字节,扩展IPv6地址时便可省略上文提到的步骤1,只执行步骤2和步骤3即可。
    【如何获得CC2530 IEEE地址】
    使用SmartRF Flash Programmer便可获得CC2530地址,通过CC2530仿真器连接CC2530目标板即可。此时CC2530的IEEE地址为00-12-4B-00-02-6E-7D-AA。那么链路本地地址为FE-80-00-00-00-00-00-00-02-12-4B-00-02-6E-7D-AA,请注意IEEE地址的首字节00被翻转为02
    可简写为FE80::212:4B00:26E:7DAA。
   
图2 CC2530 IEEE地址

3.contiki中如何使用
    很多人发邮件给我询问关于CC2530 UDP例子,问题多数反应Client和Server之间无法收发数据(除了这之外还有重启问题,下篇博文再说),
    【问题原因】
    Client程序中未指定Server的Ipv6地址,由于未指定server的Ip地址,server便直接过滤client发送的无线报文。
    【解决方法】
    修改client.c中的关于server IPv6地址设定。(链路单播地址,全局单播地址以后的博文再讨论)
  // 设置链路单播地址
  uip_ip6addr(&ipaddr,0xfe80,0,0,0,0x0212,0x4b00,0x26e,0x7daa); 
  // 设置全局单播地址
  uip_ip6addr(&ipaddr,0xaaaa,0,0,0,0x0212,0x4b00,0x26e,0x7daa); 

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. PROCESS_THREAD(udp_client_process, ev, data)  
  2. {  
  3.   static struct etimer et;  
  4.   uip_ipaddr_t ipaddr;  
  5.   PROCESS_BEGIN();  
  6.   // 设置链路单播地址  
  7.   uip_ip6addr(&ipaddr,0xfe80,0,0,0,0x0212,0x4b00,0x26e,0x7daa);  
  8.   /* new connection with remote host */  
  9.   l_conn = udp_new(&ipaddr, UIP_HTONS(3000), NULL); // 建立一个新连接,端口号为3000  
  10.   if(!l_conn) {  
  11.     PRINTF("udp_new l_conn error.\n");  
  12.   }  
  13.   udp_bind(l_conn, UIP_HTONS(LOCAL_CONN_PORT));  
  14.   PRINTF("Link-Local connection with ");  
  15.   PRINT6ADDR(&l_conn->ripaddr);  
  16.   PRINTF(" local/remote port %u/%u\n",  
  17.   UIP_HTONS(l_conn->lport), UIP_HTONS(l_conn->rport));  
  18.   // 设置全局单播地址  
  19.   uip_ip6addr(&ipaddr,0xaaaa,0,0,0,0x0212,0x4b00,0x26e,0x7daa);  
  20.   g_conn = udp_new(&ipaddr, UIP_HTONS(3000), NULL); // 建立一个新连接,端口号为3000  
  21.   if(!g_conn) {  
  22.     PRINTF("udp_new g_conn error.\n");  
  23.   }  
  24.   udp_bind(g_conn, UIP_HTONS(GLOBAL_CONN_PORT));  

4.参考资料
【】
【】

转载:http://blog.csdn.net/xukai871105/article/details/23615211
阅读(905) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~