Skip to content

armv8m33: resolve problems with pyocd and hosts#446

Open
maska989 wants to merge 2 commits intomasterfrom
maska989/mcxn94x_tweaks
Open

armv8m33: resolve problems with pyocd and hosts#446
maska989 wants to merge 2 commits intomasterfrom
maska989/mcxn94x_tweaks

Conversation

@maska989
Copy link
Contributor

@maska989 maska989 commented Jan 22, 2026

Description

To fully support multicore connection, we need to use additional options with pyocd which allows to multicore debugging (The primary effect is to modify the default software reset type for secondary core to use VECTRESET, which will fall back to emulated reset for secondary cores that are not v7-M architecture) and granting access to reboot differently each core.

To make possible execution campaign without any hick ups and make it consistent, we need to perform hard reboot before flash step also to collect more logs we need to use external UART it gives us possibility to read logs between hard restarts and prevent from changing connected ACM like it have place with build in debug chip.

Additional pyocd options:

"-Oconnect_mode=attach"
"-Oenable_multicore_debug=True"

It is also good to mention to not use hard link to debug type (Cause troubles) via "-Oreset_type=" but in some scenarios can help with connections problems

Incorrect reboot and connect handling for core1:
obraz

Correct reboot and connect handling for core1:
obraz

Motivation and Context

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Chore (refactoring, style fixes, git/CI config, submodule management, no code logic changes)

How Has This Been Tested?

  • Already covered by automatic testing.
  • New test added: (add PR link here).
  • Tested by hand on: armv8m33-mcxn94x-frdm.

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing linter checks and tests passed.
  • My changes generate no new compilation warnings for any of the targets.

Special treatment

  • This PR needs additional PRs to work (list the PRs, preferably in merge-order).
  • I will merge this PR by myself when appropriate.

@gemini-code-assist
Copy link

Summary of Changes

Hello @maska989, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces necessary adjustments to support multicore debugging and improve reboot handling for ARMv8M33 targets, particularly when utilizing pyocd. The changes involve refining serial port detection and configuring pyocd with specific options to enable robust multicore functionality, addressing issues like incorrect core reboot behavior.

Highlights

  • Serial Port Detection: Updated the serial port identification logic from 'MCU-LINK' to 'USB-serial' to ensure correct detection of the USB-Serial controller.
  • Multicore Debugging Configuration: Enhanced the PyocdProcess configuration by adding connect_mode=attach and enable_multicore_debug=True options, which are crucial for fully supporting multicore connections and debugging.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request correctly identifies the need for additional pyocd arguments for multicore support on the armv8m33 target and changes the serial port hint. The changes in flash_dut are a good step. However, to fully resolve the issues mentioned in the description, especially the reboot problem, the new multicore arguments (-Oconnect_mode=attach, -Oenable_multicore_debug=True) should also be applied to other PyocdProcess calls in the same file. Specifically, they seem to be missing in ARMv8M33Rebooter._reboot_by_debugger and MCXN947PloAppLoader.__call__. I've also added comments about using constants for hardcoded strings to improve maintainability.

@github-actions
Copy link

github-actions bot commented Jan 22, 2026

Unit Test Results

9 525 tests  ±0   8 933 ✅ ±0   52m 57s ⏱️ +16s
  583 suites ±0     592 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit 887e458. ± Comparison against base commit 4b75909.

♻️ This comment has been updated with latest results.

@maska989 maska989 marked this pull request as ready for review January 23, 2026 12:31
Copy link
Member

@mateusz-bloch mateusz-bloch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, only comments about cosmetics.

