foxBMS 2 — Battery Management System SIL Demo Guide

Live Demo (no setup required)

Open in your browser right now:

Link What you see
sil.taktflow-systems.com/bms/ Live BMS dashboard with fault injection
sil.taktflow-systems.com/bms-docs/ Full portfolio documentation (60 pages)

The BMS is running 24/7 on a Netcup VPS in Germany. No login required. You can inject faults and watch the BMS react in real-time.


Interview Demo Script (3 minutes)

Use this walkthrough to demonstrate the system in a live interview:

Step Action What to say
1 Open sil.taktflow-systems.com/bms/ "This is a live foxBMS 2 BMS running on Linux. The same C code that runs on the TMS570 microcontroller is executing here with SocketCAN."
2 Point to BMS State: NORMAL "The BMS started from UNINITIALIZED, went through INIT, IDLE, STANDBY, PRECHARGE, and reached NORMAL. Contactors are closed, 18 cells are balanced at ~3700mV."
3 Select Overvoltage, range C0–C17, click Inject "I'm injecting an overvoltage fault on all 18 cells via the plant model — this is SWE.6 black-box testing through the full CAN path."
4 Watch event log + state transition "The BMS detected the fault in ~585ms via the DIAG threshold counter (50 events). It transitions to ERROR and opens all contactors — fail-safe."
5 Click Clear "After clearing the fault, the BMS recovers through the normal startup sequence. No manual restart needed."
6 Show SWE.5 method selector "For white-box testing, I can inject faults directly into the BMS database using 11 ISO 26262 Part 5 methods — STUCK_AT, DRIFT, NOISE, etc. This bypasses CAN and tests the safety logic directly."

If asked about test coverage: "We have 2,005 ASIL-D fault injection test cases. 29 of 31 scenarios PASS — the 2 deferred tests are for cell balancing timeout and deep discharge recovery, documented in the test results."


What This Is

A complete Software-in-the-Loop (SIL) simulation of the foxBMS 2 open-source Battery Management System, running as a native Linux process with a web-based visualization dashboard. The foxBMS C source code (v1.10.0) compiles and runs on x86-64 with hardware abstracted — the same safety logic that runs on the TMS570 microcontroller executes here with full CAN communication via SocketCAN.

Key capabilities: - Live 18-cell battery pack visualization - Real foxBMS state machine: UNINIT → INIT → IDLE → STANDBY → PRECHARGE → NORMAL → ERROR - Real DIAG threshold counting (OV: 50 events, OT: 500 events, OC: 10 events) - Contactor control with welding/stuck-open detection - Fault injection at two levels: - SWE.6 (Plant/Black-box): change battery physics → BMS reacts via CAN - SWE.5 (BMS/White-box): override BMS internal database → bypass CAN path - 11 ISO 26262-5 fault injection methods (STUCK_AT, DRIFT, NOISE, etc.) - 2,005 automated test cases (ASIL-D fault injection matrix), 29/31 PASS - CAN monitor showing live bus traffic - Event log showing fault chain reaction

Measured detection times: | Fault | Detection time | Threshold | |-------|---------------|-----------| | Overvoltage (OV) | 585 ms | 50 events + 200ms delay | | Overcurrent (OC) | 116 ms | 10 events + 100ms delay | | Overtemperature (OT) | 5,510 ms | 500 events + 1000ms delay |


Prerequisites

Hardware

Software

sudo apt-get install -y gcc make python3 python3-pip can-utils iproute2 git
pip3 install --user aiohttp   # for web dashboard

Network (for remote access)


Quick Start — Docker (2 minutes)

The fastest way to run the BMS locally:

git clone --recursive https://github.com/nhuvaoanh123/foxbms-posix.git
cd foxbms-posix
docker compose up --build

Open http://localhost:8080 — done. The Docker image handles vCAN setup, build, plant model, and web server automatically.

To stop: docker compose down


Quick Start — Manual (5 minutes)

Step 1: Clone the repository

git clone --recursive https://github.com/nhuvaoanh123/foxbms-posix.git
cd foxbms-posix

Step 2: Copy HALCoGen headers and apply patches

