Skip to content

Commit 37e3eb9

Browse files
committed
samples: boards: nxp: add mimxrt700_evk dual_core_pm sample
Add a dual-core power management sample for the MIMXRT700-EVK. Signed-off-by: Zhaoxiang Jin <Zhaoxiang.Jin_1@nxp.com>
1 parent 37dad08 commit 37e3eb9

15 files changed

Lines changed: 876 additions & 0 deletions
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright 2026 NXP
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
cmake_minimum_required(VERSION 3.20.0)
5+
6+
set(REMOTE_ZEPHYR_DIR ${CMAKE_CURRENT_BINARY_DIR}/../remote/zephyr)
7+
8+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
9+
project(rt700_dual_core_pm)
10+
11+
if(NOT CONFIG_BOARD_MIMXRT700_EVK_MIMXRT798S_CM33_CPU0)
12+
message(FATAL_ERROR "${BOARD}/${BOARD_QUALIFIERS} is not supported by this sample")
13+
endif()
14+
15+
if(CONFIG_INCLUDE_REMOTE_DIR)
16+
target_include_directories(zephyr_interface
17+
INTERFACE ${REMOTE_ZEPHYR_DIR}/include/public)
18+
endif()
19+
20+
target_sources(app PRIVATE src/main.c)
21+
target_include_directories(app PRIVATE
22+
${ZEPHYR_BASE}/../modules/hal/nxp/mcux/mcux-sdk-ng/drivers/mu1)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright 2026 NXP
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
source "Kconfig.zephyr"
5+
6+
config INCLUDE_REMOTE_DIR
7+
bool "Include remote core header directory"
8+
help
9+
Include remote build header files. The RT700 CPU0 image needs the
10+
CPU1 image information header when CONFIG_SECOND_CORE_MCUX is enabled.
11+
12+
config RT700_DUAL_CORE_PM_SLEEP_SECONDS
13+
int "Power-mode measurement window in seconds"
14+
default 10
15+
range 1 3600
16+
help
17+
Number of seconds each active, sleep, or deep-sleep test case runs.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright 2026 NXP
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
source "share/sysbuild/Kconfig"
5+
6+
config RT700_DUAL_CORE_PM_REMOTE_BOARD
7+
string "RT700 dual-core PM remote board"
8+
default "mimxrt700_evk/mimxrt798s/cm33_cpu1" if $(BOARD) = "mimxrt700_evk"
9+
help
10+
Board target used for the CM33 CPU1 remote image.
11+
12+
config RT700_DUAL_CORE_PM_SLEEP_SECONDS
13+
int "Power-mode measurement window in seconds"
14+
default 10
15+
range 1 3600
16+
help
17+
Number of seconds both cores spend in each active, sleep, or
18+
deep-sleep measurement window.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
.. zephyr:code-sample:: nxp_rt700_dual_core_pm
2+
:name: RT700 EVK dual-core power management
3+
4+
Exercise active, sleep, and deep-sleep combinations on both RT700 EVK
5+
Cortex-M33 cores.
6+
7+
Overview
8+
********
9+
10+
This sample builds two Zephyr images for the MIMXRT700-EVK:
11+
12+
* the main image runs on CM33 CPU0 and boots CM33 CPU1 through the existing
13+
``CONFIG_SECOND_CORE_MCUX`` board initialization path;
14+
* the remote image runs on CM33 CPU1.
15+
16+
Both images enable Zephyr system power management and register a PM notifier.
17+
CPU0 acts as the test orchestrator and sends simple MU commands to the CPU1
18+
remote image. CPU1 acknowledges that it is ready, CPU0 sends a GO command, and
19+
then both cores run the selected measurement window.
20+
21+
The test matrix covers:
22+
23+
* both cores active;
24+
* CPU0 sleep while CPU1 stays active;
25+
* CPU1 sleep while CPU0 stays active;
26+
* both cores sleep;
27+
* CPU0 deep-sleep while CPU1 stays active;
28+
* CPU1 deep-sleep while CPU0 stays active;
29+
* both cores deep-sleep.
30+
31+
The sleep cases force ``PM_STATE_RUNTIME_IDLE`` for the next idle entry. The
32+
deep-sleep cases force ``PM_STATE_SUSPEND_TO_IDLE`` for the next idle entry.
33+
34+
The serial output gives a coarse software confirmation that both cores booted
35+
and that PM entry/exit callbacks are firing. Use the stable sleep windows for
36+
board current measurement.
37+
38+
Building and Running
39+
********************
40+
41+
Build the CPU0 and CPU1 images together with sysbuild:
42+
43+
.. zephyr-app-commands::
44+
:zephyr-app: samples/boards/nxp/mimxrt700_evk/dual_core_pm
45+
:board: mimxrt700_evk/mimxrt798s/cm33_cpu0
46+
:west-args: --sysbuild
47+
:goals: build flash
48+
:compact:
49+
50+
After reset, the console should show CPU0 stepping through the matrix and CPU1
51+
responding to each command, for example:
52+
53+
.. code-block:: console
54+
55+
RT700 dual-core PM sample: CPU0 started on mimxrt700_evk/mimxrt798s/cm33_cpu0
56+
RT700 dual-core PM sample: CPU1 started on mimxrt700_evk/mimxrt798s/cm33_cpu1
57+
CPU0: case 1: active baseline
58+
CPU1: prepared for active window
59+
CPU0: entering active window
60+
CPU1: entering active window
61+
CPU1: active window complete
62+
CPU0: local active window complete
63+
CPU0: case 4: CPU0 and CPU1 sleep
64+
CPU1: prepared for sleep window
65+
CPU0: entering sleep window
66+
67+
Measurement Notes
68+
*****************
69+
70+
Measure RT700 SoC current through JP21 on the EVK. Remove the default JP21
71+
jumper and insert the current meter or power analyzer in series. JP21 measures
72+
the RT700 SoC rail, so it does not isolate CPU0 and CPU1 independently. To see
73+
the contribution of each core, compare the active baseline, single-core sleep,
74+
single-core deep-sleep, and coordinated sleep/deep-sleep windows.
75+
76+
The default low-power window is 10 seconds. It can be changed at build time:
77+
78+
.. code-block:: console
79+
80+
west build -p always --sysbuild \
81+
-b mimxrt700_evk/mimxrt798s/cm33_cpu0 \
82+
samples/boards/nxp/mimxrt700_evk/dual_core_pm \
83+
-- -DSB_CONFIG_RT700_DUAL_CORE_PM_SLEEP_SECONDS=30
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Copyright 2026 NXP
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
CONFIG_SECOND_CORE_MCUX=y
5+
CONFIG_INCLUDE_REMOTE_DIR=y
6+
CONFIG_COUNTER=y
7+
CONFIG_MCUX_OS_TIMER_PM_POWERED_OFF=y
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright 2026 NXP
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/*
8+
* The dual-core PM sample does not use I2C or the on-board PCA9422 PMIC.
9+
*
10+
* On CPU0 the LPI2C15 functional clock is sourced from the SENSE domain base
11+
* clock, which is configured by CPU1 (not CPU0). When the PMIC MFD driver is
12+
* pulled in it initializes LPI2C15 while its clock rate is still 0, which makes
13+
* the MCUX LPI2C driver divide by zero during baud-rate setup. Disabling the
14+
* unused bus (and the PMIC node on it) keeps the sample focused on dual-core
15+
* power-management coordination over the MU.
16+
*/
17+
18+
&lpi2c15 {
19+
status = "disabled";
20+
};
21+
22+
&pca9422 {
23+
status = "disabled";
24+
};
25+
26+
/*
27+
* In the dual-core PM matrix CPU0 enters deep sleep while CPU1 keeps running
28+
* (cases 5-7). The default SLEEPCON0 deep-sleep mask gates the SENSE-domain and
29+
* common main clocks and powers down every oscillator (XTAL, FRO0-2, LPOSC),
30+
* and the default PDSLEEPCFG2/3 masks power down the SRAM partitions that hold
31+
* CPU1's code and data (0x5C0000-0x67FFFF). Either one freezes CPU1's core.
32+
* Override the deep-sleep config so CPU0 deep sleep keeps the clocks and RAM
33+
* CPU1 depends on alive.
34+
*
35+
* deep-sleep-config words map to the SoC power code's excl[] mask (bits to
36+
* NOT gate / NOT power down):
37+
* word0 = SLEEPCON0 SLEEPCFG keep-alive (clocks/oscillators)
38+
* word1 = PDSLEEPCFG0 keep-powered (voltage domains)
39+
* word2 = PDSLEEPCFG1 keep-powered
40+
* word3 = PDSLEEPCFG2 keep-powered (SRAM partitions 0-31)
41+
* word4 = PDSLEEPCFG3 keep-powered (SRAM partitions 32-63)
42+
* word5 = PDSLEEPCFG4 keep-powered (caches / OTP / peripherals)
43+
* word6 = PDSLEEPCFG5 keep-powered
44+
*
45+
* word0 = 0xA000FFA6 keeps: SENSEP/SENSES/COMN main clocks (bits 1,2,5),
46+
* XTAL/FRO0-2/LPOSC (bits 7-11), all PLLs (bits 12-15) and the FRO0/FRO2
47+
* output gates (bits 29,31). word1 = 0x140 keeps VDDN_COM fully powered
48+
* (VNCOM_DSR bit8 + V2NMED_DSR bit6) so CPU0 resumes in place instead of
49+
* warm-resetting into ROM. word3/word4 = 0xFFFFFFFF keep all SRAM partitions
50+
* powered so CPU1's image survives CPU0 deep sleep.
51+
*/
52+
&deepsleep {
53+
deep-sleep-config = <0xa000ffa6 0x140 0x0
54+
0xffffffff 0xffffffff 0x400c00 0x0>;
55+
};
56+
57+
/*
58+
* Deep sleep retention reuses the same dual-core keep-alive mask as deep sleep
59+
* (case 8: CPU0 DSR while CPU1 is parked in deep sleep). Full deep-sleep
60+
* retention (FDSR) is a dual-domain mode: it only engages when both the compute
61+
* and sense domains request deep sleep. Keeping the SENSE / COMN clocks and all
62+
* SRAM partitions alive lets both cores resume in place afterwards.
63+
*
64+
* word1 = 0x1C0 excludes V2COM_DSR (bit7) in addition to VNCOM_DSR (bit8) and
65+
* V2NMED_DSR (bit6). PCFG0_DSR requests all three, but V2COM_DSR (the shared
66+
* VDD2 common rail) must only be retained when *every* VDD2/VDDN companion is
67+
* also retained (PMC rule: "when V2COM_DSR, other VDD2 and VDDN switches should
68+
* be off"). Since not every VDD2/VDDN companion enters retention here, V2COM_DSR
69+
* must be excluded - otherwise the PMC enters an inconsistent retention state,
70+
* the common VDD2/VDDN rail collapses, and CPU0 warm-resets into the boot ROM
71+
* instead of resuming in place. Excluding it leaves only V2COMP_DSR (CPU0's own
72+
* compute logic), which together with the FDSR domain bits is exactly what
73+
* case 8 needs.
74+
*/
75+
&dsr {
76+
deep-sleep-retention-config = <0xa000ffa6 0x1c0 0x0
77+
0xffffffff 0xffffffff 0x400c00 0x0>;
78+
};
79+
80+
/*
81+
* In DSR (case 8) the OS Timer that drives the system tick loses power because
82+
* it sits in the VDD2_COMP rail that DSR collapses. Enable the always-on IRTC
83+
* wake timer as the companion counter so the OS Timer can program a wakeup and
84+
* resume in place. rtc0 must be okay for its wake-timer child to be usable.
85+
*/
86+
/ {
87+
chosen {
88+
zephyr,system-timer-companion = &irtc_wake;
89+
};
90+
};
91+
92+
&rtc0 {
93+
status = "okay";
94+
};
95+
96+
&irtc_wake {
97+
status = "okay";
98+
wakeup-source;
99+
};
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2026 NXP
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
CONFIG_PM=y
5+
CONFIG_PRINTK=y
6+
7+
# The deep-sleep-retention (STANDBY) entry/exit path runs on the idle thread
8+
# stack and uses more stack than a plain WFI idle (context save/restore, clock
9+
# reconfiguration). Enlarge the idle stack so it does not overflow.
10+
CONFIG_IDLE_STACK_SIZE=2048
11+
12+
# Interactive menu over the console: read the user's case selection
13+
# character by character.
14+
CONFIG_CONSOLE_SUBSYS=y
15+
CONFIG_CONSOLE_GETCHAR=y
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2026 NXP
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
cmake_minimum_required(VERSION 3.20.0)
5+
6+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
7+
project(rt700_dual_core_pm_remote)
8+
9+
if(NOT CONFIG_BOARD_MIMXRT700_EVK_MIMXRT798S_CM33_CPU1)
10+
message(FATAL_ERROR "${BOARD}/${BOARD_QUALIFIERS} is not supported by this sample")
11+
endif()
12+
13+
target_sources(app PRIVATE src/main.c)
14+
target_include_directories(app PRIVATE
15+
${ZEPHYR_BASE}/../modules/hal/nxp/mcux/mcux-sdk-ng/drivers/mu1)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright 2026 NXP
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
source "Kconfig.zephyr"
5+
6+
config RT700_DUAL_CORE_PM_SLEEP_SECONDS
7+
int "Power-mode measurement window in seconds"
8+
default 10
9+
range 1 3600
10+
help
11+
Number of seconds each active, sleep, or deep-sleep test case runs.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Copyright 2026 NXP
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
CONFIG_SECOND_CORE_MCUX=y
5+
CONFIG_BUILD_OUTPUT_HEX=y
6+
CONFIG_BUILD_OUTPUT_INFO_HEADER=y
7+
CONFIG_GLIKEY_MCUX_GLIKEY=y

0 commit comments

Comments
 (0)