🇩🇪 Deutsche Version: README.de.md
Static reverse-engineering analysis of the Marstek Venus firmware (models D, A and E3: Control/EMS, micro-inverter/VNS, BMS) using Ghidra, as the basis for a Home Assistant integration via the devices' Modbus TCP interface. All findings are based on static analysis of the firmware images, not on live debug access (SWD/JTAG), unless noted otherwise.
Models: Venus D/E (VNSD-0), Venus A (VNSA-0), Venus E3 (VNSEE3-0); ARM Cortex-M MCUs, FreeRTOS
Analyzed firmware versions:
- Venus D: Control 151 / 150 / 149.2 / 149 / 147, Micro/VNS 116 / 115, BMS 118 / 117.7
- Venus A: Control 151 / 150 / 1509, Micro 1211, BMS 115 / 110 / 1105
- Venus E3: Control 151 / 150, Micro 119, BMS 115
The binary-fingerprint table below covers the Venus D images only (status as noted there).
Read live from Ghidra (status 2026-10-14). All nine programs are imported at their real load base and are fully named (every function has a non-default name, "named" is the Ghidra symbol status only). The flash range is the mapped extent of the image (base + file size − 1); the string count is the Ghidra count of defined strings.
| Firmware | Version | File | Size | Flash range | Initial SP | Reset handler | Functions (named/total) | Strings |
|---|---|---|---|---|---|---|---|---|
| Control | 151 (current) | VNSD-0_ems_app_0151_0929_094333.bin |
393,216 B (384 KB) | 0x08004800–0x080647FF |
0x20022010 |
0x08004A71 |
1956 / 1956 (100 %) | 4237 |
| Control | 150 | VNSD-0_app_0150_0805_115146.bin |
389,120 B (380 KB) | 0x08004800–0x080637FF |
0x2001F7E8 |
0x08004A71 |
1954 / 1954 (100 %) | 4101 |
| Control | 149.2 | VNSD-0_app_1492_0702_142136.bin |
385,024 B (376 KB) | 0x08004800–0x080627FF |
0x2001F7D8 |
0x08004A71 |
1936 / 1936 (100 %) | 4097 |
| Control | 149 | VNSD-0_app_0149_0521_094621.bin |
385,024 B (376 KB) | 0x08004800–0x080627FF |
0x2001F778 |
0x08004A71 |
1932 / 1932 (100 %) | 4076 |
| Control | 147 | VNSD-0_202601281721320b2053125.bin |
372,736 B (364 KB) | 0x08004800–0x0805F7FF |
0x2001F3E0 |
0x08004A71 |
1908 / 1908 (100 %) | 4000 |
| Micro/VNS | 116 (current) | VNSD-0_vd_inv_app_0116_0702_ota_163439.bin |
115,712 B (113 KB) | 0x08004000–0x080203FF |
0x20009A70 |
0x080042AD |
693 / 693 (100 %) | 1047 |
| Micro/VNS | 115 | VNSD-0_202601230921310c0e30687.bin |
115,712 B (113 KB) | 0x08004000–0x080203FF |
0x20009A70 |
0x080042B1 |
696 / 696 (100 %) | 1046 |
| BMS | 118 (current) | VNSD-0_20260119100535e43806957.bin |
106,496 B (104 KB) | 0x08002800–0x0801C7FF |
0x2000CBA0 |
0x08002A6D |
711 / 711 (100 %) | 740 |
| BMS | 117.7 | VNSD-0_20251010135647565eb2036.bin |
106,496 B (104 KB) | 0x08002800–0x0801C7FF |
0x2000CB90 |
0x08002A6D |
710 / 710 (100 %) | 741 |
Common properties of these nine Venus D images: ARM Cortex-M4F, Thumb-2, little-endian, FreeRTOS
(heap_4, ARM_CM4F port). Load base: Control 0x08004800, Micro/VNS 0x08004000, BMS 0x08002800
(the region below the base is not part of the update image).
| Firmware | Compiler | Crypto | Cell monitoring | Communication |
|---|---|---|---|---|
| Control | GCC | mbedTLS 2.28.10 | — | WiFi + Ethernet (CH395) + RS485 + CAN |
| Micro/VNS | RVDS/Keil ARM | — (none) | — | CAN + RS485 |
| BMS | RVDS/Keil ARM | — (none) | KA495XX (BMIC) | CAN + RS485 |
Notable: Micro/VNS 115 and 116 as well as BMS 117.7 and 118 each occupy exactly the same flash address range despite differing functionality — suggests a fixed OTA slot size per firmware type rather than a variable image size.
File naming: Documents that apply to only one device carry the device prefix VNSD_
(Venus D), VNSA_ (Venus A) or VNSE3_ (Venus E3). Only cross-device documents
(methodology, device comparison, diff workflow) have no prefix. Not renamed is the subfolder
Modbus_RS485_TCP/Scan_Logs/.
This directory is the root of the repository; all paths in the documents are
repo-relative (e.g. Modbus_RS485_TCP/…, Control_FW/…, BMS/…). What exists only locally
is listed in the section "Not in the repository (local only)" further below.
| Folder | Contents |
|---|---|
Control_FW/ |
Control/EMS firmware (main processor). Venus D: full function analysis for v149.2 (name tracking table, ~1600 functions, batch history) and v147 (diff-based analysis against 149.2, 340 only-in-147 functions documented individually). For v150 additionally the cloud watchdog including the root-cause analysis of the 30-minute grid outages (§4a of the v150 analysis) and the case study VNSD_Cloud_Watchdog_Case_Study_2026-08-26.md — including the four refuted interim hypotheses and the methodology that settled them. Conversion of the BMS charge limit into power, PV curtailment and the 42011/force_mode coupling in VNSD_Control_Charge_Power_PV_Curtailment_v150.md; Venus A Control 1509 analysis VNSA_Control_FW_v1509_Full_Analysis.md; Venus A Control 151 analysis VNSA_Control_FW_v151_Full_Analysis.md with the diff tables VNSA_Control_Diff_v1509_v151.md and VNSA_Control_Diff_v150_v151.md; Venus A Control 150 analysis VNSA_Control_FW_v150_Full_Analysis.md with VNSA_Control_Diff_v150_v1509.md; Venus E3 Control 150 analysis VNSE3_Control_FW_v150_Full_Analysis.md (incl. verification of the HTTP OTA body-start selector) with the diff table VNSE3_Control_Diff_v150_v151.md; cross-device OTA HTTP body-boundary selector, OTA reader and OTA diagnostics reference OTA_HTTP_Body_Boundary_and_Diagnostics.md; Wi-Fi disconnect URC bug VNSD_FW_Bug_WLAN_Disconnected_URC_2026-10-02.md |
VNS_Micro_Inverter/ |
Micro-inverter/VNS firmware: Venus D function analysis, register maps, version diff 115→116, error/warning codes. Files with a device prefix (VNSA_…) apply only to this model — the Venus A inverter is a separate code base (0.4 % shared code with the D), its error bits are documented separately in VNSA_Error_Codes_Micro_FW_Analysis.md; Venus A micro 1211 (Novosense NS800RT) analysis: VNSA_Micro_FW_v1211_Full_Analysis.md |
BMS/ |
BMS firmware analysis (Venus D: v117.7, v118); pack rotation, discharge lower limit, special modes and measured charge taper in VNSD_BMS_Pack_Rotation_Taper_v118.md; SOH, cycle counter, full/empty detection, cell balancing and discharge current limit in VNSD_BMS_SOH_Cycles_Discharge_Limit_v118.md; battery pack recovery, firmware side (automatic recovery charge, remote BMS commands) in VNSD_Battery_Pack_Recovery_Firmware.md; Venus A BMS 1105 analysis: VNSA_BMS_FW_v1105_Full_Analysis.md; Venus A BMS 110 analysis VNSA_BMS_FW_v110_Full_Analysis.md (code base A 109 + 40 A cap) with the diff table VNSA_BMS_Diff_v1105_v110.md; Venus A BMS 115 analysis VNSA_BMS_FW_v115_Full_Analysis.md (merge of 110 and 110.5 plus SOC-imbalance pack switch, MOS recovery, RTC wake-up from STOP) with the diff table VNSA_BMS_Diff_v110_v115.md and the open points in depth (config checksum, unknown CAN ids, PE7/PD8) in VNSA_BMS_FW_v115_Open_Points.md |
Modbus_RS485_TCP/ |
External Modbus interface of the Venus devices (TCP and RS485 RTU, parallel stack with a shared descriptor table): connection reference, protocol quirks, scale factors, RS485 unlocking, full register map (CSV), register hypotheses from scan evaluation, decoded descriptor tables (CSV) including version diffs, read/write handler register maps in Scan_Logs/ (the raw scan logs themselves exist only locally), reconciliation of the BLE power values against Modbus (load test 600 W), firmware bug in the read serializer (German analysis + English vendor report), write register block 46500-46544, register resolution (functional status per register); complete code-verified register reference (all registers with status, origin/target and integration notes) in VNSD_Register_Reference.md; Venus A register map and reference (all registers, same-as-D comparison, version notes for Control 151 and BMS 110/115): VNSA_Register_Reference.md |
CAN_Bus/ |
Internal CAN bus between the MCUs: structure of the arbitration ID, target classes (inverter/BMS/RS485 path), complete function code tables of all 46 send sites of the Control against the receiver dispatchers of Micro v116 and BMS v118 (Venus D), coverage gaps |
BLE/ |
Bluetooth LE interface of the Control: command mapping (Venus D v150) and cross-reference BLE ↔ Modbus registers |
Methodik_und_Meta/ |
Reverse-engineering methodology, Ghidra workflow/lessons learned, firmware diff workflow, serial number format, open questions. Save Ghidra changes made via ReVa: ReVa_Saving_Changes.md (saving in the project window is not sufficient) |
HM_HIE_FC41D/ |
Communication module Quectel FC41D (Beken BK7231N): OTA/update analysis, software stack, version diff 202409 → 202512, SoftAP/update path, Hamedata customizations, instructions for traffic capture (Raspberry Pi, laptop AP, BLE update) |
App/ |
Analysis of the Marstek smartphone app (com.hamedata.marstek): API recon, command vocabulary of app 1.6.76, mapping of the app commands to the firmware, decompilation method |
Hardware_Recherche/ |
Internet research on components: MCU identification (Control/BMS: Nations N32G45x, Micro: STM32G474), teardown/photo research, approval and certificate documents (Markdown evaluations only, sources as links) |
SVD/ |
Vendor SVD files (Nations N32G451/452/455/457, Artery AT32F403A, STM32G474) for naming the peripheral registers in Ghidra |
Caution, terminology mix-up: "RS485" appears in the firmware in two independent roles —
(1) the external RS485 RTU Modbus stack (47,400 baud, FC03/FC06/FC10, parallel access to
the same registers as Modbus TCP, documented in Modbus_RS485_TCP/) and (2) internal
RS485/UART connections between the MCUs (Control↔micro-inverter for power setpoints/modes, BMS
master↔slave packs for 96-byte struct transfers) — a proprietary struct protocol, not Modbus,
documented in Control_FW/ and BMS/ respectively.
The following belongs to the project but is deliberately not part of this repository. The documents refer to it at the relevant places and mark it with "(local, not in the repo)":
- Decompilation exports (
Dekompilate/): complete decompilations and listings per firmware. They can be reproduced with the documented Ghidra workflow, seeMethodik_und_Meta/Decompilation_Export.md. - Own helper scripts (Python): scan/monitoring tools for Modbus, export/save scripts for Ghidra, verification and diff helpers.
- Raw scan logs (CSV/log files of the Modbus scans of various operating states).
- Third-party PDFs, screenshots and vendor headers: datasheets, manuals, test reports,
teardown screenshots and the vendor header
n32g45x.h(copyrighted; sources as links inHardware_Recherche/). - Decrypted vendor firmware and archives of the communication module's update images.
- Confidential security material (
security/), see next section.
In the course of the analysis, security-relevant findings were made (among others a hardcoded AWS IoT client certificate including private key shared across product lines, and a firmware update path without bounds check). These were reported to the vendor confidentially via responsible disclosure and are deliberately not published in this repository until a fix is available. Affected passages in the documents above are marked accordingly and refer to internal, non-public documentation.
Most relevant are Modbus_RS485_TCP/ (connection setup, register map, scale factors,
pitfalls such as the 32-register batch limit) as well as the register/struct descriptions in Control_FW/
and VNS_Micro_Inverter/.