net_event_log.h
源文件路径:
data/net_event_log/net_event_log.h所属模块:数据管理 / 网络事件日志(data/net_event_log) 代码行数:216
1. 文件职责
本头文件定义 EMS "网络/系统事件日志"模块的全部数据契约:Flash 分区地址(3 个地址备份扇区 + 32KB 事件数据环形区)、事件索引与事件码表大小、网络事件与命令事件的位域联合体、事件上报掩码、地址备份单元和 11 字节落盘记录结构。它还导出模块唯一的对外全局量 g_stNetEventLogInfo,供 midware/ethernt/ethernet.c 直接写状态位、供 net/ems.c 取事件日志文本。全部结构体置于 #pragma pack(1) 区间,保证与 Flash 落盘布局一一对应。头文件只暴露 3 个函数(初始化、周期扫描、读取上报),其余 5 个函数由 .c 内部自由使用。
2. 关键数据结构与宏
| 名称 | 类型 | 说明 |
|---|---|---|
DEBUG_EVENT_LOG | 宏 | 0,本模块调试打印总开关 |
EVENT_LOG_ADDR_RECORD_START1 / _END1 | 宏 | 0xFDC000 / 0xFDCFFF,地址备份区 1 |
EVENT_LOG_ADDR_RECORD_START2 / _END2 | 宏 | 0xFDD000 / 0xFDDFFF,地址备份区 2 |
EVENT_LOG_ADDR_RECORD_START3 / _END3 | 宏 | 0xFDE000 / 0xFDFEFF,地址备份区 3 |
EVENT_LOG_ADDR_START | 宏 | 0xFDF000,事件日志数据区起始 |
EVENT_LOG_ADDR_END | 宏 | 0xFE6FFF,事件日志数据区结束(32KB) |
EVENT_CODE_SIZE | 宏 | 32,事件码表(u8SetCode/u8ClearCode)深度 |
EVENT_CODE_NET_HARD_LINK | 宏 | 0x00,以太网物理连接事件索引 |
EVENT_CODE_NET_DHCP | 宏 | 0x01,DHCP 事件索引 |
EVENT_CODE_NET_DNS | 宏 | 0x02,DNS 事件索引 |
EVENT_CODE_NET_SOCK_STATUS | 宏 | 0x03,Socket 状态事件索引(已定义但 .c 未使用) |
EVENT_CODE_HEART_BEAT_FAIL | 宏 | 0x04,心跳超时事件索引 |
EVENT_CODE_HEART_BEAT_RST | 宏 | 0x05,心跳失败复位事件索引 |
EVENT_CODE_OSQ_DEAL_FAIL | 宏 | 0x06,OSQ 处理失败事件索引 |
EVENT_CODE_ETH_TASK_RUN_TIME_OUT | 宏 | 0x07,EthTask 超时事件索引 |
EVENT_CODE_EMS_TASK_RUN_TIME_OUT | 宏 | 0x08,EMSTask 超时事件索引 |
EVENT_CODE_SERIOUS_FAULT_RESET | 宏 | 0x0A,严重故障复位事件索引(注意 0x09 被跳过) |
NetEventTab | 联合体(pack(1)) | u32 u32NetCode 与 32 个 u8:1 位域叠加:bHardLink、bDHCP、bDNS、bSocketStatus、bHeartBeatFail、bHeartBeatRst、bOSQHandleFail、bEthTaskTimeOut、bEMSTaskTimeOut、bBit9、bSeriousFaultRst、bBit11~bBit31 |
CmdEventTab | 联合体(pack(1)) | u32 u32CmdCode 与位域 bSysRst + bBit1~bBit31;本文件仅做初始化,无扫描逻辑 |
EventMask | 联合体(pack(1)) | u32 u32Mask 与 bBit0~bBit31;用于逐事件开关上报(默认 0xffffffff) |
EventLogAddr | 结构体(pack(1)) | 单个 u32 u32EventLogAddr,即事件日志写指针的备份单元 |
NetEventLogTab | 结构体(pack(1)) | {NetEventTab stOldNetEvent; NetEventTab stNewNetEvent; EventMask stMask; u8 u8SetCode[32]; u8 u8ClearCode[32];} |
CmdEventLogTab | 结构体(pack(1)) | 与 NetEventLogTab 同构,位域类型为 CmdEventTab |
EventLogStoreTab | 结构体(pack(1)) | 落盘记录,共 11 字节:u16 u16Head(0x55AA)、u8 u8Time[6](年/月/日/时/分/秒)、u8 u8EventCode、u16 u16CRC |
g_stNetEventLogInfo | 全局变量(extern) | NetEventLogTab 实例,定义在 .c:26;被 midware/ethernt/ethernet.c 写入 stNewNetEvent 各状态位 |
3. 函数清单
本文件是纯声明头文件,不含函数定义;下表列出它声明的全部函数原型。
| 函数名 | 作用域 | 说明 |
|---|---|---|
event_log_init | 声明(全局) | 初始化事件日志模块:地址三元恢复 + 事件码表初始化 |
scan_system_event | 声明(全局) | 差分扫描系统事件并落盘 |
read_event_log_data | 声明(全局) | 读取最近记录并生成 JSON 文本写入入参缓冲 |
.c中还实现了 5 个未在本头文件声明的全局函数(event_log_tab_init、event_log_addr_init、write_event_log_addr_to_flash、write_event_log_data_to_flash、save_event_log_data),它们无法通过本头文件被其它模块引用。
4. 核心逻辑解析
本文件不含可执行逻辑,以下说明其数据布局对运行时行为的约束。
4.1 Flash 地址布局
| 区域 | 地址范围 | 大小 | 用途 |
|---|---|---|---|
| 备份区 1 | 0xFDC000~0xFDCFFF | 4KB | 写指针 4 字节/条,最多 1024 条后从头覆盖 |
| 备份区 2 | 0xFDD000~0xFDDFFF | 4KB | 同上 |
| 备份区 3 | 0xFDE000~0xFDFEFF | 约 7.75KB | 同上(声明跨度与 4KB 扇区粒度不自洽) |
| 数据区 | 0xFDF000~0xFE6FFF | 32KB | 11 字节/条的事件记录环形区(约 2980 条) |
注意 EVENT_LOG_ADDR_START(0xFDF000) 落在备份区 3 的声明范围 [0xFDE000, 0xFDFEFF] 之内,存在实际地址重叠(详见第 7 节第 2 条)。
4.2 事件码编码规则
u8SetCode[] / u8ClearCode[] 由 .c 的 event_log_tab_init 按 i*2+1 与 i*2+2 生成,即事件索引 i 与事件码一一配对:
| 事件索引 | 事件 | 置位码 | 清零码 |
|---|---|---|---|
| 0x00 | 物理连接 | 0x01 | 0x02 |
| 0x01 | DHCP | 0x03 | 0x04 |
| 0x02 | DNS | 0x05 | 0x06 |
| 0x03 | Socket 状态 | 0x07 | 0x08 |
| 0x04 | 心跳超时 | 0x09 | 0x0A |
| 0x05 | 心跳复位 | 0x0B | 0x0C |
| 0x06 | OSQ 失败 | 0x0D | 0x0E |
| 0x07 | EthTask 超时 | 0x0F | 0x10 |
| 0x08 | EMSTask 超时 | 0x11 | 0x12 |
| 0x0A | 严重故障复位 | 0x15 | 0x16 |
u8_c 字段仅有单个字节,因此事件码上限为 32×2+2 = 66,实际只用到 0x01~0x16。
4.3 位域与位序约定
NetEventTab/EventMask 采用"每个 u8 承载 8 位、共 4 个 u8 拼成 u32"的写法。在 #pragma pack(1) + 32 位小端 ARM 下,位域声明顺序与 u32 的 bit0~bit31 顺序一致,因此可以安全地把 u32_all 当整体使用(.c 里用 stBit.bBitN 直接索引,不依赖 u32 视图)。bBit9、bBit11~bBit31 是保留占位,当前无生产者也无消费者。
4.4 对外契约
g_stNetEventLogInfo.stNewNetEvent是生产者写、消费者读的单向通道:midware/ethernt/ethernet.c只置位,scan_system_event()读取后把对应位回抄到stOldNetEvent(即"读后自适应"),因此不会丢事件也不会重复上报(除 Socket 分支外)。stMask默认0xffffffff,全部事件上报打开;置 0 可屏蔽对应事件而不影响状态位更新逻辑里的比较。read_event_log_data(s8 *buf)的buf由调用方提供,需能容纳 16×21 字符的时间串加 JSON 包装(约 400 字节以上);.c内部使用无长度限制的sprintf。
5. 对外接口
导出的类型与宏
第 2 节全部结构体/联合体/宏,以及 Flash 分区常量与事件索引常量。
导出的全局变量
| 变量 | 说明 |
|---|---|
g_stNetEventLogInfo | 唯一导出的上下文,被 midware/ethernt/ethernet.c:393/400/678/921/923/951/953/1038/1059/1385/1396/1402/1434/1445/1460/1524 写入 stNewNetEvent 各状态位 |
导出的函数
见第 3 节,共 3 个原型。
本文件调用的外部接口
仅包含 chip.h 以获取 u8/u16/u32 基础类型,无函数调用。
6. 依赖关系
依赖
chip.h(u8/u16/u32类型定义)
被依赖
data/net_event_log/net_event_log.c(唯一实现者,实现event_log_init/scan_system_event/read_event_log_data并使用全部类型)midware/ethernt/ethernet.c:20(写g_stNetEventLogInfo状态位)net/ems.c:43(调用read_event_log_data,位于obtain_event_log_data)
7. 备注与风险点
- 头文件与实现的接口不对齐:
.c中另有 5 个全局函数(event_log_tab_init、event_log_addr_init、write_event_log_addr_to_flash、write_event_log_data_to_flash、save_event_log_data)以及 4 个全局变量(g_stEventLogAddr、g_stEventLogAddrFirst/Second/Third、g_stCmdEventLogInfo、g_stEventLogStoreInfo)未在此声明,存在符号污染与误引用风险;若其它模块自行extern同名符号会出现重复定义。 - 地址区间自相矛盾:
EVENT_LOG_ADDR_RECORD_END3 = 0xFDFEFF而EVENT_LOG_ADDR_START = 0xFDF000,两者重叠 4KB。同为 4KB 扇区粒度的备份区 1/2 的END都是"START + 0xFFF",只有 3 号用了+0x1EFF,看起来是笔误(可能本意是0xFDEFFF),但会实际造成备份区 3 与事件数据区互相覆盖。另外EVENT_LOG_ADDR_RECORD_END1/END2/END3三个宏在.c中从未被使用。 EVENT_CODE_NET_SOCK_STATUS定义了但未使用:.c的 Socket 分支直接写g_stNetSysInfo.u8SocketStatus原始值,绕过了本头文件设计的"事件索引 → 配对码"机制。- 事件索引
0x09缺失:EVENT_CODE_SERIOUS_FAULT_RESET = 0x0A之前没有0x09对应宏,bBit9也成为永久占位位。 CmdEventTab/CmdEventLogTab是未完成的设计:只有bSysRst一位有实义、.c里只做初始化,没有任何扫描或上报逻辑,却占用了 68 字节的静态上下文。u8SetCode/u8ClearCode数组用宏EVENT_CODE_SIZE = 32定义,但事件码表其实只由事件索引计算:若以后新增事件索引超过 31(例如把索引改成语义化的 20、30),i*2+1会溢出字节并越界写u8SetCode[32],该数组没有任何边界校验。- 无版本/魔数兼容设计:
EventLogStoreTab没有版本字段,也没有endcode之类的数据版本校验(对比flash_data_store的RESUME_END_CODE),因此固件升级后若改变记录结构,旧数据只能靠 CRC16 概率性排除。 #pragma pack(1)依赖编译器行为:位域联合体的内存映射是"实现定义"行为,本头文件把它作为二进制协议对外暴露,换编译器/换优化等级需重新验证。