PyocdProcess(
target="mcxn947", extra_args=["--format=bin", "--erase=chip"], host_log=host_log, cwd=self.boot_dir()
target="mcxn947",
extra_args=["--format=bin", "--erase=chip", "-Oconnect_mode=attach", "-Oenable_multicore_debug=True"],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be worth adding a comment explaining why additional arguments are needed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think, it's not so obvious that we need "-Oconnect_mode=attach", "-Oenable_multicore_debug=True"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Described

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#  connect to a running target without halting cores.

It's not showing why it's needed, but what is happening. According to our golden rules, described on YT page: code shouldn't need comments regarding WHAT you're doing, only WHY You're doing something

# The primary effect is to modify the default software reset type
# for secondary cores to use VECTRESET, which will fall back to emulated
# reset for secondary cores that are not v7-M architecture

Too long explanation

I think that comment like # additional options needed to allow flashing without hard reboot and support cpu1 configuration would be completely fine - placed just above the extra_args line

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Longer explanation you should leave in the commit description

Copy link
Member

@mateusz-bloch mateusz-bloch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No jira id in commit

Image

Copy link
Member

@mateusz-bloch mateusz-bloch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.

@nalajcie
Copy link
Member

If I understand correctly - this is not a simple "Bug fix", You've changed the hardware configuration of the board (added extra usb-serial adapter)? This should be clearly stated in the code (that we're using external adapter because the MCU VCOM fails when blah blah blah).

Not sure this is the correct approach - this change makes it harder to use the test runner outside of CI. I would expect the MCU link to be enough to collect the logs correctly, if there is a problem during reboot - probably the reboot procedure might be improved instead of adding additional HW.

@maska989 maska989 force-pushed the maska989/mcxn94x_tweaks branch from c539bbc to d569c59 Compare January 27, 2026 11:58
@damianloew
Copy link
Contributor

If I understand correctly - this is not a simple "Bug fix", You've changed the hardware configuration of the board (added extra usb-serial adapter)? This should be clearly stated in the code (that we're using external adapter because the MCU VCOM fails when blah blah blah).

Not sure this is the correct approach - this change makes it harder to use the test runner outside of CI. I would expect the MCU link to be enough to collect the logs correctly, if there is a problem during reboot - probably the reboot procedure might be improved instead of adding additional HW.

Unfortunately we have to choose:

  • not using an external converter - Then during reboots with power off we won't see what is happening on the system
  • using the converter - The problem with logs is solved, but of course running tests by having only the board on a desk is not possible then

Last time we had such problem, we chose together the option with external converter (imx6ull-evk target), but another opportunity has appeared - as discussed with @maska989 new options for pyocd made flashing without power off possible - that's why I would strongly recommend the approach with abandoning hard reboots on this target to unify the environment and make running on host pc possible without any changes.

Copy link
Contributor

@damianloew damianloew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finally the change with find_port will be abandoned, but had you wanted to add both, you would have needed 2 separate commits - switch to external usb-uart converer and trunner: extend the pyocd options in the flashing command on mcx target. Of course in such changes commit description with longer WHY is strongly recommended - even required

EDIT: Finally you will have to add a second commit anyway, because dismissing hard reboot is also a separate change

Small comment about commit title: trunner: prefix we are always using when changing trunner code, armv8m33 - I'd suggest using the tatget name, so mcx in this case - in the future we could have more armv8m33 targets and commit history could be misleading then

@maska989 maska989 force-pushed the maska989/mcxn94x_tweaks branch from d569c59 to eb4970c Compare February 6, 2026 10:23
@maska989 maska989 changed the title armv8m33: resolve problems with pyocd and hard reboot armv8m33: resolve problems with pyocd and hosts Feb 6, 2026
@maska989 maska989 force-pushed the maska989/mcxn94x_tweaks branch 2 times, most recently from 1e52ff2 to c55874b Compare February 6, 2026 11:58
@maska989
Copy link
Contributor Author

maska989 commented Feb 6, 2026

If I understand correctly - this is not a simple "Bug fix", You've changed the hardware configuration of the board (added extra usb-serial adapter)? This should be clearly stated in the code (that we're using external adapter because the MCU VCOM fails when blah blah blah).
Not sure this is the correct approach - this change makes it harder to use the test runner outside of CI. I would expect the MCU link to be enough to collect the logs correctly, if there is a problem during reboot - probably the reboot procedure might be improved instead of adding additional HW.

Unfortunately we have to choose:

* not using an external converter - Then during reboots with power off we won't see what is happening on the system

* using the converter - The problem with logs is solved, but of course running tests by having only the board on a desk is not possible then

Last time we had such problem, we chose together the option with external converter (imx6ull-evk target), but another opportunity has appeared - as discussed with @maska989 new options for pyocd made flashing without power off possible - that's why I would strongly recommend the approach with abandoning hard reboots on this target to unify the environment and make running on host pc possible without any changes.

