BMS 上位机

一套面向电池管理系统的上位机软件,支持 CAN / CAN FD 通讯、UDS 诊断、固件刷写与标定,用于 BMS 研发测试阶段的实时监控、参数配置、故障诊断和程序更新。

提供 WPF 和 Avalonia 双版本,兼容周立功、Vector、PCAN、同星等主流 CAN 卡。

整体架构#

系统采用分层设计,从 UI 到硬件驱动逐层解耦:

flowchart TB
    subgraph UI["UI 层"]
        WPF["WPF 版本"]
        AVA["Avalonia 版本"]
        WPF ~~~ AVA
    end

    subgraph VM["ViewModel 层"]
        MVVM["CommonUtility.Wpf / CommonUtility.Avalonia"]
    end

    subgraph BLL["业务逻辑层"]
        Parser["数据解析"]
        Protocol["协议处理"]
        Diag["诊断服务"]
        Flash["刷写流程"]
        Calib["标定管理"]
        Parser ~~~ Protocol ~~~ Diag ~~~ Flash ~~~ Calib
    end

    subgraph HAL["通讯抽象层"]
        ICAN["LibCAN · ICANDevice 接口"]
    end

    subgraph Driver["硬件驱动层"]
        PCAN["LibPCAN"]
        Vector["LibVectorCAN"]
        ZLG["LibZLGCAN"]
        ToSun["LibToSunCAN"]
        PCAN ~~~ Vector ~~~ ZLG ~~~ ToSun
    end

    UI --> VM --> BLL --> HAL --> Driver

分层职责#

层级 职责
UI 层 界面展示与用户交互,WPF / Avalonia 双版本
ViewModel 层 绑定与命令,基于 CommonUtility.Wpf / CommonUtility.Avalonia
业务逻辑层 数据解析、协议处理、诊断、刷写、标定
通讯抽象层 定义 ICANDevice 接口,隔离硬件差异
硬件驱动层 封装各厂商 SDK,提供统一调用方式

硬件驱动层设计#

不同厂商的 CAN 卡配置界面差异很大(波特率设置、通道选择、终端电阻开关等),因此驱动层按厂商拆分为独立 NuGet 包,每个包再分为 核心库 + WPF UI + Avalonia UI 三层。

硬件厂商 核心库 WPF UI Avalonia UI
通用抽象 LibCAN — —
UDS 协议 LibUDS — —
CAN 日志 LibCANLogging — —
PCAN LibPCAN LibPCAN.WPF LibPCAN.Avalonia
同星 LibToSunCAN LibToSunCAN.WPF LibToSunCAN.Avalonia
Vector LibVectorCAN LibVectorCAN.WPF LibVectorCAN.Avalonia
周立功 LibZLGCAN LibZLGCAN.WPF LibZLGCAN.Avalonia

设计思路#

核心库#

封装厂商 SDK,实现 ICANDevice 接口,不含 UI

WPF UI#

提供该硬件的 WPF 配置面板(继承自 UserControl)

Avalonia UI#

提供该硬件的 Avalonia 配置面板(跨平台复用)

CAN 日志#

LibCANLogging 采用装饰器模式,实现 ICANDevice 接口,并且持有同样实现了 ICANDevice 接口的厂商驱动对象,增加日志功能

支持三种日志格式: .asc、.csv、.blf,并于后续分析

总结#

  • 新增一家硬件,只需实现三件套(核心库 + 两个 UI 包)

  • 主程序根据当前使用的硬件,动态加载对应的 UI 包

  • 业务逻辑和主界面完全不感知硬件差异

截图#

– PCAN 同星 Vector 周立功
WPF PCAN WPF 同星 WPF Vector WPF 周立功 WPF
Avalonia PCAN Avalonia 同星 Avalonia Vector Avalonia 周立功 Avalonia

功能模块#

CAN / CANFD 通讯#

支持标准帧、扩展帧、CAN FD 长帧。接收与发送通过 ICANDevice 接口统一处理:

sequenceDiagram
    participant App as 应用层
    participant ICAN as ICANDevice
    participant Driver as 厂商驱动
    participant Bus as CAN 总线

    App->>ICAN: Send(CanFrame)
    ICAN->>Driver: 调用厂商 SDK
    Driver->>Bus: 写入 CAN 帧

    Bus->>Driver: 接收 CAN 帧
    Driver->>ICAN: 触发 FrameReceived
    ICAN->>App: 回调 CanFrame

UDS 诊断#

支持 0x10 / 0x22 / 0x27 / 0x2E / 0x31 / 0x3E 等常用服务,基于 ISO-TP 处理多帧传输。

flowchart LR
    A["发送 UDS 请求"] --> B{"单帧?"}
    B -- 是 --> C["直接发送"]
    B -- 否 --> D["ISO-TP 分包"]
    D --> E["流控帧交互"]
    E --> F["连续帧传输"]
    C --> G["等待响应"]
    F --> G
    G --> H{"响应有效?"}
    H -- 是 --> I["解析响应"]
    H -- 否 --> J["错误处理"]

安全访问流程(0x27):

sequenceDiagram
    participant Tester as 上位机
    participant ECU as BMS

    Tester->>ECU: 0x27 请求种子
    ECU-->>Tester: 返回种子
    Tester->>Tester: 计算密钥
    Tester->>ECU: 0x27 发送密钥
    ECU-->>Tester: 解锁成功

固件刷写#

基于 UDS 的 Bootloader 刷写流程:

flowchart TB
    A["进入编程会话 0x10 0x02"] --> B["安全访问 0x27"]
    B --> C["请求下载 0x34"]
    C --> D["传输数据 0x36"]
    D --> E{"传输完成?"}
    E -- 否 --> D
    E -- 是 --> F["退出传输 0x37"]
    F --> G["校验完整性 0x31"]
    G --> H["复位 ECU 0x11"]

支持 .hex / .s19 文件解析、分块传输进度显示、失败重试。

固件刷写

标定#

通过 UDS 0x2E 写入标定数据标识符(DID),提供参数读取、修改、写入和回读校验。

标定

多通道与总控联动#

多通道版本通过 Socket 与总控系统通信,充当 CAN 总线与总控系统之间的协议网关:

sequenceDiagram
    participant Master as 总控系统
    participant HMI as 上位机
    participant CAN as CAN 总线
    participant ECU as 下位机

    Master->>HMI: Socket 下发指令
    HMI->>HMI: 解析指令,转换为 UDS 请求
    HMI->>CAN: 发送 UDS 命令
    CAN->>ECU: 传输
    ECU-->>CAN: 响应
    CAN-->>HMI: 接收响应
    HMI->>HMI: 解析响应
    HMI->>Master: Socket 回传结果

多通道与总控联动

❤️ 如果这篇文章对你有帮助,欢迎赞助支持我继续维护 ❤️

☕ Support me ⚡ 爱发电赞助