A browser-based open-source debugger for ARM microcontrollers. Flash firmware, recover locked devices, and verify flash contents — all from your browser using WebUSB and CMSIS-DAP.
A debugger is a tool that developers place their trust in during the most critical moments of development. We hold ourselves to that standard:
- Reliability — Every flash and recover operation must complete correctly, or fail explicitly with clear guidance
- Stability — Robust error recovery, bounded timeouts, and concurrency guards ensure the tool never hangs or leaves a device in an unknown state
- Security — All user inputs are validated; no external network requests; least-privilege CI/CD
- Compatibility — Clean browser feature detection, graceful degradation, and a modular architecture that welcomes new targets and platforms
- Performance — Lightweight vanilla JS with zero build overhead; responsive UI that never blocks during long operations
- Flash — Upload an Intel HEX file and write it to your target MCU
- Recover — Mass erase locked devices via platform-specific access ports (e.g., Nordic CTRL-AP)
- Verify — Read back and compare flashed firmware byte-by-byte (optional)
- RTT (Real-Time Transfer) — Bidirectional terminal communication using SEGGER RTT protocol with configurable scan range and polling interval
- Extensible — Add new target MCUs via JSON definition files; add new platforms via handler modules
| MCU | Platform | Flash Controller | Status |
|---|---|---|---|
| nRF54L15 | Nordic | RRAMC | ✅ Supported |
Visit freeocd.org to use the WebDebugger directly in your browser — no build or server setup required.
For Online Use:
- A Chromium-based browser (Chrome, Edge) — WebUSB is required
- A CMSIS-DAP compatible debug probe
For Local Development:
- Node.js (v20+ recommended) — for building DAP.js
- Python 3 — for running local HTTP server
$ git clone --recurse-submodules https://github.com/FreeOCD/freeocd-web.git
$ cd freeocd-web
$ cd vendor/dapjs && npm install && npm run build && cd ../..
$ mkdir -p public/lib
$ cp vendor/dapjs/dist/dap.umd.js public/lib/dap.umd.js
$ cp vendor/dapjs/LICENSE public/lib/dapjs-LICENSE.txt$ python3 -m http.server 8000 -d publicOpen http://localhost:8000 in Chrome or Edge.
- Accept the disclaimer
- Select your target MCU from the dropdown
- Choose a firmware
.hexfile - Click Flash to erase and program the device
- (Optional) Click Recover to mass erase a locked device without flashing
- Configure RTT scan settings (start address, range, polling interval)
- Click Connect RTT to establish RTT connection
- Use the terminal to send commands and view output
- Click Disconnect RTT to close the connection
- Note: RTT connection is automatically disconnected during Flash/Recover operations; reconnect it manually after completion
WebUSB is required. The following browsers are supported:
- Google Chrome (desktop)
- Microsoft Edge (desktop)
- Other Chromium-based browsers
Safari and Firefox do not support WebUSB.
- Create a JSON definition file in
public/targets/<platform>/<family>/<mcu>.json - Add an entry to
public/targets/index.json - If the platform is new, create a handler class in
public/js/platform/and register it intarget-manager.js
See public/targets/nordic/nrf54/nrf54l15.json for an example target definition.
- AI_REVIEW.md — Code review checklist with architecture diagrams, systematic checks, and CMSIS-DAP glossary. Useful for both AI and human reviewers.
The application follows a layered architecture with clear separation of concerns:
┌─────────────────────────────────────────────────────────────┐
│ UI Layer │
│ (index.html + css/style.css) │
│ - Modal dialogs, step progress, terminal UI │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Application Layer │
│ (main.js) │
│ - Event handling, operation orchestration, state management│
│ - Operation locking to prevent conflicts │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Platform Layer │
│ (platform/) │
│ - TargetManager: Loads target definitions │
│ - PlatformHandler: Abstract base for platform operations │
│ - NordicHandler: Nordic-specific implementation │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Core Layer │
│ (core/) │
│ - hex-parser.js: Intel HEX parsing │
│ - dap-operations.js: Low-level DAP transfer operations │
│ - rtt-handler.js: SEGGER RTT protocol implementation │
│ - terminal.js: Terminal UI component │
│ - state-manager.js: Connection state monitoring │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Transport Layer │
│ (transport/) │
│ - TransportInterface: Abstract transport contract │
│ - WebUSBTransport: WebUSB implementation │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Hardware Layer │
│ - CMSIS-DAP debug probe (via WebUSB) │
│ - Target MCU (e.g., nRF54L15) │
└─────────────────────────────────────────────────────────────┘
Transport Layer
- Abstracts device communication (currently WebUSB only)
- Allows future support for WebSerial or other transports
TransportInterfacedefines the contract for all transports
Core Layer
hex-parser.js: Parses Intel HEX files into binary datadap-operations.js: Raw DAP_TRANSFER operations bypassing DAP.js bugsrtt-handler.js: Implements SEGGER RTT for bidirectional communicationterminal.js: Simple terminal UI without external dependenciesstate-manager.js: Monitors device/RTT connection state with polling
Platform Layer
TargetManager: Loads target JSON definitions and instantiates handlersPlatformHandler: Abstract base defining recover/flash/verify/reset contractNordicHandler: Nordic-specific implementation (CTRL-AP, RRAMC/NVMC)
Application Layer
main.js: Orchestrates operations with step-by-step progress- Operation locking prevents Flash/Recover/RTT conflicts
- State management for UI updates and error recovery
Target definitions are JSON files in public/targets/<platform>/<family>/<mcu>.json:
{
"name": "nRF54L15",
"description": "Nordic nRF54L15",
"platform": "nordic",
"usbFilters": [{"vendorId": "0x1915"}],
"ctrlAp": {
"num": 2,
"idr": "0x288e0181"
},
"eraseAllStatus": {
"busy": 2,
"readyToReset": 1,
"error": 0
},
"flashController": {
"type": "rramc",
"base": "0x41080000",
"registers": {
"config": {"offset": "0x504", "enableValue": "0x1"},
"ready": {"offset": "0x400"}
}
},
"capabilities": ["flash", "recover"]
}Flash Operation
- User selects target MCU and HEX file
runFlash()acquires operation lock- Disconnect RTT if connected
- Connect via WebUSB and DAP
- Call
handler.recover()for mass erase - Create fresh DAP connection
- Call
handler.flash()to write firmware - If verify enabled, call
handler.verify() - Call
handler.reset()to restart device - Release lock and cleanup
RTT Connection
- User clicks "Connect RTT"
connectRtt()acquires RTT lock- Connect via WebUSB and DAP
- Halt and reset target
- Scan memory for RTT control block signature
- Initialize RTT handler with buffer info
- Resume target
- Start StateManager polling (1s interval)
- Start RTT data polling (configurable interval)
- Enable terminal for bidirectional communication
public/ # Deployable static site
├── index.html # Main UI
├── css/style.css # Styles
├── js/
│ ├── main.js # Application entry point
│ ├── core/ # HEX parser, low-level DAP operations
│ ├── transport/ # Transport abstraction (WebUSB, future: WebSerial)
│ └── platform/ # Platform handlers (Nordic, future: STM32, RP2040)
├── targets/ # JSON target definitions
│ └── nordic/nrf54/ # Nordic nRF54 series
└── lib/ # Built dependencies (gitignored)
scripts/ # Development scripts
└── validate-json.js # Target JSON validator
vendor/dapjs/ # DAP.js source (git submodule)
AI_REVIEW.md # Code review checklist for AI/human reviewers
This project is licensed under the BSD 3-Clause License. See LICENSE for details.
- DAP.js — MIT License (Copyright (c) Arm Limited 2018, Microsoft Corporation)