单芯片解决方案,开启全新体验——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 Client示例
本篇文章,我们将详细介绍如何在W55MH32芯片上面实现TCP通信。使用W55MH32的TOE引擎,我们只需进行简单的socket编程及寄存器读写,便可轻松实现TCP协议应用。接下来我们通过实战例程,为大家讲解如何使用TOE引擎进行TCP Client模式的数据回环测试。
该例程用到的其他网络协议,例如DHCP,请参考相关章节。有关W55MH32的初始化过程,请参考Network Install章节,这里将不再赘述。
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处于同一网段。
步骤一:开启TCP Keepalive功能
在W55MH32中,KeepAlive的时间单元为5秒,这里我们设置6个单元,则W55MH32会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
步骤二:在主循环中运行TCP Client回环测试程序
while (1) { loopback_tcpc(SOCKET_ID, ethernet_buf, dest_ip, dest_port); }
loopback_tcpc()函数的四个传参分别为,SOCKET ID,TCP协议缓存数组,目标服务器IP地址,目标服务器端口号。
注意:当我们想提高吞吐速度时,可以设置Sn_TXBUF_SIZE(socket n发送缓存大小寄存器)和Sn_RXBUF_SIZE(socket n接收缓存大小寄存器)来重新分配socket缓存大小,同时提高TCP协议缓存数组的大小。
示例的目标服务器IP地址和端口号为:192.168.1.20:8080。
loopback_tcpc()函数内容如下:
/** * @brief tcp client loopback test * @param sn: socket number * @param buf: Data sending and receiving cache * @param destip: Destination IP address * @param destport: Destination port * @return value for SOCK_ERRORs,return 1:no error */ int32_t loopback_tcpc(uint8_t sn, uint8_t *buf, uint8_t *destip, uint16_t destport) { int32_t ret; // return value for SOCK_ERRORs uint16_t size = 0, sentsize = 0; // Destination (TCP Server) IP info (will be connected) // >> loopback_tcpc() function parameter // >> Ex) uint8_t dip[4] = {192, 168, 0, 214}; uint16_t dport = 5000; getSn_DIPR(sn, dip); dport = getSn_DPORT(sn); // Port number for TCP client (will be increased) static uint16_t any_port = 50000; // Socket Status Transitions // Check the W5500 Socket n status register (Sn_SR, The 'Sn_SR' controlled by Sn_CR command or Packet send/recv status) switch (getSn_SR(sn)) { case SOCK_ESTABLISHED: if (getSn_IR(sn) & Sn_IR_CON) // Socket n interrupt register mask; TCP CON interrupt = connection with peer is successful { #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 #ifdef _LOOPBACK_DEBUG_ printf("%d:Connected to - %d.%d.%d.%d : %drn", sn, destip[0], destip[1], destip[2], destip[3], destport); #endif setSn_IR(sn, Sn_IR_CON); // this interrupt should be write the bit cleared to '1' } ////////////////////////////////////////////////////////////////////////////////////////////// // Data Transaction Parts; Handle the [data receive and send] process ////////////////////////////////////////////////////////////////////////////////////////////// if ((size = getSn_RX_RSR(sn)) > 0) // Sn_RX_RSR: Socket n Received Size Register, Receiving data length { if (size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; // DATA_BUF_SIZE means user defined buffer size (array) ret = recv(sn, buf, size); // Data Receive process (H/W Rx socket buffer -> User's buffer) buf[size] = 0x00; printf("rece from %d.%d.%d.%d:%d data:%srn", dip[0], dip[1], dip[2], dip[3], dport, buf); if (ret <= 0) return ret; // If the received data length <= 0, receive failed and process end size = (uint16_t)ret; sentsize = 0; // Data sentsize control while (size != sentsize) { ret = send(sn, buf + sentsize, size - sentsize); // Data send process (User's buffer - > Destination through H/W Tx socket buffer) if (ret < 0) // Send Error occurred (sent data length < 0) { close(sn); // socket close 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:Try to connect to the %d.%d.%d.%d : %drn", sn, destip[0], destip[1], destip[2], destip[3], destport); #endif if ((ret = connect(sn, destip, destport)) != SOCK_OK) return ret; // Try to TCP connect to the TCP server (destination) break; case SOCK_CLOSED: close(sn); if ((ret = socket(sn, Sn_MR_TCP, any_port++, 0x00)) != sn) { if (any_port == 0xffff) any_port = 50000; return ret; // TCP socket open with 'any_port' port number } #ifdef _LOOPBACK_DEBUG_ printf("%d:TCP client loopback startrn", sn); printf("%d:Socket openedrn", sn); #endif break; default: break; } return 1; }
在这个程序中,会运行TCP Client状态机,基于不同的的SOCKET的状态执行对应的操作,SOCKET的状态变化如下图所示:
SOCK_CLOSED:当前SOCKET未打开,配置连接服务器及连接端口号后打开SOCKET,打开成功后SOCKET会进入SOCK_INIT状态。
注意:在W55MH32异常断开服务器时,服务器并不知道我们已经掉线了,所以继续使用上一次连接的端口进行连接时会被服务器拒绝连接,所以这里在连接失败后会将连接端口自动加1。如果是在一些特定的场景下,服务器只允许客户端使用固定端口连接,这里就不能使用连接端口自动加1的操作。
SOCK_INIT:SOCKET执行连接服务器操作,如果连接成功,SOCKET状态改为SOCK_ESTABLISHED;连接失败,SOCKET状态改为关闭状态。
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数据回环测试,当服务器未开启时,会一直打印打开socket和连接服务器提示消息。
接下来我们打开一个网络调试工具,例如SocketTester,设置为TCP Server模式,选择PC的IP地址和需要进行TCP通讯的端口号,然后点击”Listen”建立TCP Server软件的侦听。接着我们就能看到W55MH32的连接信息了,最后向W55MH32发送数据进行回环测试。
9总结
本文介绍在 W55MH32芯片上实现 TCP客户端模式进行数据回环测试的方法。阐述 TCP协议概念、特点、与 UDP区别、应用场景及相关机制。展示实现过程,包括开启 Keepalive功能,在主循环运行测试程序。烧录例程后进行 PHY链路检测、获取网络地址,再借助网络调试工具测试。
下一篇将讲解在该芯片上实现 TCP服务器模式监听端口进行数据回环测试,解析相关原理及步骤。敬请期待!
WIZnet是一家无晶圆厂半导体公司,成立于 1998年。产品包括互联网处理器 iMCU™,它采用 TOE(TCP/IP卸载引擎)技术,基于独特的专利全硬连线 TCP/IP。iMCU™面向各种应用中的嵌入式互联网设备。
WIZnet在全球拥有 70多家分销商,在香港、韩国、美国设有办事处,提供技术支持和产品营销。
香港办事处管理的区域包括:澳大利亚、印度、土耳其、亚洲(韩国和日本除外)。
审核编辑 黄宇
-
以太网
+关注
关注
41文章
5727浏览量
176700 -
物联网
+关注
关注
2933文章
46401浏览量
394913
发布评论请先 登录
第二章 W55MH32 DHCP示例

第五章 W55MH32 UDP示例

第九章 W55MH32 HTTP Server示例

第十五章 W55MH32 SNMP示例

第二十九章 W55MH32 Modbus_TCP_Server示例

第三十章 W55MH32 HTTP_Server&NetBIOS示例

评论