一、系统架构设计
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, ¤t_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
六、工程配置建议
-
编译器优化
# IAR编译选项 -Ohs # 最高优化级别 -DUSE_FREEMODBUS=1 -DUIP_CONF_BUFFER_SIZE=1024
-
内存分配策略
#define MEM_HEAP_SIZE 2048 static uint8_t mem_heap[MEM_HEAP_SIZE]; mem_init(mem_heap, MEM_HEAP_SIZE);
-
调试接口
#define MODBUS_DEBUG 1 #if MODBUS_DEBUG #define mb_printf(...) printf(__VA_ARGS__) #else #define mb_printf(...) #endif