uip学习记录.docx

上传人:b****6 文档编号:6618661 上传时间:2023-01-08 格式:DOCX 页数:16 大小:20.60KB
下载 相关 举报
uip学习记录.docx_第1页
第1页 / 共16页
uip学习记录.docx_第2页
第2页 / 共16页
uip学习记录.docx_第3页
第3页 / 共16页
uip学习记录.docx_第4页
第4页 / 共16页
uip学习记录.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

uip学习记录.docx

《uip学习记录.docx》由会员分享,可在线阅读,更多相关《uip学习记录.docx(16页珍藏版)》请在冰豆网上搜索。

uip学习记录.docx

uip学习记录

1.要知道uip是TCP/IP协议族一种简化并实现的协议栈。

实现TCP/IP协议有uip还有lwip,这两种是比较常用的协议栈,在嵌入式应用中发挥了作用。

2.uip可以作为webclient向指定的网站提交数据,也可以作为一个webserver作为网页服务器,提供一个小型的动态页面访问功能。

3.uip用到的rom有6kb,而ram只有几百字节,相对于lwip更适合于非操作系统的单片机。

Uip的文件架构

学习uip需要知道uip协议里到底都有那些东东?

1uip_app;uip_lib,uip本身核心代码,uip底层驱动与以太网控制器模块有关,

Uip_app是uip的一些应用示例程序smtp,rsolve,dhcp,telnetd,以及webclient。

Lib里边是memb.c是分配内存的文件。

Uip里边有uip.ctimer.c因为要为TCP和ARP提供定时器服务,比如心跳包,刷新老化程序需要有定时器的配置。

如果使用ENC28U60,还需要ENC28U60.H

Uip的数据通过网卡Enc28j60从物理层剥离,所以需要先配置Uip和Enc28j60的数据交互。

这个部分在tapdev.c文件中:

tapdev_init():

网卡初始化函数,初始化网卡的工作模式。

tapdev_read(void):

读包函数。

将网卡收到的数据放入全局缓存区uip_buf中,返回包的长度,赋给uip_len。

voidtapdev_send(void):

发包函数。

将全局缓存区uip_buf里的数据(长度放在uip_len中)发送出去。

在uip1.0中,clock_archo。

C是用来管理时钟的。

├─appsapps目录下为uip提供的一些应用示例

│├─dhcpc

│├─hello-world

│├─resolv

│├─smtp

│├─telnetd

│├─webclient

│└─webserver

||___tcpclient

||___tcpcserver

│└─httpd-fs

├─docdoc下放置的为说明文档,程序中用不上

│└─html

├─liblib下为内存块管理函数源码

├─uipuip下为uip和核心实现源码

└─unixunix环境里的uip应用例子,可以参照这个例子实现应用

 

2

3

4

5

6

7

8

9

10

11

#include"clock-arch.h"

#include"stm32f10x.h"

extern__IOint32_tg_RunTime;

/*---------------------------------------------------------------------------*/

clock_time_t

clock_time(void)

{

returng_RunTime;

}

/*---------------------------------------------------------------------------*/

使用stm32滴答定时器中断代码:

User/stm32f10x_it.c

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

__IOint32_tg_RunTime=0;

voidSysTick_Handler(void)

{

staticuint8_ts_count=0;

if(++s_count>=10)

{

s_count=0;

g_RunTime++;/*全局运行时间每10ms增1*/

if(g_RunTime==0x80000000)

{

g_RunTime=0;

}

}

}

 

3.uipopt.h/uip-conf.h是配置文件,用来设置本地的IP地址、网关地址、MAC地址、全局缓冲区的大小、支持的最大连接数、侦听数、ARP表大小等。

可以根据需要配置。

#defineUIP_FIXEDADDR1

决定uIP是否使用一个固定的IP地址。

如果uIP使用一个固定的IP地址,应该置位(set)这些uipopt.h中的选项。

如果不的话,则应该使用宏uip_sethostaddr(),uip_setdraddr()和uip_setnetmask()。

#defineUIP_PINGADDRCONF0PingIP地址赋值。

#defineUIP_FIXEDETHADDR0指明uIPARP模块是否在编译时使用一个固定的以太网MAC地址。

#defineUIP_TTL255uIP发送的IPpackets的IPTTL(timetolive)。

#defineUIP_REASSEMBLY0uIP支持IPpackets的分片和重组。

#defineUIP_REASS_MAXAGE40一个IPfragment在被丢弃之前可以在重组缓冲区中存在的最大时间。

#defineUIP_UDP0是否编译UDP的开关。

#defineUIP_ACTIVE_OPEN1决定是否支持uIP打开一个连接。

#defineUIP_CONNS10同时可以打开的TCP连接的最大数目。

