pCCU 新增真实CCU配电桥接(rcu链路原帧透传+网页显示)并适配板卡端口拓扑

- protocol/DisProtocol: 配电协议8条消息(指令0x0001~4/反馈0x0005~8, Sum8),复用pmSysvariable结构体+static_assert核对
- ChecksumPolicy 新增 Sum8;Frame 支持 1 字节校验和
- MessageRegistry 支持 (id+帧总长) 二维查找:配电指令与PM操控指令共用id按帧长区分(帧头length字段不可信)
- LinkManager: 按实际帧长分发 + sendRaw原帧透传 + 非本协议帧头落库节流告警;UdpEndpoint sendTo 加锁
- comm/RcuLinkManager: 真实CCU链路;core/DisBridge: 配电桥接器(反馈转pPowerManger+解码显示,指令转真实CCU,0x0004仅显示不转发)
- 网页新增"真实CCU"页签全字段展示;SnapshotBuilder realCcu 节 + rcu 链路描述
- h100.moos: 端口腾挪(真实CCU固定上报5001归pCCU,pPowerManger iport=5002),rcu_remote=192.168.0.140:7000
- 测试: pccuTest 新增配电/Sum8/长度分发/RCU注册表用例(176项);集成测试新增桥接字节一致+不误转发用例
This commit is contained in:
zjk
2026-09-01 15:06:11 +08:00
parent 5b8f0b1421
commit 0639b5904d
28 changed files with 1609 additions and 53 deletions
+134
View File
@@ -15,10 +15,12 @@
#include "../../src/pCCU/protocol/MessageRegistry.h"
#include "../../src/pCCU/protocol/FcProtocol.h"
#include "../../src/pCCU/protocol/PmProtocol.h"
#include "../../src/pCCU/protocol/DisProtocol.h"
#include "../../src/pCCU/protocol/CanBms.h"
#include "../../src/pCCU/comm/LinkManager.h"
#include "../../src/pCCU/comm/FcLinkManager.h"
#include "../../src/pCCU/comm/PmLinkManager.h"
#include "../../src/pCCU/comm/RcuLinkManager.h"
#include "../../src/pCCU/store/DbStore.h"
using namespace ccu;
@@ -390,6 +392,134 @@ static void testCanBmsDecode() {
!isCanBcuId(0x100181FF) && !isCanBcuId(0x10370000));
}
//--------------------------------------------------------------------------
// 9. 配电协议帧长度与 Sum8 校验
static void testDisFrameLengths() {
DisHighVolBusCmdMessage hvCmd; CHECK(hvCmd.totalLength() == 21); // 6+14+1
DisHighAVolBusCmdMessage hvaCmd; CHECK(hvaCmd.totalLength() == 13); // 6+6+1
DisHighBVolBusCmdMessage hvbCmd; CHECK(hvbCmd.totalLength() == 14); // 6+7+1
DisLowBusCmdMessage lvCmd; CHECK(lvCmd.totalLength() == 15); // 6+8+1
DisHighVolBusFbMessage hvFb; CHECK(hvFb.totalLength() == 60); // 6+53+1
DisHighAVolBusFbMessage hvaFb; CHECK(hvaFb.totalLength() == 32); // 6+25+1
DisHighBVolBusFbMessage hvbFb; CHECK(hvbFb.totalLength() == 41); // 6+34+1
DisLowBusFbMessage lvFb; CHECK(lvFb.totalLength() == 36); // 6+29+1
}
//--------------------------------------------------------------------------
// 10. 配电指令/反馈编解码往返(Sum8 校验,篡改检测)
static void testDisRoundTrip() {
// 指令:高压母线(含启动类字节)
disHighVolBusCmd hv;
hv.fuelCellCircuitBreaker = DIS_BREAKER_ON;
hv.powerLithiumBatteryCircuitBreaker = DIS_BREAKER_OFF;
hv.dcdc5Module = 1; hv.coolingSystem = 0;
DisHighVolBusCmdMessage hvMsg;
std::vector<uint8_t> hf = hvMsg.encode(hv);
CHECK(hf.size() == 21);
// Sum8 校验和位于帧尾 1 字节
unsigned sum = 0;
for (size_t i = 0; i + 1 < hf.size(); ++i) sum += hf[i];
CHECK(hf.back() == (sum & 0xFF));
disHighVolBusCmd hvOut;
CHECK(hvMsg.decode(hf, static_cast<void*>(&hvOut)));
CHECK(hvOut.fuelCellCircuitBreaker == DIS_BREAKER_ON);
CHECK(hvOut.powerLithiumBatteryCircuitBreaker == DIS_BREAKER_OFF);
CHECK(hvOut.dcdc5Module == 1 && hvOut.coolingSystem == 0);
// 篡改数据域 -> Sum8 失败
std::vector<uint8_t> bad = hf; bad[8] ^= 0xFF;
CHECK(!hvMsg.decode(bad, static_cast<void*>(&hvOut)));
// 指令:低压主母线 / 仪表汇流排
disLowMainBusCmd hvb; hvb.dcC1DCDistributionPanelCircuitBreaker = DIS_BREAKER_ON;
DisHighBVolBusCmdMessage hvbMsg;
std::vector<uint8_t> bf = hvbMsg.encode(hvb);
CHECK(bf.size() == 14);
disLowMainBusCmd hvbOut;
CHECK(hvbMsg.decode(bf, static_cast<void*>(&hvbOut)));
CHECK(hvbOut.dcC1DCDistributionPanelCircuitBreaker == DIS_BREAKER_ON);
disLowBusCmd lv; lv.unit2CircuitBreaker = DIS_BREAKER_ON;
DisLowBusCmdMessage lvMsg;
std::vector<uint8_t> lf = lvMsg.encode(lv);
CHECK(lf.size() == 15);
disLowBusCmd lvOut;
CHECK(lvMsg.decode(lf, static_cast<void*>(&lvOut)));
CHECK(lvOut.unit2CircuitBreaker == DIS_BREAKER_ON);
// 反馈:高压母线A(断路器+u16 电气量抽查)
disHighAVolBusState hva;
hva.bowFTDevice123CircuitBreaker = DIS_BREAKER_ON;
hva.busbarBVoltage = 0x1234; hva.bowFTDevice123Current = 567;
DisHighAVolBusFbMessage hvaMsg;
std::vector<uint8_t> af = hvaMsg.encode(hva);
CHECK(af.size() == 32);
disHighAVolBusState hvaOut;
CHECK(hvaMsg.decode(af, static_cast<void*>(&hvaOut)));
CHECK(hvaOut.bowFTDevice123CircuitBreaker == DIS_BREAKER_ON);
CHECK(hvaOut.busbarBVoltage == 0x1234);
CHECK(hvaOut.bowFTDevice123Current == 567);
CHECK(isDisCmdMessage(&hvMsg) && isDisFbMessage(&hvaMsg));
CHECK(!isDisMessage(nullptr));
}
//--------------------------------------------------------------------------
// 11. 注册表 (id+帧长) 二维分发:配电指令与 PM 指令共用 id 不串扰
static void testRegistryLengthDispatch() {
MessageRegistry reg;
registerPmMessages(reg); // 0x0001(45B) 0x0002(28B) 0x0003(12B) 0x0004(248B)
registerDisCmdMessages(reg); // 0x0001(21B) 0x0002(13B) 0x0003(14B) 0x0004(15B)
CHECK(reg.size() == 8);
// 精确长度命中
CHECK(reg.find(0x0001, 45)->name() == std::string("pm_control"));
CHECK(reg.find(0x0001, 21)->name() == std::string("dis_hv_cmd"));
CHECK(reg.find(0x0002, 28)->name() == std::string("pm_param_set"));
CHECK(reg.find(0x0002, 13)->name() == std::string("dis_hva_cmd"));
CHECK(reg.find(0x0004, 248)->name() == std::string("pm_status"));
CHECK(reg.find(0x0004, 15)->name() == std::string("dis_lv_cmd"));
// LinkManager 收帧分发:配电指令短帧 -> dis 消息;PM 长帧 -> pm 消息
LinkManager lm("test_pm", 0);
registerPmMessages(lm.registry());
registerDisCmdMessages(lm.registry());
std::string gotName;
lm.setOnMessage([&](Message* m, const std::vector<uint8_t>&) {
gotName = m ? m->name() : "";
});
disHighVolBusCmd hv; hv.fuelCellCircuitBreaker = DIS_BREAKER_ON;
DisHighVolBusCmdMessage hvMsg;
CHECK(lm.handleIncoming(hvMsg.encode(hv)));
CHECK(gotName == "dis_hv_cmd");
PmControlValue pc; pc.mode = 2;
PmControlMessage pcMsg;
CHECK(lm.handleIncoming(pcMsg.encode(pc)));
CHECK(gotName == "pm_control");
}
//--------------------------------------------------------------------------
// 12. RCU 链路注册表:配电反馈 + 真实CCU 状态报文可识别
static void testRcuRegistry() {
RcuLinkManager rcu(0, "127.0.0.1", 1);
// 反馈命中
disHighVolBusState hv; hv.powerBusVoltage = 0x0FA0;
DisHighVolBusFbMessage hvMsg;
std::vector<uint8_t> f = hvMsg.encode(hv);
std::string gotName;
rcu.setOnMessage([&](Message* m, const std::vector<uint8_t>&) {
gotName = m ? m->name() : "";
});
CHECK(rcu.handleIncoming(f));
CHECK(gotName == "dis_hv_fb");
// 真实CCU 状态报文(PM 状态消息复用)
PmStatusValue st; st.heartbeat = 9;
PmStatusMessage stMsg;
CHECK(rcu.handleIncoming(stMsg.encode(st)));
CHECK(gotName == "pm_status");
}
//--------------------------------------------------------------------------
int main() {
testFrameLengths();
@@ -401,6 +531,10 @@ int main() {
testLinkDispatch();
testDbStore();
testCanBmsDecode();
testDisFrameLengths();
testDisRoundTrip();
testRegistryLengthDispatch();
testRcuRegistry();
std::printf("\n==== pccuTest: %d passed, %d failed ====\n", g_pass, g_fail);
return g_fail == 0 ? 0 : 1;