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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user