W55MH32 RTThread+TCP通信测试

目录

[TCP 协议简介](#TCP 协议简介)

[TCP 的协议特点](#TCP 的协议特点)

RT-Thread简介

RT-Thread特点

TCP应用场景

使用TCP进行数据交互的流程

TCP的ACK机制、重传机制和Keepalive机制

TCP的重传机制

实现过程

运行结果

总结


本篇文章,我们将详细介绍如何在 W55MH32 芯片上结合 RT-Thread 实时操作系统实现高效的 TCP 通信。利用 W55MH32 内置的 TOE(TCP/IP Offload Engine)引擎,我们无需在软件层面处理复杂的协议栈,只需通过简单的 Socket 编程及寄存器配置,即可轻松构建稳定的网络应用。 接下来,我们将通过实战例程,为大家演示如何在一个工程中同时运行 TCP Client(客户端) 和 TCP Server(服务器) 双模式。该例程利用 RT-Thread 的多线程特性,创建两个独立的任务分别处理不同的 Socket 连接,并进行数据回环测试。这不仅展示了 W55MH32 强大的硬件并发处理能力,也为开发复杂的多任务网络应用提供了标准的参考范式。

该例程用到的其他网络协议,例如DHCP,请参考相关章节。有关W55MH32的初始化过程,请参考Network Install章节,这里将不再赘述。

TCP 协议简介

TCP (Transmission Control Protocol) 是一种面向连接的、可靠的传输层协议,它用于在网络中可靠地传输数据。TCP 是互联网协议族中的核心协议之一,通常与 IP 协议(Internet Protocol)一起使用,形成套接字通信

TCP 的协议特点

  • **面向连接:**在传输数据之前,TCP 需要建立一个连接,保证发送方与接收方能够彼此通信。通过三次握手(Three-Way Handshake)过程来建立连接,确保双方的通信是可靠的。
  • **可靠性:**TCP 提供可靠的数据传输,确保数据完整并且按顺序到达接收端。如果数据丢失或出错,TCP 会自动重传丢失的数据包。
  • **流量控制:**TCP 使用流量控制机制来调节数据的发送速度,防止接收方处理不过来导致数据丢失。常用的流量控制方法是滑动窗口(Sliding Window)。
  • **拥塞控制:**TCP 可以动态调整传输速率,以避免网络拥塞。采用算法如慢启动、拥塞避免、快速重传等。
  • **全双工通信:**在 TCP 连接建立后,数据可以在两个方向同时进行传输,支持双向通信
  • **有序数据传输:**TCP 会对数据包进行编号,确保数据按顺序传输,即使网络发生延迟,接收端也能按顺序接收到数据。
  • **拥塞控制:**TCP 传输的数据是字节流,不关心应用层数据的边界,应用层需要自己解析数据边界。

RT-Thread简介

  • RT-Thread 是一款由中国社区主导开发的开源、硬实时嵌入式操作系统(RTOS)。它诞生于 2006 年,经过近 20 年的发展,已经从最初的一个小巧的内核,演变成了一个组件丰富、生态完善的物联网操作系统平台。
  • 简单来说,它就像是物联网设备的"大脑"和"管家",负责管理硬件资源、调度任务,并提供网络连接等高级功能。

RT-Thread特点

  • **极致轻量与可裁剪:**它的内核非常精简,Nano 版本最小仅需 3KB ROM 和 1KB RAM,可以运行在资源极其有限的芯片上(如 Cortex-M0)。同时,它采用"内核+组件"的架构,你可以像搭积木一样,通过图形化工具(Env)按需裁剪系统功能。
  • **硬实时性:**采用抢占式调度算法,保证高优先级任务能立即抢占低优先级任务,中断响应时间达到微秒级,非常适合对时间要求严苛的工业控制和汽车电子场景。
  • **丰富的软件生态:**这是 RT-Thread 最大的亮点之一。它拥有类似手机应用商店的软件包机制,内置了 TCP/IP 协议栈、文件系统、GUI 引擎以及大量的传感器驱动和云连接组件(如 MQTT、AWS、阿里云)。开发者可以直接复用这些资源,极大地加速开发。
  • **开源与商业友好:**遵循 Apache License 2.0 协议,这意味着你可以免费将其用于商业产品,且无需公开你自己的产品代码。

TCP应用场景

  • 远程监控和数据采集:嵌入式设备通常用于采集传感器数据,并通过以太网连接上传到远程服务器,TCP协议确保数据传输的可靠性和完整性。
  • 设备远程控制:许多嵌入式系统需要通过网络接收控制指令(例如工业自动化中的PLC控制),TCP协议提供了可靠的通信通道。
  • 物联网(IoT):许多物联网设备使用TCP协议与云服务器或其他设备进行通信,传输数据、执行命令等。
  • 嵌入式Web服务器:一些嵌入式设备内置Web服务器(例如路由器、网关、传感器设备等),通过TCP协议提供网页接口给用户进行配置和监控。

使用TCP进行数据交互的流程

TCP 连接建立(三次握手)

在开始传输数据之前,TCP 会通过三次握手建立连接:

1.第一次握手 :客户端向服务器发送一个带有 SYN 标志的数据包,表示请求建立连接。

2.第二次握手 :服务器收到 SYN 数据包后,回复一个带有 SYN 和 ACK 标志的数据包,表示同意建立连接。

3.第三次握手:客户端收到服务器的 SYN+ACK 后,发送一个带有 ACK 标志的数据包,连接建立完成。

TCP 连接断开(四次挥手)

当通信结束时,TCP 需要通过四次挥手来断开连接:

1.第一次挥手 :客户端发送一个 FIN 数据包,表示数据发送完毕,准备关闭连接。

2.第二次挥手 :服务器收到 FIN 数据包后,回复一个 ACK 数据包,表示同意关闭连接。

3.第三次挥手 :服务器发送一个 FIN 数据包,表示数据发送完毕,准备关闭连接。

3.第四次挥手:客户端收到服务器的 FIN 数据包后,发送一个 ACK 数据包,连接正式关闭。

TCP的ACK机制、重传机制和Keepalive机制

TCP的ACK机制

ACK 是 TCP 用于确认已成功接收到数据包的机制。在 TCP 通信中,每个数据包都包含一个序列号,接收方用 ACK 来告诉发送方已经成功收到的字节序列。

1.ACK 字段: ACK 包含在 TCP 报文头中,表示接收方期望接收的下一个字节的序列号。

2.累积确认: TCP 使用累积确认方式,表示接收方已经连续收到所有数据,直到某个序列号为止。

**3.超时重传:**如果发送方在超时时间内未收到 ACK,就会重传该数据包。

TCP的重传机制

TCP 的重传机制保证了数据的可靠传输。以下是常见的重传机制:

1.超时重传:

· 发送方设置一个定时器,当发送的数据包在规定时间内未收到 ACK,则触发重传。

· 超时时间是动态调整的,由 TCP 的往返时间(RTT, Round Trip Time)估算得出。

2.快速重传:

· 当接收方发现数据包丢失时,发送重复的 ACK(称为冗余 ACK),提醒发送方某个数据包未到达。

· 如果发送方连续收到 3 个重复的 ACK,就会立即重传对应的数据包,而不必等待超时。

3.选择性重传(Selective Repeat, SACK):

· 在累积确认的基础上,TCP 还可以通过 SACK 选项告诉发送方哪些特定的块已收到,哪些未收到

· 这可以减少不必要的重传,提高效率。

TCP Keepalive 机制

TCP Keepalive 是 TCP 协议的一种可选机制,用于检测长时间空闲的连接是否仍然有效。它的主要作用是:

1.维护连接状态: 检测对方主机是否仍在线,避免资源被长期占用。

2.释放死连接: 如果连接已经失效(如网络中断或对方主机崩溃),Keepalive 可以及时释放资源。

3.防止中间设备超时关闭连接: 一些 NAT、路由器或防火墙可能会在连接长时间不活动时自动关闭,Keepalive 可防止这种情况。

用法:在W55MH32的TOE引擎中,需要在Sn_KPALVTR寄存器中设置对应socket的Keepalive时间,然后在该socket成功连接服务器后发送一条数据来激活Keepalive

实现过程

接下来,我们一起来看看如何在 W55MH32 芯片上,利用 RT-Thread 操作系统创建双线程,分别实现 TCP 客户端(Client)和 TCP 服务器(Server)模式,并进行数据回环测试。

步骤1:设置W55MH32和电脑的基本网络参数,使其处于同一网段内

cpp 复制代码
#define DEFAULT_MAC_EN        1 // 1:默认MAC 0:自定义MAC
#define SOCKET_TCPC           0 // TCP客户端Socket号
#define SOCKET_TCPS           1 // TCP服务器Socket号
#define ETHERNET_BUF_MAX_SIZE (1024 * 2) // 网络缓冲区大小(2KB)

// TCP客户端:目标服务器IP+端口
uint8_t  dest_ip[4] = {192, 168, 1, 120};
uint16_t dest_port  = 8087;
// TCP服务器:本地监听端口
uint16_t local_port = 8084;

步骤 2:RT-Thread 线程配置

cpp 复制代码
// TCP客户端线程参数
#define TASK_TCPC_PRIO     1
#define TASK_TCPC_STK_SIZE 256
static rt_thread_t Task_TCPC_Handler = RT_NULL;

// TCP服务器线程参数
#define TASK_TCPS_PRIO     1
#define TASK_TCPS_STK_SIZE 256
static rt_thread_t Task_TCPS_Handler = RT_NULL;

步骤 3:网络参数初始化

cpp 复制代码
wiz_NetInfo default_net_info = {
    .mac  = {0x00, 0x08, 0xdc, 0x12, 0x22, 0x12}, // 自定义MAC
    .ip   = {192, 168, 1, 30},                     // 静态IP
    .gw   = {192, 168, 1, 1},                      // 网关
    .sn   = {255, 255, 255, 0},                    // 子网掩码
    .dns  = {8, 8, 8, 8},                          // DNS
    .dhcp = NETINFO_DHCP                           // 开启DHCP
};

步骤 4:开启 TCP Keepalive 保活

cpp 复制代码
setSn_KPALVTR(SOCKET_TCPC, 6); // TCP客户端 30s保活
setSn_KPALVTR(SOCKET_TCPS, 6); // TCP服务器 30s保活

步骤 5:系统初始化与线程启动

cpp 复制代码
int app_init(void)
{
    rt_kprintf("%s RTThread TCP example\n", _WIZCHIP_ID_);
    wiz_toe_init(); // W55MH32 TOE引擎初始化
    // 注册RT-Thread临界区函数(线程安全)
    reg_wizchip_cris_cbfunc(rt_enter_critical, rt_exit_critical);
#if DEFAULT_MAC_EN == 1
    getSHAR(default_net_info.mac); // 使用芯片默认MAC
#endif
    wiz_phy_link_check(); // 检测以太网物理链路
    network_init(tcpc_ethernet_buf, &default_net_info); // 网络初始化

    // 开启Keepalive + 创建并启动双TCP线程
    setSn_KPALVTR(SOCKET_TCPC, 6);
    setSn_KPALVTR(SOCKET_TCPS, 6);
    Task_TCPC_Handler = rt_thread_create("Task TCP Client", Task_TCPC, RT_NULL, TASK_TCPC_STK_SIZE, TASK_TCPC_PRIO, 20);
    Task_TCPS_Handler = rt_thread_create("Task TCP Server", Task_TCPS, RT_NULL, TASK_TCPS_STK_SIZE, TASK_TCPS_PRIO, 20);
    rt_thread_startup(Task_TCPC_Handler);
    rt_thread_startup(Task_TCPS_Handler);
    return 0;
}
INIT_APP_EXPORT(app_init); // RT-Thread自动初始化

步骤 6:TCP 线程任务函数

cpp 复制代码
// TCP客户端线程:循环连接服务器+数据回环
void Task_TCPC(void *parameter)
{
    while (1)
    {
        loopback_tcpc(SOCKET_TCPC, tcpc_ethernet_buf, dest_ip, dest_port);
        rt_thread_mdelay(1);
    }
}

// TCP服务器线程:循环监听端口+数据回环
void Task_TCPS(void *parameter)
{
    while (1)
    {
        loopback_tcps(SOCKET_TCPS, tcps_ethernet_buf, local_port);
        rt_thread_mdelay(1);
    }
}

在这个程序中,会运行TCP 客户端 + TCP 服务器双状态机,基于不同的 SOCKET 状态执行对应的操作,SOCKET 的状态变化如下图所示:
系统整体初始化与调度流程图

· SOCK_CLOSED: 当前SOCKET未打开,配置连接服务器及连接端口号后打开SOCKET,打开成功后SOCKET会进入SOCK_INIT状态。

· 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状态。

运行结果

1.烧录例程运行后,首先可以看到 PHY 链路检测、DHCP 获取 IP,然后 TCP 初始化完成并开始监听端口,信息如下图所示:

注意:
1.测试实例需要 PC 端和 W55MH32 处于同一网段。
2.TCP 客户端连接失败时,程序会自动重新尝试连接,无需手动复位。
3.RT-Thread 线程栈大小不可过小,否则会导致线程崩溃;
4.提高数据吞吐量时,可增大ETHERNET_BUF_MAX_SIZE并调整 W55MH32 的 Socket 收发缓存寄存器;
5.多线程网络操作已注册 RT-Thread 临界区函数,保证硬件操作线程安全。

接下来我们打开两个网络调试工具,例如SOCKETTESTER 网络调试助手,分别设置为 TCP Client 和 TCP Server 模式,与 W55MH32 的双线程 TCP 通信例程进行双向测试。

1.TCP Server 模式(PC 端)打开 NetAssist,设置为TCP Server模式,选择 PC 的 IP 地址(如192.168.1.121)和端口号8087,点击「开启侦听」。此时 W55MH32 的 TCP 客户端线程会主动连接该服务器,串口调试工具中会打印连接成功日志。向 W55MH32 发送数据(如WIZNET),设备会将数据原样回发,实现数据回环测试。

2.TCP Client 模式(PC 端)打开另一个 NetAssist 窗口,设置为TCP Client模式,远程主机地址填写 W55MH32 的 IP(如192.168.1.129)和端口号8084,点击「连接」。W55MH32 的 TCP 服务器线程会响应连接请求,串口工具打印客户端接入日志。向设备发送数据(如WIZNET),设备会将数据回发,验证服务器功能正常。 通过串口调试工具(WIZ UartTool)可以同时观察设备的 TCP 客户端和服务器线程运行日志,包括连接状态、收发数据内容,验证双线程并发通信的稳定性。

总结

本文介绍了在 W55MH32 芯片上结合 RT-Thread 操作系统实现 TCP 客户端与服务器双模式的方法。通过创建独立的 RT-Thread 线程分别管理客户端和服务器的 Socket 状态机,实现了全双工的数据回环测试。示例中展示了如何配置 Keepalive 机制以维持长连接,以及如何处理 Socket 的状态流转。

下一篇文章将讲解W55MH32芯片实现UDP+client和UDP+server双模式并行通信,介绍 UDP 相关原理和实现步骤。敬请期待!

相关推荐
刘佬GEO8 小时前
口腔门诊第一次做 GEO:第一步动作与起步策略拆解
网络·人工智能·搜索引擎·ai·语言模型
盟接之桥8 小时前
盟接之桥说制造:深耕长尾市场,跨越价值“临界点”
大数据·网络·安全·低代码·汽车·制造
北方的流星8 小时前
华三网络设备MSTP+VRRP架构配置
运维·网络·华三
HABuo10 小时前
【linux(四)】套接字编程--基于UDP协议的客户端服务端
linux·服务器·c++·网络协议·ubuntu·udp·centos
艾莉丝努力练剑10 小时前
【Linux网络】Linux 网络编程入门:UDP Socket 编程(下)
linux·运维·服务器·网络·计算机网络·安全·udp
Johnstons17 小时前
Wireshark ExpertInfo是什么?一文讲透异常分级、适用场景、和传统抓包阅读的区别与排查标准
网络·测试工具·wireshark·es
alxraves17 小时前
医疗器械软件注册指导原则注意事项
网络·安全·健康医疗·制造
liann11919 小时前
3.2_红队攻击框架--MITRE ATT&CK‌
python·网络协议·安全·网络安全·系统安全·信息与通信
GCKJ_082420 小时前
观成科技:利用DoH加密通信的恶意木马流量分析
网络