单芯片解决方案,开启全新体验——W55MH32高性能以太网单片机
W55MH32是WIZnet重磅推出的高性能以太网单片机,它为用户带来前所未有的集成化体验。这颗芯片将强大的组件集于一身,具体来说,一颗W55MH32内置高性能Arm® Cortex-M3核心,其主频最高可达216MHz;配备1024KB FLASH与96KB SRAM,满足存储与数据处理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP协议栈、内置MAC以及PHY,拥有独立的32KB以太网收发缓存,可供8个独立硬件socket使用。如此配置,真正实现了All-in-One解决方案,为开发者提供极大便利。
在封装规格上,W55MH32提供了两种选择:QFN100和QFN68。
W55MH32L采用QFN100封装版本,尺寸为12x12mm,其资源丰富,专为各种复杂工控场景设计。它拥有66个GPIO、3个ADC、12通道DMA、17个定时器、2个I2C、5个串口、2个SPI接口(其中1个带I2S接口复用)、1个CAN、1个USB2.0以及1个SDIO接口。如此丰富的外设资源,能够轻松应对工业控制中多样化的连接需求,无论是与各类传感器、执行器的通信,还是对复杂工业协议的支持,都能游刃有余,成为复杂工控领域的理想选择。同系列还有QFN68封装的W55MH32Q版本,该版本体积更小,仅为8x8mm,成本低,适合集成度高的网关模组等场景,软件使用方法一致。更多信息和资料请进入http://www.w5500.com/网站或者私信获取。
此外,本W55MH32支持硬件加密算法单元,WIZnet还推出TOE+SSL应用,涵盖TCP SSL、HTTP SSL以及 MQTT SSL等,为网络通信安全再添保障。
为助力开发者快速上手与深入开发,基于W55MH32L这颗芯片,WIZnet精心打造了配套开发板。开发板集成WIZ-Link芯片,借助一根USB C口数据线,就能轻松实现调试、下载以及串口打印日志等功能。开发板将所有外设全部引出,拓展功能也大幅提升,便于开发者全面评估芯片性能。
若您想获取芯片和开发板的更多详细信息,包括产品特性、技术参数以及价格等,欢迎访问官方网页:http://www.w5500.com/,我们期待与您共同探索W55MH32的无限可能。

第四章 W55MH32 TCP Server示例
本篇文章,我们将详细介绍如何在W55MH32芯片上面实现TCP通信。并通过实战例程,为大家讲解如何使用W55MH32作为TCP Server进行数据回环测试,有关TCP协议的简介以及特点,请参考TCP Client章节。
该例程用到的其他网络协议,例如DHCP,请参考相关章节。有关W55MH32的初始化过程,也请参考相关章节,这里将不再赘述。
1 TCP协议简介
TCP (Transmission Control Protocol)是一种面向连接的、可靠的传输层协议,它用于在网络中可靠地传输数据。TCP是互联网协议族中的核心协议之一,通常与 IP协议(Internet Protocol)一起使用,形成套接字通信。
2 TCP协议特点
面向连接:在传输数据之前,TCP需要建立一个连接,保证发送方与接收方能够彼此通信。通过三次握手(Three-Way Handshake)过程来建立连接,确保双方的通信是可靠的。
可靠性:TCP提供可靠的数据传输,确保数据完整并且按顺序到达接收端。如果数据丢失或出错,TCP会自动重传丢失的数据包。
流量控制:TCP使用流量控制机制来调节数据的发送速度,防止接收方处理不过来导致数据丢失。常用的流量控制方法是滑动窗口(Sliding Window)。
拥塞控制:TCP可以动态调整传输速率,以避免网络拥塞。采用算法如慢启动、拥塞避免、快速重传等。
全双工通信:在 TCP连接建立后,数据可以在两个方向同时进行传输,支持双向通信。
有序数据传输:TCP会对数据包进行编号,确保数据按顺序传输,即使网络发生延迟,接收端也能按顺序接收到数据。
字节流服务:TCP传输的数据是字节流,不关心应用层数据的边界,应用层需要自己解析数据边界。
3 TCP与 UDP的区别
TCP是可靠的、面向连接的协议,适合需要数据完整性和顺序保证的应用,如网页浏览、文件传输等。
UDP(User Datagram Protocol)是无连接、不可靠的协议,适合对时效性要求较高且可以容忍丢包的应用,如视频流、在线游戏等。
4 TCP应用场景
接下来,我们了解下在W55MH32上,可以使用TCP协议完成哪些操作及应用呢?
远程监控和数据采集:嵌入式设备通常用于采集传感器数据,并通过以太网连接上传到远程服务器,TCP协议确保数据传输的可靠性和完整性。
设备远程控制:许多嵌入式系统需要通过网络接收控制指令(例如工业自动化中的PLC控制),TCP协议提供了可靠的通信通道。
物联网(IoT):许多物联网设备使用TCP协议与云服务器或其他设备进行通信,传输数据、执行命令等。
嵌入式Web服务器:一些嵌入式设备内置Web服务器(例如路由器、网关、传感器设备等),通过TCP协议提供网页接口给用户进行配置和监控。
5使用TCP进行数据交互的流程
TCP连接建立(三次握手)
在开始传输数据之前,TCP会通过三次握手建立连接:
第一次握手:客户端向服务器发送一个带有 SYN标志的数据包,表示请求建立连接。
第二次握手:服务器收到 SYN数据包后,回复一个带有 SYN和 ACK标志的数据包,表示同意建立连接。
第三次握手:客户端收到服务器的 SYN+ACK后,发送一个带有 ACK标志的数据包,连接建立完成。
数据交互
TCP连接断开(四次挥手)
当通信结束时,TCP需要通过四次挥手来断开连接:
第一次挥手:客户端发送一个 FIN数据包,表示数据发送完毕,准备关闭连接。
第二次挥手:服务器收到 FIN数据包后,回复一个 ACK数据包,表示同意关闭连接。
第三次挥手:服务器发送一个 FIN数据包,表示数据发送完毕,准备关闭连接。
第四次挥手:客户端收到服务器的 FIN数据包后,发送一个 ACK数据包,连接正式关闭。
ACK字段:ACK包含在 TCP报文头中,表示接收方期望接收的下一个字节的序列号。