由于TCP连接是静态分配的,减小这个数目将占用更少的RAM。

每一个TCP连接需要大约30字节的内存。

#defineUIP_LISTENPORTS10同时监听的TCP端口的最大数目。

每一个TCP监听端口需要2个字节的内存。

#defineUIP_RECEIVE_WINDOW32768建议的接收窗口的大小。

如果应用程序处理到来的数据比较慢,那么应该设置的小一点(即,相对与uip_buf缓冲区的大小来说),相反如果应用程序处理数据很快,可以设置的大一点(32768字节)。

#defineUIP_URGDATA1决定是否支持TCPurgentdatanotification。

#defineUIP_RTO3Theinitialretransmissiontimeoutcountedintimerpulses.不要改变

#defineUIP_MAXRTX8在中止连接之前,应该重发一个段的最大次数。

不要改变

#defineUIP_TCP_MSS(UIP_BUFSIZE–UIP_LLH_LEN–40)TCP段的最大长度。

它不能大于UIP_BUFSIZE–UIP_LLH_LEN–40.

#defineUIP_TIME_WAIT_TIMEOUT120一个连接应该在TIME_WAIT状态等待多长。

不要改变

#defineUIP_ARPTAB_SIZE8ARP表的大小。

如果本地网络中有许多到这个uIP节点的连接,那么这个选项应该设置为一个比较大的值。

#defineUIP_BUFSIZE1500uIPpacket缓冲区不能小于60字节,但也不必大于1500字节。

#defineUIP_STATISTICS1决定是否支持统计数字。

统计数字对调试很有帮助,并展示给用户。

#defineUIP_LOGGING0输出uIP登陆信息。

#defineUIP_LLH_LEN14链接层头部长度。

对于SLIP,应该设置成0。

uip-conf.h中增加几个主要结构体定义,不include任何应用

1

2

3

4

5

6

7

8

9

10

11

12

13

14

#defineUIP_CONF_LOGGING0//loggingoff

typedefintuip_tcp_appstate_t;//出错可注释

typedefintuip_udp_appstate_t;//出错可注释

/*#include"smtp.h"*/

/*#include"hello-world.h"*/

/*#include"telnetd.h"*/

/*#include"webserver.h"*/

/*#include"dhcpc.h"*/

/*#include"resolv.h"*/

/*#include"webclient.h"*/

#include"app_call.h"//加入一个Uip的数据接口文件

uIP在接受到底层传来的数据包后,调用UIP_APPCALL(),将数据送到上层应用程序处理。

User/app_call.c

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

#include"stm32f10x.h"

#ifndefUIP_APPCALL

#defineUIP_APPCALLUip_Appcall

#endif

#ifndefUIP_UDP_APPCALL

#defineUIP_UDP_APPCALLUdp_Appcall

#endif

voidUip_Appcall(void);

voidUdp_Appcall(void);

voidUip_Appcall(void)

{

}

voidUdp_Appcall(void)

{

}

4.加入uIP的的主循环代码架构

User/main.c

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

1

#include"stm32f10x.h"

#include"stdio.h"

#include"string.h"

#include"uip.h"

#include"uip_arp.h"

#include"tapdev.h"

#include"timer.h"

#include"ENC28J60.h"

#include"SPI.h"

#definePRINTF_ON1

#defineBUF((structuip_eth_hdr*)&uip_buf[0])

#ifndefNULL

#defineNULL(void*)0

#endif/*NULL*/

staticunsignedcharmymac[6]={0x04,0x02,0x35,0x00,0x00,0x01};

voidRCC_Configuration(void);

voidGPIO_Configuration(void);

voidUSART_Configuration(void);

intmain(void)

