打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Uip + Stm32移植问题总结-Changing's Blog
#include "clock-arch.h"#include "stm32f10x.h"extern __IO int32_t g_RunTime;/*---------------------------------------------------------------------------*/clock_time_tclock_time(void){	return g_RunTime;}/*---------------------------------------------------------------------------*/
使用stm32 滴答定时器中断代码:
User/stm32f10x_it.c
__IO int32_t g_RunTime = 0;void SysTick_Handler(void){	static uint8_t s_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 表大小等。可以根据需要配置。
#define UIP_FIXEDADDR 1
决定uIP是否使用一个固定的IP地址。
如果uIP使用一个固定的IP地址,应该置位(set)这些uipopt.h中的选项。如果不的话,则应该使用宏uip_sethostaddr(),uip_setdraddr() 和 uip_setnetmask()。
#define UIP_PINGADDRCONF 0            Ping IP地址赋值。
#define UIP_FIXEDETHADDR 0            指明uIP ARP模块是否在编译时使用一个固定的以太网MAC地址。
#define UIP_TTL 255                           uIP发送的IP packets的IP TTL (time to live)。
#define UIP_REASSEMBLY 0                uIP支持IP packets的分片和重组。
#define UIP_REASS_MAXAGE 40          一个IP fragment在被丢弃之前可以在重组缓冲区中存在的最大时间。
#define UIP_UDP 0                              是否编译UDP的开关。
#define UIP_ACTIVE_OPEN 1                决定是否支持uIP打开一个连接。
#define UIP_CONNS 10                        同时可以打开的TCP连接的最大数目。由于TCP连接是静态分配的,减小这个数目将占用更少的RAM。每一个TCP连接需要大约30字节的内存。
#define UIP_LISTENPORTS 10                同时监听的TCP端口的最大数目。每一个TCP监听端口需要2个字节的内存。
#define UIP_RECEIVE_WINDOW 32768   建议的接收窗口的大小。如果应用程序处理到来的数据比较慢,那么应该设置的小一点(即,相对与uip_buf缓冲区的大小来说),相反如果应用程序处理数据很快,可以设置的大一点(32768字节)。
#define UIP_URGDATA 1                       决定是否支持TCP urgent data notification。
#define UIP_RTO 3                                The initial retransmission timeout counted in timer pulses.不要改变
#define UIP_MAXRTX 8                         在中止连接之前,应该重发一个段的最大次数。不要改变
#define UIP_TCP_MSS (UIP_BUFSIZE – UIP_LLH_LEN – 40)             TCP段的最大长度。它不能大于UIP_BUFSIZE – UIP_LLH_LEN – 40.
#define UIP_TIME_WAIT_TIMEOUT 120    一个连接应该在TIME_WAIT状态等待多长。不要改变
#define UIP_ARPTAB_SIZE 8                    ARP表的大小。如果本地网络中有许多到这个uIP节点的连接,那么这个选项应该设置为一个比较大的值。
#define UIP_BUFSIZE 1500                        uIP packet缓冲区不能小于60字节,但也不必大于1500字节。
#define UIP_STATISTICS 1                        决定是否支持统计数字。统计数字对调试很有帮助,并展示给用户。
#define UIP_LOGGING 0                        输出uIP登陆信息。
#define UIP_LLH_LEN 14                        链接层头部长度。对于SLIP,应该设置成0。
uip-conf.h 中增加几个主要结构体定义,不include任何应用
#define UIP_CONF_LOGGING         0                //logging offtypedef int uip_tcp_appstate_t;			//出错可注释typedef int uip_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
#include "stm32f10x.h"#ifndef UIP_APPCALL	#define UIP_APPCALL					Uip_Appcall#endif#ifndef UIP_UDP_APPCALL	#define UIP_UDP_APPCALL				Udp_Appcall#endifvoid Uip_Appcall(void);void Udp_Appcall(void);void Uip_Appcall(void){	}void Udp_Appcall(void){	}
4.加入uIP 的的主循环代码架构
User/main.c
#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"#define	 PRINTF_ON  1#define BUF ((struct uip_eth_hdr *)&uip_buf[0])#ifndef NULL#define NULL (void *)0#endif /* NULL */static unsigned char mymac[6] = {0x04,0x02,0x35,0x00,0x00,0x01};void RCC_Configuration(void);void GPIO_Configuration(void);void USART_Configuration(void);int main(void){	int i;	uip_ipaddr_t ipaddr;	struct timer periodic_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();				/* If the above function invocation resulted in data that				   should be sent out on the network, the global variable uip_len is set to a value > 0. */				if(uip_len > 0) 				{				  uip_arp_out();				  tapdev_send();				}	      	}else if(BUF->type == htons(UIP_ETHTYPE_ARP)){	 //如果收到的是ARP数据,调用uip_arp_arpin处理				uip_arp_arpin();				/* If the above function invocation resulted in data that				   should be sent out on the network, the global variable uip_len is set to a value > 0. */				if(uip_len > 0) 				{				  tapdev_send();				}		    }		    }else if(timer_expired(&periodic_timer)){			//查看0.5s是否到了,调用uip_periodic处理TCP超时程序		      timer_reset(&periodic_timer);		      for(i = 0; i < UIP_CONNS; i++) {						uip_periodic(i);						/* If the above function invocation resulted in data that					   should be sent out on the network, the global variable uip_len is set to a value > 0. */						if(uip_len > 0) 					{					  uip_arp_out();					  tapdev_send();					}		      }										  	  for(i = 0; i < UIP_UDP_CONNS; i++) 			  {						uip_udp_periodic(i);								//处理udp超时程序						/* If the above function invocation resulted in data that					   should be sent out on the network, the global variable uip_len is set to a value > 0. */						if(uip_len > 0) 					{					  uip_arp_out();					  tapdev_send();					}		      }	      		      /* Call the ARP timer function every 10 seconds. */			 //10s到了就处理ARP		      if(timer_expired(&arp_timer)) 			  {					timer_reset(&arp_timer);					uip_arp_timer();		      }	    }	}}/*******************************Stm32 Set***************************************/void GPIO_Configuration(void){  	GPIO_InitTypeDef GPIO_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); }void RCC_Configuration(void){	/* 定义枚举类型变量 HSEStartUpStatus */	ErrorStatus HSEStartUpStatus;  	/* 复位系统时钟设置*/  	RCC_DeInit();  	/* 开启HSE*/  	RCC_HSEConfig(RCC_HSE_ON);  	/* 等待HSE起振并稳定*/  	HSEStartUpStatus = RCC_WaitForHSEStartUp();	/* 判断HSE起是否振成功,是则进入if()内部 */  	if(HSEStartUpStatus == SUCCESS)  	{    	/* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */    	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)时钟源为HSE 1分频,倍频数为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);		} void USART_Configuration(void){	USART_InitTypeDef USART_InitStructure;	USART_ClockInitTypeDef USART_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);}#if	 PRINTF_ONint fputc(int ch,FILE *f){	USART_SendData(USART1,(u8) ch);	while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);	return ch;}#endif
5.解决编译过程中的错误。归总如下:
  • Uip/uip-split.c  注释所有的 tcpip_output()函数  消除uip_fw_output()函数的注释
  • Uip/memb.c 中 memb_free()函数 返回值 return -1 改为 return 1
  • Apps/resolv.c 中resolv_conf() 中 
                 //resolv_conn = uip_udp_new(dnsserver, HTONS(53));
                  resolv_conn = uip_udp_new((uip_ipaddr_t*)dnsserver, HTONS(53));
解决完所有问题后,编译成功后下载到stm32,ping 测试。。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Uip + Stm32移植问题总结
关于uIP移植以及部分特性解析和勘误
uIP协议栈分析
一种uIP TCP/IP协议栈在51系列单片机上的实现
LWIP UDP 协议分析
C语言基础:do{...}while(0)的使用,很秀
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服