分类: 嵌入式
2012-10-23 15:29:49
环境:IAR
硬件:cc2530
1,先打开uipopt.h中的关于IPv6的宏定义;
#ifndef UIP_CONF_IPV6
/** Do we use IPv6 or not (default: no) */
#define UIP_CONF_IPV6 1
#endif
2,在uip-ds6.h
typedef struct uip_ds6_netif {
uint32_t link_mtu;
uint8_t cur_hop_limit;
uint32_t base_reachable_time; /* in msec */
uint32_t reachable_time; /* in msec */
uint32_t retrans_timer; /* in msec */
uint8_t maxdadns;
uip_ds6_addr_t addr_list[UIP_DS6_ADDR_NB];
** uip_ds6_aaddr_t aaddr_list[UIP_DS6_AADDR_NB];
uip_ds6_maddr_t maddr_list[UIP_DS6_MADDR_NB];
} uip_ds6_netif_t;
**处,在刚开始调试的时候,里面的宏值为0.....找了一个小时!!!
//Uip.h
#include
#define UIP_CONF_IPV6 1
//contiki-conf.h
#if UIP_CONF_IPV6
#define UIP_CONF_ROUTER 1
......
这里直接在contiki-conf.h中定义UIP_CONF_IPV6 为1,由于此宏本来是在uipopt.h中定义的,但是在contiki-conf.h中在#if UIP_CONF_IPV6处不能感知已经定义了此宏为1,因为uipopt.h中包含contiki-conf.h。
在网上问了别人,说是在IAR环境变量里面可以加预置宏可以实现。我没搞成功,就简单的进行了上面的定义。
由于contiki-conf.h 和uipopt.h中关于UIP_CON_IPV6不统一,所以导致很多问题。
3,由于tdma.c文件有些错误,就直接不编译了,因为Ipv6的mac用的sicslowpan协议。
4,在contiki-conf.h中定义了#define UIP_CONF_IP_FORWARD 0
5,在contiki-conf.h中定义了
#ifdef PROJECT_CONF_H
#include "project-conf.h"
#endif /* PROJECT_CONF_H */
这个对于不同的例子,应该包含不同的project-conf.h,而PROJECT_CONF_H是没有定义的,这里在contiki-conf.h中定义下就行了。
6:
上面是由于无意中将下面的库给搞错了,所以出现了上面的错误。
7,打印函数有问题,需要对uip-debug.h中的打印宏进行重新定义。
现在只是简单把PRINTF屏蔽了,使用了putstring来实现了下。 PRINT6ADDR这个宏的实现也需要改下,因为不能实现打印16数据,所以只能分两次经行打印
puthex((a&0xff00)>>8);
puthex((a&0x00ff));
8:在client.c和ping.c中有目标IP地址的设置,这里根据server的IPv6地址来设置。
#if UIP_CONF_ROUTER
uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0,0,0,0,0);
uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
#if SERVER_RPL_ROOT
dag = rpl_set_root(&uip_ds6_get_global(ADDR_PREFERRED)->ipaddr);
if(dag != NULL) {
uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0,0,0,0,0);
rpl_set_prefix(dag, &ipaddr, 64);
// PRINTF("Created a new RPL dag\n");
putstring("Created a new RPL dag\n");
}
#endif /* SERVER_RPL_ROOT */
#endif /* UIP_CONF_ROUTER */
从上面可以看出,sever.c中的IP地址是由0xaaaa,0,0,0作为网络前缀,后面加上了uip_lladdr,形成了128位的IPv6地址。
但是uip_ds6_set_addr_iid()中
#if (UIP_LLADDR_LEN == 8)
memcpy(ipaddr->u8 + 8, lladdr, UIP_LLADDR_LEN);
ipaddr->u8[8] ^= 0x02;
也就是将EUI-64的第7位,也就是本地/全局标志位设置为1,1表示本地有效,表示Local,
所以这里client和ping 的时候应该给注意一下,不能简单的加上前缀和MAC地址就行了, 必须注意第七位一定是1.
9,一次发送的数据不能过大,应该是100字节以内,这个没有详细测过,但是如果数据过大,通信是会出问题的。
10,通过简单的修修改服务器和客户端之间的发送数据,就能变成实用的一个UDP通信的东西,虽然简陋了点。负责化的话,无非就是把状态考虑的全一些。
11,在调试ping的时候,弄了N久,原来是IP地址的前缀搞错了,在实际通信的时候,前缀是0xfe80,而默认文件是0xaaaa,后面根据客户端的连接,才反应过来........,这里应该设置成0xfe80
从上面可以看出,链路本地单播地址是0xfe80开头的,而0xaaaa 是未分配的地址空间。yes
通过这个例子,熟悉了UDP通信的基本模型,怎样进行链接,经行通信,以及一些节点地址方面的操作。小地方比较多,慢慢熟悉就好了。
调试通过了,happy
hnylcxq2013-11-25 16:15:55
joven_cumt:请问宏值为1的需要作什么处理
这个要查代码了,这里讲不清楚,你利用source insight 跟踪代码可以看到。如不配置的话,你的工程将不会支持IPv6的东西
回复 | 举报