EMS 知识库
首页 / knowledge/代码解析/net

ems.h

源文件路径:net/ems.h 所属模块:net(网络应用层) 代码行数:526

1. 文件职责

本文件是云端 EMS 通信模块(net/ems.c)的对外契约头,集中定义了 EMS 主控与 AlphaCloud 服务器之间 TCP/JSON 协议所需的命令字、状态机状态、事件位掩码、时间常量以及全部报文结构体。它是整个上报链路的"字典":net/ems.c 用这些宏组装报文、驱动状态机,net/server.c 用同一套命令字解析下行帧,data/、logic/、midware/ 各模块则通过这里 extern 的全局标志位(g_u8SetConfigFlag、g_u8RestartFlag、g_u8DispatchFlag …)向通信任务投递"有事要上报/要应答"的请求。

48 个源文件包含本头文件(见第 6 节),因此它实际上充当了 EMS 应用层与网络层之间的公共接口声明文件。文件本身不含任何可执行代码,只有宏、类型与 extern 声明。

2. 关键数据结构与宏

2.1 时间与计数常量

名称类型说明
SENCOND_1MS / SENCOND_30MS / SENCOND_100MS / SENCOND_800MS宏毫秒级节拍常量(1/30/100/800),用于 OSTimeGet() 差值比较
SENCOND_1S … SENCOND_600S宏秒级节拍常量,以 1000 * n 表示(1/2/3/5/10/15/30/60/90/150/180/210/300/600 秒)
SENCOND_30M / SENCOND_1H / SENCOND_3H宏30 分/1 时/3 时节拍(600 应为 1800 秒,见备注)
REQUEST_UPDATE_INTERVAL宏请求升级文件分片的间隔,等于 SENCOND_100MS(100 ms)
HEART_BEAT_FAIL宏 (10)心跳接收超时门限,由 midware/ethernt/ethernet.c 使用
NET_DATA_SEND_TRY宏 (50)同一报文经消息队列最多重试 50 次,超限后由 check_idle_process() 丢弃
OSQ_DEAL_FAIL宏 (3)消息队列投递失败计数门限(事件码 EVENT_CODE_OSQ_DEAL_FAIL)
HEART_RST_FAIL宏 (3)心跳异常复位门限
DHCP_FAIL_NUM宏 (12)DHCP 连续失败门限
LOGIN_NO_ACK_NUM / LOGIN_NO_ACK_RST_NUM宏 (18 / 3)登录无应答门限与随之的复位次数门限
MAX_SIZE_TCP_PACKET宏 (1400)TCP 单包最大长度;与 midware/ethernt/ethernet.h:25 同名同值重复定义(内容一致,C 语言允许)
MAX_CNT_REQ_FILE_ERROR宏 (5)请求升级文件信息连续失败次数上限
MAX_CNT_REQUEST_FILE / MAX_CNT_RESUME_FILE宏 (50 / 50)请求文件、断点续传的重试次数上限
WIFI_TYPE_MAX_LEN / WIFI_TYPE_MAX_RESERVED_LEN宏 (30 / 10)网络类型字符串缓冲长度及为直连型号预留的长度
UPLOAD_INTERVAL_0xA3宏 (600)CMD_SEND_BMS_SELF_INFO(0xA3) 默认上传周期(秒)
MASK_CHECK_ALL_UPDATE / MASK_CHECK_EMS_SW / MASK_CHECK_INV1_SW / MASK_CHECK_INV2_SW宏升级版本校验掩码:全设备 0xFFFFFFFF、EMS 0x01、主逆变 0x04、从逆变 0x08
DEBUG_TCP_CLIENT_STATE宏 (0)本模块调试打印总开关,默认关闭

2.2 枚举

