Initial commit: CCU621_M firmware project with BLE debug link support.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-08 17:28:36 +08:00
commit 9ceb218f80
1597 changed files with 724159 additions and 0 deletions
+954
View File
@@ -0,0 +1,954 @@
#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