TCP 3次握手示意图
TCP 4次挥手示意图
6 TCP的ACK机制、重传机制和Keepalive机制
TCP的ACK机制
ACK是 TCP用于确认已成功接收到数据包的机制。在 TCP通信中,每个数据包都包含一个序列号,接收方用 ACK来告诉发送方已经成功收到的字节序列。
累积确认:TCP使用累积确认方式,表示接收方已经连续收到所有数据,直到某个序列号为止。
超时重传:如果发送方在超时时间内未收到 ACK,就会重传该数据包。
TCP的重传机制
TCP的重传机制保证了数据的可靠传输。以下是常见的重传机制:
超时重传:
发送方设置一个定时器,当发送的数据包在规定时间内未收到 ACK,则触发重传。
超时时间是动态调整的,由 TCP的往返时间(RTT, Round Trip Time)估算得出。
快速重传:
当接收方发现数据包丢失时,发送重复的 ACK(称为冗余 ACK),提醒发送方某个数据包未到达。
如果发送方连续收到 3个重复的 ACK,就会立即重传对应的数据包,而不必等待超时。
选择性重传(Selective Repeat, SACK):
在累积确认的基础上,TCP还可以通过 SACK选项告诉发送方哪些特定的块已收到,哪些未收到。
这可以减少不必要的重传,提高效率。
TCP Keepalive 机制
TCP Keepalive是 TCP协议的一种可选机制,用于检测长时间空闲的连接是否仍然有效。它的主要作用是:
维护连接状态:检测对方主机是否仍在线,避免资源被长期占用。
释放死连接:如果连接已经失效(如网络中断或对方主机崩溃),Keepalive可以及时释放资源。
防止中间设备超时关闭连接:一些 NAT、路由器或防火墙可能会在连接长时间不活动时自动关闭,Keepalive可防止这种情况。
用法:在W55MH32的TOE引擎中,需要在Sn_KPALVTR寄存器中设置Keepalive时间,然后在成功连接服务器后发送一条数据来激活Keepalive。
7实现过程
接下来,我们一起来看看如何在W55MH32上实现TCP服务器模式,监听端口并进行回环测试。
注意:测试实例需要PC端和W55MH32处于同一网段。
步骤1:开启TCP KeepAlive功能(避免出现假连接情况)
在W55MH32中,KeepAlive的时间单元为5秒,因为设我们设置6个单元,即30秒发送1次KeepAlive报文。
/* Enable keepalive,Parameter 2 is the keep alive time, with a unit of 5 seconds */ setSn_KPALVTR(SOCKET_ID, 6); // 30s keepalive
步骤2:在主循环中运行TCP Server回环测试程序
while (1) { loopback_tcps(SOCKET_ID, ethernet_buf, local_port); }
loopback_tcps()函数的三个传参分别为,SOCKET ID,交互的缓存数组,本地端口号。
示例的本地端口号为:8080。
loopback_tcps()函数内容如下:
/** * @brief tcp server loopback test * @param sn: socket number * @param buf: Data sending and receiving cache * @param port: Listen port * @return value for SOCK_ERRORs,return 1:no error */ int32_t loopback_tcps(uint8_t sn, uint8_t *buf, uint16_t port) { int32_t ret; uint16_t size = 0, sentsize = 0; #ifdef _LOOPBACK_DEBUG_ uint8_t destip[4]; uint16_t destport; #endif switch (getSn_SR(sn)) { case SOCK_ESTABLISHED: if (getSn_IR(sn) & Sn_IR_CON) { #ifdef _LOOPBACK_DEBUG_ getSn_DIPR(sn, destip); destport = getSn_DPORT(sn); printf("%d:Connected - %d.%d.%d.%d : %drn", sn, destip[0], destip[1], destip[2], destip[3], destport); #endif #if KEEPALIVE_ENABLE == 1 // We need to send a packet of data to activate keepalive ret = send(sn, (uint8_t *)"", 1); // Data send process if (ret < 0) // Send Error occurred (sent data length < 0) { close(sn); // socket close return ret; } #endif setSn_IR(sn, Sn_IR_CON); } if ((size = getSn_RX_RSR(sn)) > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur. { if (size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; ret = recv(sn, buf, size); if (ret <= 0) return ret; // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY. size = (uint16_t)ret; sentsize = 0; buf[size] = 0x00; printf("rece data:%srn", buf); while (size != sentsize) { ret = send(sn, buf + sentsize, size - sentsize); if (ret < 0) { close(sn); return ret; } sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. } } break; case SOCK_CLOSE_WAIT: #ifdef _LOOPBACK_DEBUG_ printf("%d:CloseWaitrn", sn); #endif if ((ret = disconnect(sn)) != SOCK_OK) return ret; #ifdef _LOOPBACK_DEBUG_ printf("%d:Socket Closedrn", sn); #endif break; case SOCK_INIT: #ifdef _LOOPBACK_DEBUG_ printf("%d:Listen, TCP server loopback, port [%d]rn", sn, port); #endif if ((ret = listen(sn)) != SOCK_OK) return ret; break; case SOCK_CLOSED: #ifdef _LOOPBACK_DEBUG_ printf("%d:TCP server loopback startrn", sn); #endif if ((ret = socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; #ifdef _LOOPBACK_DEBUG_ printf("%d:Socket openedrn", sn); #endif break; default: break; } return 1; }
在这个程序中,会运行TCP Server状态机,基于SOCKET不同的状态执行对应的操作,SOCKET的状态变化如下图所示:

SOCK_CLOSED:当前SOCKET未打开,配置连接服务器及连接端口号后打开SOCKET,打开成功后SOCKET会进入SOCK_INIT状态。
SOCK_INIT:SOCKET打开成功,开始监听端口,当有客户端进行连接时,SOCKET状态改为SOCK_ESTABLISHED。
SOCK_ESTABLISHED:首先清除连接成功中断,并发送1包数据激活KeepAlive,然后读取Sn_RX_RSR(空闲接收缓存寄存器)寄存器值,当收到服务器数据时,Sn_RX_RSR寄存器的值会大于0,此时我们将接收到的数据打印并将数据回环发送。
SOCK_CLOSE_WAIT:当客户端主动断开连接时,SOCKET状态改为SOCK_CLOSE_WAIT状态,这是一个半关闭状态,可以进行关闭前最后的数据传输。使用disconnect()函数彻底断开连接时,SOCKET状态将改为SOCK_CLOSED状态。
8运行结果
烧录例程运行后,首先进行了PHY链路检测,然后是通过DHCP获取网络地址并打印网络地址信息,最后则是进行TCP数据回环测试,当客户端未连接时,会一直监听,等待客户端连接。

接下来我们打开SocketTester网络调试工具,设置为TCP Client模式,输入W55MH32的IP地址和端口后进行连接,然后就能看到W55MH32打印客户端连接信息了,最后用SocketTester向W55MH32发送数据进行回环测试。

9总结
本文介绍在 W55MH32芯片上实现 TCP服务器模式进行数据回环测试的方法。先回顾 TCP协议相关知识,接着展示实现过程,包括开启 Keepalive功能,在主循环运行测试程序。程序依据 SOCKET不同状态执行操作,状态从关闭、初始化、监听,到连接建立、关闭等待。烧录例程后经 PHY链路检测、获取网络地址,借助网络调试工具完成测试。
下一篇将讲解在该芯片上实现 UDP通信及数据回环测试,介绍 UDP相关原理和实现步骤。敬请期待!
WIZnet是一家无晶圆厂半导体公司,成立于 1998年。产品包括互联网处理器 iMCU™,它采用 TOE(TCP/IP卸载引擎)技术,基于独特的专利全硬连线 TCP/IP。iMCU™面向各种应用中的嵌入式互联网设备。
WIZnet在全球拥有 70多家分销商,在香港、韩国、美国设有办事处,提供技术支持和产品营销。
香港办事处管理的区域包括:澳大利亚、印度、土耳其、亚洲(韩国和日本除外)。
审核编辑 黄宇
-
以太网
+关注
关注
41文章
5925浏览量
179550 -
物联网
+关注
关注
2939文章
47325浏览量
407989 -
TCP
+关注
关注
8文章
1418浏览量
83026
发布评论请先 登录
第三十章 W55MH32 HTTP_Server&NetBIOS示例
第二十九章 W55MH32 Modbus_TCP_Server示例
第二十六章 W55MH32 上位机搜索和配置示例
第二十五章 W55MH32 TCP_Server_Multi_Socket示例
第二十四章 W55MH32TCP_Client_Multi_Socket示例
第十八章 W55MH32 FTP_Server示例
第十六章 W55MH32 PING示例
第十五章 W55MH32 SNMP示例
第十四章 W55MH32 TFTP示例
第十章 W55MH32 SNTP示例
第九章 W55MH32 HTTP Server示例
第六章 W55MH32 UDP Multicast示例
第五章 W55MH32 UDP示例
第三章 W55MH32 TCP Client示例
第二章 W55MH32 DHCP示例

第四章 W55MH32 TCP Server示例
评论