名称类型说明
ENDevType枚举报文首字节的"设备域":EMS = 0x01、SMART_HOME = 0x10
NET_CONNECT_TYPE枚举物理链路类型:W5500 = 0x01、WIRELESS = 0x02、MAX_NET_TYPE
ENCmdTMode枚举帧方向:REQUEST_COMM = 0x01(网关→服务器)、RESPONSE_COMM = 0x02(网关→服务器的应答)
ENCmdType枚举协议命令字(见 2.3)
ENStatus枚举net/ems.c 主状态机的全部状态,STATUS_IDLE 起步,STATUS_MAX 收尾(见 2.4)
ENInfoType枚举事件/即时消息位掩码(位域式枚举,见 2.5)
UpgradeInfoType枚举升级进度上报状态:UPGRADE_NONE/DOWNLOAD_START/DOWNLOAD_FINISH/UPGRADE_START/UPGRADE_FINISH
Uploadfaultscord枚举故障录波上传状态:UPLOAD_NONE/START/ING/FINISH(仅 INOVANCE 方案使用)

2.3 ENCmdType 命令字(按用途分组)

用途命令字
基础链路CMD_HEART_BEAT0x00、CMD_REGISTER0x01、CMD_LOGIN0x02
配置(旧/扩展 1/扩展 2)CMD_GET_CONFIG_INFO0x03、CMD_SEND_CONFIG_INFO0x04、CMD_GET_CONFIG_DEV_EXTEND10x14、CMD_SET_CONFIG_DEV_EXTEND10x15、CMD_GET_CONFIG_DEV_EXTEND20x60、CMD_SET_CONFIG_DEV_EXTEND20x61
信息/特殊指令CMD_SPECIAL_INTERFACE0x08、CMD_INFO_INTERFACE0x09
数据上报CMD_SEND_DAT_SYS_RUN0x05、CMD_SEND_DAT_SYS_RUN_EXTEND10x16、CMD_SEND_SECOND_DATA0x10、CMD_SEND_DISPATCH_DATE0x1C、CMD_SEND_ENERGY_DATE0x1D
电力辅助服务CMD_SEND_FCAS_DATA0x11、CMD_SEND_FFR_DATA0x12、CMD_SEND_VERY_FAST_FCAS_DATA0x19、CMD_SEND_FAST_FCAS_DATA0x1B、CMD_SEND_CT_SAMPLING_DATE0x1A
升级/续传/日志CMD_RESUME_INTERFACE0x0C、CMD_UPDATE_FAULT_LOG0x0D、CMD_UPDATE_ERROR_LOG0x0F、CMD_CHECK_UPDATE0x20、CMD_REQUEST_FILE_UPDATE0x21、CMD_SEND_UPGRADE_INFO0x24、CMD_SEND_BAT_LOG0x1F
老化/调试CMD_SEND_BURNIN_DATA0x18、CMD_SEND_DEBUG_RUN_INFO0x23、CMD_SEND_DEVICE_DEBUG_DATA0x50
设备明细CMD_SEND_RUN_INFO0x44、CMD_SEND_SELF_TEST_INFO0x45、CMD_SEND_SAFETY_INFO0x47、CMD_SEND_CELL_DATE0x55、CMD_SEND_FAULT_RECORD_DATA0x56、CMD_SEND_AFCI_LOG_DATA0x62、CMD_SEND_CAN_LOG_DATA0x63
安规配置CMD_SET_CONFIG0x42、CMD_GET_CONFIG0x43、CMD_SET_SAFETY_CONFIG_INFO0x4A、CMD_SEND_SAFETY_CONFIG_INFO0x4B、CMD_SET_CONFIG_EXTEND10x4C、CMD_GET_CONFIG_EXTEND10x4D、CMD_SEND_RUN_INFO_EXTEND10x4E、CMD_SET_SAFETY_CONFIG0x57、CMD_SEND_SAFETY_CONFIG0x58
电池/电表/油机CMD_SEND_BMS_SELF_INFO0xA3、CMD_RXD_METER_DATA0xA4、CMD_RXD_WIFI_INFO0xA5、CMD_SEND_MIXBAT_INFO0xA6、CMD_SEND_GENSET_DATA0x36

2.4 ENStatus 主状态机状态

