uIP使用记录

uIP(WIKI:https://en.wikipedia.org/wiki/UIP_(micro_IP))的初始开发者是Adam Dunkels(http://dunkels.com/adam/),这是一个开源的轻量级的TCP/IP协议栈,适用于8位或16位MCU,占用的RAM可从几百byte到几千byte不等,它仅可以处理单网络接口:IP、ICMP、UDP、TCP。uIP可从Adam Dunkels的Github获取,最新的版本是1.0,且已经不更新,现在uIP已经是开源系统Contiki的一部分,更新的部分也会在Contiki中完成。

我们先来看看uIP在系统中的位置
uIP位置
硬件驱动是需要提前完成,然后和uIP连接。在本例中,网卡驱动就是ENC28J60驱动。

uIP1.0文件结构如下:
文件结构
apps/ - 例子应用
doc/ - 文档
lib/ - 一些应用会使用到的
uip/ - uIP TCP/IP协议栈核心代码
unix/ - 与硬件平台有关的代码
我们本次移植涉及到文件夹apps、uip、unix。

我们将uip文件中的源码放入uip_core中,将unix文件中的源码放入uip_dev中(除了main.c)

1.uip_dev/clock-arch.h
这里写图片描述
2.uip_dev/tapdev.c
我们需要在这个文件中完成3个驱动函数。
这里写图片描述

#include "tapdev.h"
#include "uip.h"
#include "enc28j60.h"

//用于固定IP地址开关打开后的IP设置
#define UIP_DRIPADDR0   192
#define UIP_DRIPADDR1   168
#define UIP_DRIPADDR2   1
#define UIP_DRIPADDR3   15

//MAC地址
const u8 mymac[6]={0x04,0x02,0x35,0x00,0x00,0x01};

//网卡初始化
u8 tapdev_init(void)
{
    u8 i,res=0;
    res=ENC28J60_Init((u8*)mymac);

    for (i = 0; i < 6; i++)uip_ethaddr.addr[i]=mymac[i];
    //LED控制寄存器
    ENC28J60_PHY_Write(PHLCON,0x0476);
    return res;
}
//读取一包数据
uint16_t tapdev_read(void)
{
    return  ENC28J60_Packet_Receive(MAX_FRAMELEN,uip_buf);
}
//发送一包数据
void tapdev_send(void)
{
    ENC28J60_Packet_Send(uip_len,uip_buf);
}

3.uip_dev/uip_conf.h
根据需要配置uIP,并取消include的App头文件
这里写图片描述

//STM32是小端模式
#define UIP_CONF_BYTE_ORDER      LITTLE_ENDIAN
//关闭log记录
#define UIP_CONF_LOGGING         0

4.uip_dev/clock-arch.c
时钟部分,我们需要为uIP提供10ms的时钟,我们定义了全局变量uip_timer,使用了一个定时器,在中断中,全局变量uip_timer加1
这里写图片描述

#include "clock-arch.h"
clock_time_t uip_timer;
clock_time_t clock_time(void)
{
  return uip_timer;
}

好,我们开始编译,之后会出现比较多的错误和警告,具体如下:
1. uIP\core\uip.h(1180): error: #20: identifier “uip_tcp_appstate_t” is undefined
这里写图片描述

2. uIP\core\psock.c(303): warning: #167-D: argument of type “char ” is incompatible with parameter of type “u8_t
这个使用强制类型转换

//原本为buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
buf_setup(&psock->buf, (u8_t*)psock->bufptr, psock->bufsize);

3. uIP\core\psock.c(188): warning: #513-D: a value of type “const char ” cannot be assigned to an entity of type “const u8_t
这个使用强制类型转换

//原本为s->sendptr = buf;
s->sendptr = (const u8_t *)buf;

4. uIP\core\psock.c(179): warning: #550-D: variable “PT_YIELD_FLAG” was set but never used
注释掉pt.h中的两处即可
这里写图片描述
5. uIP\core\uip.c(700): warning: #223-D: function “UIP_APPCALL” declared implicitly
.\Output\STM32Test.axf: Error: L6218E: Undefined symbol UIP_APPCALL (referred from uip.o).
这两个错误都和UIP_APPCALL有关,我们在uip.h中加入一个宏定义

#define UIP_APPCALL()

6. uIP\core\uip.c(1847): warning: #177-D: label “ip_send_nolen” was declared but never referenced

//将label ip_send_nolen放入宏中
#if UIP_UDP
 ip_send_nolen:
#endif

7. uIP\core\uip.c(113): warning: #177-D: variable “all_ones_addr” was declared but never referenced
注释掉all_ones_addr变量
这里写图片描述

8. uIP\core\uip-neighbor.c(90): warning: #223-D: function “printf” declared implicitly
注释掉printf

9. uIP\core\uip-split.c(90): warning: #223-D: function “tcpip_output” declared implicitly
将tcpip_output注释掉
这里写图片描述

10. uIP\dev\tapdev.c(57): error: #20: identifier “uip_ethaddr” is undefined
uip_ethaddr这个变量的定义在uip.c中,在此处使用需要声明
这里写图片描述

extern struct uip_eth_addr uip_ethaddr;

11.若之前uip_conf.h中的log记录没有关闭,就会出现下述的linking错误
这里写图片描述

至此我们是0 Error(s),0 Warning(s)
由于这时我们没有调用uip相关的函数,所以这时程序的大小是和加入uip之前是一样的。

我们将uip/unix下的main.c中的main函数复制到新工程中,这时,STM32就可以响应ping命令了,这样一个简单的uIPdemo,大概占用了9K的FLASH,3K的RAM

【Reference】http://forum.eepw.com.cn/thread/262079/1/

posted @ 2015-11-01 16:50  水煮海鲜  阅读(1997)  评论(0编辑  收藏  举报