To enable XIP from external Flash, the FlexSPI peripheral must be properly initialized.
3.1. Configure the FlexSPI clock
/* Flexspi frequency 150MHz / 2 = 75MHz */
CLOCK_SetClkDiv(kCLOCK_DivFlexspiClk, 2U);
CLOCK_AttachClk(kPLL0_to_FLEXSPI); /*!< Switch FLEXSPI to PLL0 */
3.2 Initialize the FlexSPI driver
Integrate the FlexSPI driver, which is provided in the SDK, into the project,
/*Get FLEXSPI default settings and configure the flexspi. */
FLEXSPI_GetDefaultConfig(&config);
/*Set AHB buffer size for reading data through AHB bus. */
config.ahbConfig.enableAHBPrefetch = true;
config.rxSampleClock = EXAMPLE_FLEXSPI_RX_SAMPLE_CLOCK;
config.ahbConfig.enableAHBBufferable = true;
config.ahbConfig.enableAHBCachable = true;
FLEXSPI_Init(base, &config);
/* Configure flash settings according to serial flash feature. */
FLEXSPI_SetFlashConfig(base, &deviceconfig, FLASH_PORT);
#if defined(EXAMPLE_FLASH_RESET_CONFIG)
uint32_t TempFastReadSDRLUTCommandSeq[4];
memcpy(TempFastReadSDRLUTCommandSeq, FastReadSDRLUTCommandSeq, sizeof(FastReadSDRLUTCommandSeq));
#endif
4. Configure MCUXpresso Project to Support Octal Flash
In MCUXpresso IDE, go to MCU Settings > Memory, and add a new memory region:
- Name: OSPI_FLASH (or OCTAL_FLASH)
- Start Address: Set according to the external flash address connected to your chip.
According to the user manual, the FLEXSPI start address is 0x80000000.
Next, select the corresponding external flash driver provided by NXP.
The FRDM_MCXN947 board is connected to the mt35xu512aba flash, which supports SFDP, so we can choose MCXN9xx_SFDP_FlexSPI.cfx.
After adding it, you will see the memory details displayed.

5. Add Linker Script and Migrate Model Data
5.1 Create Linker Script Fragments
Add two files to the linkscripts/ folder in your project:
text.ldt (for code sections)
rodata.ldt (for model read-only data)
Contents:
<#if memory.name=="OSPI_FLASH">
KEEP (*(.model_data*))
KEEP (*(model.o*))
KEEP(*(.text.OSPI_FLASH*))
*(.text.QSPI_FLASH*)
*(.text.${memory.alias}*)
*(.text.${memory.name}*)
</#if>
This ensures that model data (e.g., the .model_data section) is properly retained and placed in the XIP (Execute In Place) region.
5.2 Place Model Data in XIP Region
Use the following method to place the model into the .model_data section (in C code):
__attribute__((section(".model_data")))
const unsigned char model_data[] = {
#include "model_data.inc"
};
6. Build and Verify
After building the project, the Image Memory Map Report in MCUXpresso IDE will show that parts of the .text and .rodata sections have been successfully placed into the Octal Flash (OSPI_FLASH) region. For example:
OSPI_FLASH: 100144 B 262140 KB 0.04%
After downloading and running the program, the system boots from internal Flash and successfully reads model data directly from external Flash, completing the AI inference task.
Conclusion
Through the configuration steps introduced in this article, the MCXN947 successfully implements a hybrid storage solution combining internal boot with external XIP execution. This approach retains the advantage of fast boot speed while significantly expanding the available storage capacity for programs and models, providing strong support for deploying complex AI models.
For resource-constrained MCU platforms, this architecture is not only a practical and feasible choice, but also represents an optimized strategy that is likely to be widely adopted in future embedded AI applications.