mkdir -p foxbms-2/build/app_host_unit_test/include
cp halcogen-headers/* foxbms-2/build/app_host_unit_test/include/

# Copy FreeRTOS POSIX port
mkdir -p foxbms-2/src/os/freertos/freertos/portable/ThirdParty/GCC/Posix/utils
cp freertos-posix-port/port.c freertos-posix-port/portmacro.h \
   foxbms-2/src/os/freertos/freertos/portable/ThirdParty/GCC/Posix/
cp freertos-posix-port/utils/* \
   foxbms-2/src/os/freertos/freertos/portable/ThirdParty/GCC/Posix/utils/

# Apply all foxBMS source patches
bash patches/apply_all.sh

Step 3: Build

cd src
make -j$(nproc)
# Output: foxbms-vecu binary

Step 4: Set up virtual CAN interface

sudo modprobe vcan
sudo ip link add vcan1 type vcan
sudo ip link set vcan1 up

Step 5: Run the SIL demo

Open three terminals (or use & for background):

Terminal 1 — Plant model (battery simulator):

python3 src/plant_model.py vcan1

Terminal 2 — foxBMS vECU:

FOXBMS_CAN_IF=vcan1 src/foxbms-vecu

Terminal 3 — Web dashboard:

python3 web/server.py --can vcan1 --port 8080 --host 0.0.0.0

Step 6: Open the dashboard

Browse to: http://localhost:8080

(Or from another machine: http://<laptop-ip>:8080)

You should see: - Battery pack with 18 green cells at ~3700mV - BMS state progressing: UNINITIALIZED → ... → NORMAL (takes ~7 seconds) - SOC slowly decreasing (1A discharge at 0.33C) - CAN monitor showing live traffic


One-Command Start

After building once, use this to start everything:

cd foxbms-posix
python3 src/plant_model.py vcan1 &>/dev/null &
FOXBMS_CAN_IF=vcan1 src/foxbms-vecu &>/dev/null &
python3 web/server.py --can vcan1 --port 8080 --host 0.0.0.0

Stop everything:

killall foxbms-vecu python3

Dashboard Guide

Battery — Physical (Plant Model)

The left panel shows 18 battery cells in a 3×6 grid. These represent the physical reality — what the battery actually produces. Each cell shows: - Cell ID (C0–C17) - Voltage in mV - Temperature dot (blue=cold, green=normal, red=hot) - Color: green (normal), yellow (warning), red (fault)

Plant Model — Physics

Shows the battery simulation parameters: - SOC: State of Charge (decreases under discharge) - OCV: Open-circuit voltage from SOC lookup - Pack Voltage: Sum of cell voltages minus IR drop - IR Drop: Voltage loss due to internal resistance (I × R_total) - Current: Discharge current (positive = discharge) - Status: DISCHARGING / IDLE / CHARGING

BMS Inputs (What foxBMS Sees)

Shows what the BMS actually reads from the battery via CAN/SPI: - AFE: Cell voltage min/max/delta, cell temperature min/max - IVT: Pack current, pack voltage, pack power

When you inject a fault via SWE.6 (Plant), these values change because the plant's CAN output changes. When you inject via SWE.5 (BMS), these values change because the internal database is overridden.

BMS State Machine

Shows the foxBMS state machine with the current state highlighted: - UNINITIALIZEDINITIALIZATIONINITIALIZEDIDLE - STANDBYPRECHARGENORMAL (operating state) - ERROR (fault detected, contactors opened)

State history shows timestamped transitions.

Contactors

Three contactors: - Main+ (String Plus): connects positive terminal - Main- (String Minus): connects negative terminal - Precharge: pre-charges the bus capacitance (opens after precharge sequence)

In NORMAL state: Main+ CLOSED, Main- CLOSED, Precharge OPEN. On fault: all three OPEN.

Fault Injection

Two modes:

Plant (SWE.6) — Black-box testing: - Changes the plant model's CAN output - foxBMS receives the fault through normal CAN path - Battery panel shows the changed values - Tests the complete data path: CAN RX → DECAN → Database → SOA → DIAG

BMS (SWE.5) — White-box testing: - Overrides the foxBMS internal database on READ - Battery panel stays unchanged (plant not affected) - Tests the safety logic: SOA → DIAG → State Machine → Contactor - Method selector with 11 ISO 26262-5 fault methods

Inject types: - Overvoltage: Set cell voltage above OV MSL (4250mV). Range: C0 to C17. - Undervoltage: Set cell voltage below UV MSL (2500mV). Range: C0 to C17. - Overtemperature: Set sensor temperature above OT MSL (55°C). Range: S0 to S7. - Overcurrent: Set pack current above OC MSL (15A). Fixed 200A.

Event Log

Shows the fault chain reaction with timestamps:

22:15:00  ⚡ PLANT: cell_voltage [0] = 4500
22:15:01  🔍 FAULT: OV_MSL (DIAG ID 18)
22:15:01  🔄 NORMAL → ERROR
22:15:01  🔓 Main+ OPENED
22:15:01  🔓 Main- OPENED

Diagnostics

CAN Monitor

Live CAN bus traffic, color-coded: - Green (0x2xx): foxBMS CAN TX (state, SOC, cell voltages) - Blue (0x6xx): Plant telemetry (SOC, OCV, IR drop) - Purple (0x7Fx): SIL probes (internal state)


Running Automated Tests

Smoke test (15 seconds)

python3 src/test_smoke.py vcan1

Fault injection tests (P1, 10 tests, ~2 minutes)

python3 src/test_fault_injection.py vcan1 --max 10 --priority P1 \
  --csv docs/test/fault-injection-test-matrix-asild.csv --timeout 10000

Full test suite (2,005 tests, ~5 hours)

python3 src/test_fault_injection.py vcan1 \
  --csv docs/test/fault-injection-test-matrix-asild.csv --timeout 15000

Scenario tests (high-risk scenarios)

python3 src/test_scenarios.py vcan1

Architecture

┌─────────────────┐     SocketCAN (vcan1)      ┌──────────────────┐
│                 │                              │                  │
│  Plant Model    │ ──── 0x270 Cell Voltages ──→ │                  │
│  (Python)       │ ──── 0x280 Cell Temps    ──→ │  foxBMS vECU     │
│                 │ ──── 0x521 IVT Current   ──→ │  (C binary)      │
│  Battery +      │ ──── 0x210 State Request ──→ │                  │
│  IVT Sensor     │                              │  Same C code as  │
│  Simulation     │ ←── 0x220 BMS State      ─── │  TMS570 target   │
│                 │ ←── 0x7F0 SIL Probes     ─── │                  │
│                 │                              │  170+ source     │
│  Reads 0x7F0    │     CAN 0x6E0 (plant cmd)    │  files compiled  │
│  for contactor  │ ←────────────────────────── │  for x86-64      │
│  feedback       │                              │                  │
└─────────────────┘                              └──────────────────┘
        │                                                │
        │ CAN 0x600-0x607                    CAN 0x7F0-0x7FF
        │ (plant telemetry)                  (SIL probes)
        │                                                │
        └──────────────────┐    ┌────────────────────────┘
                           │    │
                    ┌──────┴────┴──────┐
                    │                  │
                    │  Web Server      │
                    │  (Python aiohttp)│
                    │                  │
                    │  HTTP :8080      │
                    │  WebSocket /ws   │
                    │                  │
                    └──────────────────┘
                           │
                    ┌──────┴──────┐
                    │             │
                    │  Browser    │
                    │  Dashboard  │
                    │             │
                    └─────────────┘

CAN Message Map

CAN ID Direction Content
0x210 Plant → BMS State request (STANDBY/NORMAL)
0x270 Plant → BMS Cell voltages (18 cells, multiplexed)
0x280 Plant → BMS Cell temperatures (8 sensors, multiplexed)
0x521 Plant → BMS IVT current (mA)
0x522-524 Plant → BMS IVT voltage (mV)
0x527 Plant → BMS IVT temperature
0x220 BMS → all BMS state (multiplexed)
0x600-602 Plant → Web Plant telemetry (SOC, OCV, IR)
0x603-607 Plant → Web Per-cell voltages (for dashboard)
0x6E0 Web → Plant Plant override commands (SWE.6)
0x7E0 Web → BMS BMS DB override commands (SWE.5)
0x7F0-7FF BMS → Web SIL probes (state, DIAG, contactor)

foxBMS Configuration (NMC Chemistry)

Parameter MSL RSL MOL
Overvoltage 4250 mV 4200 mV 4150 mV
Undervoltage 2500 mV 2600 mV 2700 mV
OT Discharge 55.0°C 50.0°C 45.0°C
OT Charge 45.0°C 40.0°C 35.0°C
String Current 15000 mA
OV threshold 50 events + 200ms delay
OT threshold 500 events + 1000ms delay
OC threshold 10 events + 100ms delay

Battery Pack Configuration

Parameter Value
Cells in series 18
Cell capacity 3000 mAh (3 Ah)
Cell resistance 50 mΩ
Discharge current 1 A (0.33C)
Nominal voltage 3700 mV (50% SOC)
OCV range 3400 mV (0%) – 4200 mV (100%)
AFE averaging 16-sample moving average
Measurement noise ±3 mV Gaussian

Patches Applied to foxBMS

The foxBMS source (v1.10.0) is unmodified in the submodule. All changes are applied at build time via Python patch scripts in patches/:

Patch What it does
patch_all_regs.py Redirect TMS570 register bases to RAM
patch_canreg.py CAN register redirect
patch_sbc.py/sbc2.py SBC returns RUNNING (no physical SBC)
patch_rtc.py RTC returns initialized
patch_can_sensor.py Current sensor present = true
patch_database.py DATA_IterateOverDatabaseEntries extern
patch_database2.py Database trace
patch_ftask.py Engine/precyclic trace
patch_sys2.py SYS_Trigger trace
patch_bms2.py BMS_Trigger trace
patch_10ms2.py 10ms task trace
patch_precharge.py Precharge always OK
patch_battery_cfg.py NMC voltage/current thresholds
patch_diag_posix.py Disable 42 hardware-absent DIAG IDs
patch_diag_probe.py SIL probe + startup grace period in DIAG
patch_db_inject.py Deep fault injection at DB READ path

File Structure

foxbms-posix/
├── foxbms-2/              # foxBMS v1.10.0 submodule (unmodified)
├── halcogen-headers/      # 91 HALCoGen generated headers (BSD)
├── freertos-posix-port/   # FreeRTOS POSIX port (MIT)
├── patches/               # 16 Python patch scripts
│   └── apply_all.sh       # Apply all patches in order
├── src/
│   ├── foxbms_posix_main.c   # Main loop + SIL probes
│   ├── hal_stubs_posix.c     # 80+ HAL stubs + SPS simulation
│   ├── sil_layer.c/h         # SIL override + probe system
│   ├── posix_overrides.h     # FAS_ASSERT + portmacro
│   ├── plant_model.py        # Dynamic battery simulator
│   ├── plant_model_replay.py # BMW i3 trip replay
│   ├── Makefile              # Build system
│   ├── test_smoke.py         # Smoke test
│   ├── test_fault_injection.py # Automated FI test runner
│   ├── test_scenarios.py     # High-risk scenario tests
│   └── fi/                   # 17-module test framework
├── web/
│   ├── server.py             # CAN-to-WebSocket bridge
│   └── index.html            # Dashboard (single file)
├── docs/
│   ├── test/                 # Test matrix (2,005 cases)
│   ├── plans/                # Implementation plans
│   ├── lessons-learned.md    # 9 lessons documented
│   ├── test-progress.md      # Test execution results
│   └── aspice-cl2/           # ASPICE folder structure
│       ├── 11-SWE.4-.../test-results/  # Unit test report
│       ├── 12-SWE.5-.../test-results/  # Integration test report
│       └── 13-SWE.6-.../test-results/  # Qualification test report
├── GAP-ANALYSIS.md           # 33/33 gaps closed
├── PLAN.md                   # Phase 1-4 roadmap (96% complete)
├── Dockerfile                # Docker build
└── docker-compose.yml        # Docker compose

Troubleshooting

BMS doesn't reach NORMAL

Web dashboard shows no data

Cell voltages all zero

Fault injection doesn't trigger BMS reaction

Processes die after SSH disconnect


License