Hardware Reference
LibreScoot runs on two ARM boards inside the scooter: the MDB (vehicle control) and the DBC (dashboard UI and navigation).
MDB — Middle Driver Board
The main vehicle controller. Talks to the ECU over CAN, reads keycards and batteries via NFC, and manages cellular/GPS connectivity.
| Component | Details |
|---|---|
| SoC | ARMv7 Cortex-A series |
| RAM | DDR3 |
| Storage | eMMC (A/B Mender partitions) |
| CAN Bus | ECU communication (Bosch / Votol motor controller) |
| NFC | PN7150 (keycard authentication + battery BMS communication) |
| 4G Modem | SIM7100E (cellular + GPS) |
| Bluetooth/nRF | nRF52840 co-processor via USOCK (UART + CBOR) |
| IP Address | 192.168.7.1 (USB Ethernet gadget) |
nRF52840 Co-processor
The nRF52840 handles Bluetooth Low Energy and LED control. It communicates with the MDB via a USOCK protocol (UART framing with CBOR encoding). The bluetooth-service on the MDB owns this interface and exposes BLE state to Redis.
DBC — Dashboard Computer
Runs the dashboard UI (Qt on a 480×480 display) and offline navigation.
| Component | Details |
|---|---|
| SoC | NXP i.MX6DL — dual Cortex-A9 @ 800 MHz |
| Display | 480×480 parallel RGB565 at 59.1 Hz |
| GPU | Vivante GC2000 (3D, etnaviv) + GC355 (2D) |
| Ambient Light | OPT3001 sensor, read by dbc-backlight-service for auto-brightness |
| Storage | eMMC (A/B Mender partitions + /data user partition) |
| IP Address | 192.168.7.2 (USB Ethernet gadget, via MDB) |
Display pipeline
The IPU (Image Processing Unit) drives the parallel display via /dev/fb0. The GPU renders to an EGL surface using the render node (/dev/dri/renderD128) and blits to the framebuffer. The GPU and display are separate subsystems; etnaviv has no KMS connectors.
Network Topology
The MDB and DBC are connected via USB Ethernet gadget. The MDB runs a Redis instance; DBC services connect to it over the network.
Redis :6379
SSH :22
Redis client → 192.168.7.1:6379
SSH :22
From an external machine, SSH into the MDB first, then jump to the DBC:
ssh root@<mdb-ip> # MDB direct ssh -J root@<mdb-ip> root@192.168.7.2 # DBC via jump
UART Debug Access
Both boards expose a 3-pin UART debug header at 115200 baud, 8N1. No hardware flow control.
MDB Debug UART
| Pin | Signal |
|---|---|
| Pin 1 | GND |
| Pin 2 | TXD (MDB transmits) |
| Pin 3 | RXD (MDB receives) |
Baud rate: 115200
DBC Debug UART
6-pin header at the bottom of the DBC, next to the main connectors. Accessible without opening the case.
| Pin | Signal |
|---|---|
| Pin 1 (square) | GND |
| Pin 2 | — |
| Pin 3 | — |
| Pin 4 | RXD (DBC receives) |
| Pin 5 | TXD (DBC transmits) |
| Pin 6 | — |
Baud rate: 115200
Voltage: 3.3V logic — do not use 5V
If you get no output, try swapping pins 4 and 5.
Boot Flow
MDB Boot Sequence
- U-Boot loads from eMMC boot partition
- Kernel decompresses and initializes hardware
- systemd starts services in dependency order
vehicle-serviceentersstand-bystate, scooter is ready for keycard
DBC Boot Sequence
- U-Boot (stored in eMMC boot partition, mmcblk3boot0) loads kernel and DTB from
/boot/on the active rootfs partition - Kernel initializes i.MX6DL, IPU, and etnaviv GPU
- Boot animation starts early (~T+3s), rendered by ThorVG to
/dev/fb0, runs until multi-user.target scootui-qtQt dashboard starts viadbc-dispatcher- The
/datapartition (mmcblk3p4) mounts at ~T+7s after fsck, so it's not available for early services
Mender A/B Partitions
Both boards use Mender for OTA updates with atomic A/B partition switching. The active partition is selected by U-Boot on each boot. A failed update automatically rolls back to the previous partition on the next boot attempt.
| Partition | Contents |
|---|---|
| mmcblk?p1 | U-Boot environment |
| mmcblk?p2 | Rootfs A (active) |
| mmcblk?p3 | Rootfs B (inactive / update target) |
| mmcblk?p4 | /data, persistent user data (maps, settings) |