FreeRTOS on Raspberry Pi Pico: Give Core One a Single Startup Owner
Combining a bare-metal multicore example with a FreeRTOS SMP example can create two owners for the second processor. Both pieces may compile, yet their startup assumptions are incompatible: one expects its application entry point to keep running, while the other takes control of that core for the scheduler.
Resolve that architectural choice before adding more inter-core messages. The source checks below concern the RP2040 port in FreeRTOS V11.3.1 and the Pico SDK 2.3.1 multicore interface. They are not a validated recipe for every Pico-family chip or SDK/kernel pairing.

Trace the scheduler's core-one startup
In the tagged RP2040 port, the multicore scheduler-start path asserts that startup occurs on core zero, claims its configured spinlocks, resets core one and launches the scheduler entry there. Its inter-core interrupt path also uses the FIFO.
That is more than starting another ordinary application task. A previously launched bare-metal function cannot be assumed to retain ownership of core one after this path executes. Similarly, restarting core one from application code while the SMP scheduler is active is not a harmless way to restart one worker task.
For a hypothetical acquisition product, choose whether the acquisition work is a scheduler-managed task or intentionally runs outside the scheduler on a separately managed core. Do not silently combine those two models. The appropriate port and synchronization arrangement must support the model you select.
Include the FIFO in the ownership decision
The SDK multicore header documents reset-and-launch prerequisites and warns that the inter-core FIFOs are used by SDK facilities and can be required exclusively by an RTOS. It suggests using an appropriate queue for ordinary inter-core data when those reservations apply.
A FIFO is therefore not automatically spare application transport just because a demonstration used it to send a number between cores. An application consumer can remove a word intended for another protocol; an application writer can inject traffic that the other owner does not interpret as payload.
Prefer a communication mechanism whose ownership is explicit in the chosen integration. If using a queue, define which execution contexts may produce and consume, how full conditions are handled and who owns pointer payloads. The mechanism must fit the kernel and SDK arrangement rather than merely replace one function name with another.
Find every reset, launch and FIFO access
Review the complete linked application, including helper libraries and copied examples. Search for core reset and launch calls, FIFO handlers, FIFO reads and writes, and any code that claims the scheduler's configured spinlocks. Record the intended owner of each resource.
Then examine initialization order. A bare-metal core-one entry that briefly runs before scheduler startup may produce reassuring log output, but that does not demonstrate that it remains the active owner afterward. Make observations at defined stages instead of treating any core-one print as proof of the final architecture.
Do not use a live core reset as a diagnostic shortcut. In a kernel-managed multicore system it can interrupt shared state updates and obscure the original failure. Reproduce from reset in a development setup with one clear startup sequence.
Validate one model at a time
Begin with the official minimal example closest to the intended core model, then add the acquisition or processing work as an application component. Test communication pressure and worker failure without changing the core-management policy at the same time.
If the product genuinely needs a non-kernel core, verify that arrangement against the selected port's documented configuration and supported interoperation. Do not infer support from the fact that the chip has two processors.
The goal is a simple ownership statement another engineer can check: who starts core one, who schedules work there, and who owns the inter-core signaling resources. Once those answers agree, debugging data transfer becomes a bounded application problem instead of a conflict between two startup systems.