网络上关于uIP协议栈的文章不少,大多是讲解自带的http服务器为例子,没有过多的说明作为CS客户端在实际中的应用。
本文主要讲述ENC28J60和uIP协议栈作为CS模式在客户端的应用,即采用主动连接与服务器进行用户数据交互,保持长连接,支持自动重连。
编译器:Keil3 C51 8.18 uIP版本:0.9 ENC28J60:ENC28J60-I/SO 28-Lead SOIC 单片机:SST89E516RD(1K RAM,64K program ROM 支持在线仿真,兼容51单片机) STC89C58RD+ (512 RAM 32K program ROM)烧录测试
特点:查询方式收包,定时更新ARP缓存表,协议栈、收、发共用缓存(内存开销少) 事件回调函数uip_appcall() 支持ICMP/TCP/UDP,端口监听,主/被动连接 2 代码文件结构图:2.1 文件列表:2.2 代码流程图:3 系统开销:对于一个完成的TCP /IP协议栈来说,uIP算占用资源比较少的,根据实际应用,本例将去除了demo程序中自带的http服务器,fs部分,将连接数、监听端口表、ARP缓存表大小都设置为1,关掉日志,统计信息,重组包,把系统开销降到更低。
下表描述uIP系统主要开销情况(估算):
如果自己新建工程使用本例代码,请将工程属性“Target->Memocy Mode”设置成:Large: variables in XDATA,即使用最大外部内存,否则将产生编译错误,提示内存不足,因为uIP的RAM开销超过了单片机内部内存128字节(超出mov寻址范围),所以需要movx来完成更多内存访问,有些单片机都内置了外存,打开此选项,Keil C51 C编译器会自动完成外部内存访问。
4 网卡硬件原理图:下图为ENC28J60网卡的参考设计图,SCK,CS,SO,SI直接PIN TO PIN接到单片机(SI和SO不需要反接,不同于串口的是SPI的SO,SI都是相对于slave而言的),有些单片自带SPI接口,例如本例中使用的SST89E516RD,但我们程序中仍然采用IO口模拟SPI方式,通用性更好。
5 SPI接口驱动:本例SPI接口采用单片机IO口模拟,只需根据实际的硬件电路设计(IO口需要上/下拉电阻),在spi.h文件中修改IO脚定义即可,需要注意的是ENC28J60采用SPI0模式,即时钟信号上升沿接收数据,下降沿发送数据,本例中SPI通讯时序已经调通,可以直接使用,至少要接SCK,CS,SI,SO即可,INT没有使用,可以不接,如果接上,ENC28J60驱动代码已经开启了接收中断,程序中可以接收到,但在使用中断模式时,请考虑收,发包的同步情况,比如:网卡支持全双工模式,正在发送包时,又收到一个包产生中断,而uIP协议栈是共用缓存的(为节约内存),如果再次去调用协议栈,会将协议栈缓存出错。 spi.h
SPI相关讯息请参考其它资料,本例略。
6 ENC28J60驱动:ENC28J60除初始化enc28j60_init()外,还需要提供两个主要原生数据收发接口函数给uIP协议栈:enc28j60PacketReceive()网卡收数据,enc28j60PacketSend()网卡发数据。
本例中ENC28J60驱动已经调试成功,可以直接使用,在此只做简单说明,更详细请参考相关手册。
注:ENC28J60初始化会等待网卡应答,错误无法进入系统。 7 uIP协议栈TCP应用demo:7.1 uIP代码结构:7.2 main.c代码说明:
8 应用程序接口uip_appcall():对于处理应用数据的用户,对uIP整个流程做一个了解即可,uIP将处理后的结果全部都回调到uip_appcall()函数统一处理,所以重点需要完成的工作全部在uip_appcall()函数中,以下介绍一个demo代码:
已开启主动连接功能uip.h 行300 #define UIP_ACTIVE_OPEN 1
8.1 uip_send 使用举例:uip_send(uip_appdata,sprintf((char*)uip_appdata,"%s","Hello,Iconnected to you! thanks"));
uip_send("idle",4);
注:uip_send并没有真正将数据发送到物理网卡,也不保证数据正确到达,仅将数据存储到uIP协议栈中,由uIP来决定发送到物理网卡(空闲时),结果将产生回调,根据事件代码进行相应处理,如:收到ACK,可继续下一包,超时重连,重发等。 9 配置参数:实际应用中MAC地址,IP地址,网关地址,服务器地址,端口号,应该是可以动态设置的,而MAC,IP地址(除VLAN外)在同一网络中必须是唯一的,否则导致网络不可用。
MAC地址可以在烧录程序时让烧录程序(或烧录器)自动加一,写到ROM固定位置,出厂时就设定好,但是MAC地址是有标准的,去IEEE申请还没有这个必要,可以借用其它厂家的,或是用01:02:34:56:78:90:AB这样累加的地址,但MAC地址冲突或不可用这种情况是会有的,比如有些交换机是会拒接一些MAC地址的,还有就是与部分网卡MAC冲突等。
本机IP,服务器IP,网关,端口号这些地址必须是可供用户修改的,出厂时无法确定用户的网络环境,需要提供UI供用户修改并保存到E2PROM或其它Flash中。
以下为各自参数配置代码位置: 9.1 用户设定:初始化时将从E2PROM或flash中读取的设置参数替换以下处即可:
9.2 固定(仅供测试):以下是固定地址,由编译时决定,出厂后无法修改,不建议使用:
10 uIP协议栈事件列表:见uip.h 行:493-600,大部分事件已在demo代码中描述。 uipotp.h uIP协议栈的配置参数 11 常见问题:测试中发现windows操作系统,会出现TCP checksum错误,导致丢包现象,是由于网卡硬件校验原因:
解决办法: 网卡配置->高级->Rx Checksum Offload/Tx Checksum Offload,很可能你的这两处
|
|
来自: 汉江秋月夜 > 《14101-stm32_tcp/ip》