Sadly, after further investigation there is still some kind of error and rebooting it with power off is the only possible way to make target runs consistent in time. Part of the problem discussed here: https://community.arm.com/support-forums/f/keil-forum/57462/issue-with-pyocd-flashing-with-cmsis-pack-nxp-mcxn947_dfp-25-09-00. Downgrading version is not easy process but still manageable, but still doesn't bring solution because other versions still have problems with consistent connections

@maska989 maska989 force-pushed the maska989/mcxn94x_tweaks branch from c55874b to da676f1 Compare February 9, 2026 13:30
@maska989 maska989 force-pushed the maska989/mcxn94x_tweaks branch from da676f1 to e7a3a2e Compare February 24, 2026 12:58
mateusz-bloch
mateusz-bloch previously approved these changes Feb 25, 2026
Copy link
Member

@mateusz-bloch mateusz-bloch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, only correct commit message :P

Image

@maska989 maska989 force-pushed the maska989/mcxn94x_tweaks branch from e7a3a2e to 32f5b6b Compare February 25, 2026 12:41
@maska989 maska989 force-pushed the maska989/mcxn94x_tweaks branch from 32f5b6b to 38694f8 Compare February 25, 2026 12:50
cwd=self.app_host_dir,
).load(load_file=app.file, load_offset=self.ram_addr + offset)

# There is hardware difference between test unit and out of the box unit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What difference? The behavior should be the same both for rpi and host pc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that on rpi, loading the test binary causes reboot and we have to enter plo once again, on host-pc not. I understand that hw difference is an external uart usb converter with a diode (?), but it shouldn't cause board reset.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a difference between a device straight out of the box and one that has been modified for continuous and uninterrupted operation in a test environment.

The first modification, as you mentioned, is the addition of an external UART to prevent loss of logs and to maintain connectivity during hard reboots.

The second important modification that was implemented involves disabling the possibility of powering the FRDM board from the MCU-LINK communication port. This was achieved by removing the diode on the power supply line. However, this change may cause issues when connecting via pyOCD. Depending on the version, older releases did not include an authentication procedure, which meant that application loading did not trigger reboots.

Comment on lines +108 to +109
# For consistent testing without any error we're using full power down sequence
if self.host.has_gpio():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly:

Suggested change
# For consistent testing without any error we're using full power down sequence
if self.host.has_gpio():
# Without a hard reboot before flashing, intermittent failures occurred after several consecutive test campaigns
if self.host.has_gpio():

AFAIK it is not seen on host-pc, because usually we power up the board a moment before running sth on it.

Btw it looks like the issue - the board should work stable during many campaigns without a hard reboot, have you investigated this? Maybe sth is wrong in our system and that's the reason - issue should be raised in phoenix-rtos-project then.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not strictly an issue with our environment, but rather with unpredictable interactions between pyOCD and the FT2232H located on the FRDM board, for two key reasons:

pyOCD does not natively provide a library for supporting the MCXN947; this support is developed by the community, and the implemented solutions are not always correct or fully reliable.

Modifications related to the power supply path between the FT2232H and the CPU also affect the behavior of pyOCD.

Failures occurred in this case scenario are connected with "cannot go to bootloader mode".

PyocdProcess(target="mcxn947", extra_args=["--format=bin", "--no-reset"], cwd=self.app_host_dir).load(
load_file=app.file, load_offset=self.ram_addr + offset
)
# In this approach, pyocd remember last used configuration with connection after flashing sequence
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

configuration with connection after flashing sequence - what do you mean? It's not clear. Adding -Oenable_multicore_debug=True caused that?
remembers*

Please update the comment to be more descriptive (not longer)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My apologies — this is a leftover from a previous code iteration, and the old comment remained. It has already been removed.

target="mcxn947", extra_args=["--format=bin", "--erase=chip"], host_log=host_log, cwd=self.boot_dir()
cwd=self.boot_dir(),
host_log=host_log,
# additional options needed to allow flashing without hard reboot and support cpu1 configuration
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without hard reboot? How?

Copy link
Contributor Author

@maska989 maska989 Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I explained it incorrectly — I meant tests performed without the test environment (standalone).
Comment removed.

maska989 added 2 commits March 2, 2026 12:52
Adding multicore setup and edit connection way with pyocd

JIRA: CI-592
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants