Files
CCU621M/app/fault_cheak/fault_interface.c
T

955 lines
45 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "fault_cheak/faultcheck_task.h"
#include "flash_file_mgr/fault_flash_impl.h"
#include "app_init/app_init.h"
#include "mylog/mylog.h"
#include "app_rtc/app_rtc.h"
#include "fault_cheak/fault_interface.h"
#include "collect_ctrl/collect_task.h"
#include "flowctrl/flow_interface.h"
#if(FATFS_EN)
#include "app_fatfs/fatfs_init.h"
#endif
#if(MY_SHELL_EN) //Shell 使能
#include "letter_shell/shell_port.h"
#endif
#define FAULT_TEST 0 //测试使能 1则屏蔽故障信息
#define FAULT_LOG(fmt, ...) MYLOG_MSG(TASK_ID_FaultCheck, (fmt), ##__VA_ARGS__)
//extern S_HIS_FAULT_MNG s_hisFaultMng; //故障告警信息记录
extern REAL_FAULT_DATA_T s_real_fault; //实时故障告警记录存储
//故障动作缓存
static FAULT_ACTION_CACHE_T s_fault_action_cache = {0};
static void v_set_fault_data_internal(E_FAULT_SITE f_site ,E_FAULT_TYPE type , E_FAULT_INFO e_info, U8_T action_type, S16_T data1 , S16_T data2);
static void v_fault_persist_record(HIS_FAULT_DATA_T *fault_data);
/**
* @brief 将故障动作持久化到 Flash,并在 FATFS 故障模块使能时写入缓存
*/
static void v_fault_persist_record(HIS_FAULT_DATA_T *fault_data)
{
#if (FAULT_FLASH_MGR_ENABLE)
v_hisFault_save_record(fault_data);
#endif
#if FATFS_ENABLE_FAULT
cache_add_fault(fault_data);
#endif
}
#if 1 //故障说明映射表
const static S_FAULT_INFO fault_info[] =
{
//常规停止代码
{E_NORMAL_1000, "Charge complete stop"}, // 充满停止
{E_NORMAL_1001, "Local stop charging"}, // 本地停止充电
{E_NORMAL_1002, "Remote stop charging"}, // 后台停止充电
{E_NORMAL_1003, "Stop at set charging time"}, // 达到设置充电时长停止
{E_NORMAL_1004, "Stop at set energy"}, // 达到设置充电电量停止
{E_NORMAL_1005, "Stop at set amount"}, // 达到设置充电金额停止
{E_NORMAL_1006, "Stop at offline condition"}, // 达到离线停机条件
{E_NORMAL_1007, "Stop at SOC threshold"}, // 达到SOC终止条件停止
{E_NORMAL_1008, "User unplug stop"}, // 用户拔枪停止
{E_NORMAL_1009, "APP stop charging"}, // APP停止充电
// {E_NORMAL_1010, "Vehicle S2 proactive disconnect"}, // 车端S2主动断开
{E_NORMAL_1011, "BMS stop charging"}, // BMS停止充电
{E_NORMAL_1012, "Insufficient account balance"}, // 账户余额不足
{E_NORMAL_1013, "Insufficient prepay amount"}, // 预付金额不足
// {E_NORMAL_1014, "Vehicle S2 close timeout"}, // 车辆S2闭合超时
// {E_NORMAL_1015, "Vehicle S2 disconnect timeout while charging"}, // 充电中车辆S2断开超时
{E_NORMAL_1016, "Stop at trickle charging condition"}, // 达到涓流充电停机条件
//直流充电设备异常代码
{E_FAULT_13000, "AC input breaker fault"}, // 交流输入断路器故障
{E_FAULT_13001, "SPD fault"}, // 避雷器故障
{E_FAULT_13002, "AC input contactor sticking fault"}, // 交流输入接触器粘连故障
{E_FAULT_13003, "AC input contactor action fault"}, // 交流输入接触器拒动/误动故障
{E_FAULT_13004, "DC output contactor sticking fault"}, // 直流输出接触器粘连故障
{E_FAULT_13005, "DC output contactor action fault"}, // 直流输出接触器拒动/误动故障
{E_FAULT_13006, "DC output fuse fault"}, // 直流输出熔断器故障
{E_FAULT_13007, "Auxiliary power fault"}, // 辅助电源故障
{E_FAULT_13008, "Discharge relay action fault"}, // 泄放继电器拒动/误动故障
{E_FAULT_13009, "Discharge relay sticking"}, // 泄放继电器粘连
{E_FAULT_13010, "Gun e-lock lock fault"}, // 充电枪电子锁上锁故障
{E_FAULT_13011, "Gun e-lock unlock fault"}, // 充电枪电子锁解锁故障
// {E_FAULT_13012, "PE disconnection fault"}, // PE 断线故障
{E_FAULT_13013, "Charging connector overtemperature fault"}, // 充电接口过温故障
{E_FAULT_13014, "Charging connector overtemperature warning"}, // 充电接口过温告警
{E_FAULT_13015, "Control pilot voltage abnormal"}, // 控制导引电压异常
{E_FAULT_13016, "Control pilot fault while charging"}, // 充电中车辆控制导引故障
{E_FAULT_13017, "Emergency stop fault"}, // 急停
{E_FAULT_13018, "Door access fault"}, // 门禁
{E_FAULT_13019, "Cabinet door access fault"}, // 充电机柜门禁故障
{E_FAULT_13020, "Power control module fault"}, // 功率控制模块故障
{E_FAULT_13021, "Power control module warning"}, // 功率控制模块告警
{E_FAULT_13022, "Power control module communication fault"}, // 功率控制模块通信故障
{E_FAULT_13023, "Bridge contactor action fault"}, // 桥接接触器拒动/误动故障
{E_FAULT_13024, "Bridge contactor sticking fault"}, // 桥接接触器粘连故障
// {E_FAULT_13025, "ESAM fault"}, // ESAM 故障
{E_FAULT_13026, "Liquid cooling oil overtemperature"}, // 液冷油温过高
// {E_FAULT_13027, "Charger overtemperature fault optional"}, // 充电桩过温故障( 可选)
// {E_FAULT_13028, "Charger overtemperature warning optional"}, // 充电桩过温告警( 可选)
// {E_FAULT_13029, "Cabinet overtemperature warning"}, // 充电机柜过温告警
// {E_FAULT_13030, "Cabinet overtemperature fault"}, // 充电机柜过温故障
{E_FAULT_13031, "Liquid cooling warning"}, // 液冷报警
{E_FAULT_13032, "Smoke alarm warning"}, // 烟感报警
{E_FAULT_13033, "Charger water immersion fault"}, // 充电桩水浸故障
// {E_FAULT_13034, "Cabinet water immersion fault"}, // 充电机柜水浸故障
{E_FAULT_13035, "Cabinet humidity warning"}, // 充电机环境湿度告警
// {E_FAULT_13036, "Data validity check failure"}, // 数据合法性校验失败
// {E_FAULT_13037, "Controller version check not finished"}, // 充电控制器 版本校验 未完成
// {E_FAULT_13038, "Controller charging parameter download not finished"}, // 充电控制器 下发充电参数 未完成
// {E_FAULT_13039, "Charger paused service reject start"}, // 充电桩暂停服务, 拒绝启动
{E_FAULT_13040, "Previous charge complete but not unplugged"}, // 上次充电完成未拔枪
// {E_FAULT_13041, "Vehicle not connected reject start"}, // 充电桩与车辆处于未连接状态,拒绝启动
{E_FAULT_13042, "Insulation monitoring fault"}, // 绝缘监测故障
{E_FAULT_13043, "Insulation monitoring warning"}, // 绝缘监测告警
// {E_FAULT_13044, "Power allocation strategy execution failure"}, // 充电桩执行功率分配策略失败故障
// {E_FAULT_13045, "Reserved input overvoltage fault"}, // 预留( 输入电压过压故障)
// {E_FAULT_13046, "Reserved input undervoltage fault"}, // 预留( 输入电压欠压故障)
{E_FAULT_13047, "Discharge circuit fault"}, // 泄放回路故障
{E_FAULT_13048, "DC output overvoltage fault"}, // 直流输出电压过压故障
{E_FAULT_13049, "DC output overcurrent fault"}, // 直流输出电流过流故障
{E_FAULT_13050, "DC output undervoltage fault"}, // 直流输出电压欠压故障
// {E_FAULT_13051, "No idle module available"}, // 无空闲模块可用( 限智能分配功率)
// {E_FAULT_13052, "Battery reverse connection fault"}, // 电池反接故障
{E_FAULT_13053, "Precharge regulation failure"}, // 预充阶段调压失败
{E_FAULT_13054, "Output current exceeds vehicle demand"}, // 输出电流大于车辆需求电流
{E_FAULT_13055, "Power controller not in working state while charging"}, // 充电过程中功率控制器为非工作状态
{E_FAULT_13056, "Energy metering abnormal"}, // 电能计量异常
{E_FAULT_13057, "Vehicle authentication code mismatch"}, // 车辆鉴权码不一致
// {E_FAULT_13058, "Unreported transaction records full"}, // 未上送交易记录已满
// {E_FAULT_13059, "Transaction record storage failure"}, // 交易记录存储失败
// {E_FAULT_13060, "CAN protocol version check abnormal"}, // CAN 通讯版本校验异常
// {E_FAULT_13061, "Process running abnormal"}, // 进程运行异常
// {E_FAULT_13062, "Program file checksum failure"}, // 程序文件校验失败
// {E_FAULT_13063, "Program file damaged"}, // 程序文件损坏
{E_FAULT_13064, "Illegal VIN"}, // 非法 VIN
// {E_FAULT_13065, "Non plug and charge device"}, // 非即插即充设备
// {E_FAULT_13066, "Charger in pause state"}, // 充电桩处于“暂停” 状态( 27930中的暂停状态)
{E_FAULT_13067, "Plug and charge authentication failed"}, // 即插即充鉴权失败
// {E_FAULT_13068, "Pause timeout while charging"}, // 充电桩充电中暂停超时( 27930中的暂停充电)
{E_FAULT_13069, "Charging controller communication timeout"}, // 充电控制器通讯超时
{E_FAULT_13070, "Card reader communication timeout"}, // 读卡器通讯超时
{E_FAULT_13071, "Meter communication timeout"}, // 电表通讯超时
{E_FAULT_13072, "Controller communication timeout in dual gun one vehicle mode"}, // 两枪同充一车模式下充电控制器间通信超时
{E_FAULT_13074, "Liquid cooling communication timeout"}, // 液冷通讯超时
// {E_FAULT_13073, "Abnormal power loss"}, // 异常掉电
// {E_FAULT_13074, "Reserved"}, // 预留
{E_FAULT_13075, "Power controller inter-communication timeout"}, // 功率控制器间通讯超时
// {E_FAULT_13076, "Power controller remote control telemetry timeout"}, // 功率控制器接收遥控、 遥信报文超时故障
// {E_FAULT_13077, "Power controller environment module communication timeout"}, // 功率控制器与环境信息采集模块通讯超时
// {E_FAULT_13078, "Vehicle identification frame receive timeout"}, // 车辆识别数据帧接收超时
// {E_FAULT_13079, "Charge start command response timeout"}, // 充电启动命令应答超时
// {E_FAULT_13080, "Wait charge start complete timeout"}, // 等待充电启动完成状态超时
// {E_FAULT_13081, "Charge stop command response timeout"}, // 充电停止命令应答超时
// {E_FAULT_13082, "Wait charge stop complete timeout"}, // 等待充电停止完成状态超时
// {E_FAULT_13083, "Charge start complete confirm timeout"}, // 充电启动完成状态确认超时
// {E_FAULT_13084, "Power regulation command response timeout"}, // 功率调节指令应答超时
// {E_FAULT_13085, "Charge stop complete confirm timeout"}, // 充电停止完成状态确认超时
// {E_FAULT_13086, "Controller communication abnormal in parallel charging"}, // 充电控制器间并枪时通信异常
// {E_FAULT_13087, "Power controller address conflict"}, // 功率控制器地址冲突
// {E_FAULT_13088, "Charging controller address conflict"}, // 充电控制器地址冲突
{E_FAULT_13089, "HMI communication abnormal"}, // 人机通信异常
// {E_FAULT_13090, "Device self-check timeout fault"}, // 设备自检超时故障
// {E_FAULT_13091, "Internal communication fault"}, // 内部通讯故障
// {E_FAULT_13092, "Parking lock fault"}, // 车位锁故障
// {E_FAULT_13093, "Parking lock battery exhausted"}, // 车位锁电池耗尽故障
// {E_FAULT_13094, "Parking lock down lock failure"}, // 车位锁落锁失败故障
// {E_FAULT_13095, "Terminate order number abnormal"}, // 终止订单号异常
{E_FAULT_13096, "DCU output box communication fault"}, // 开出盒通讯故障(DCU)
// {E_FAULT_13097, "Input box communication fault"}, // 开入盒通讯故障
// {E_FAULT_13098, "Insulation sampling box communication fault"}, // 绝缘采样盒通讯故障
{E_FAULT_13099, "AB board communication fault"}, // AB板通讯故障
// {E_FAULT_13100, "Pilot board communication fault"}, // 导引板通讯故障
// {E_FAULT_13101, "Lamp board communication warning"}, // 灯板通讯告警
// {E_FAULT_13102, "Unknown stop reason from charging controller"}, // 充电控制器未知停止原因
{E_FAULT_13103, "Aux power voltage switching circuit fault"}, // 辅助电源电压切换回路故障
{E_FAULT_13104, "Output current exceeds vehicle maximum"}, // 输出电流超过车辆最高允许电流
// {E_FAULT_13105, "System clock abnormal"}, // 系统时钟异常
// {E_FAULT_13106, "Billing model request timeout fault"}, // 计费模型请求超时故障
// {E_FAULT_13107, "Billing model invalid fault"}, // 计费模型不合法故障
// {E_FAULT_13108, "Time synchronization timeout fault"}, // 对时超时故障
// {E_FAULT_13109, "Invalid time synchronization fault"}, // 对时时间不合法故障
//直流充电电源异常代码
{E_FAULT_14000, "Switch module fault"}, // 开关模块故障
{E_FAULT_14001, "Switch module warning"}, // 开关模块告警
{E_FAULT_14002, "Switch module communication fault"}, // 开关模块通信故障
{E_FAULT_14003, "Switch module action fault"}, // 开关模块拒动/误动故障
{E_FAULT_14004, "Switch module sticking fault"}, // 开关模块粘连故障
// {E_FAULT_14005, "Reserved switch module action warning"}, // 预留(开关模块拒动/误动告警)
// {E_FAULT_14006, "Reserved switch module sticking warning"}, // 预留(开关模块粘连告警)
{E_FAULT_14007, "Charging module fault"}, // 充电模块故障
// {E_FAULT_14008, "Charging module overtemperature fault"}, // 充电模块过温故障
// {E_FAULT_14009, "Charging module overtemperature warning"}, // 充电模块过温告警
// {E_FAULT_14010, "Charging module output short-circuit fault"}, // 充电模块输出短路故障
// {E_FAULT_14011, "Charging module output overcurrent warning"}, // 充电模块输出过流告警
// {E_FAULT_14012, "Charging module output overvoltage warning"}, // 充电模块输出过压告警
// {E_FAULT_14013, "Charging module output undervoltage warning"}, // 充电模块输出欠压告警
// {E_FAULT_14014, "Charging module AC input warning"}, // 充电模块交流输入告警
// {E_FAULT_14015, "Charging module input overvoltage warning"}, // 充电模块输入过压告警
// {E_FAULT_14016, "Charging module input undervoltage warning"}, // 充电模块输入欠压告警
// {E_FAULT_14017, "Charging module input phase loss warning"}, // 充电模块输入缺相告警
// {E_FAULT_14018, "Charging module input unbalance warning"}, // 充电模块输入不平衡告警
{E_FAULT_14019, "Charging module communication fault"}, // 充电模块通信故障
{E_FAULT_14020, "Charging module start failure"}, // 充电模块启动失败
{E_FAULT_14021, "Charging module shutdown failure"}, // 充电模块关机失败
// {E_FAULT_14022, "Charging module fan fault"}, // 充电模块风扇故障
// {E_FAULT_14023, "Charging module discharge fault"}, // 充电模块泄放故障
// {E_FAULT_14024, "Charging module address abnormal"}, // 充电模块地址异常
// {E_FAULT_14025, "PFC circuit overtemperature fault"}, // PFC 电路过温故障
// {E_FAULT_14026, "Main transformer overtemperature fault"}, // 主变压器过温故障
// {E_FAULT_14027, "DC/DC circuit overtemperature fault"}, // DC/DC 电路过温故障
// {E_FAULT_14028, "Output isolation diode fault"}, // 输出隔离二极管故障
// {E_FAULT_14029, "Module start fault non-protection induced"}, // 模块启动故障(非保护动作造成的模块启动失败)
// {E_FAULT_14030, "PFC circuit general fault"}, // PFC 电路总故障
// {E_FAULT_14031, "PFC circuit overvoltage fault"}, // PFC 电路过压故障
// {E_FAULT_14032, "PFC circuit bias fault"}, // PFC 电路偏压故障
// {E_FAULT_14033, "DC/DC circuit general fault"}, // DC/DC 电路总故障
// {E_FAULT_14034, "High/low voltage switching circuit fault"}, // 高低压切换电路故障
// {E_FAULT_14035, "Output circuit unbalance fault"}, // 输出电路不平衡故障
// {E_FAULT_14036, "Charging module no-output warning"}, // 充电模块不输出告警
// {E_FAULT_14037, "Outside contactor voltage above charger max before start"}, // 启动充电前直流输出接触器外侧电压大于充电机最大输出电压
// {E_FAULT_14038, "Outside contactor voltage below charger min before start"}, // 启动充电前直流输出接触器外侧电压小于充电机最小输出电压
//直流充电车辆异常代码
{E_FAULT_15000, "BMS communication fault"}, // BMS 通讯故障
{E_FAULT_15001, "DC charging controller judges BMS fault"}, // 直流充电控制模块判断BMS故障
// {E_FAULT_15002, "BMS fault information reported"}, // BMS 发送故障信息
{E_FAULT_15003, "BCP charging parameter frame timeout"}, // BCP 充电参数配置报文超时
{E_FAULT_15004, "BRO ready frame timeout"}, // BRO 充电准备就绪报文超时
{E_FAULT_15005, "BCS battery status frame timeout"}, // BCS 电池充电状态报文超时
{E_FAULT_15006, "BCL battery demand frame timeout"}, // BCL 电池充电需求报文超时
{E_FAULT_15007, "BST stop charging frame timeout"}, // BST 中止充电报文超时
{E_FAULT_15008, "BSM battery status frame timeout"}, // BSM 动力蓄电池状态报文超时
{E_FAULT_15009, "BRO frame 0x00 receive timeout"}, // BRO 报文(0x00 接收超时
{E_FAULT_15010, "BRO frame 0xAA receive timeout"}, // BRO 报文(0xAA 接收超时
{E_FAULT_15011, "BRM vehicle identification frame timeout"}, // BRM 车辆辨识报文超时
// {E_FAULT_15012, "BSM single cell overvoltage"}, // BSM 报文中单体动力蓄电池电压过高
// {E_FAULT_15013, "BSM single cell undervoltage"}, // BSM 报文中单体动力蓄电池电压过低
// {E_FAULT_15014, "BSM SOC too high"}, // BSM 报文中 SOC 过高
// {E_FAULT_15015, "BSM SOC too low"}, // BSM 报文中 SOC 过低
// {E_FAULT_15016, "BSM charging overcurrent"}, // BSM 报文中充电过流
// {E_FAULT_15017, "BSM battery overtemperature"}, // BSM 报文中动力蓄电池温度过高
// {E_FAULT_15018, "BSM battery insulation abnormal"}, // BSM 报文中动力蓄电池绝缘状态异常
// {E_FAULT_15019, "BSM connector connection abnormal"}, // BSM 报文中连接器连接状态异
// {E_FAULT_15020, "BRO canceled after ready"}, // BRO 准备就绪后取消
// {E_FAULT_15021, "BST unknown stop fault"}, // BST 停止未知故障
// {E_FAULT_15022, "BST insulation fault"}, // BST 绝缘故障
// {E_FAULT_15023, "BST connector overtemperature"}, // BST 连接器过温
// {E_FAULT_15024, "BST component and output connector overtemperature"}, // BST 元件、 输出连接器过温
// {E_FAULT_15025, "BST connector fault"}, // BST 连接器故障
// {E_FAULT_15026, "BST battery pack over-temperature"}, // BST 电池组过温
// {E_FAULT_15027, "BST other fault"}, // BST 其他故障
// {E_FAULT_15028, "BST detection point 2 voltage detection fault"}, // BST 检测点 2 电压检测故障
// {E_FAULT_15029, "BST high-voltage relay fault"}, // BST 高压继电器故障
// {E_FAULT_15030, "BST overcurrent"}, // BST 电流过大
// {E_FAULT_15031, "BST voltage abnormal"}, // BST 电压异常
// {E_FAULT_15032, "BRM frame data item abnormal"}, // BRM 报文数据项异常
// {E_FAULT_15033, "BCP frame data item abnormal"}, // BCP 报文数据项异常
{E_FAULT_15034, "Outside contactor voltage exceeds 60V before insulation test"}, // 绝缘监测前直流输出接触器外侧电压越限(60V)
{E_FAULT_15035, "Outside contactor voltage differs from battery frame over +/-5%"}, // 启动充电前直流输出接触器外侧电压与通信报文电池电压相差>±5%
{E_FAULT_15036, "Battery max charge voltage below charger minimum output voltage"}, // 电池最高允许充电电压小于充电机最小输出电压
{E_FAULT_15037, "Output voltage exceeds vehicle max charge voltage"}, // 输出电压大于车辆最高允许充电电压
{E_FAULT_15038, "Demand current exceeds vehicle max charge current"}, // 需求电流超过车辆最高允许充电电流
{E_FAULT_15039, "Demand voltage exceeds vehicle max charge voltage"}, // 需求电压超过车辆最高允许充电电压
{E_FAULT_15040, "BCS max cell voltage exceeds BCP allowed max cell voltage"}, // BCS 中最高单体电池电压超过BCP 中最高允许单体电池电压
// {E_FAULT_15041, "BSM max battery temp exceeds BCP allowed max temp"}, // BSM 中最高动力蓄电池温度超过BCP 中单体动力蓄电池最高允许温度
{E_FAULT_15042, "SOC reached upper limit"}, // SOC 达到上限值
// {E_FAULT_15043, "BMS communication protocol version mismatch"}, // BMS 通信协议版本不匹配
{E_FAULT_15044, "Output current exceeds maximum allowed charging current"}, // 输出电流大于最高允许充电电流
{E_FAULT_15045, "Battery terminal voltage exceeds maximum allowed charge voltage"}, // 电池端电压大于电池最高允许充电电压
// {E_FAULT_15046, "SOC reaches 100 with continuous large current request optional"}, // SOC 达到 100 持续请求大电流(可选)
};
#endif
#if 1 //故障动作缓存管理
/**
* ************************************************************************
* @brief - 故障动作缓存初始化
*
*
* @author jiankalka
* @date 2025-12-18
* ************************************************************************
*/
void v_fault_cache_init(void)
{
memset(&s_fault_action_cache, 0, sizeof(FAULT_ACTION_CACHE_T));
s_fault_action_cache.front = 0;
s_fault_action_cache.rear = 0;
s_fault_action_cache.count = 0;
}
/**
* ************************************************************************
* @brief - 添加故障动作到缓存队列
*
* @param[in] f_site - 故障位置
* @param[in] type - 动作类型
* @param[in] e_info - 故障信息
* @param[in] action_type - 拔枪恢复使能
* @param[in] data1 - 测量值1
* @param[in] data2 - 测量值2
*
* @return U8_T - 1成功,0失败(缓存已满)
*
* @author jiankalka
* @date 2025-12-18
* ************************************************************************
*/
U8_T u8_fault_cache_add(E_FAULT_SITE f_site ,E_FAULT_TYPE type , E_FAULT_INFO e_info, U8_T action_type, S16_T data1 , S16_T data2)
{
if(s_fault_action_cache.count >= FAULT_ACTION_CACHE_SIZE)
{
return 0; //缓存已满
}
//添加到队列尾部
s_fault_action_cache.items[s_fault_action_cache.rear].f_site = f_site;
s_fault_action_cache.items[s_fault_action_cache.rear].type = type;
s_fault_action_cache.items[s_fault_action_cache.rear].e_info = e_info;
s_fault_action_cache.items[s_fault_action_cache.rear].action_type = action_type;
s_fault_action_cache.items[s_fault_action_cache.rear].data1 = data1;
s_fault_action_cache.items[s_fault_action_cache.rear].data2 = data2;
s_fault_action_cache.rear = (s_fault_action_cache.rear + 1) % FAULT_ACTION_CACHE_SIZE;
s_fault_action_cache.count++;
return 1;
}
/**
* ************************************************************************
* @brief - 从缓存队列获取一个故障动作
*
* @param[out] p_item - 故障动作项指针
*
* @return U8_T - 1成功,0失败(缓存为空)
*
* @author jiankalka
* @date 2025-12-18
* ************************************************************************
*/
static U8_T u8_fault_cache_get(FAULT_ACTION_CACHE_ITEM_T *p_item)
{
if(s_fault_action_cache.count == 0)
{
return 0; //缓存为空
}
if(p_item == NULL)
{
return 0;
}
//从队列头部获取
memcpy(p_item, &s_fault_action_cache.items[s_fault_action_cache.front], sizeof(FAULT_ACTION_CACHE_ITEM_T));
s_fault_action_cache.front = (s_fault_action_cache.front + 1) % FAULT_ACTION_CACHE_SIZE;
s_fault_action_cache.count--;
return 1;
}
/**
* ************************************************************************
* @brief - 处理缓存中的故障动作
*
*
* @author jiankalka
* @date 2025-12-18
* ************************************************************************
*/
void v_fault_cache_process(void)
{
FAULT_ACTION_CACHE_ITEM_T item;
U8_T processed_count = 0;
const U8_T MAX_PROCESS_PER_CYCLE = 5; //每个周期最多处理5个动作,避免占用太多时间
//每个周期处理最多MAX_PROCESS_PER_CYCLE个缓存动作
while(processed_count < MAX_PROCESS_PER_CYCLE && u8_fault_cache_get(&item))
{
//调用内部函数执行实际的故障动作
v_set_fault_data_internal(item.f_site, item.type, item.e_info,
item.action_type, item.data1, item.data2);
processed_count++;
}
//如果缓存仍然有未处理的动作,记录日志
if(s_fault_action_cache.count > 0)
{
// FAULT_LOG("Fault cache pending=%d\n", s_fault_action_cache.count);
}
}
#endif
#if 1 //对外函数接口
/**
* ************************************************************************
* @brief - 设置故障内容-故障动作记录(内部实现,不对外公开)
*
* @param[in] f_site - 故障位置 E_WHOLE_PILE/整桩 E_GUN/A枪 E_GUN_B/B枪
* @param[in] type - 动作类型 E_RES = 0/恢复 E_FAULT/故障 E_WARN/警告
* @param[in] e_info - 故障信息 详看枚举
* @param[in] action_type - 拔枪恢复使能
* @param[in] data1 - 测量值1 故障内容自定义
* @param[in] data2 - 测量值2 故障内容自定义
*
*
* @author jiankalka
* @date 2025-09-09
* ************************************************************************
*/
static void v_set_fault_data_internal(E_FAULT_SITE f_site ,E_FAULT_TYPE type , E_FAULT_INFO e_info, U8_T action_type, S16_T data1 , S16_T data2)
{
HIS_FAULT_DATA_T fault_data;
Comm_Time curTime;
U8_T i;
char mag[FAULT_GET_MAG_MAX_LEN]= {0};
char c_site_mag[NUM_30] = {0};
if(FAULT_TEST == 1)
return;
memset(&fault_data,0,sizeof(HIS_FAULT_DATA_T));
GetCurrentTime(&curTime);
memcpy(&fault_data.s_occur_time, &curTime, sizeof(Comm_Time)); //发生时间
fault_data.e_site = f_site;
fault_data.ActType = type;
fault_data.e_fault_info = e_info;
fault_data.s16_value1 = data1;
fault_data.s16_value2 = data2;
v_fault_get_site_mag(f_site,c_site_mag,NUM_30);
if(type == E_RES) //恢复
{
if(s_real_fault.u8_fault_cnt != 0) //实时故障记录不为0,找到对应的故障数据 清空
{
for(i=0;i<CURR_FAULT_MAX_CNT;i++)
{
if(s_real_fault.fault_data[i].e_mag == e_info && s_real_fault.fault_data[i].e_ingun == f_site)
{
// v_hisFault_save_record(&fault_data); //保存动作记录
s_real_fault.u8_fault_cnt -- ;
memset(&s_real_fault.fault_data[i],0,sizeof(Fault_data));
v_get_fault_info(e_info , mag ,FAULT_GET_MAG_MAX_LEN);
FAULT_LOG("Fault RES %s:%d %s\n",c_site_mag,e_info,mag);
break;
}
}
}
if(s_real_fault.u8_warn_cnt != 0) //实时告警记录不为0,找到对应的故障数据 清空
{
for(i=0;i<CURR_ALARM_MAX_CNT;i++)
{
if(s_real_fault.warn_data[i].e_mag == e_info && s_real_fault.warn_data[i].e_ingun == f_site)
{
// v_hisFault_save_record(&fault_data); //保存动作记录
s_real_fault.u8_warn_cnt -- ;
memset(&s_real_fault.warn_data[i],0,sizeof(Fault_data));
v_get_fault_info(e_info , mag ,FAULT_GET_MAG_MAX_LEN);
FAULT_LOG("Warn RES %s:%d %s\n",c_site_mag,e_info,mag);
break;
}
}
}
}
else if(type == E_FAULT) //故障
{
for(i=0;i<CURR_FAULT_MAX_CNT;i++)
{
if(s_real_fault.fault_data[i].e_mag == e_info && s_real_fault.fault_data[i].e_ingun == f_site)
{
return; //故障粗在 则退出
}
}
if(s_real_fault.u8_fault_cnt < CURR_FAULT_MAX_CNT)
{
for(i=0;i<CURR_FAULT_MAX_CNT;i++)
{
if(s_real_fault.fault_data[i].e_mag == E_FAULT_NULL)
{
// 故障动作持久化(默认 Flash;可按宏同时写 FATFS 缓存)
v_fault_persist_record(&fault_data);
s_real_fault.u8_fault_cnt ++ ;
s_real_fault.fault_data[i].e_mag = e_info;
s_real_fault.fault_data[i].e_ingun = f_site;
s_real_fault.fault_data[i].u8_type = action_type;
memcpy(&s_real_fault.fault_data[i].time , &curTime , sizeof(Comm_Time));
v_get_fault_info(e_info , mag ,FAULT_GET_MAG_MAX_LEN);
FAULT_LOG("Fault SET %s:%d %s\n",c_site_mag,e_info,mag);
break;
}
}
}
}
else if(type == E_WARN) //告警
{
for(i=0;i<CURR_ALARM_MAX_CNT;i++)
{
if(s_real_fault.warn_data[i].e_mag == e_info && s_real_fault.warn_data[i].e_ingun == f_site)
{
return; //故障粗在 则退出
}
}
if(s_real_fault.u8_warn_cnt < CURR_ALARM_MAX_CNT)
{
for(i=0;i<CURR_ALARM_MAX_CNT;i++)
{
if(s_real_fault.warn_data[i].e_mag == E_FAULT_NULL)
{
// 告警动作持久化(默认 Flash;可按宏同时写 FATFS 缓存)
v_fault_persist_record(&fault_data);
s_real_fault.u8_warn_cnt ++ ;
s_real_fault.warn_data[i].e_mag = e_info;
s_real_fault.warn_data[i].e_ingun = f_site;
s_real_fault.warn_data[i].u8_type = action_type;
memcpy(&s_real_fault.warn_data[i].time ,&curTime, sizeof(Comm_Time)); //发生时间
v_get_fault_info(e_info , mag ,FAULT_GET_MAG_MAX_LEN);
FAULT_LOG("Warn SET %s:%d %s\n",c_site_mag,e_info,mag);
break;
}
}
}
}
}
/**
* ************************************************************************
* @brief - 设置故障内容-故障动作记录(对外接口,将动作缓存)
*
* @param[in] f_site - 故障位置 E_WHOLE_PILE/整桩 E_GUN/A枪 E_GUN_B/B枪
* @param[in] type - 动作类型 E_RES = 0/恢复 E_FAULT/故障 E_WARN/警告
* @param[in] e_info - 故障信息 详看枚举
* @param[in] action_type - 拔枪恢复使能
* @param[in] data1 - 测量值1 故障内容自定义
* @param[in] data2 - 测量值2 故障内容自定义
*
*
* @author jiankalka
* @date 2025-09-09
* ************************************************************************
*/
void v_set_fault_data(E_FAULT_SITE f_site ,E_FAULT_TYPE type , E_FAULT_INFO e_info, U8_T action_type, S16_T data1 , S16_T data2)
{
// 将故障动作添加到缓存队列
if(u8_fault_cache_add(f_site, type, e_info, action_type, data1, data2) == 0)
{
// FAULT_LOG("Fault cache add fail: %d %d %d\n", f_site, type, e_info);
}
}
/**
* ************************************************************************
* @brief - 获取故障告警数据的 中文解析数据
*
* @param[in] e_info - 故障告警数据
* @param[in] mag - 对应中文说明缓存数组
* @param[in] u16_len - 缓存数组长度
*
*
* @author jiankalka
* @date 2025-09-09
* ************************************************************************
*/
void v_get_fault_info(E_FAULT_INFO e_info , char *mag ,U16_T u16_len)
{
U16_T i;
U16_T info_size;
if ((mag == NULL) || (u16_len == 0u)) {
return;
}
info_size = (U16_T)(sizeof(fault_info) / sizeof(fault_info[0]));
memset(mag, 0, u16_len);
for (i = 0u; i < info_size; i++) {
if (e_info == fault_info[i].e_mag) {
strncpy(mag, fault_info[i].info, u16_len - 1u);
mag[u16_len - 1u] = '\0';
return;
}
}
(void)snprintf(mag, u16_len, "Unknown fault: %u", (unsigned int)e_info);
}
/**
* ************************************************************************
* @brief - 对外获取故障告警数量
*
* @param[in] u8_seat - 故障位置 0整桩,不包含A、B枪故障 1A枪 2B枪
* @param[in] flag - 故障类型 0故障数量 1告警数量
*
* @return U8_T - 故障、告警数量值返回
*
* @author jiankalka
* @date 2025-09-09
*
* ************************************************************************
*/
U8_T u8_get_fault_sum(U8_T u8_seat, U8_T u8_flag)
{
U8_T i,u8_ret = 0;
if(u8_seat >= 1 && u8_seat <= GUN_MAX_CNT) //1-N 是枪的范围
{
if(u8_flag == 0 && s_real_fault.u8_fault_cnt != 0)
{
for(i=0;i<CURR_FAULT_MAX_CNT;i++)
{
if(s_real_fault.fault_data[i].e_mag != 0 &&
s_real_fault.fault_data[i].e_ingun == E_GUN+u8_seat-1)
{
u8_ret++;
}
}
}
if(u8_flag == 1 && s_real_fault.u8_warn_cnt != 0)
{
for(i=0;i<CURR_ALARM_MAX_CNT;i++)
{
if(s_real_fault.warn_data[i].e_mag != 0 &&
s_real_fault.warn_data[i].e_ingun == E_GUN+u8_seat-1)
{
u8_ret++;
}
}
}
}
else //整桩故障、告警数量
{
if(u8_flag == 0 && s_real_fault.u8_fault_cnt != 0)
{
for(i=0;i<CURR_FAULT_MAX_CNT;i++)
{
if(s_real_fault.fault_data[i].e_mag != 0 &&
(s_real_fault.fault_data[i].e_ingun == E_WHOLE_PILE || //整桩
s_real_fault.fault_data[i].e_ingun == E_WHOLE_HOST)) //主机故障
//s_real_fault.fault_data[i].e_ingun >= E_CHAR_MDU)) //模块或开关故障 此处先不加了 模块开关故障 可能可以充电
{
u8_ret++;
}
}
}
if(u8_flag == 1 && s_real_fault.u8_warn_cnt != 0)
{
for(i=0;i<CURR_ALARM_MAX_CNT;i++)
{
if(s_real_fault.warn_data[i].e_mag != 0 &&
(s_real_fault.warn_data[i].e_ingun == E_WHOLE_PILE ||
s_real_fault.warn_data[i].e_ingun == E_WHOLE_HOST ))
//s_real_fault.warn_data[i].e_ingun >= E_CHAR_MDU))
{
u8_ret++;
}
}
}
}
return u8_ret;
}
/**
* ************************************************************************
* @brief - 对外接口 获取故障告警数据
*
* @param[in] rl_data - 故障告警获取结构体指针
*
*
* @author jiankalka
* @date 2025-09-09
* ************************************************************************
*/
void v_get_fault_data(REAL_FAULT_DATA_T *rl_data)
{
if(rl_data == NULL)
return;
memset(rl_data,0,sizeof(REAL_FAULT_DATA_T));
memcpy(rl_data,&s_real_fault,sizeof(REAL_FAULT_DATA_T));
}
/**
* ************************************************************************
* @brief - 获取 故障是否存在在列表中
*
* @param[in] e_info - 告警数据
* @param[in] f_site - 故障位置
*
* @return U8_T - 0 未存在 1存在为故障 2存在为告警
*
* @author jiankalka
* @date 2025-09-09
* ************************************************************************
*/
U8_T u8_cheak_fault_flag(E_FAULT_INFO e_info , E_FAULT_SITE f_site)
{
U8_T i,ret = 0;
if(s_real_fault.u8_fault_cnt != 0)
{
for(i=0;i<CURR_FAULT_MAX_CNT;i++)
{
if(s_real_fault.fault_data[i].e_mag == e_info && s_real_fault.fault_data[i].e_ingun == f_site)
{
ret = 1;
break;
}
}
}
if(s_real_fault.u8_warn_cnt != 0)
{
for(i=0;i<CURR_ALARM_MAX_CNT;i++)
{
if(s_real_fault.warn_data[i].e_mag == e_info && s_real_fault.warn_data[i].e_ingun == f_site)
{
ret = 2;
break;
}
}
}
return ret;
}
#endif
#if 1 //内部数据获取
/**
* ************************************************************************
* @brief - 故障检测任务 获取外部数据
*
* @param[in] u8_gunNo - 枪号 0-N 部分数据无意义
* @param[in] e_dataType - 数据类型 详看枚举
* @param[in] u16_dataPara - 数据参数 部分数据无意义
*
* @return U16_T - 返回值
*
* @author jiankalka
* @date 2025-09-09
* ************************************************************************
*/
U16_T u16_fault_get_sys_data(U8_T u8_gunNo,E_FAULT_GET_DATA_TYPE e_dataType,U16_T u16_dataPara)
{
U16_T u16_ret = 0;
switch (e_dataType)
{
case E_FAULT_GET_DATA_EMERGENCY : //急停
{
u16_ret = u8_get_sys_yx_data(YX_PILE_EMERGENCY);
break;
}
case E_FAULT_GET_DATA_DOOR: //门禁
{
u16_ret = u8_get_sys_yx_data(YX_PILE_DOOR);
break;
}
case E_FAULT_GET_DATA_WARTER: //水浸
{
u16_ret = u8_get_sys_yx_data(YX_PILE_WARTER);
break;
}
case E_FAULT_GET_DATA_SPD: //防雷状态
{
u16_ret = u8_get_sys_yx_data(YX_PILE_SPD);
break;
}
case E_FAULT_GET_DATA_SMOKE: //烟感
{
u16_ret = u8_get_sys_yx_data(YX_PILE_SMOKE);
break;
}
case E_FAULT_GET_DATA_GUN_DC_FUSE: //直流熔断器状态
{
u16_ret = u8_get_gun_yx_data(YX_GUN_DC_FUSE,u8_gunNo );
break;
}
case E_FAULT_GET_DATA_GUN_TEMP_THRESHOLD: //枪温阈值
{
u16_ret = g_t_share_data.t_sys_fix_cfg.u8_threshold_gunTemp*10;
break;
}
case E_FAULT_GET_DATA_GUN_TEMP: //枪温 精度 0.1度
{
if(u16_dataPara == 0) //正极枪温
u16_ret = (U16_T)(f32_get_gun_yc_data(ADC_GUN_TEMP_PLUS,u8_gunNo)*10);
else //负极枪温
u16_ret = (U16_T)(f32_get_gun_yc_data(ADC_GUN_TEMP_MINUS,u8_gunNo)*10);
break;
}
case E_FAULT_GET_DATA_GUN_CNT: //枪数量
{
u16_ret = g_t_share_data.t_sys_fix_cfg.u8_gunCnt;
break;
}
case E_FAULT_GET_DATA_DOOR_EN: //门禁使能
{
u16_ret = g_t_share_data.t_sys_fix_cfg.u_enable.bit_enable.bit_doorEnable;
break;
}
case E_FAULT_GET_DATA_AC_CONTACT_EN: //交流接触器使能
{
u16_ret = g_t_share_data.t_sys_fix_cfg.u_enable.bit_enable.bit_AcContactEna;
break;
}
case E_FAULT_GET_DATA_GUN_LINK: //枪连接标志 0未连接 1已连接
{
u16_ret = u8_get_gun_yx_data(YX_GUN_LINK,u8_gunNo);
break;
}
case E_FAULT_GET_DATA_GUN_CHAR_FLAG: //充电标志 0未充电 1充电中
{
E_FLOW_REAL_STATE flow_state = (E_FLOW_REAL_STATE)u16_flow_put_data(u8_gunNo , E_FLOW_PUT_DATA_GUN_REAL_STATE,0); //0空闲 1充电启动 2绝缘启动 3绝缘计算完成 4绝缘检测模块停止 5开始预充 6预充完成 7充电中 8BMS通讯超时 9充电停止 10充电停止完成
if(flow_state == E_FLOW_REAL_CHARGEING) //充电中
{
u16_ret = 1 ;
}
else
{
u16_ret = 0 ;
}
break;
}
case E_FAULT_GET_DATA_AC_KM: //交流输入接触器反馈
{
u16_ret = u8_get_sys_yx_data(YX_PILE_KM);
break;
}
case E_FAULT_GET_DATA_BUS_KM: //母联直流接触器反馈
{
u16_ret = u8_get_sys_yx_data(YX_PILE_BUS_KM);
break;
}
case E_FAULT_GET_DATA_BUS_KM_EN: //母联继电器使能
{
u16_ret = g_t_share_data.t_sys_fix_cfg.u_enable.bit_enable.bit_dcBusEn;
break;
}
case E_FAULT_GET_DATA_FLOW_STATE: //本枪流程状态(供故障检测,不对外混用 flow 枚举头时可只读数值)
{
if (u8_gunNo < GUN_MAX_CNT)
u16_ret = u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_FLOW_STATE, 0);
break;
}
case E_FAULT_GET_DATA_CHAR_TIME: //本枪充电持续时间 秒
{
if (u8_gunNo < GUN_MAX_CNT)
u16_ret = u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_CHAR_TIME, 0);
break;
}
case E_FAULT_GET_DATA_GUN_DC_KM_POS: //正母线直流输出接触器状态
{
if (u8_gunNo < GUN_MAX_CNT)
u16_ret = u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_KM_POS, 0);
break;
}
case E_FAULT_GET_DATA_GUN_DC_KM_NEG: //负母线直流输出接触器状态
{
if (u8_gunNo < GUN_MAX_CNT)
u16_ret = u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_KM_NEG, 0);
break;
}
default:
break;
}
return u16_ret;
}
void v_fault_get_site_mag(E_FAULT_SITE e_site , char *mag , U8_T u8_len)
{
memset(mag , 0 ,u8_len);
if(e_site == E_WHOLE_PILE)
snprintf(mag ,u8_len, "Pile-Terminal");
else if(e_site == E_WHOLE_HOST)
snprintf(mag ,u8_len, "Pile-Host");
else if(e_site < E_CHAR_MDU)
snprintf(mag ,u8_len, "[%d] Gun",e_site-E_GUN);
else if(e_site < E_SWH_MDU)
snprintf(mag ,u8_len, "[%d] Module",e_site-E_CHAR_MDU);
else if(e_site < E_OTHER)
snprintf(mag ,u8_len, "[%d] Switch",e_site-E_SWH_MDU);
else
snprintf(mag ,u8_len, "[%d] Other",e_site-E_OTHER);
}
#endif
#if(MY_SHELL_EN) //Shell 使能
//shell 注册命令
void v_fault_data_show()
{
char buffer[64] = {0};
char c_site_mag[NUM_30] = {0};
U8_T i,mag[FAULT_GET_MAG_MAX_LEN]={0};
E_FAULT_INFO e_info;
E_FAULT_SITE e_site;
sprintf( &buffer[0], "故障数量= %u ,告警数量= %u\r\n",
s_real_fault.u8_fault_cnt,s_real_fault.u8_warn_cnt);
shell_send_String(buffer);
for(i=0;i<CURR_FAULT_MAX_CNT;i++)
{
if(s_real_fault.fault_data[i].e_mag != 0)
{
e_info = s_real_fault.fault_data[i].e_mag;
e_site = s_real_fault.fault_data[i].e_ingun;
v_fault_get_site_mag(e_site,c_site_mag,NUM_30);
v_get_fault_info(e_info , (char*)mag,FAULT_GET_MAG_MAX_LEN);
memset(buffer , 0,64);
sprintf( &buffer[0], "%s故障 %d %s \r\n",c_site_mag,e_info,mag);
shell_send_String(buffer);
}
}
for(i=0;i<CURR_ALARM_MAX_CNT;i++)
{
if(s_real_fault.warn_data[i].e_mag != 0)
{
e_info = s_real_fault.warn_data[i].e_mag;
e_site = s_real_fault.warn_data[i].e_ingun;
v_fault_get_site_mag(e_site,c_site_mag,NUM_30);
v_get_fault_info(e_info , (char*)mag,FAULT_GET_MAG_MAX_LEN);
memset(buffer , 0,64);
sprintf( &buffer[0], "%s告警 %d %s \r\n",c_site_mag,e_info,mag);
shell_send_String(buffer);
}
}
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), fault_data, v_fault_data_show,myshlle-- fault data info);
#endif