# STM32CubeProgrammer Python Wrapper
A Python library **and** command-line tool for driving **STM32CubeProgrammer CLI** (`STM32_Programmer_CLI`) to flash, read, erase, reset, and configure STM32 MCUs—using a clean Python API.
---
## Requirements
- **STM32CubeProgrammer** installed (includes `STM32_Programmer_CLI`)
- **Python 3.8+**
- `STM32_Programmer_CLI` available via one of:
- In your **PATH**
- Environment variable: `STM32CUBEPRG_CLI=/full/path/to/STM32_Programmer_CLI[.exe]`
- Passed explicitly as `--cli` (CLI) or `cli_path="..."` (library)
> The wrapper auto-detects the CLI on Windows/macOS/Linux, including Windows Registry lookup and user-local installs.
---
## Installation
```bash
git clone https://github.com/rajcks007/stm32cubeprog.git
cd stm32cubeprog
# No extra deps needed (stdlib only)
```
If you plan to reuse it elsewhere, you can `pip install -e .` after adding a minimal `pyproject.toml`, but that’s optional.
---
## Working with Multiple Programmers
If you have more than one ST-LINK or other supported probe connected, you can select which one to use by **serial number** or **index**.
## Getting serial numbers programmatically
```python
import re
prog = CubeProgCLI()
out = prog.list_probes()
sns = re.findall(r"ST-LINK SN\s*:\s*([0-9A-F]+)", out)
print("ST-LINK SN :", sns)
```
Example output:
- ST-LINK SN : 57FF6F067186535460351387
- ST-LINK SN : 066EFF303451897067120842
## Usage as a Library
```python
from stm32cubeprog_wrapper import CubeProgCLI
# Create the programmer (auto-detects STM32_Programmer_CLI)
prog = CubeProgCLI()
# 1) Flash firmware (BIN/HEX/ELF) at 0x08000000, verify + reset
prog.flash_firmware(
"firmware.bin",
address=0x08000000,
verify=True,
reset=True,
port="SWD",
freq=4000, # kHz
on_progress=lambda pct, _line: print(f"{pct}%"),
on_log=lambda stream, line: print(f"[{stream}] {line}"),
)
# 2) Read memory (4 KB) to a file
prog.read_memory(
address=0x08000000,
size=4096,
out_file="dump.bin",
file_type="bin", # or "hex"
port="SWD",
freq=4000,
)
# 3) Erase (all/bank/sector)
prog.erase(scope="all", port="SWD", freq=4000)
# prog.erase(scope="bank", bank=1, port="SWD")
# prog.erase(scope="sector", sector=2, port="SWD")
# 4) Reset target (software by default; pass sw=False for hardware reset)
prog.reset(port="SWD", freq=4000) # software reset
prog.reset(sw=False, port="SWD") # hardware reset
# 5) Info helpers
print(prog.get_version()) # STM32CubeProgrammer version banner
print(prog.list_probes()) # Connected ST-LINKs/ports
print(prog.read_device_info()) # Device info / option bytes
# 6) Option bytes (key=value pairs)
prog.write_option_bytes(["RDP=0xAA", "nWRP=0x0"],
port="SWD"
)
# 7) Set RDP level (0|1|2) (Readout Protection)
prog.set_rdp(level="0", port="SWD") # 0 = no protection
prog.set_rdp(level="1", port="SWD") # 1 = read protected
prog.set_rdp(level="2", port="SWD") # 2 = full lock
# 8) Choose by serial number
prog.flash_firmware(
"firmware.bin",
address=0x08000000,
port="SWD", freq=4000,
sn="57FF6F067186535460351387",
)
# 9) choose by index
prog.flash_firmware(
"firmware.bin",
address=0x08000000,
port="SWD", freq=4000,
index=1,
)
# 10) Flashing multiple boards (sequentially)
serials = ["57FF6F067186535460351387", "066EFF303451897067120842"]
for sn in serials:
prog.flash_firmware("firmware.bin", 0x08000000, port="SWD", freq=4000, sn=sn)
# 11) Flashing multiple boards in parallel
import threading
serials = ["57FF6F067186535460351387", "066EFF303451897067120842"]
def flash_one(sn):
CubeProgCLI().flash_firmware("firmware.bin", 0x08000000, port="SWD", freq=4000, sn=sn)
threads = [threading.Thread(target=flash_one, args=(sn,)) for sn in serials]
[t.start() for t in threads]
[t.join() for t in threads]
```
### Connection options you can pass (as keyword args)
- `port="SWD" | "JTAG" | "USBx" | "UARTx"`
- `freq=4000` (kHz for SWD/JTAG)
- `mode="hotplug" | "underreset" | ...`
- `reset_mode="swrst" | "hwrst"`
- `index=<probe_index>` or `sn="<stlink_serial>"`
- UART: `baud=115200`, `parity="even"`, `stopbits=1`
---
## How to Use (Quick Start)
1. **Install STM32CubeProgrammer** from ST.
2. Connect your **ST-LINK** and target board.
3. Put your firmware at a known path, e.g. `firmware.bin`.
4. Pick the correct **flash start address** for your MCU (commonly `0x08000000`).
5. Use the **library** (Python script) or the **CLI** (terminal) examples below.
---
## Usage as a CLI Tool
Run the script directly:
```bash
python stm32cubeprog_wrapper.py <command> [options]
```
Common global options (append to any command):
- `--cli "C:\Path\to\STM32_Programmer_CLI.exe"` (override autodetect)
- `--port SWD` `--freq 4000` `--mode hotplug` `--index 0` `--sn XXXXXX`
- `--timeout 300` `--no-live` (disable live console output)
### Commands
- `version` — Show STM32CubeProgrammer CLI version
- `list` — List connected probes/ports
- `flash <file> <address> [--type bin|hex|elf] [--no-verify] [--no-reset]`
- `read <address> <size> <out> [--type bin|hex]`
- `erase <all|bank|sector> [--bank N] [--sector N]`
- `reset [--hard]`
- `info` — Device info/option bytes (raw)
- `ob <KV...>` — Write option bytes (e.g., `RDP=0xAA nWRP=0x0`)
- `rdp <0|1|2>` — Set Readout Protection level
---
## Listing available probes (CLI)
```bash
python stm32cubeprog_wrapper.py list
```
Example output:
- ST-LINK SN : 57FF6F067186535460351387
- ST-LINK SN : 066EFF303451897067120842
## Examples (CLI)
**By serial number (recommended for stability):**
```bash
python stm32cubeprog_wrapper.py flash firmware.bin 0x08000000 --port SWD --freq 4000 --sn Serial_numbe (e.g 57FF6F067186535460351387)
```
**By index:**
```bash
python stm32cubeprog_wrapper.py flash firmware.bin 0x08000000 --port SWD --freq 4000 --index 1
```
### Flash a binary at 0x08000000 (verify + reset)
```bash
python stm32cubeprog_wrapper.py flash firmware.bin 0x08000000 --port SWD --freq 4000
```
### Flash a HEX, no auto-reset
```bash
python stm32cubeprog_wrapper.py flash app.hex 0x08000000 --type hex --port SWD --no-reset
```
### Read 4 KB from flash to `dump.bin`
```bash
python stm32cubeprog_wrapper.py read 0x08000000 4096 dump.bin --port SWD --freq 4000
```
### Erase full flash
```bash
python stm32cubeprog_wrapper.py erase all --port SWD
```
### Hardware reset
```bash
python stm32cubeprog_wrapper.py reset --hard --port SWD
```
### Show connected probes
```bash
python stm32cubeprog_wrapper.py list
```
### Set RDP Level 1 (readout protected)
```bash
python stm32cubeprog_wrapper.py rdp 1 --port SWD
```
### Write option bytes
```bash
python stm32cubeprog_wrapper.py ob RDP=0xAA nWRP=0x0 --port SWD
```
---
## Tips & Troubleshooting
- **CLI not found**
Set env var or pass `--cli`:
```bash
# Windows (PowerShell)
setx STM32CUBEPRG_CLI "C:\Program Files\STMicroelectronics\STM32CubeProgrammer\bin\STM32_Programmer_CLI.exe"
# Linux/macOS (bash)
export STM32CUBEPRG_CLI="/usr/local/STMicroelectronics/STM32CubeProgrammer/bin/STM32_Programmer_CLI"
```
- **Permissions (Linux/macOS)**
You might need `sudo` or proper udev rules for ST-LINK.
- **Address correctness**
Ensure the flash base address matches your MCU (commonly `0x08000000`).
- **DFU/UART modes**
Use `--port USBx` for DFU or `--port UARTx` with UART settings.
- **Tips : For Device Selection**
```bash
Prefer `sn=` over `index=` for consistent device selection.
Lower `freq` if you get connection issues.
You can attach `on_progress` and `on_log` callbacks to monitor each device individually.
```
---
## License
MIT License
STM32CubeProgrammer and `STM32_Programmer_CLI` are © STMicroelectronics.
---
Raw data
{
"_id": null,
"home_page": null,
"name": "stm32cubeprog",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "stm32, stm32cubeprogrammer, stlink, embedded, flashing, dfu",
"author": "raj_cks",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/5b/e6/ada42c974bf90e23544dc163ee18fb62eae889ae20d81970dce7708c1b95/stm32cubeprog-0.1.2.tar.gz",
"platform": null,
"description": "# STM32CubeProgrammer Python Wrapper\r\n\r\nA Python library **and** command-line tool for driving **STM32CubeProgrammer CLI** (`STM32_Programmer_CLI`) to flash, read, erase, reset, and configure STM32 MCUs\u2014using a clean Python API.\r\n\r\n---\r\n\r\n## Requirements\r\n\r\n- **STM32CubeProgrammer** installed (includes `STM32_Programmer_CLI`)\r\n- **Python 3.8+**\r\n- `STM32_Programmer_CLI` available via one of:\r\n - In your **PATH**\r\n - Environment variable: `STM32CUBEPRG_CLI=/full/path/to/STM32_Programmer_CLI[.exe]`\r\n - Passed explicitly as `--cli` (CLI) or `cli_path=\"...\"` (library)\r\n\r\n> The wrapper auto-detects the CLI on Windows/macOS/Linux, including Windows Registry lookup and user-local installs.\r\n\r\n---\r\n\r\n## Installation\r\n\r\n```bash\r\ngit clone https://github.com/rajcks007/stm32cubeprog.git\r\ncd stm32cubeprog\r\n# No extra deps needed (stdlib only)\r\n```\r\n\r\nIf you plan to reuse it elsewhere, you can `pip install -e .` after adding a minimal `pyproject.toml`, but that\u2019s optional.\r\n\r\n---\r\n\r\n## Working with Multiple Programmers\r\n\r\nIf you have more than one ST-LINK or other supported probe connected, you can select which one to use by **serial number** or **index**.\r\n\r\n## Getting serial numbers programmatically\r\n```python\r\nimport re\r\nprog = CubeProgCLI()\r\nout = prog.list_probes()\r\nsns = re.findall(r\"ST-LINK SN\\s*:\\s*([0-9A-F]+)\", out)\r\nprint(\"ST-LINK SN :\", sns)\r\n```\r\nExample output:\r\n- ST-LINK SN : 57FF6F067186535460351387\r\n- ST-LINK SN : 066EFF303451897067120842\r\n\r\n## Usage as a Library\r\n\r\n```python\r\nfrom stm32cubeprog_wrapper import CubeProgCLI\r\n\r\n# Create the programmer (auto-detects STM32_Programmer_CLI)\r\nprog = CubeProgCLI()\r\n\r\n# 1) Flash firmware (BIN/HEX/ELF) at 0x08000000, verify + reset\r\nprog.flash_firmware(\r\n \"firmware.bin\",\r\n address=0x08000000,\r\n verify=True,\r\n reset=True,\r\n port=\"SWD\",\r\n freq=4000, # kHz\r\n on_progress=lambda pct, _line: print(f\"{pct}%\"),\r\n on_log=lambda stream, line: print(f\"[{stream}] {line}\"),\r\n)\r\n\r\n# 2) Read memory (4 KB) to a file\r\nprog.read_memory(\r\n address=0x08000000,\r\n size=4096,\r\n out_file=\"dump.bin\",\r\n file_type=\"bin\", # or \"hex\"\r\n port=\"SWD\",\r\n freq=4000,\r\n)\r\n\r\n# 3) Erase (all/bank/sector)\r\nprog.erase(scope=\"all\", port=\"SWD\", freq=4000)\r\n# prog.erase(scope=\"bank\", bank=1, port=\"SWD\")\r\n# prog.erase(scope=\"sector\", sector=2, port=\"SWD\")\r\n\r\n# 4) Reset target (software by default; pass sw=False for hardware reset)\r\nprog.reset(port=\"SWD\", freq=4000) # software reset\r\nprog.reset(sw=False, port=\"SWD\") # hardware reset\r\n\r\n# 5) Info helpers\r\nprint(prog.get_version()) # STM32CubeProgrammer version banner\r\nprint(prog.list_probes()) # Connected ST-LINKs/ports\r\nprint(prog.read_device_info()) # Device info / option bytes\r\n\r\n# 6) Option bytes (key=value pairs)\r\nprog.write_option_bytes([\"RDP=0xAA\", \"nWRP=0x0\"],\r\n port=\"SWD\"\r\n )\r\n\r\n# 7) Set RDP level (0|1|2) (Readout Protection)\r\nprog.set_rdp(level=\"0\", port=\"SWD\") # 0 = no protection\r\nprog.set_rdp(level=\"1\", port=\"SWD\") # 1 = read protected\r\nprog.set_rdp(level=\"2\", port=\"SWD\") # 2 = full lock\r\n\r\n# 8) Choose by serial number\r\nprog.flash_firmware(\r\n \"firmware.bin\",\r\n address=0x08000000,\r\n port=\"SWD\", freq=4000,\r\n sn=\"57FF6F067186535460351387\",\r\n)\r\n\r\n# 9) choose by index\r\nprog.flash_firmware(\r\n \"firmware.bin\",\r\n address=0x08000000,\r\n port=\"SWD\", freq=4000,\r\n index=1,\r\n)\r\n\r\n# 10) Flashing multiple boards (sequentially)\r\nserials = [\"57FF6F067186535460351387\", \"066EFF303451897067120842\"]\r\nfor sn in serials:\r\n prog.flash_firmware(\"firmware.bin\", 0x08000000, port=\"SWD\", freq=4000, sn=sn)\r\n\r\n# 11) Flashing multiple boards in parallel\r\nimport threading\r\n\r\nserials = [\"57FF6F067186535460351387\", \"066EFF303451897067120842\"]\r\n\r\ndef flash_one(sn):\r\n CubeProgCLI().flash_firmware(\"firmware.bin\", 0x08000000, port=\"SWD\", freq=4000, sn=sn)\r\n\r\nthreads = [threading.Thread(target=flash_one, args=(sn,)) for sn in serials]\r\n[t.start() for t in threads]\r\n[t.join() for t in threads]\r\n\r\n```\r\n\r\n### Connection options you can pass (as keyword args)\r\n- `port=\"SWD\" | \"JTAG\" | \"USBx\" | \"UARTx\"`\r\n- `freq=4000` (kHz for SWD/JTAG)\r\n- `mode=\"hotplug\" | \"underreset\" | ...`\r\n- `reset_mode=\"swrst\" | \"hwrst\"`\r\n- `index=<probe_index>` or `sn=\"<stlink_serial>\"`\r\n- UART: `baud=115200`, `parity=\"even\"`, `stopbits=1`\r\n\r\n---\r\n\r\n## How to Use (Quick Start)\r\n\r\n1. **Install STM32CubeProgrammer** from ST.\r\n2. Connect your **ST-LINK** and target board.\r\n3. Put your firmware at a known path, e.g. `firmware.bin`.\r\n4. Pick the correct **flash start address** for your MCU (commonly `0x08000000`).\r\n5. Use the **library** (Python script) or the **CLI** (terminal) examples below.\r\n\r\n---\r\n\r\n## Usage as a CLI Tool\r\n\r\nRun the script directly:\r\n\r\n```bash\r\npython stm32cubeprog_wrapper.py <command> [options]\r\n```\r\n\r\nCommon global options (append to any command):\r\n- `--cli \"C:\\Path\\to\\STM32_Programmer_CLI.exe\"` (override autodetect)\r\n- `--port SWD` `--freq 4000` `--mode hotplug` `--index 0` `--sn XXXXXX`\r\n- `--timeout 300` `--no-live` (disable live console output)\r\n\r\n### Commands\r\n\r\n- `version` \u2014 Show STM32CubeProgrammer CLI version\r\n- `list` \u2014 List connected probes/ports\r\n- `flash <file> <address> [--type bin|hex|elf] [--no-verify] [--no-reset]`\r\n- `read <address> <size> <out> [--type bin|hex]`\r\n- `erase <all|bank|sector> [--bank N] [--sector N]`\r\n- `reset [--hard]`\r\n- `info` \u2014 Device info/option bytes (raw)\r\n- `ob <KV...>` \u2014 Write option bytes (e.g., `RDP=0xAA nWRP=0x0`)\r\n- `rdp <0|1|2>` \u2014 Set Readout Protection level\r\n\r\n---\r\n\r\n## Listing available probes (CLI)\r\n```bash\r\npython stm32cubeprog_wrapper.py list\r\n```\r\nExample output:\r\n- ST-LINK SN : 57FF6F067186535460351387\r\n- ST-LINK SN : 066EFF303451897067120842\r\n\r\n## Examples (CLI)\r\n\r\n**By serial number (recommended for stability):**\r\n```bash\r\npython stm32cubeprog_wrapper.py flash firmware.bin 0x08000000 --port SWD --freq 4000 --sn Serial_numbe (e.g 57FF6F067186535460351387)\r\n```\r\n\r\n**By index:**\r\n```bash\r\npython stm32cubeprog_wrapper.py flash firmware.bin 0x08000000 --port SWD --freq 4000 --index 1\r\n```\r\n\r\n### Flash a binary at 0x08000000 (verify + reset)\r\n```bash\r\npython stm32cubeprog_wrapper.py flash firmware.bin 0x08000000 --port SWD --freq 4000\r\n```\r\n\r\n### Flash a HEX, no auto-reset\r\n```bash\r\npython stm32cubeprog_wrapper.py flash app.hex 0x08000000 --type hex --port SWD --no-reset\r\n```\r\n\r\n### Read 4 KB from flash to `dump.bin`\r\n```bash\r\npython stm32cubeprog_wrapper.py read 0x08000000 4096 dump.bin --port SWD --freq 4000\r\n```\r\n\r\n### Erase full flash\r\n```bash\r\npython stm32cubeprog_wrapper.py erase all --port SWD\r\n```\r\n\r\n### Hardware reset\r\n```bash\r\npython stm32cubeprog_wrapper.py reset --hard --port SWD\r\n```\r\n\r\n### Show connected probes\r\n```bash\r\npython stm32cubeprog_wrapper.py list\r\n```\r\n\r\n### Set RDP Level 1 (readout protected)\r\n```bash\r\npython stm32cubeprog_wrapper.py rdp 1 --port SWD\r\n```\r\n\r\n### Write option bytes\r\n```bash\r\npython stm32cubeprog_wrapper.py ob RDP=0xAA nWRP=0x0 --port SWD\r\n```\r\n\r\n---\r\n\r\n## Tips & Troubleshooting\r\n\r\n- **CLI not found**\r\n Set env var or pass `--cli`:\r\n ```bash\r\n # Windows (PowerShell)\r\n setx STM32CUBEPRG_CLI \"C:\\Program Files\\STMicroelectronics\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI.exe\"\r\n\r\n # Linux/macOS (bash)\r\n export STM32CUBEPRG_CLI=\"/usr/local/STMicroelectronics/STM32CubeProgrammer/bin/STM32_Programmer_CLI\"\r\n ```\r\n- **Permissions (Linux/macOS)**\r\n You might need `sudo` or proper udev rules for ST-LINK.\r\n- **Address correctness**\r\n Ensure the flash base address matches your MCU (commonly `0x08000000`).\r\n- **DFU/UART modes**\r\n Use `--port USBx` for DFU or `--port UARTx` with UART settings.\r\n- **Tips : For Device Selection**\r\n ```bash\r\n Prefer `sn=` over `index=` for consistent device selection.\r\n Lower `freq` if you get connection issues.\r\n You can attach `on_progress` and `on_log` callbacks to monitor each device individually.\r\n ```\r\n---\r\n\r\n## License\r\n\r\nMIT License\r\nSTM32CubeProgrammer and `STM32_Programmer_CLI` are \u00a9 STMicroelectronics.\r\n\r\n---\r\n",
"bugtrack_url": null,
"license": null,
"summary": "Python wrapper + CLI for STM32CubeProgrammer",
"version": "0.1.2",
"project_urls": {
"Homepage": "https://github.com/rajcks007/stm32cubeprog",
"Issues": "https://github.com/rajcks007/stm32cubeprog/issues",
"Repository": "https://github.com/rajcks007/stm32cubeprog"
},
"split_keywords": [
"stm32",
" stm32cubeprogrammer",
" stlink",
" embedded",
" flashing",
" dfu"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "ed3262f2dadbd9857def7062ae46891796c914ca4d86d13fece2c8c3e1c7c118",
"md5": "e0f14e0d8f9ca2f41130af6dc4e93f0c",
"sha256": "8e46b8ab2e08071621fc93e58be0c7618bcb411f09b278e152ee58f4f574288e"
},
"downloads": -1,
"filename": "stm32cubeprog-0.1.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "e0f14e0d8f9ca2f41130af6dc4e93f0c",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 13136,
"upload_time": "2025-08-13T12:46:32",
"upload_time_iso_8601": "2025-08-13T12:46:32.221060Z",
"url": "https://files.pythonhosted.org/packages/ed/32/62f2dadbd9857def7062ae46891796c914ca4d86d13fece2c8c3e1c7c118/stm32cubeprog-0.1.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "5be6ada42c974bf90e23544dc163ee18fb62eae889ae20d81970dce7708c1b95",
"md5": "b36a1af139d693b8b10948743ddecfef",
"sha256": "6362c69bd4c0d2e71a81c4fd177fdb220200a322f9aa70bb84b21c653acf9026"
},
"downloads": -1,
"filename": "stm32cubeprog-0.1.2.tar.gz",
"has_sig": false,
"md5_digest": "b36a1af139d693b8b10948743ddecfef",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 15481,
"upload_time": "2025-08-13T12:46:33",
"upload_time_iso_8601": "2025-08-13T12:46:33.129421Z",
"url": "https://files.pythonhosted.org/packages/5b/e6/ada42c974bf90e23544dc163ee18fb62eae889ae20d81970dce7708c1b95/stm32cubeprog-0.1.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-13 12:46:33",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "rajcks007",
"github_project": "stm32cubeprog",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "stm32cubeprog"
}