1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// SPDX-License-Identifier: MIT OR Apache-2.0
//! Second-core (APP CPU) bring-up harness (#35 C4).
//!
//! Every binary hand-rolls the same dance to put work on the APP core: build a
//! [`CpuControl`], defensively park the APP core (a JTAG-reset workaround),
//! create an esp-rtos [`InterruptExecutor`], start the core on a `waiti` idle
//! loop, and start the executor at a priority. [`run_app_core`] encapsulates all
//! of it; the binary supplies only the stack, the priority, and a closure that
//! spawns its APP-core tasks from the [`SendSpawner`].
extern crate alloc;
use SendSpawner;
use Priority;
use SoftwareInterrupt;
use CPU_CTRL;
use ;
use InterruptExecutor;
/// Park + start the APP core running an [`InterruptExecutor`] at `prio`; `init`
/// runs on the APP core with the executor's [`SendSpawner`] to spawn its tasks.
///
/// Encapsulates the defensive `park_core(AppCpu)` reset — probe-rs's JTAG reset
/// doesn't always return the APP-core control registers to power-on state, so a
/// JTAG-flashed boot can find the core reported "running" and `start_app_core`
/// panics with `CoreAlreadyRunning`; parking clears that, and `start_app_core`
/// unparks before the core runs. (Documented perf tradeoff on CoreS3: the
/// disturbance measurably slows LCD render — accepted for boot reliability.)
///
/// Call from the PRO core (main). The returned [`AppCoreGuard`] must be kept
/// alive for the program's lifetime — dropping it stops the APP core.
///
/// `sw_int` is one of `SystemResources::sw_int.software_interruptN`; `stack` is
/// a `&'static mut Stack<N>` the caller allocates (e.g. `mk_static!`/`StaticCell`).