pyocd / pyocd/pyOCD

How to hit a breakpoint multiple times in a loop

Open
#1,708 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
1.5k
Forks
560
Avg merge
1h 41m
Merged PRs (30d)
3

Description

PyOCD version: 0.36.0
Hardware: STM32F407ZGT6 (ARM Cortex-M4) CMSIS-DAP debugger

I have set a breakpoint for a certain function using the Python API "target.set_breakpoin()". My firmware program calls this function multiple times.

My expectation is that each time the MCU reaches this function, the Core will halt, allowing me to perform read and write operations on some registers or RAM values. I would then use a Python API to resume the Core to running status. This process would repeat whenever the MCU executes this function again.

The question is: when I use the API "tarrget.resume()" to resume the Core, it does not take effect. I have to remove the breakpoint before calling resume(), only then can the Core continue running. However, after doing so, the Core will not halt when the MCU executes this function again in the future.

Is there a method to allow the Core to resume running without having to remove the breakpoint? Or are there any other approaches to achieve the desired effect?

Below is my test code:

#!/usr/bin/env python3
from pyocd.core.helpers import ConnectHelper
from pyocd.core.target import Target
from pyocd.debug.elf.symbols import ELFSymbolProvider
from pyocd.flash.file_programmer import FileProgrammer

options = {
    'target_override': 'stm32f407zgtx',
    'config_file': "pyocd.yaml"
}

session = ConnectHelper.session_with_chosen_probe(options=options)

with session:
    target = session.target
    target_context = target.get_target_context()

    # programmer = FileProgrammer(session)
    # program_options = {
    #     'erase': 'auto',
    #     'trust_crc': False,
    #     'smart_flash': True
    # }
    # programmer.program('Template.axf', **program_options)

    target.elf = 'Template.elf'
    provider = ELFSymbolProvider(target.elf)
    address = provider.get_symbol_value("halt_and_wait")
    ret = target.set_breakpoint(address)

    target.reset_and_halt()
    target.resume()
    while target.get_state() != Target.State.HALTED:
        pass

    pc = target.read_core_register("pc")
    print("  pc: 0x%X" % pc)
    assert pc == address & ~0x01  # mask off LSB

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the behavior with the supplied STM32F407 test script, starting at target.set_breakpoint(), target.resume(), and target.get_state() around reset_and_halt(). Compare what happens when the breakpoint is retained versus removed. Done means the core can resume with the breakpoint installed and halt again on later calls, or the supported limitation is documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools, embedded-iot
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.