View all posts

pyOCD 0.33.0 released

Jan 24, 2022
Chris Reed

Version 0.33.0 of pyOCD has just been released and is available from PyPI. It’s been several months since a feature release, and this one includes some nice additions. A large number of smaller changes and bug fixes have also been included in this release. The complete list is shown below.

To upgrade pyOCD, just run pip:

pip install --upgrade pyocd

The most exciting addition is an rtt subcommand that adds support for Segger RTT. This is just the start of more RTT and trace related features. The new subcommand streams RTT output from the target to the console, and vice versa for input from the console. The best part is that it works with all debug probes, not just the J-Link. (But note that it doesn’t yet take advantage of the J-Link’s built-in RTT support.)

The commander subcommand and user scripts have some additions, as well. Command files can be run using the new -x / --execute argument. Multiple command file arguments are allowed, and can be mixed with -c / --command arguments. Pass a filename of “-“ to execute commands from stdin.

It is now possible to create custom commands in the user script using the @command decorator. User-defined commands are accessible both the commander subcommand and gdbserver monitor commands (basically anywhere you can run commands). Here’s a simple example that prints the first four vectors from a Cortex-M NVIC vector table.

@command(help="Decode and print the first few NVIC vectors")
def vectable(base: int):
    vecs = target.read_memory_block32(base, 4)
    print(f"Initial SP:     {vecs[0]:#010x}")
    print(f"ResetHandler:   {vecs[1]:#010x}")
    print(f"NMI:            {vecs[2]:#010x}")
    print(f"HardFault:      {vecs[3]:#010x}")

It demonstrates how command function arguments are automatically parsed and converted. PyOCD sees the single base argument with an int type annotation, and thus will configure the command with one argument converted to an int. The user-defined commands documentation has all the details.

Aside from the above features, you will immediately notice that log output is colourised and the formatting simplified. The --color argument and the PYOCD_COLOR environment variable give you direct control if you wish to change the default.

Finally, it’s worth mentioning that the new CI system is up and running. Every commit and pull request will be tested on a set of boards on macOS, Linux, and Windows 10. Arm have graciously provided resources for the test servers and boards. Azure Pipelines manages the test runs. The best thing about using Azure Pipelines is that all test results are publicly accessible!

Thanks again to all the contributors who helped make this release possible! ❤️

v0.33.0 on GitHub
v0.33.0 on PyPI


  • Basic SEGGER RTT read/write support with an rtt subcommand. This subcommand streams stdio from/to the target. It works with all debug probe types, not only J-Link. (Thanks @mikisama, @ccattuto)
  • There is no longer a need to install libusb separately when installing pyocd. The libusb-package Python package was created so that an up to date libusb library can be automatically installed along with pyocd on all OSes.
  • Log output is now colorized by default when outputting to a tty. The --color command line argument controls this feature. Also simplified the log output formatting so it is easier to read.
  • Commander: Add -x/--execute argument to run commands from a file. Multiple command files can be run and mixed with -c commands.
  • Commander: Add -i/--interactive to stay in REPL after running commands from either a file or command line.
  • Commander: Introduce the @command decorator that can be used in user scripts to create user-defined commands, accessible from Commander and as gdbserver monitor commands. See the documentation for details.

Boards and targets

  • Add Maxim MAX32660 target and MAX32660EVSYS board. (Thanks @ozersa)
  • Correct RAM size of Maxim MAX32630 to 512 KiB.
  • Add several NXP board IDs: FRDM-K32L3A6, TWR-KM35Z75M, MIMXRT1160-EVK, FRDM-KW38, USB-KW38, KW38-ER-RD.
  • Add micro:bit v2 board IDs. (Thanks @mbrossard)
  • NXP LPC55xx family: re-unlock debug access after reset. (Thanks @LeBlue)

