基于uIP协议栈移植FreeModbus TCP的方案

基于uIP协议栈移植FreeModbus TCP的方案

一、系统架构设计

1. 硬件配置方案

模块 推荐参数 功能说明
主控芯片 STM32F407ZG (ARM Cortex-M4) 支持以太网MAC+PHY
网络接口 ENC28J60 (SPI接口) 10/100Mbps以太网控制器
存储 1MB Flash + 192KB RAM 协议栈及数据存储
电源管理 3.3V LDO稳压 低功耗设计

2. 协议栈架构

graph TDA[应用层] -->|Modbus TCP请求| B(Modbus协议栈)B -->|封装TCP数据| C(uIP协议栈)C -->|处理TCP连接| D[网络接口层]D -->|物理层传输| E[以太网控制器]

二、关键移植步骤

1. uIP协议栈初始化

// 初始化以太网MAC和PHY
void eth_init() {enc28j60_init(mymac);        // 初始化SPI接口enc28j60_phy_write(PHLCON, 0x476); // 配置PHY寄存器init_ip_arp_udp_tcp(mymac, myip, 80); // 初始化IP层
}// 启动uIP协议栈
void uip_start() {uip_listen(HTONS(502));      // 监听Modbus TCP默认端口uip_set_appcall(uip_modbus_appcall); // 设置应用层回调
}

2. FreeModbus TCP适配

// 修改FreeModbus端口接口
BOOL xMBTCPPortInit(USHORT usTCPPort) {if(usTCPPort == 0) usTCPPort = 502; // 使用标准端口return TRUE;
}// 数据接收处理
BOOL xMBTCPPortGetRequest(UCHAR **ppucMBTCPFrame, USHORT *usTCPLength) {*ppucMBTCPFrame = ucTCPRequestFrame;*usTCPLength = uip_len;return TRUE;
}// 数据发送处理
BOOL xMBTCPPortSendResponse(const UCHAR *pucMBTCPFrame, USHORT usTCPLength) {memcpy(ucTCPResponseFrame, pucMBTCPFrame, usTCPLength);uip_send(ucTCPResponseFrame, usTCPLength);return TRUE;
}

3. Modbus TCP数据处理

// Modbus TCP事件处理
void uip_modbus_appcall() {if(uip_connected()) {mb_tcp_state = MB_TCP_CONNECTED;}if(uip_newdata()) {// 处理Modbus请求mb_tcp_request_len = uip_len;memcpy(mb_tcp_request_buf, uip_appdata, uip_len);xMBPortEventPost(EV_FRAME_RECEIVED); // 触发FreeModbus事件}if(uip_poll()) {if(mb_tcp_state == MB_TCP_READY) {uip_send(mb_tcp_response_buf, mb_tcp_response_len);}}
}

三、核心代码

1. MBAP头处理

// 构建MBAP头
void build_mbap_header(uint8_t *buffer, uint16_t trans_id, uint16_t protocol_id, uint16_t length, uint8_t unit_id) {buffer[0] = (trans_id >> 8) & 0xFF;buffer[1] = trans_id & 0xFF;buffer[2] = (protocol_id >> 8) & 0xFF;buffer[3] = protocol_id & 0xFF;buffer[4] = (length >> 8) & 0xFF;buffer[5] = length & 0xFF;buffer[6] = unit_id;
}// 解析MBAP头
void parse_mbap_header(uint8_t *buffer, uint16_t *trans_id,uint16_t *protocol_id, uint16_t *length,uint8_t *unit_id) {*trans_id = (buffer[0] << 8) | buffer[1];*protocol_id = (buffer[2] << 8) | buffer[3];*length = (buffer[4] << 8) | buffer[5];*unit_id = buffer[6];
}

2. 数据帧处理流程

void process_modbus_tcp() {static uint8_t frame_buffer[MB_TCP_BUF_SIZE];// 接收数据uint16_t recv_len = xMBTCPPortGetRequest(&frame_buffer, &current_length);if(recv_len > 0) {// 解析MBAP头parse_mbap_header(frame_buffer, &trans_id, &proto_id, &pdu_length, &unit_id);// 处理PDU数据mb_error = eMBTCPReceive(frame_buffer + 7, pdu_length);// 构建响应build_mbap_header(response_buffer, trans_id, proto_id, 2 + pdu_length, unit_id);memcpy(response_buffer + 7, mb_tcp_response, pdu_length + 2);// 发送响应xMBTCPPortSendResponse(response_buffer, 7 + pdu_length + 2);}
}

四、调试与验证

1. 抓包分析示例

No.     Time           Source                Destination           Protocol Length Info1 0.000000000    192.168.1.100         192.168.1.15          TCP      74     54321→502 [SYN] 2 0.000123456    192.168.1.15          192.168.1.100         TCP      74     502→54321 [SYN, ACK]3 0.000234567    192.168.1.100         192.168.1.15          TCP      66     54321→502 [ACK]4 0.001000000    192.168.1.100         192.168.1.15          Modbus   132    Read Coils (03)5 0.001111111    192.168.1.15          192.168.1.100         Modbus   126    Read Coils Response

2. 常见问题解决

问题现象 解决方案
无法建立TCP连接 检查IP地址配置和防火墙设置
数据包丢失 调整uIP的TCP重传参数
响应延迟大 优化中断处理优先级,减少任务阻塞
CRC校验失败 验证网络层和协议层CRC实现一致性

五、扩展功能

1. 多从站支持

// 多从站地址映射表
typedef struct {uint8_t slave_addr;uint16_t holding_start;uint16_t holding_size;
} mb_slave_config;mb_slave_config slaves[] = {{1, 0x0000, 100},{2, 0x0100, 50}
};// 处理多从站请求
void handle_multi_slave() {for(int i=0; i<sizeof(slaves)/sizeof(slaves[0]); i++) {if(current_slave == slaves[i].slave_addr) {// 处理对应从站数据break;}}
}

2. 安全增强方案

// 添加TLS加密支持
void enable_tls() {#include "mbedtls/config.h"mbedtls_ssl_init(&ssl_ctx);mbedtls_ssl_config_init(&conf);mbedtls_ssl_config_defaults(&conf,MBEDTLS_SSL_IS_SERVER,MBEDTLS_SSL_TRANSPORT_STREAM,MBEDTLS_SSL_PRESET_DEFAULT);mbedtls_ssl_setup(&ssl_ctx, &conf);
}// 在uIP发送前加密数据
void uip_send_encrypted(uint8_t *data, uint16_t len) {uint8_t encrypted[2048];mbedtls_ssl_write(&ssl_ctx, data, len, encrypted, sizeof(encrypted));uip_send(encrypted, len);
}

参考代码 uip协议,modbusTCP协议,移植freemodbus TCP www.youwenfan.com/contentcnj/70744.html

六、工程配置建议

  1. 编译器优化

    # IAR编译选项
    -Ohs        # 最高优化级别
    -DUSE_FREEMODBUS=1
    -DUIP_CONF_BUFFER_SIZE=1024
    
  2. 内存分配策略

    #define MEM_HEAP_SIZE 2048
    static uint8_t mem_heap[MEM_HEAP_SIZE];
    mem_init(mem_heap, MEM_HEAP_SIZE);
    
  3. 调试接口

    #define MODBUS_DEBUG 1
    #if MODBUS_DEBUG
    #define mb_printf(...) printf(__VA_ARGS__)
    #else
    #define mb_printf(...)
    #endif