ethernet.h
SERVER_POINT_E 与 s_serverInfo[] 的强耦合4.3 IP_ADDR_TAB_T 的存储布局4.4 临时指向超时字段5. 对外接口6. 依赖关系7. 备注与风险点源文件路径:
midware/ethernt/ethernet.h所属模块:midware/ethernt(有线/无线网络接入层) 代码行数:288
1. 文件职责
本文件是 EMS 网络接入层的公共头文件,统一定义了有线(W5500 以太网)与无线(易联 WIFI/4G 通讯棒)两条通道共用的类型、宏和全局变量。
它把"云端服务器指向"这一策略抽象成一张静态表加一个枚举(SERVER_POINT_E + ServerInfo_t),并提供端口/加密方式的选择接口声明,供 TCP 客户端、WIFI 通讯棒初始化、DNS 解析三处共用。
文件同时声明了两个 uCOS-II 任务入口 task_ethernet()、task_ethernet_monitor(),这两个任务在 user/main.c 中静态创建。
IP_ADDR_TAB_T 是掉电保存的网参结构体(含 CRC),被 data/ 下的参数存储模块直接读写,因此本头文件处在"配置持久化 ↔ 网络运行时"的中间位置。
2. 关键数据结构与宏
| 名称 | 类型 | 说明 |
|---|---|---|
W5500_DEBUG | 宏 | 置 1 时打开 W5500 全流程串口打印;默认 0 |
EMS_18031_DEBUG | 宏 | 置 1 时把非固定指向检测/临时指向计时从小时级缩短到 60s,用于调试 18031 版本 |
ETHERNET_Q_LEN | 宏 | 网络发送消息队列长度,值为 20 |
AT_DEFAULT_PWD | 宏 | 易联通讯棒默认登录密码 "12345678";不支持一机一密时使用 |
WIRELESS_SEND_SIZE | 宏 | 无线通道单次分片发送长度 5*1024 字节 |
MAX_SIZE_TCP_PACKET | 宏 | TCP 最大包长 1400 |
CUSTOM_SERVER_NAME | 宏 | 映射到 g_system_custom_info.s8_socket_point,用户自定义域名 |
CUSTOM_SERVER_PORT(X) | 宏 | 自定义服务器非加密端口;按 X 奇偶在 u16_socket_port1/port2 间二选一 |
CUSTOM_SERVER_ENCRYPTION_PORT(X) | 宏 | 自定义服务器加密端口,同上取二 |
FORMAL_SERVER_NAME / FORMAL_CHINA_SERVER_NAME | 宏 | cloudiot.alphaess.com / chinaiot.alphaess.com |
FORMAL_SERVER_PORT(X) | 宏 | 正式服务器非加密端口 7777(固定值,X 未使用) |
FORMAL_SERVER_ENCRYPTION_PORT(X) | 宏 | 正式服务器私有算法加密端口 17777 |
FORMAL_SERVER_TLS_PORT(X) | 宏 | 正式服务器 TLS 端口 4040 |
RD_TEST_SERVER_NAME / _PORT / _ENCRYPTION_PORT / _TLS_PORT | 宏 | dev.alphaess.com,8117 / 17777 / 4040 |
PRODUCTION_TEST_SERVER_NAME / _PORT(X) | 宏 | mes.alphaess.com,产线测试非加密端口按 X 奇偶取 8117 / 8119 |
OEM_ZOE_FORMAL_SERVER_NAME / _PORT | 宏 | www.zonergyess.com : 7777 |
OEM_BYTEWATT_FORMAL_SERVER_NAME / _PORT | 宏 | monitor.byte-watt.com : 7777 |
OEM_BYTEWATT_TEST_SERVER_NAME / _ENCRYPTION_PORT / _TLS_PORT | 宏 | test-socket.byte-watt.com : 17777 / 4040 |
OTHER_SERVER_NAME / _PORT(X) | 宏 | 内网测试 192.168.8.7,8117 / 8119 |
RD_TEST_SERVER_V2_NAME / _PORT / _ENCRYPTION_PORT / _TLS_PORT | 宏 | 平台架构升级新测试服 staging.alphaess.com,7777 / 17777 / 4040 |
RD_TEST_SERVER_GRAY_NAME / _PORT / _ENCRYPTION_PORT / _TLS_PORT | 宏 | 灰度测试服 huiduiot.alphaess.com(2025.08.10 新增),7777 / 17777 / 4040 |
ARRAY_SIZE(x) | 宏 | 静态数组元素个数 |
LOCAL_PORT | 宏 | 本地端口 0(由协议栈随机分配) |
IP_METHOD_AUTO / IP_METHOD_MANUAL | 宏 | 0x00 DHCP 动态获取,0x01 静态 IP |
IP_ADDR1..4_DEFAULT | 宏 | 静态 IP 默认值 192.168.1.1 |
SUBNET_ADDR1..4_DEFAULT | 宏 | 默认掩码 255.255.255.0 |
GATEWAY_ADDR1..4_DEFAULT | 宏 | 默认网关 192.168.1.1 |
SOCK_DNS / SOCK_DHCP / SOCK_TCP_CLIENT / SOCK_TCP_SERVER | 宏 | W5500 的 4 个 socket 号分配:0/1/2/3 |
MEC_SERVER_PORT | 宏 | Modbus TCP 从站端口 502 |
MY_MAX_DHCP_RETRY | 宏 | DHCP 单轮最大重试次数 3 |
MAX_DHCP_BUF_SIZE | 宏 | DHCP 缓冲区 548 字节 |
S7_INT..S0_INT | 宏 | 位掩码 0x80…0x01,供状态位解析 |
DHCP_PRO / DNS_PRO | 宏 | 流程标识 1 / 2 |
S_INIT / S_CONN | 宏 | Socket 初始化/已连接状态码(0x01/0x02,本工程内未实际使用) |
S_RECEIVE / S_TRANSMITOK | 宏 | 收发完成标志(0x01/0x02) |
W5500_RST / W5500_RST_PORT / W5500_INT / W5500_POWER_PIN 等 | 宏 | 全部被注释掉实际取值,仅剩裸宏名,等价于空定义 |
NOT_ENCRYPTED_PROTOCAL / TLS_ENCRYPTED_PROTOCAL | 宏 | 字符串 "tcp" / "tcps",用于给 WIFI 棒下发域名前缀 |
ALPHAESS_WIFI_SSID_SUFFIX / E_LINKER_WIFI_SSID_SUFFIX | 宏 | 自研 WIFI 热点后缀 "AW" / 易联 WIFI 热点后缀 "EL" |
ENEthernetStatus | 枚举 | 网络总体状态:NET_STATUS_NONE/IDLE/DHCP/DNS/TCP_CLIENT/TCP_SERVER/MAX |
SERVER_POINT_E | 枚举 | 固定域名指向,14 个成员,必须与 s_serverInfo[] 逐项对应,注释明确"不可跳值和在中段插入" |
ETHERNET_ENCRYPTION_TYPE | 枚举 | 加密方式:NET_NOT_ENCRYPTED(1)、NET_PRIVATE_ENCRYPTED(2)、NET_TLS_ENCRYPTED(3)、NET_MQTT_ENCRYPTED(4)、NET_MQTTS_ENCRYPTED(5)、NET_MAX_ENCRYPTION_TYPE |
ServerInfo_t | 结构体(#pragma pack(1)) | 固定域名表项:point 枚举值、name 域名、port1+port1_encrypted_state(非 TLS,用于网线及不支持 TLS 的 WIFI)、Port2+port2_encrypted_state(TLS,仅支持 TLS 的 WIFI) |
STEthernetSys | 结构体(#pragma pack(1)) | 网络运行时全局状态:DHCP/DNS/Socket 成功标志、各阶段 tick、W5500/EMS 初始化标志、域名解析结果 Domain_IP[4]、socket/链路状态、非固定指向缓存(s_skip_addr[65]/端口/加密/变更标志)、扩展 ICDC 升级标志 |
STEthernetData | 结构体(#pragma pack(1)) | 网络发送消息体:u8Type 消息类型、pu8Info 数据指针、u32Len 长度、u8lock 发送互斥锁 |
IP_ADDR_TAB_T | 结构体(#pragma pack(1)) | 掉电保存的网参表:头 u16_head、MAC、IP 方式、4 组 IP/网关/掩码(每字节一个 u16 存)、服务器指向 u8_server_point、网络类型、非固定指向 1/2 的地址/端口/加密/变更标志、支持性检查状态、临时指向开关及倒计时、14 字节保留、CRC16 |
STATIC_ASSERT(ASSERT_FLASH_SECTOR_SIZE % sizeof(IP_ADDR_TAB_T) == 0) | 编译期断言 | 要求 Flash 扇区大小能被该结构体整除,保证一整扇区存整数条网参记录 |
3. 函数清单
本文件为头文件,只包含函数声明(原型),无函数定义。
| 函数名 | 作用域 | 说明(一句话) |
|---|---|---|
void task_ethernet(void *p_arg) | 全局(声明) | 网络主任务,由 user/main.c 静态创建,负责消息队列发送与 W5500 状态机推进 |
void task_ethernet_monitor(void *p_arg) | 全局(声明) | 网络监控任务,周期调无线检测与各类异常复位判定 |
void net_init(void) | 全局(声明) | 置位 g_stNetSysInfo.u8EMSInit,触发下一轮网络重新初始化 |
void internet_time_handle(void) | 全局(声明) | 每秒驱动 DHCP/DNS 协议栈超时计时 |
char* get_ethernet_server_point(void) | 全局(声明) | 返回当前应连接的域名 |
u16 get_ethernet_server_port(u8 network_type, u8 tls_support_flag) | 全局(声明) | 返回当前应连接的端口,并刷新加密方式 |
u8 get_server_data_encryption_flag(void) | 全局(声明) | 返回当前数据加密方式,决定收发是否套私有加解密 |
char* wireless_get_ethernet_server_point(char *s_skip_addr, u8 protocol_type) | 全局(声明) | 拼出给 WIFI 棒下发的 协议://域名 字符串 |
void ip_add_skip_change_clear(void) | 全局(声明) | 清空非固定指向缓存并置位网参保存标志 |
4. 核心逻辑解析
本头文件不含可执行逻辑,核心是"域名指向策略"的三层结构设计,理解它才能读懂 ethernet.c。
4.1 服务器指向的三级优先级
注释中明确给出优先级(ethernet.c:1621-1691 的实现对应):
- 非固定指向(客户临时指定域名/端口)——
u8_skip_change_flag1/2有效时优先; - 用户自定义指向——
g_system_custom_info.u8_socket_flag有效时使用g_system_custom_info里的域名和端口; - 固定域名表——
IP_Address.u8_server_point作为下标查s_serverInfo[]。
第 3 级内部再分两支:端口 1(非 TLS,用于有线 LAN 和不支持 TLS 的 WIFI 棒)、端口 2(TLS,仅用于支持 TLS 的 WIFI 棒)。选择条件是"走无线通道 且 WIFI 棒上报支持 TLS 且未处于临时指向状态"。
4.2 SERVER_POINT_E 与 s_serverInfo[] 的强耦合
头文件第 147 行注释与 ethernet.c:1586-1587 的注释反复强调:枚举成员顺序、表项顺序、宏定义三者必须一一对应且不可跳值。原因是 s_serverInfo[] 用 SERVER_POINT_E 的值做数组下标(ethernet.c:1681-1682),而 IP_Address.u8_server_point 又是从 Flash 里读出来的历史值,一旦顺序变动,老设备升级后会连到错误的服务器。
4.3 IP_ADDR_TAB_T 的存储布局
#pragma pack(1) 下该结构体紧凑排列,末尾带 u16_crc_code。文件末尾的 STATIC_ASSERT 要求 Flash 扇区大小是其整数倍,说明该表是以"整表刷写到 Flash 扇区"的方式持久化的(对应 data/ 模块的断电续传)。u8_reserve[14] 是留给后续字段的余量——注意这里的风险:任何字段增删都会改变结构体大小与 CRC 覆盖范围,老设备读回旧数据时可能校验失败或字段错位。
4.4 临时指向超时字段
u8_server_temp_switchover(开关)+ u8_server_temp_switchover_tim(剩余小时数)这一对字段,配合 ethernet.c:server_skip_support_check() 使用:每当倒计时减到 0 就关闭临时指向、置位 g_t_config_save_flag.u8_set_net_para_flag 并调 net_init() 触发重连。EMS_18031_DEBUG == 1 时该倒计时单位从 1 小时降为 60 秒,便于现场测试。
5. 对外接口
本文件导出(供其他模块调用/引用)
- 类型与宏(全局可见):
ENEthernetStatus、SERVER_POINT_E、ETHERNET_ENCRYPTION_TYPE、ServerInfo_t、STEthernetSys、STEthernetData、IP_ADDR_TAB_T,以及上表全部宏常量。 - 全局变量(extern 声明):
wiz_NetInfo g_stNetInfo— 当前生效网参(MAC/IP/掩码/网关/DNS/dhcp 模式)OS_EVENT *g_pEthernetQ— 网络发送消息队列OS_EVENT *g_pUpdateSem— 升级用信号量STEthernetData g_stNetDataSend— 发送数据描述STEthernetSys g_stNetSysInfo— 网络运行时状态IP_ADDR_TAB_T IP_Address— 持久化网参
- 函数原型:
task_ethernet、task_ethernet_monitor、net_init、internet_time_handle、get_ethernet_server_point、get_ethernet_server_port、get_server_data_encryption_flag、wireless_get_ethernet_server_point、ip_add_skip_change_clear。
本文件引用的外部内容
wizchip_conf.h(W5500 ioLibrary)——提供wiz_NetInfo类型wireless_driver.h——提供无线运行时结构体与无线检测接口debug.h——调试输出- 被外部引用:
g_system_custom_info由宏CUSTOM_SERVER_NAME/CUSTOM_SERVER_PORT间接引用(定义在data/system_config),ASSERT_FLASH_SECTOR_SIZE来自 Flash 存储模块
6. 依赖关系
- 依赖:
wizchip_conf.h(W5500 协议栈)、wireless_driver.h、debug.h。 - 被依赖:
midware/ethernt/ethernet.c——本文件的唯一实现文件net/ems.h:15#include "ethernet.h"midware/ethernt/wireless/wifi/e_linker_wifi.c:17#include "ethernet.h"(使用AT_DEFAULT_PWD、ALPHAESS_WIFI_SSID_SUFFIX、E_LINKER_WIFI_SSID_SUFFIX、g_stNetSysInfo)midware/ethernt/wireless/wireless_driver.c通过wireless_driver.h→间接使用g_stNetSysInfo、IP_Address、SOCK_OKmidware/ethernt/wireless/elink_parse.h中的 AT 指令宏被wireless_driver.c、e_linker_wifi.c引用
7. 备注与风险点
- 空宏残留:
W5500_RST、W5500_RST_PORT、W5500_INT、W5500_INT_PORT、W5500_POWER_PIN、W5500_POWER_PORT的取值全被注释掉(第 123-130 行),宏名仍保留但展开为空。这是版本遗留代码:硬件引脚实际由hardware/gpio统一管理。 - 未使用的宏:
S_INIT/S_CONN/S_RECEIVE/S_TRANSMITOK/DHCP_PRO/DNS_PRO/S7_INT..S0_INT/MAX_SIZE_TCP_PACKET(ethernet.h中定义的同时net/ems.h:51又重复定义了一份MAX_SIZE_TCP_PACKET,值相同但存在重定义隐患)在ethernet.c中均未使用。 ARRAY_SIZE宏重复定义风险:common/与其他头文件中也可能定义同名宏,无#ifndef保护。- 枚举与表强耦合:
SERVER_POINT_E依赖注释约束而非编译期校验,s_serverInfo[]数组若不慎增删条目而枚举未同步,会静默读到错误域名/端口。建议加STATIC_ASSERT(ARRAY_SIZE(s_serverInfo) == MAX_SEVER)。 IP_ADDR_TAB_T兼容性:字段增删会同时改变结构体大小、CRC 覆盖范围和 Flash 扇区整除关系;u8_reserve[14]只是缓解手段,STATIC_ASSERT在字段变更后可能直接编译失败(这是好事,但有升级风险)。- 宏参数 X 未使用:
FORMAL_SERVER_PORT(X)、RD_TEST_SERVER_PORT(X)等留下形参但函数体不用,属于历史多服务器轮询机制的残留(ethernet.h:38-39, 45-46的注释版本按X%3选端口)。 #pragma pack(1)作用域:第 178 行#pragma pack(1)与第 267 行#pragma pack()配对,ServerInfo_t/STEthernetSys/STEthernetData/IP_ADDR_TAB_T全部按 1 字节对齐——对wiz_NetInfo无影响(它在外部头文件里),但结构体内u16/u32成员在 GD32F407 上会做非对齐访问,属可接受但有性能损耗的写法。- 魔法数字:
s_skip_addr[65]的 65、MAX_DHCP_BUF_SIZE 548、ETHERNET_Q_LEN 20等缺少来源说明。 AT_DEFAULT_PWD明文硬编码:默认密码"12345678"直接写在头文件里,若该密码用于设备安全接入需评估。