Update: Isolated the issue to project/linker configuration, not application code
Since posting, I ran a decisive test that narrows this down significantly.
Test: Does NXP's own unmodified multicore example work on this exact hardware?
Imported multicore_examples/hello_world (primary + secondary) for LPCXpresso55S69 fresh, completely unmodified, and debugged it as-is.
Result: it works. The onboard RGB LED blinks at a clean, regular 500ms on/500ms off rate — confirmed by comparing directly against my own project flashed onto the same board (LED off with my project, LED blinking with the unmodified example, LED off again when I re-flash my own project). This is conclusive: dual-core execution is possible on this exact board, probe, and IDE installation.
Test: Does the example's own application code work inside my project's configuration?
To isolate whether the problem was in my application code or my project's build/link configuration, I copied the working example's secondary-core main.c, app.h, and hardware_init.c verbatim (byte-for-byte, unmodified) into my own slave project, replacing my own application code entirely.
Result: the LED does not blink. Identical, unmodified NXP code that works in the original example project fails to start Core 1 when built inside my own project's configuration.
What this proves
The issue is not in application-level code (confirmed twice now - independently in a hand-written register implementation and in an MCMGR-based implementation, and now a third time with literally the example's own source files). It is something specific to how my project's Multicore linker settings / memory region configuration differs from the working example's, despite my best efforts to match it point-for-point:
- CPUCFG, CPBOOT, CPUCTRL all read back exactly as intended after MCMGR_StartCore()
- The embedded image's vector table is independently verified valid (correct stack pointer, correct reset handler address matching the real ResetISR symbol)
- Master Memory Region is set to a RAM region (not PROGRAM_FLASH), matching the working example's approach of embedding Core 1's image in RAM rather than flash
- Core 1's own private memory does not overlap Core 0's
One structural difference I've found but not yet resolved: the working example's secondary core project has no PROGRAM_FLASH memory region override at all in its .cproject (only two custom RAM-derived regions). My from-scratch wizard-created slave project has three regions including a relocated PROGRAM_FLASH. Attempting to remove that region entirely (to match the working example precisely) crashes MCUXpresso's MCU Settings page (NullPointerException: this.mcuPage is null), suggesting the IDE's tooling doesn't gracefully support a project with no flash region defined - which may itself be relevant to why matching the working example's exact configuration by hand has been difficult.
Question
Is there a specific, documented multicore project configuration (beyond what the wizard's "M33SLAVE" role + Multicore linker settings produce) required to get a from-scratch project into the same working state as the SDK's own hello_world example? Or is there a known limitation/bug in MCUXpresso IDE v25.6.136's project wizard for multicore LPC55S69 projects that the example's project files work around in a way the wizard doesn't replicate?
Happy to share both projects' complete .cproject files for direct comparison if useful.