MCXN947: Combining Internal Flash Boot with External Flash XIP – Analysis and Configuration

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

MCXN947: Combining Internal Flash Boot with External Flash XIP – Analysis and Configuration

MCXN947: Combining Internal Flash Boot with External Flash XIP – Analysis and Configuration

1.Overview

The NXP MCXN947 is a high-performance microcontroller that supports booting from either internal or external Flash memory. For most embedded applications, the on-chip Flash provides sufficient capacity to host both code and resources. However, in domains such as AI, image processing, or speech recognition—especially when deploying large neural network models with the eIQ toolchain—the size of the models can easily exceed the available internal Flash space.

Although the MCXN947 supports executing directly from external Flash (XIP), the system typically boots from a fixed entry point in either internal or external Flash. This raises the question: can we combine the best of both worlds by booting from internal Flash while placing large resources or code segments in external Flash for direct execution?

This article presents a demo implementation of exactly such a hybrid “internal boot + external XIP execution” scheme. The approach preserves fast and flexible system startup, while significantly expanding available storage capacity—ideal for hosting large AI models.

Hardware Environment:

  • Development Board: FRDM-MCXN947

Software Environment:

2. External Flash Hardware Configuration and Pin Assignment

The FRDM-MCXN947 board integrates an external 8-line Octal Flash, connected to the MCU’s FlexSPI interface. The key pin assignments are as follows:

Harry_Zhang_0-1756458008577.png

Octal Flash Pin Function MCXN947 Connection

HyperRAM Chip Pin Function Connected to MCXN947
CS SPI communication chip select signal P3_0 / FLEXSPI0_A_SS0_b
SCK SPI communication clock signal P3_7 / FLEXSPI0_A_SCLK
DQS SPI communication data strobe signal P3_6 / FLEXSPI0_A_DQS
DQ0 OSPI data signal D0 P3_8 / FLEXSPI0_A_DATA0
DQ1 OSPI data signal D1 P3_9 / FLEXSPI0_A_DATA1
DQ2 OSPI data signal D2 P3_10 / FLEXSPI0_A_DATA2
DQ3 OSPI data signal D3 P3_11 / FLEXSPI0_A_DATA3
DQ4 OSPI data signal D4 P3_12 / FLEXSPI0_A_DATA4
DQ5 OSPI data signal D5 P3_13 / FLEXSPI0_A_DATA5
DQ6 OSPI data signal D6 P3_14 / FLEXSPI0_A_DATA6
DQ7 OSPI data signal D7 P3_15 / FLEXSPI0_A_DATA7
The configuration code begins with 
   /* Enables the clock for PORT3: Enables clock */
       CLOCK_EnableClock(kCLOCK_Port3);

       const port_pin_config_t port3_0_pinB17_config = {/* Internal pull-up/down resistor is disabled */
           kPORT_PullDisable,
           /* Low internal pull resistor value is selected. */
           kPORT_LowPullResistor,
           /* Fast slew rate is configured */
           kPORT_FastSlewRate,
           /* Passive input filter is disabled */
           kPORT_PassiveFilterDisable,
           /* Open drain output is disabled */
           kPORT_OpenDrainDisable,
           /* Low drive strength is configured */
           kPORT_LowDriveStrength,
           /* Pin is configured as FLEXSPI0_A_SS0_b */
           kPORT_MuxAlt8,
           /* Digital input enabled */
           kPORT_InputBufferEnable,
           /* Digital input is not inverted */
           kPORT_InputNormal,
           /* Pin Control Register fields [15:0] are not locked */
           kPORT_UnlockRegister};
       /* PORT3_0 (pin B17) is configured as FLEXSPI0_A_SS0_b */
       PORT_SetPinConfig(PORT3, 0U, &port3_0_pinB17_config);
 
The same procedure is repeated for all FlexSPI pins.
3. FlexSPI Module Initialization
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.
Harry_Zhang_1-1756458846963.png
  • Size: For example, 128MB

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.

Harry_Zhang_2-1756458878141.png

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" 
};
Harry_Zhang_3-1756459055137.png

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:

Harry_Zhang_4-1756459105739.png

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.

Harry_Zhang_5-1756459182471.png

 

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.

ラベル(1)
評価なし
バージョン履歴
最終更新日:
金曜日
更新者: