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

diesel_generator.h

源文件路径:midware/meter/diesel_generator.h 所属模块:midware/meter(电表/油机中间件) 代码行数:88

1. 文件职责

这是油机(柴油发电机组)控制器 Modbus 采集模块的对外头文件。它把三类信息集中在一处:寄存器映射常量(Page 4/5/7/154 的起始寄存器号与寄存器个数)、查询时序常量(500ms 轮询节拍、15s 通讯丢失门限)、以及油机运行数据与节拍控制表的结构体定义。

在数据流中,它定义的数据模型是 EMS 对油机的"唯一视图":midware/meter/diesel_generator.c 按 500ms 节拍填充 g_t_diesel_gen,net/ems.c 读取该表组装 CMD_SEND_GENSET_DATA 报文上报云端。头文件同时用 extern 把 g_t_diesel_gen 暴露给网络层。

logic/ 层不 include 本文件——油机数据只做监视上报,不参与能量调度。

2. 关键数据结构与宏

名称类型说明
__DIESEL_GENERATOR_H__宏头文件防重复包含保护
GENSET_DEBUG_INFO宏0,调试打印开关;diesel_generator.c 用 #if GENSET_DEBUG_INFO 包裹全部 printf
GENSET_ADDR宏99,油机控制器的 Modbus 从站地址
DG_PAGE_4_A0_33_REG_ADDR宏4*256 = 1024 (0x0400),Page 4 "Basic Instrumentation" 起始寄存器(A0)
DG_PAGE_5_A10_11_REG_ADDR宏5*256+10 = 1290 (0x050A),Page 5 "Extended Instrumentation" 的 A10
DG_PAGE_7_A6_9_REG_ADDR宏7*256+6 = 1798 (0x0706),Page 7 "Accumulated Instrumentation" 的 A6
DG_PAGE_154_ALARM_REG_ADDR宏154*256 = 39424 (0x9A00),Page 154 "Alarm Conditions" 起始寄存器
DG_PAGE_4_A0_33_REG_NUM宏34,Page 4 一次读 34 个寄存器
DG_PAGE_5_A10_11_REG_NUM宏2,Page 5 一次读 2 个寄存器
DG_PAGE_7_A6_9_REG_NUM宏4,Page 7 一次读 4 个寄存器
DG_PAGE_154_ALARM_REG_NUM宏9,Page 154 一次读 9 个寄存器(8 个告警字 + 1 个被跳过的字)
DG_QUERY_SPEED_VALUE宏500,两次查询之间的最小间隔 500ms
DG_COMM_LOST_VALUE宏1000*15 = 15000ms,15 秒无有效响应判通讯丢失
Query_DG_E枚举页轮询序号:PAGE_4_BASIC_E=1、PAGE_5_EXTEND_E=2、PAGE_7_ACCUMULATED_E=3、PAGE_154_ALARM_E=4、PAGE_N_MAX_E=5
GENSET_RUN_TABLE_T结构体油机运行数据表(最后一个成员是 u16_alarm[8] 告警字数组)
GENSET_CONTROL_CMD_TABLE_T结构体时序控制表:u32_get_data_last_time、u32_dg_query_tick
DIESEL_GENERATOR_TABLE_T结构体汇总结构体:t_dg_run_data + t_dg_ctrl_cmd
g_t_diesel_genextern 变量DIESEL_GENERATOR_TABLE_T 的全局唯一实例,定义在 diesel_generator.c:20
genset_comm_handle函数声明油机采集入口,由 task_meter() 每轮调用

GENSET_RUN_TABLE_T 字段与量纲

字段类型量纲来源页(注释标注)
u16_dg_fuel_levelu161%p4
u16_dg_engine_bat_voltu160.1Vp4
u32_dg_fuel_consumptionu320.01 L/hp5
u32_dg_volt_a/b/cu320.1Vp4
u32_dg_cur_a/b/cu320.1Ap4
s32_dg_actpower_a/b/cs321Wp4(唯一有符号字段)
u32_dg_positive_energyu320.1kWhp7
u16_dg_frequ160.1Hzp4
u32_dg_engine_run_timeu321sp7
u16_alarm[8]u16[8]位域p154

Query_DG_E 枚举成员

成员值说明
PAGE_4_BASIC_E1基础仪表页(电气量、油位)
PAGE_5_EXTEND_E2扩展仪表页(油耗)
PAGE_7_ACCUMULATED_E3累积仪表页(运行时长、发电量)
PAGE_154_ALARM_E4告警页
PAGE_N_MAX_E5非真实页,仅作"回到起点"的哨兵值;同时也是静态游标的初值,使首次调用立即从 Page 4 开始

3. 函数清单

本文件为纯头文件,不包含任何函数定义,仅在 :86 声明了 1 个由 diesel_generator.c 实现的导出函数:

函数名作用域说明
void genset_comm_handle(void)全局(外部实现)油机数据轮询入口:判断使能、按 500ms 节拍轮流查询 4 个寄存器页、15s 无响应时清零数据

4. 核心逻辑解析

本文件无运行逻辑。以下说明它约定的寄存器映射、时序参数与数据模型如何被实现文件使用。

4.1 寄存器映射约定(非标准 Modbus 用法)

四组宏都用 page*256 + offset 的形式编码一个 16 位的 Modbus 寄存器号:

寄存器号 = (页号 << 8) | 页内寄存器号

4.2 时序参数

参数值作用
DG_QUERY_SPEED_VALUE500ms相邻两次查询(不同页)的最小间隔
DG_COMM_LOST_VALUE15000ms无任何有效响应即判丢失;等于 30 个查询周期(4 页轮换时约 7.5 个完整循环)

由于四页轮询 + 500ms 节拍,实现文件中一个完整数据刷新周期约 2 秒;15 秒门限相当于连续约 7 轮无响应才清零,对偶发丢帧有较好容忍度。

4.3 数据模型(三层结构体)

DIESEL_GENERATOR_TABLE_T g_t_diesel_gen
 ├── GENSET_RUN_TABLE_T          t_dg_run_data   ← 上报给云端的全部量测值
 └── GENSET_CONTROL_CMD_TABLE_T  t_dg_ctrl_cmd   ← 纯内部时序状态,不上报

4.4 与 uCOS-II 的配合

头文件不涉及任务、信号量或消息邮箱。约定为单写单读的共享全局数据:

4.5 通信协议帧格式

头文件不定义帧格式。帧格式全部在 diesel_generator.c 中以硬编码下标实现:请求 8 字节(地址 + 0x03 + 起始寄存器大端 + 数量大端 + CRC16/Modbus 小端),响应为标准 0x03 响应(地址 + 功能码 + 字节数 + 寄存器数据大端 + CRC)。头文件只提供了寄存器地址与数量这两类组帧参数。

4.6 未防御的取值点

DG_PAGE_154_ALARM_REG_NUM 定义为 9,而 GENSET_RUN_TABLE_T.u16_alarm[8] 长度为 8——实现文件正是靠"响应有 9 个寄存器、只取后 8 个"来对应的(跳过第一个寄存器)。这个 9 vs 8 的差值在头文件里没有任何注释说明,仅靠 diesel_generator.c 的偏移量隐含表达,是本文件最容易误读的地方。

5. 对外接口

导出(供外部调用)

名称说明
extern DIESEL_GENERATOR_TABLE_T g_t_diesel_gen全局油机数据表,net/ems.c:1585-1617 读取上报
void genset_comm_handle(void)油机采集入口,midware/meter/meter.c:5876 调用
GENSET_ADDR、DG_PAGE_*_REG_ADDR、DG_PAGE_*_REG_NUM寄存器映射宏(当前仅实现文件使用,未见其他文件引用)
DG_QUERY_SPEED_VALUE、DG_COMM_LOST_VALUE时序宏(当前仅实现文件使用)
Query_DG_E、GENSET_RUN_TABLE_T、GENSET_CONTROL_CMD_TABLE_T、DIESEL_GENERATOR_TABLE_T类型定义

使用的外部符号(本文件自身依赖)

名称来源
u16 / u32 / s32chip.h(:16 include);随 includes.h 或 MDK 器件头提供基本类型
TRUE仅在 diesel_generator.c 使用,本头文件未直接使用

6. 依赖关系

7. 备注与风险点

  1. DG_PAGE_154_ALARM_REG_NUM = 9 与 u16_alarm[8] 的数量差没有注释——实际语义是"Page 154 的 A0 不是告警字",但这层映射只存在于实现文件的字节偏移里,头文件读者无法从 9 与 8 的差异推断出究竟哪个寄存器被丢弃。
  2. 最后一次成员 u16_alarm[8] 是位域而不是位数组——云端上报时把 8 个 16bit 字逐个展开为 Alarm1..Alarm8(net/ems.c:1611-1614),语义是"每字 16 个告警位",但结构体里没有位域定义,位与告警项的对应关系完全依赖上游解析,EMS 侧不做展开。
  3. s32_dg_actpower_a/b/c 是全表唯一有符号字段——其余同名"测量值"都用 u32。同时 u32_dg_volt_*/u32_dg_cur_* 在报文中被当作无符号传给 fmt_fixed(),而 s32_dg_actpower_* 用 %d 直接格式化,类型约定在 net/ems.c 消费端也必须对齐,容易出错。
  4. chip.h 与工程统一公共头的混用——本目录其他头文件(如 bb_update.h、meter_upgrade.h)都用 #include <includes.h>,meter.h 亦同。本文件单独用 chip.h 属于风格不一致;一旦包含顺序变化(例如某 .c 先 include 本头文件再 include 别的),u16/u32 的可用性依赖 chip.h 是否已定义这些别名。
  5. 无统一量纲辅助宏——0.1V、0.01L/h、0.1kWh 等缩放因子只写在行尾注释里,net/ems.c 分别用 fmt_fixed(x, 10) / fmt_fixed(x, 100) 硬编码对应缩放,两边靠人工对齐,无编译期约束。
  6. GENSET_ADDR 硬编码 99——油机从站地址不可配置。若现场油机地址不是 0x63,整条采集链路静默失效(只表现为 15s 后数据清零,无显式配置项)。对比 meter.h 中电网/PV 电表地址都有成组宏,此处缺少可配置性。
  7. DG_PAGE_4_A0_33_REG_ADDR 等宏名把"页内寄存器号"写进名字,但表达式为 page*256——Page 5 的宏名带了 +10 却把常量写在表达式里(5*256+10),命名与实现一致,可读性尚可;但 DG_PAGE_4_A0_33_REG_ADDR 的 4*256 与名字中的 "A0" 对应关系需要读者自行体会。
  8. 时序宏未与底层总线超时联动——DG_QUERY_SPEED_VALUE(500ms) 远小于 usart1_send_data() 的超时(1000ms,见 meter.c:57)。若串口发送真的阻塞满 1 秒,则轮询节拍会被拉长,但代码没有做补偿;这是一个隐含的时序耦合,本文件未记录。
  9. extern 变量无 volatile、无访问函数收口——g_t_diesel_gen 直接暴露给 net/ 层,字段级约束(如告警 0x1111 表示无效)无法在头文件层面表达,只能靠约定。