Program Lifecycle on MCXC151#
The MCXC151 device exposes a PROGRAM_LIFECYCLE (0x17) debug-mailbox command that advances the customer lifecycle stored in CMPA (LIFECYCLE_STATE + LIFECYCLE_STATE_DP). Unlike writing CMPA over ISP, this command works directly through the debug probe, which makes it useful for moving a freshly provisioned board from DEVELOP into an in-field lifecycle without going through pfr write.
The device enforces strict preconditions before it will program the new value:
The device must currently be in
DEVELOP. Any other lifecycle (IN_FIELD1,IN_FIELD2,IN_FIELD_LOCKED,BRICKED) causes the command to be rejected immediately and the new value is never written. Lifecycle transitions are one-way; once you leaveDEVELOPyou cannot come back.CMPA integrity check must pass. If the CMPA boot-config region has a valid header marker, its CRC must match. The same applies to the CMPA password region. If either CRC fails, the command is rejected and nothing is programmed. An erased CMPA (all
0xFF) trivially passes this check because no header markers are present.Both
LIFECYCLE_STATEandLIFECYCLE_STATE_DPare written from the same input word. You supply one 32-bit value and it is mirrored into both lifecycle slots.The device resets immediately after the new lifecycle is programmed. The debug-mailbox response may therefore not be received by the host; SPSDK handles this by treating the post-command timeout as success.
The new lifecycle value is not validated against the cmpa_lc enum on the device side — whatever 32-bit word you supply is written. Programming an invalid value will brick the device, since flash phrase programming is one-shot. For this reason nxpdebugmbox program-lifecycle accepts the symbolic names defined in cmpa_lc.json (e.g. IN_FIELD1, IN_FIELD2, IN_FIELD_LOCKED, BRICKED) in addition to raw integers.
WARNING!#
Lifecycle transitions are irreversible. Use this notebook on a development board you are willing to leave in the target lifecycle. For real device provisioning, define your own CMPA configuration and double-check the target lifecycle before executing the command.
1. Prerequisites#
SPSDK is needed with examples extension.
pip install spsdk[examples](Please refer to the installation documentation.)This example uses an MCXC151 board in
DEVELOPlifecycle, connected via ISP UART and a J-Link debug probe.
1.1 Let’s prepare the environment#
# Import required modules
import os
# This env variable sets colored logger output to STDOUT
%env JUPYTER_SPSDK=1
# Set a magic for command execution and echo
%alias execute echo %l && %l
%alias_magic ! execute
# Setup workspace
WORKSPACE = "workspace/"
VERBOSITY = "-v"
# Create output directory
os.makedirs(WORKSPACE, exist_ok=True)
# Device configuration
FAMILY = "mcxc151"
INTERFACE = "jlink"
# Target lifecycle for this run. Accepted names come from cmpa_lc.json:
# IN_FIELD1, IN_FIELD2, IN_FIELD_LOCKED, BRICKED
# (DEVELOP is the starting state and is not a valid target.)
TARGET_LIFECYCLE = "IN_FIELD1"
env: JUPYTER_SPSDK=1
Created `%!` as an alias for `%execute`.
1.2 Let’s prepare the device#
Use nxpdevscan to check that the device is connected to the PC in ISP mode.
# check if the device is connected and detected by PC
%! nxpdevscan $VERBOSITY
nxpdevscan -v
Scanning USB devices... Nothing found
Scanning UART devices...INFO:spsdk.sdp.sdp:TX-CMD: ReadStatus
INFO:spsdk.sdp.sdp:RX-CMD: Timeout Error
INFO:spsdk.sdp.sdp:TX-CMD: ReadStatus
INFO:spsdk.sdp.sdp:RX-CMD: Timeout Error
INFO:spsdk.sdp.sdp:TX-CMD: ReadStatus
INFO:spsdk.sdp.sdp:RX-CMD: Timeout Error
INFO:spsdk.sdp.sdp:TX-CMD: ReadStatus
INFO:spsdk.sdp.sdp:RX-CMD: Timeout Error
INFO:spsdk.sdp.sdp:TX-CMD: ReadStatus
INFO:spsdk.sdp.sdp:RX-CMD: Timeout Error
╔════════════════════════════════════════════╗
║ Connected NXP UART Devices (1 device) ║
╠════════════════════════════════════════════╣
║ Port : COM4 ║
║ Type : mboot device ║
╚════════════════════════════════════════════╝
Scanning LPCUSBSIO devices... Nothing found
Scanning UUU devices... Nothing found
# choose the ISP UART interface based on the result of nxpdevscan
UART = "-p COM4"
# check if the board responds in ISP mode
%! blhost $VERBOSITY $UART get-property 1
blhost -v -p COM4 get-property 1
INFO:spsdk.mboot.mcuboot:Connect: identifier='uart', device=COM4
INFO:spsdk.mboot.mcuboot:Connect: identifier='uart', device=COM4
INFO:spsdk.mboot.mcuboot:CMD: GetProperty(CurrentVersion, index=0)
INFO:spsdk.mboot.mcuboot:CMD: GetProperty(CurrentVersion, index=0)
INFO:spsdk.mboot.mcuboot:CMD: Status: 0 (0x0) Success.
INFO:spsdk.mboot.mcuboot:CMD: Status: 0 (0x0) Success.
Response status = 0 (0x0) Success.
Response word 1 = 1258356736 (0x4b010000)
Current Version = K1.0.0
INFO:spsdk.mboot.mcuboot:Closing: identifier='uart', device=COM4
INFO:spsdk.mboot.mcuboot:Closing: identifier='uart', device=COM4
Step 1: Verify current lifecycle is DEVELOP#
The PROGRAM_LIFECYCLE command is honored only while the device is in DEVELOP. On MCXC151 the current lifecycle is exposed as blhost property 17 (life-cycle).
Expected output: Current Value = DEVELOP (or the matching encoded value 0x96368FC3).
If the device reports any other lifecycle, do not continue — the command will be rejected and you risk leaving the device in an unexpected state.
%! blhost $UART get-property 17
%! blhost $UART get-property 7
blhost -p COM4 get-property 17
Response status = 0 (0x0) Success.
Response word 1 = 1520786085 (0x5aa55aa5)
Response word 2 = 3 (0x3)
Security State = UNSECURE
blhost -p COM4 get-property 7
Response status = 0 (0x0) Success.
Response word 1 = 3423 (0xd5f)
Available Commands = ['FlashEraseAll', 'FlashEraseRegion', 'ReadMemory', 'WriteMemory', 'FillMemory', 'GetProperty', 'Execute', 'Reset', 'SetProperty']
Step 2: Ensure CMPA integrity#
A CMPA integrity check runs before programming. For the boot-config and password regions:
If the header is
0xFF...FF(erased), the region is skipped — the check passes.If the header matches the CMPA marker, the region’s CRC must match the value stored alongside it.
The safest way to guarantee a clean check on a development board is to mass-erase the flash. Skip this step if your CMPA is already in a known-good state (valid markers + CRCs, or fully erased).
%! blhost $UART flash-erase-all
blhost -p COM4 flash-erase-all
Response status = 0 (0x0) Success.
Step 3: Start the debug mailbox#
Open the debug-mailbox session over the J-Link probe. PROGRAM_LIFECYCLE uses a two-phase handshake: the first phase returns an ACK token, the second phase carries the 32-bit lifecycle value.
%! nxpdebugmbox -i $INTERFACE cmd --family $FAMILY start
nxpdebugmbox -i jlink cmd --family mcxc151 start
# Interface Id Description Architecture
-------------------------------------------------------------------------
0 Jlink 852002625 Segger J-Link Compact PLUS arm-cortex
Start Debug Mailbox succeeded
Step 4: Program the lifecycle#
Issue program-lifecycle with the target lifecycle name. SPSDK resolves the name to the encoded 32-bit value from cmpa_lc.json, sends the two-phase debug-mailbox command, and accepts the post-command timeout as success because the device resets immediately after the new lifecycle is programmed.
%! nxpdebugmbox -i $INTERFACE cmd -f $FAMILY program-lifecycle -l $TARGET_LIFECYCLE
nxpdebugmbox -i jlink cmd -f mcxc151 program-lifecycle -l IN_FIELD1
# Interface Id Description Architecture
-------------------------------------------------------------------------
0 Jlink 852002625 Segger J-Link Compact PLUS arm-cortex
Program lifecycle IN_FIELD1 (0x9635f807) succeeded
Step 5: Verify the new lifecycle#
After the device resets, re-query life-cycle via ISP. The reported value should match the requested TARGET_LIFECYCLE. From this point onwards, PROGRAM_LIFECYCLE will no longer be accepted — the device has left DEVELOP for good.
%! blhost $UART get-property 17
%! blhost $UART get-property 7
blhost -p COM4 get-property 17
Response status = 0 (0x0) Success.
Response word 1 = 1520786085 (0x5aa55aa5)
Response word 2 = 7 (0x7)
Security State = UNSECURE
blhost -p COM4 get-property 7
Response status = 0 (0x0) Success.
Response word 1 = 3153 (0xc51)
Available Commands = ['FlashEraseAll', 'FillMemory', 'GetProperty', 'Reset', 'SetProperty']
Summary#
This notebook demonstrated programming the customer lifecycle on MCXC151 via the debug-mailbox PROGRAM_LIFECYCLE (0x17) command:
✓ Verified the device was in
DEVELOP(required precondition).✓ Ensured CMPA integrity by mass-erasing flash.
✓ Opened the debug mailbox over J-Link.
✓ Programmed the new lifecycle (
IN_FIELD1) and let the device reset.✓ Confirmed the new lifecycle via
blhost get-property 17.
The device is now in the target in-field lifecycle and the transition is permanent.