{

inti;

uip_ipaddr_tipaddr;

structtimerperiodic_timer,arp_timer;

RCC_Configuration();

GPIO_Configuration();

USART_Configuration();

SPInet_Init();

timer_set(&periodic_timer,CLOCK_SECOND/2);

timer_set(&arp_timer,CLOCK_SECOND*10);

SysTick_Config(72000);//配置滴答计时器

//以太网控制器驱动初始化

tapdev_init(mymac);

//Uip协议栈初始化

uip_init();

uip_ipaddr(ipaddr,192,168,1,15);//配置Ip

uip_sethostaddr(ipaddr);

uip_ipaddr(ipaddr,192,168,1,1);//配置网关

uip_setdraddr(ipaddr);

uip_ipaddr(ipaddr,255,255,255,0);//配置子网掩码

uip_setnetmask(ipaddr);

while

(1){

uip_len=tapdev_read();//从网卡读取数据

if(uip_len>0)

{//如果数据存在则按协议处理

if(BUF->type==htons(UIP_ETHTYPE_IP)){//如果收到的是IP数据,调用uip_input()处理

uip_arp_ipin();

uip_input();

/*Iftheabovefunctioninvocationresultedindatathat

shouldbesentoutonthenetwork,theglobalvariableuip_lenissettoavalue>0.*/

if(uip_len>0)

{

uip_arp_out();

tapdev_send();

}

}elseif(BUF->type==htons(UIP_ETHTYPE_ARP)){//如果收到的是ARP数据,调用uip_arp_arpin处理

uip_arp_arpin();

/*Iftheabovefunctioninvocationresultedindatathat

shouldbesentoutonthenetwork,theglobalvariableuip_lenissettoavalue>0.*/

if(uip_len>0)

{

tapdev_send();

}

}

}elseif(timer_expired(&periodic_timer)){//查看0.5s是否到了,调用uip_periodic处理TCP超时程序

timer_reset(&periodic_timer);

for(i=0;i

uip_periodic(i);

/*Iftheabovefunctioninvocationresultedindatathat

shouldbesentoutonthenetwork,theglobalvariableuip_lenissettoavalue>0.*/

if(uip_len>0)

{

uip_arp_out();

tapdev_send();

}

}

for(i=0;i

{

uip_udp_periodic(i);//处理udp超时程序

/*Iftheabovefunctioninvocationresultedindatathat

shouldbesentoutonthenetwork,theglobalvariableuip_lenissettoavalue>0.*/

if(uip_len>0)

{

uip_arp_out();

tapdev_send();

}

}

/*CalltheARPtimerfunctionevery10seconds.*///10s到了就处理ARP

if(timer_expired(&arp_timer))

{

timer_reset(&arp_timer);

uip_arp_timer();

}

}

}

}

/*******************************Stm32Set***************************************/

voidGPIO_Configuration(void)

{

GPIO_InitTypeDefGPIO_InitStructure;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;

GPIO_Init(GPIOA,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA,&GPIO_InitStructure);

}

voidRCC_Configuration(void)

{

/*定义枚举类型变量HSEStartUpStatus*/

ErrorStatusHSEStartUpStatus;

/*复位系统时钟设置*/

RCC_DeInit();

/*开启HSE*/

RCC_HSEConfig(RCC_HSE_ON);

/*等待HSE起振并稳定*/

HSEStartUpStatus=RCC_WaitForHSEStartUp();

/*判断HSE起是否振成功,是则进入if()内部*/

if(HSEStartUpStatus==SUCCESS)

{

/*选择HCLK(AHB)时钟源为SYSCLK1分频*/

RCC_HCLKConfig(RCC_SYSCLK_Div1);

/*选择PCLK2时钟源为HCLK(AHB)1分频*/

RCC_PCLK2Config(RCC_HCLK_Div1);

/*选择PCLK1时钟源为HCLK(AHB)2分频*/

RCC_PCLK1Config(RCC_HCLK_Div2);

/*设置FLASH延时周期数为2*/

FLASH_SetLatency(FLASH_Latency_2);

/*使能FLASH预取缓存*/

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

/*选择锁相环(PLL)时钟源为HSE1分频,倍频数为9,则PLL输出频率为8MHz*9=72MHz*/

RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);

/*使能PLL*/

RCC_PLLCmd(ENABLE);

/*等待PLL输出稳定*/

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);

/*选择SYSCLK时钟源为PLL*/

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

/*等待PLL成为SYSCLK时钟源*/

while(RCC_GetSYSCLKSource()!

=0x08);

}

/*打开APB2总线上的GPIOA时钟*/

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);

}

voidUSART_Configuration(void)

{

USART_InitTypeDefUSART_InitStructure;

USART_ClockInitTypeDefUSART_ClockInitStructure;

USART_ClockInitStructure.USART_Clock=USART_Clock_Disable;

USART_ClockInitStructure.USART_CPOL=USART_CPOL_Low;

USART_ClockInitStructure.USART_CPHA=USART_CPHA_2Edge;

USART_ClockInitStructure.USART_LastBit=USART_LastBit_Disable;

USART_ClockInit(USART1,&USART_ClockInitStructure);

USART_InitStructure.USART_BaudRate=9600;

USART_InitStructure.USART_WordLength=USART_WordLength_8b;

USART_InitStructure.USART_StopBits=USART_StopBits_1;

USART_InitStructure.USART_Parity=USART_Parity_No;

USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;

USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;

USART_Init(USART1,&USART_InitStructure);

USART_Cmd(USART1,ENABLE);

}

#ifPRINTF_ON

intfputc(intch,FILE*f)

{

USART_SendData(USART1,(u8)ch);

while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);

returnc

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1