Skip to content

Commit 474f919

Browse files
committed
Initial public template: ESP32 BLE Legacy DFU firmware
0 parents  commit 474f919

42 files changed

Lines changed: 3299 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.pio
2+
.vscode/.browse.c_cpp.db*
3+
.vscode/c_cpp_properties.json
4+
.vscode/launch.json
5+
.vscode/ipch

.vscode/extensions.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
// See http://go.microsoft.com/fwlink/?LinkId=827846
3+
// for the documentation about the extensions.json format
4+
"recommendations": [
5+
"platformio.platformio-ide"
6+
],
7+
"unwantedRecommendations": [
8+
"ms-vscode.cpptools-extension-pack"
9+
]
10+
}

README.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# ESP32 BLE Legacy DFU Template
2+
3+
Production-ready ESP32 firmware template for OTA updates over **Bluetooth Low Energy (BLE)** using the **Nordic Legacy DFU profile**.
4+
5+
This repository focuses on the ESP32 firmware side.
6+
The companion iOS app is maintained as a separate app/repository and is only included here as a development reference under `iOS/ESP32-DFU`.
7+
8+
## What This Template Provides
9+
10+
- BLE DFU service compatible with Nordic Legacy DFU UUID set.
11+
- Dual-slot OTA partition layout for safer updates.
12+
- Firmware streaming through DFU Packet characteristic.
13+
- Pre-commit validation by image size and CRC32 before activation.
14+
- Packet Receipt Notification (PRN) support.
15+
- Verbose serial diagnostics for protocol-level debugging.
16+
- Clean modular structure for long-term maintainability.
17+
18+
## BLE Stack Overview
19+
20+
- BLE library: `NimBLE-Arduino`
21+
- Role: GATT server on ESP32
22+
- Service UUID: `00001530-1212-EFDE-1523-785FEABCD123`
23+
- Characteristics:
24+
- Control Point (`1531`): command/response path
25+
- Packet (`1532`): firmware and init payload stream
26+
- Version (`1534`): DFU protocol version information
27+
28+
### Supported Legacy DFU Opcodes
29+
30+
- `0x01` Start DFU
31+
- `0x02` Init DFU Parameters
32+
- `0x03` Receive Firmware Image
33+
- `0x04` Validate
34+
- `0x05` Activate and Reset
35+
- `0x06` Reset
36+
- `0x08` Packet Receipt Notification Request
37+
38+
### Validation Logic
39+
40+
Before finalizing an update, firmware validates:
41+
42+
- expected image size (if provided)
43+
- expected CRC32 (if provided in init packet)
44+
45+
Only after validation passes, `Update.end(true)` is called and new image is committed.
46+
47+
## Project Structure
48+
49+
- `platformio.ini` — PlatformIO environment and dependencies.
50+
- `partitions_ota.csv` — OTA partition table with `otadata`, `app0`, `app1`, `spiffs`, `coredump`.
51+
- `src/main.cpp` — firmware entrypoint (`setup()` / `loop()`).
52+
- `src/dfu_ble.h` — DFU module public interface.
53+
- `src/dfu_ble.cpp` — DFU BLE protocol implementation and OTA flow.
54+
55+
## OTA Partition Strategy
56+
57+
Template uses dual app slots:
58+
59+
- active app runs from one slot
60+
- incoming firmware is written to the inactive slot
61+
- boot metadata in `otadata` switches active slot only after successful validation
62+
63+
This minimizes risk of bricking during interrupted updates.
64+
65+
## Requirements
66+
67+
- ESP32 board supported by `espressif32` PlatformIO platform
68+
- PlatformIO Core (CLI or VS Code extension)
69+
- BLE DFU client (mobile app or custom client implementing Legacy DFU flow)
70+
71+
## Quick Start
72+
73+
1. Clone repository.
74+
2. Open the folder in VS Code with PlatformIO extension.
75+
3. Build firmware:
76+
77+
```bash
78+
pio run
79+
```
80+
81+
4. Flash firmware:
82+
83+
```bash
84+
pio run -t upload
85+
```
86+
87+
5. Open serial monitor:
88+
89+
```bash
90+
pio device monitor
91+
```
92+
93+
## Typical Update Flow (Client Side)
94+
95+
1. Connect to ESP32 DFU peripheral.
96+
2. `Start DFU` with expected app size.
97+
3. `Init DFU Params` start, send init payload, then complete init.
98+
4. `Receive FW Image`, stream binary in chunks.
99+
5. `Validate` and confirm success response.
100+
6. `Activate and Reset`.
101+
102+
## Example Integrations
103+
104+
- iOS app (SwiftUI + CoreBluetooth) acting as Legacy DFU client.
105+
- Android app with BLE GATT write/notify implementation.
106+
- Desktop updater script using BLE library and custom opcode sequence.
107+
108+
## Naming and Style Conventions
109+
110+
- Keep protocol constants explicit and close to implementation.
111+
- Use structured serial prefixes (`[DFU][STATE]`, `[DFU][ERROR]`) for fast log filtering.
112+
- Keep `main.cpp` minimal; place protocol logic in dedicated modules.
113+
- Prefer deterministic state transitions over implicit side effects.
114+
115+
## Troubleshooting
116+
117+
- Build fails for missing deps:
118+
- run `pio pkg update`
119+
- Device not visible in scanner:
120+
- verify BLE advertising started in serial log
121+
- Validate fails:
122+
- check expected size/CRC in init packet versus transmitted image
123+
- OTA boot issues:
124+
- confirm partition table is exactly `partitions_ota.csv`
125+
126+
## Security Notes
127+
128+
This template implements protocol-level integrity checks (size and CRC32), but does not include cryptographic signature verification by default.
129+
For production deployments, add signed artifacts and authenticity checks in bootloader or app-level policy.
130+
131+
## Separate Mobile App Publication
132+
133+
For releases, publish the mobile DFU client as a separate app/repository with its own versioning, signing, and release notes.
134+
Keep this repository focused on firmware template quality and embedded protocol behavior.
135+
136+
## License
137+
138+
Add your preferred license before publishing (for example, MIT or Apache-2.0).

0 commit comments

Comments
 (0)