STATUS_NONE(0) → STATUS_IDLE(1) → STATUS_RECONENCT(2) → … → STATUS_SEND_CAN_LOG_DATA(最后) → STATUS_MAX。 除 STATUS_NONE/STATUS_IDLE 外的状态基本都是"一次性动作":进入即组包投递,随即被 changed_state_tcp_protocol() 复位为 STATUS_IDLE。与业务对应的状态包括:登录/注册类(STATUS_LOGIN、STATUS_REGISTE、STATUS_HEART_BEART)、配置类(STATUS_READ_CONFIG、STATUS_READ_CONFIG_EXTEND1/2、STATUS_SEND_CONFIG、STATUS_SEND_CONFIG_EXTEND1/2、STATUS_GET_CONFIG、STATUS_SET_CONFIG*、STATUS_SEND_SAFETY_CONFIG*、STATUS_SET_SAFETY_CONFIG*)、数据类(STATUS_SEND_DATA_TO_SERVER、STATUS_SEND_SECOND_DATA、STATUS_SEND_ENERGY_DATA、STATUS_SEND_RUN_INFO*、STATUS_SEND_BMS_MIN_DATA、STATUS_SEND_BSM_SELF_INFO、STATUS_SEND_MIXBAT_INFO、STATUS_SEND_GENSET_DATA、STATUS_SEND_BURNIN_DATA、STATUS_SEND_DEBUG_RUN_INFO)、调频类(STATUS_SEND_FCAS_DATA、STATUS_SEND_FAST_FCAS_DATA、STATUS_SEND_VERY_FAST_FCAS_DATA、STATUS_SEND_FFR_DATA、STATUE_SEND_DISPATCH_DATA、STATUS_SEND_GRID_CT_SAMPLING_DATE)、升级类(STATUS_UPDATE_CHECK、STATUS_GET_UPDATE_FILE、STATUS_SEND_UPGRADE_INFO、STATUS_RESPSONED_FORCE_UPDATE)、续传类(STATUS_SEND_RESUME_TO_SERVER、STATUS_RESPSONED_RESUME)、以及一大批 STATUS_RESPSONED_*(对云端特殊指令的应答:重启/配置/远控/对时/调度/参数/功率因数/充电桩使能/域名/G100 重启/扩展域名/CAN 下发/SOC 校准/电池激活时间/上传周期/电芯品牌)。

2.5 ENInfoType 事件位掩码

SYSTEM_RESTART0x01、SOCKET_STATUS0x02、BMS_FIRM_DOWNLOAD0x04、INVC_FIRM_DOWNLOAD0x08、EVENT_LOG0x10、METER_FIRM_DOWNLOAD0x20、SERVER_SWITCH0x40、EVC_FIRM_DOWNLOAD0x80、INV_ARM_DOWNLOAD0x100、EVC_DEBUG_LOG0x200、INV_UPGRADE_LOG0x400、GRID_STATUS0x800、LEASE_STATUS0x1000、SOC_LOW_STATUS0x2000、INV_OVERLOAD_STATUS0x4000、PREVENT_BACKFLOW_STATUS0x8000、SELF_TEST_RESULT0x10000、BAT_SELFLOCK_STATUS0x20000、EEPROM_FAULT0x40000、ICDC_UPDATE_STATUS0x80000、AFCI_SELFCHECK_STATUS0x100000、AFCI_FIRM_DOWNLOAD0x200000、INFO_MAX。该掩码累积存放在 STEMSTab.u32InfoType 中,由 set_info_status() 置位、clear_info_status() 清除、get_info_status() 读取。

2.6 结构体