Changes and fixes

  • Cortex-M: Fix regression with writing CFBP and xPSR subregisters (CONTROL, FAULTMASK, BASEPRI, PRIMASK, and xPSR variants).
  • Gdbserver: While the target is running (continue command in gdb), retry reading target status within a timeout after the first fault on such a check. This is intended to primarily help with firmware putting the core to sleep. The debug.status_fault_retry_timeout session option controls the timeout; set it to 0 to disable this experimental feature.
  • Commander: Fix broken Python (“$”) and system (“!”) commands in certain cases.
  • Commander: The shell-like lexer for commands has been replaced with a custom lexer that is simpler and more predictable. It breaks words on all non-alphanumeric characters except dash (for instance, “mem-ap” is considered one word). Single and double quoted values with backslash-escapes are supported.
  • Commander: If a user script has been loaded, Python ‘$’ commands share the user script’s namespace.
  • Commands: Add flushprobe command that ensures all outstanding transfers on the probe have been completed.
  • Commands: Fix reg output so it is properly redirected when called as a gdbserver monitor command.
  • Commands: reg and wreg' improvements. -p option to force lookup as peripheral register. reg will print any number of registers. Add rr and wr` aliases.
  • User scripts: print() calls from user scripts get routed through any output direction, for example, such that the output will appear in the gdb console when a user-defined command is called as a gdbserver monitor command.
  • Flash: Change default value of keep_unwritten session option to false.
  • CMSIS-DAP: Better handling of protocol versions.
  • CMSIS-DAP: All USB backends have a USB packet trace logger.
  • CMSIS-DAP: Add cmsis_dap.prefer_v1 session option that forces pyocd to use the CMSIS-DAP v1 interface on a debug probe that provides both v1 and v2. (Naturally, the default is to choose v2, since it is faster.) This is intended primarily for testing.
  • CMSIS-DAP: Introduced timeouts for USB reads.
  • CMSIS-DAP: Limit number of outstanding command packets to 30 on macOS using hidapi for CMSIS-DAP v1. This fixes a failure that occurred when certain memory transfers due to an in-built limit on the queue size in the macOS version of hidapi.
  • CMSIS-DAP: Update list of known CMSIS-DAP probes; correspondingly update udev rules.
  • STLink: use JTAG_GET_BOARD_IDENTIFIERS command to read board ID faster than extracting it from the “mbed.htm” file on the MSD volume. Requires V2J36 or V3J6 firmware versions.
  • STLink: Setting the SWD frequency on an STLinkV3 was completely broken, and is now fixed.
  • STLink: Add stlink.v3_prescaler session option to control the internal HCLK prescaler on the probe, which affects the set of available SWD/JTAG and other I/O frequencies.
  • Probe server: Fix race causing server to terminate immediately is certain rare cases.
  • Probe server: Improve connect/disconnect log messages.
  • Session options: Probe-specific options in a config file takes precedence over global options.
  • Session options: A warning is logged if a multiple probe-specific option sections in a config file match the active debug probe’s UID.
  • Session: Change the working directory to the project directory on session creation.
  • Gdbserver: Cleanup and fix connection disconnect code. This changes behaviour if the gdb disconnect command is used so that the persist option is honoured (disconnect previously would never cause the gdbserver to stop). (Thanks @claymation)
  • Gdbserver: exit monitor command that will shut down all gdbservers and quit pyocd.
  • Gdbserver: Handle connection aborted and reset errors more cleanly.
  • Gdbserver: Better logging of RTOS discovery issues, and only one log message is output when attempting to load RTOS plugins, in addition to a message on successful load.
  • CoreSight DAP: Unlock probe on error. (Thanks @claymation)
  • CoreSight: Don’t read CoreSight registers for non-CoreSight components. (Thanks @j4cbo)
  • CoreSight: Set CSW.DBGSWEN for CSSoC-400 APB-AP to resolve an issue that caused DBGMCU (and other) peripherals to be inaccessible on certain STM32 devices, and likely similar issues on other devices.
  • Dependencies: Switch from naturalsort to natsort. (Thanks @dvzrv)

View Full Changelog