pyOCD
pyOCD is an open-source Python library and command-line tool for programming and debugging Arm Cortex-M microcontrollers using various debug probes such as CMSIS-DAP, J-Link, and ST-Link. It provides a flexible Python API for low-level target control, suitable for automated testing and CI/CD workflows, alongside a powerful command-line interface for common operations like GDB server, flashing, and erasing. Currently at version 0.44.0, pyOCD maintains an active development cycle with several minor releases annually.
Warnings
- breaking Python 3.7 is no longer supported starting with pyOCD v0.37.0. Projects must use Python 3.8 or later.
- breaking The `run` subcommand introduced significant changes and new configurations for RTT, SystemView, and Semihosting in versions 0.42.0 and 0.43.0. Older scripts relying on specific `run` subcommand behaviors or arguments might need updates.
- breaking Flash programming operations were split into separate erase and program operations starting from v0.44.0. Direct flash programming might now require explicit erase calls depending on the workflow.
- breaking The RTT channel mode `telnet` was renamed to `server` in pyOCD v0.44.0.
- gotcha The Python API is considered unstable prior to version 1.0, with planned breaking changes to align with PEP8 naming conventions. Additionally, the command-line tools are planned to be merged into a single utility in future 1.0 releases.
- gotcha Installation of the `libusb` binary shared library is a manual, OS-dependent step and is not handled automatically by pip. Without it, pyOCD cannot communicate with USB debug probes.
- gotcha On Linux, without proper udev rules, pyOCD might require root privileges (sudo) to detect and access debug probes. This is a common permission issue.
Install
-
pip install pyocd -
pip install pyocd[pemicro]
Imports
- ConnectHelper
from pyocd.core.helpers import ConnectHelper
- FileProgrammer
from pyocd.flash.file_programmer import FileProgrammer
Quickstart
import time
import logging
import os
from pyocd.core.helpers import ConnectHelper
from pyocd.flash.file_programmer import FileProgrammer
logging.basicConfig(level=logging.INFO)
FIRMWARE_PATH = "your_firmware.hex" # Replace with the actual path to your firmware
# Create a dummy firmware file for demonstration if it doesn't exist
if not os.path.exists(FIRMWARE_PATH):
with open(FIRMWARE_PATH, "w") as f:
f.write(":100000000000000000000000000000000000000000\n") # Minimal valid HEX file
try:
# Connect to the target with the first found probe.
# For a specific probe, use unique_id="E6616407E3646B29"
# For a specific target, use options={"target_override": "nrf52840"}
with ConnectHelper.session_with_chosen_probe() as session:
target = session.target
board_id = session.board.unique_id if session.board else "Unknown"
logging.info(f"Connected to probe: {board_id}, target: {target.name}")
# Halt the target
target.halt()
logging.info("Target halted.")
# Program firmware
logging.info(f"Programming {FIRMWARE_PATH}...")
FileProgrammer(session).program(FIRMWARE_PATH)
logging.info("Programming complete.")
# Reset and run
target.reset_and_run()
logging.info("Target reset and running.")
# Allow the target to run for a short period (demonstration)
time.sleep(1)
except Exception as e:
logging.error(f"An error occurred: {e}")
logging.info("Please ensure a debug probe is connected and compatible firmware is specified.")