名称类型说明
STEMSTab结构体通信主控块(全局变量 g_stEMSInfo)。含登录/建链标志(bIsLogin、bIsBuiltSocket、b_modbus_Socket、bUpdateCheck)、当前升级/续传状态、配置读写状态(u8SetDevConfig*、u8GetDevConfig)、秒级时间戳(time_ticksenddata*、time_ticksenddatagen)与毫秒级 tick(u64TickLogin、u64TickReconnect、u64TickSendHeartBeat、u64TickSendConfigData*、u64TickRequestUpdateFile、u64TickCheckUpdateFile、u64TickSendResumeData、u64TickHeartRcv、u64TickSecData、u64TickRequestSysInfo*、u64TickSendAgingData、u64TickSendDebugRunData、u64TickSendEnergyDate、u32TickSendUpgradeData、u32TickSendBMSData、u32TickSendBMSSelfInfo、u32TickSendFaultRecord、u32TickSendMIXBatInfo、u32EMSTaskTick、u32TickSendUpdateInfo、u32_error_log_send_tick)、失败计数(u16OSQDealFailCnt、u16HeartRstCnt、u8LogInNoAckRstCnt、u8LogInCnt)、事件掩码 u32InfoType、安规配置标志 u8_set_safety_config_flag/u32_set_safety_config_tick、强制升级标志 u8_forceupdt_flag 与升级表指针 pstCurrUpt、升级表 stUpt[UPDT_MAX]
APP_TAB结构体局域网/APP 通道控制块(g_t_app_info):连接标志、心跳 tick 与九种一次性请求标志(设/读配置、运行信息、自检、扩展配置 1、安规配置)
FREQ_DISPATCH_BUFFER_T结构体(#pragma pack(1),约 16 KB)调频/调度数据环形缓存(g_t_freq_dispatch_data):t_datetime + 各 200 点的 u8_dispatch_flag、s16_batpower、s16_power、u16_freq、s32_meter_power、s32_pv_power、s32_pv_meter_power、s32_reactpower,加 u8_dispatch_mode、u32_dispatch_data_interval 和 11771 字节的 JSON 组装缓冲 u8_send_buff
DEBUG_RUN_INFO_T结构体调试运行数据上传配置:使能位、持续时间 u32_debug_run_info_time、上传间隔 u32_debug_run_info_time_interval
UPGRADE_INFO_T结构体升级过程上报块:u8_id_cmd_update[32](指令 ID)、u8_dev_code[16](设备码)、u8_upgrade_status、u32_upgrade_file_offset、结束原因字符串 s8_upgrade_end_reason[32],以及位域联合 u16_upgrade_error(web_error/download_error/system_ups/md5_error/timeout/boot_error)
FAULT_SCORD_T结构体(#pragma pack(1),约 40 KB)故障录波数据(仅 INVERTER_TYPE == INOVANCE_TYPE 时定义):record_id[9]、故障时间、4 组故障字 + 4 组告警字、s16_channel[19][320] 与 s32_channel[8][320] 采样通道
struct RTC_DateTime外部结构体(pcf8563.h/system_aux.h)系统时间结构(bYears 为 2000 偏移年),本文件多处用作报文时间戳来源

2.7 导出的全局变量(extern 声明,实际定义在 net/ems.c)

g_stEMSInfo(STEMSTab)、g_u8RestartFlag、g_u8SetConfigFlag、g_u8RemoteControlFlag、g_u8SyncFlag、g_u8DispatchFlag、g_u8ExtraFlag、g_u8RequestConfigFlag、g_u8RequestConfigFlagExtend11、g_u8RequestConfigFlagExtend12、g_u8appConfigFlag、g_u8appConfigFlagExtend1、g_u8appConfigFlagExtend2、g_u8_send_bms_self_info_flag、g_u8_resp_resume_flag、g_u8_powerfactor_flag、g_u8_evchargeen_flag、g_u8_sys_shutdownen_flag、g_u8_set_charge_flag、g_u8_request_safetyconfig_flag、g_u8_send_safetyconfig_flag、g_u8ReumeFailCnt、g_as8SpecialCmdId[32]、g_t_app_info、g_t_debug_run_info、g_u8_devicedebug_flag、g_u8_send_energy_data_flag、g_t_upgrade_run_info、g_u8_sys_self_test_flag、g_u8_icdcupdatet_flag、g_u8_g100_reboot_flag、g_u8_set_bms_activate_time_flag、g_u8_soc_calibration_flag、g_t_fault_scord_data、g_u8_bat_log_send_flag、g_u8_expand_icdcupdatet_flag、g_u8_resp_set_upload_interval、g_u8_resp_set_bat_brand。

3. 函数清单

本文件为纯头文件,不含函数定义,只声明 15 个接口函数(供 net/ems.c 实现、其它模块调用)。

函数名作用域(static/全局)说明(一句话)
socket_abnormal_handle (:508)全局声明套接字异常时复位登录/建链标志与状态机,供 midware/ethernt/ethernet.c 调用
tcp_init_ems (:509)全局声明初始化 EMS 通信全部 tick 与状态机,建链后调用
Set_Setup_Config_Status (:510)全局声明置位/清零"配置信息已发送"标志并复位发送 tick
Set_Setup_Config_Extend1_Status (:511)全局声明扩展配置 1 的同类标志设置
Set_Setup_Config_Extend2_Status (:512)全局声明扩展配置 2 的同类标志设置
set_info_status (:513)全局声明按位或置位事件掩码 u32InfoType
task_net_app (:514)全局声明网络应用任务主体,由 user/main.c:255 创建
get_info_status (:515)全局声明读取当前事件掩码
clear_info_status (:516)全局声明按传入掩码与运算清除事件位(调用方传 ~(1<<bit))
set_fault_scord_status (:517)全局声明推进故障录波分包序号(仅 INOVANCE 方案实现)
fault_scord_init (:518)全局声明初始化故障录波分包计数(仅 INOVANCE 方案实现)
reply_upload_can_log (:521)全局声明回复云端 UploadCanLog 指令,由 net/server.c 调用
check_can_log_upload_task (:522)全局声明(与 .c 中 static 定义不一致,见 7)CAN 日志采集轮询
is_can_log_upload_ready (:523)全局声明查询 CAN 日志是否还有待上报分片
fill_send_can_log_data (:524)全局声明打包一包 CAN 日志 JSON 报文

4. 核心逻辑解析

本文件无逻辑代码,此处说明它定义的"协议契约"如何在系统中被使用,以及常量之间的耦合关系。

帧结构契约:ENDevType(1 字节设备域)+ ENCmdTMode(1 字节方向)+ ENCmdType(1 字节命令字)+ 2 字节保留 + 2 字节长度(=报文总长-7),其后为 JSON 明文,末尾 2 字节 Modbus CRC16。net/ems.c:333 的 fill_common_data() 是唯一的封帧实现,net/server.c 按同一布局解帧。

状态机契约:s_u8Flag1(net/ems.c:115)保存当前 ENStatus;changed_state_tcp_protocol() 在传入值 ≥ STATUS_MAX 时强制回到 STATUS_IDLE,因此新增状态必须插入到 STATUS_MAX 之前。

时间基准:SENCOND_* 系列以毫秒为单位,与 OSTimeGet()(OS_TICKS_PER_SEC = 1000,即 1 tick = 1 ms,见 UCOSII/uCOS-CONFIG/os_cfg.h:51)配套使用;而 STEMSTab.time_ticksenddata* 保存的是 get_rtc_tick() 返回的 Unix 秒(midware/auxiliary/system_aux.c:373 用 mktime() 生成),两者在同一文件中混用,改动超时逻辑时须注意。

事件掩码契约:ENInfoType 是位掩码而非序号枚举,set_info_status() 只做或置位;net/server.c:6767-6770 通过 clear_info_status(~(1 << bitIndex)) 逐位清除,因此新增事件类型必须保证不超过 32 位(AFCI_FIRM_DOWNLOAD 已到 bit21,INFO_MAX 之后仍有空间)。

外部标志位契约:extern 的 g_u8*Flag 是"跨模块异步请求"的载体(如 logic/logic.c 置 g_u8DispatchFlag,通信任务在 check_idle_process() 中轮询并应答),无互斥保护,依赖单写多读的约定。

升级掩码契约:MASK_CHECK_* 与 net/upd_download.h 的 ENUpdateType 顺序对应(EMS→bit0、INV1→bit2、INV2→bit3),供 net/server.c 判断升级完成情况。

5. 对外接口

本文件导出(供其它模块使用)

本文件依赖的外部符号(用于其声明)

6. 依赖关系

依赖

被依赖(48 个文件 #include "ems.h",主要几类)

7. 备注与风险点

  1. clear_info_status() 的语义陷阱:实现是 g_stEMSInfo.u32InfoType &= type;(net/ems.c:2736),名字叫 clear 却做与运算。调用方必须传"取反后的保留掩码"(net/server.c:6770 传 ~(1 << bitIndex));传位掩码本身会把除该位以外的所有事件全部清掉。
  2. SENCOND_30M 命名与实际值不符:#define SENCOND_30M (1000 * 1800)(第 38 行)实际为 1800 秒 = 30 分钟,字面对应 30 分没错,但同一行注释风格与 SENCOND_1H (1000*3600) 混排,容易误读成"1800 分钟"。另 CMD_SEND_MIXBAT_INFO 在 net/ems.c:5242 直接硬编码 600000(10 分钟),未使用本文件的 SENCOND_600S。
  3. check_can_log_upload_task 声明与定义冲突:ems.h:522 声明为非 static,而 net/ems.c:6849 定义为 static void check_can_log_upload_task(void)。按 C 规则"static 声明跟随非 static 声明"属错误,Keil/ARMCC 会报错,本快照下该文件很可能无法编译(详见 net/ems.c.md 同类问题)。
  4. INOVANCE 专属声明未加条件编译:g_t_fault_scord_data、set_fault_scord_status()、fault_scord_init() 在 net/ems.c 中位于 #if (INVERTER_TYPE == INOVANCE_TYPE) 之内,而本头文件无条件 extern/声明它们;在 INVERTER_TYPE 取默认值 INVERTER_NULL(midware/inverter/inverter.h:172)的本快照中会出现"声明有、定义无",仅因当前无人链接才不报错(midware/inverter/inovance/inovance_comm_usart.c 会引用)。
  5. 重复声明/重复宏定义:g_u8_request_safetyconfig_flag、g_u8_send_safetyconfig_flag 在 486-487 行与 493-494 行各声明一次;MAX_SIZE_TCP_PACKET 与 midware/ethernt/ethernet.h:25 重复(值相同,无害但易失同步)。
  6. 命名与类型不一致:STEMSTab 中大量 u64/time_ 前缀字段实际是 u32(如 u64TickLogin、u64TickSendHeartBeat、time_ticksenddata 为 time_t);u32TickSendBMSSelfInfo 参与秒级 ×1000 的运算(net/ems.c:5205),存在 32 位毫秒计数回绕的隐患(约 49.7 天)。
  7. 本文件大量常量并未被 net/ems.c 使用。经逐项核对(grep -c,全部结果为 0,行号无引用):SENCOND_1MS、SENCOND_30MS、SENCOND_100MS、SENCOND_800MS、SENCOND_1S、SENCOND_3S、SENCOND_30S、SENCOND_90S、SENCOND_150S、SENCOND_180S、SENCOND_210S、SENCOND_300S、SENCOND_600S、SENCOND_30M、SENCOND_1H、SENCOND_3H、MAX_SIZE_TCP_PACKET、MAX_CNT_REQUEST_FILE、MAX_CNT_RESUME_FILE、MASK_CHECK_ALL_UPDATE、HEART_BEAT_FAIL、DHCP_FAIL_NUM、LOGIN_NO_ACK_NUM、OSQ_DEAL_FAIL、HEART_RST_FAIL。net/ems.c 实际只用 SENCOND_2S(1 次,且在 INOVANCE 条件编译块内)、SENCOND_5S(3)、SENCOND_10S(11)、SENCOND_15S(1)、SENCOND_60S(5)、REQUEST_UPDATE_INTERVAL(1)。MAX_CNT_REQ_FILE_ERROR、HEART_BEAT_FAIL、DHCP_FAIL_NUM、LOGIN_NO_ACK_NUM、OSQ_DEAL_FAIL、HEART_RST_FAIL 由 midware/ethernt/ethernet.c、data/net_event_log/net_event_log.c、net/server.c 使用。修改时不要假定这些常量与当前 net/ems.c 的超时逻辑一致。