pytest-embedded-jtag
pytest-embedded-jtag is a plugin for pytest-embedded that enables interaction with JTAG-connected devices, providing services for OpenOCD and GDB utilities. It allows for advanced embedded testing scenarios by integrating debugging and flashing tools directly into pytest tests. The current version is 2.7.0, and it follows the release cadence of the broader pytest-embedded project.
Common errors
-
pytest.FixtureLookupError: Unknown fixture 'openocd' or 'gdb'
cause The JTAG service was not enabled when running pytest, so the `openocd` or `gdb` fixtures were not registered.fixRun pytest with the `--embedded-services jtag` command-line option, for example: `pytest --embedded-services jtag test_jtag.py` -
Target not responding / No JTAG device found
cause OpenOCD or GDB failed to connect to the target device. This is typically an external environmental issue, such as the JTAG probe not being connected, incorrect target configuration, or power issues.fixVerify that your JTAG probe is correctly connected to the target and the host machine. Ensure the target device is powered on and correctly configured (e.g., boot mode). Check your OpenOCD configuration files (`.cfg`) for correct target and interface settings. -
Writing to DUT doesn't work when application console is configured with ESP_CONSOLE_USB_SERIAL_JTAG
cause This is a known issue, specifically observed with ESP32-S3 targets, where writing to the DUT via serial might fail if the application console uses the USB Serial/JTAG interface instead of UART.fixConsider reconfiguring the embedded application to use UART for console output if possible. Alternatively, review the `pytest-embedded` and `pytest-embedded-jtag` documentation or GitHub issues for workarounds specific to `ESP_CONSOLE_USB_SERIAL_JTAG`.
Warnings
- breaking pytest-embedded-jtag, as part of the pytest-embedded ecosystem, dropped support for Python 3.7, 3.8, and 3.9 in version 2.0.0. It now requires Python 3.10 or higher.
- gotcha The pytest-embedded project, including pytest-embedded-jtag, recommends installing with `~=2.0` (e.g., `pip install -U pytest-embedded-jtag~=2.0`). This is because bug fix versions might sometimes introduce non-breaking new features, and using a compatible release specifier helps avoid unintended breaking changes while still getting new features.
- gotcha Common JTAG connectivity issues (e.g., clock speed mismatch, voltage level mismatch, faulty physical connections, or PCB layout problems) can manifest as 'target not responding' or unexpected behavior during tests. These are often hardware-related and not issues with the `pytest-embedded-jtag` library itself.
Install
-
pip install pytest-embedded-jtag
Imports
- Dut
from pytest_embedded import Dut
- Gdb
from pytest_embedded_jtag.gdb import Gdb
- OpenOcd
from pytest_embedded_jtag.openocd import OpenOcd
Quickstart
import pytest
from pytest_embedded import Dut
def test_jtag_connection(dut: Dut, openocd, gdb):
# To enable these fixtures, run pytest with --embedded-services jtag
# The 'openocd' and 'gdb' fixtures are automatically provided when 'jtag' service is active.
# 'openocd' is an instance of pytest_embedded_jtag.openocd.OpenOcd
# 'gdb' is an instance of pytest_embedded_jtag.gdb.Gdb
print(f"OpenOCD instance: {openocd}")
print(f"GDB instance: {gdb}")
# Example: Send a command to OpenOCD (requires OpenOCD to be running and connected)
# In a real test, you'd interact with OpenOCD or GDB to flash, debug, or verify state.
try:
openocd.write("version") # Assuming 'version' is a valid OpenOCD command
version_output = dut.expect("Open On-Chip Debugger").group(0)
print(f"OpenOCD version output: {version_output}")
except Exception as e:
print(f"Could not interact with OpenOCD: {e}")
# Example: Basic DUT interaction (from pytest-embedded)
dut.expect_exact("Hello from target") # Replace with expected output from your embedded target
print("Target responded 'Hello from target'")