cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7B3 continously resetting when executing code from external flash

devanshu5
Associate

We have a working production firmware for the STM32H7B3 that uses a Winbond W25Q01JVZEIM external flash using QSPI in memory-mapped mode to store data and assets for a TouchGFX and other applications.

Now, due to internal flash limitations, we are attempting to execute some code directly from the same external flash. As a starting point, we created a simple test function to run from external flash:

__attribute__((section("ExtFlashSection")))

void test_ext_flash_func(void) {

    volatile int x = 1;

    x++;

}

The rest of the application continues to run from internal flash. However, when this function is called, the MCU enters a continuous reboot loop. We have added Hard fault handler but couldn't see any prints for different register values.

Current Configuration

  1. Linker Script
MEMORY

{

  ...

  OSPI (xr) : ORIGIN = 0x93170000, LENGTH = 32M

}



SECTIONS

{

  ...

  ExtFlashSection :

  {

    *(ExtFlashSection ExtFlashSection.*)

    *(.gnu.linkonce.r.*)

    . = ALIGN(0x4);

  } > OSPI

}

2. MPU Configuration

I have added this now for getting the code to execute from external flash based on some online documentation that I saw. This wasn't present in our earlier implementation.

void MPU_Config(void)

{

    // Disable MPU

    MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;



    // Configure Region 0 for QSPI external flash

    MPU->RNR  = 0;                          // Select Region 0

    MPU->RBAR = 0x93170000;                 // Base address of QSPI flash



    // Region size = 32MB → log2(32MB) = 25 → 0x19 << 1 = 0x32

    MPU->RASR = (0x19 << MPU_RASR_SIZE_Pos) |  // Size = 32MB

                (0 << MPU_RASR_TEX_Pos)      | // TEX = 0

                (1 << MPU_RASR_C_Pos)        | // Cacheable

                (0 << MPU_RASR_B_Pos)        | // Not bufferable

                (0 << MPU_RASR_S_Pos)        | // Not shareable

                (3 << MPU_RASR_AP_Pos)       | // Full access

                (0 << MPU_RASR_XN_Pos)       | // Executable

                (1 << MPU_RASR_ENABLE_Pos);    // Enable region



    // Enable MPU with default memory map for privileged access

    MPU->CTRL = MPU_CTRL_ENABLE_Msk | MPU_CTRL_PRIVDEFENA_Msk;



    // Ensure MPU settings take effect

    __DSB();

    __ISB();

}

3. OCTOSPI Driver Initialization

static void enableMemoryMappedMode( void )    // QPI mode only

{

  OCTOSPI1->CR &= (~(OCTOSPI_CR_FMODE | OCTOSPI_CR_FTHRES));

  OCTOSPI1->CR |= (OCTOSPI_CR_FMODE_1 | OCTOSPI_CR_FMODE_0);

  OCTOSPI1->CCR = OSPI_COMM_CFG_CMD_ADDR_DATA;

  OCTOSPI1->TCR = (FLASH_CFG_QPI_NO_OF_DUMMY_CLK << OCTOSPI_TCR_DCYC_Pos) | OCTOSPI_TCR_SSHIFT;

  OCTOSPI1->IR = FLASH_CMD_FAST_READ_QPI;

}

OSPIDriverinit()

{

flashSendCMDNoData( FLASH_CMD_ENABLE_4B_ADDR_WB, true );   // Enable the 4 byte addressing mode for all commands

        flashReadChipData( FLASH_CMD_READ_SR2_REG_WB, &tmpSRData.statusReg2, 1, 0, true );

        if( (tmpSRData.statusReg2 & FLASH_SR2_QE_MASK_WB) == 0 )

        {

          tmpSRData.statusReg2 |=  FLASH_SR2_QE_MASK_WB;

          flashSendCMDNoData( FLASH_CMD_WRITE_ENABLE, true );

          flashWriteChipData( FLASH_CMD_WRITE_SR2_REG_WB, &tmpSRData.statusReg2, 1, true );

          do

          {

            flashReadChipData( FLASH_CMD_READ_SR1, &tmpSRData.statusReg1, 1, 0, true );

          } while( (tmpSRData.statusReg1 & FLASH_SR1_BUSY) != 0 );

        }

        // Enable QPI mode

        flashSendCMDNoData( FLASH_CMD_ENABLE_QPI_WB, true );

        // Configure the number of dummy cycles for 100 MHz operation

        tmpData = FLASH_CFG_QPI_RD_CFG_REG_WB;

        flashWriteChipData( FLASH_CMD_WRITE_RD_CFG_WB, &tmpData, 1, false );

        selectedDie = 0;

        isDualDieStatReg = true;

        flashWriteChipData( FLASH_CMD_SELECT_DIE_WB, &selectedDie, 1, false );

      }

__NVIC_DisableIRQ( OCTOSPI1_IRQn );

  __NVIC_SetPriority( OCTOSPI1_IRQn, OCTOSPI1_PRIO );

 enableMemoryMappedMode();

}

4. Main Function

int main(void){

SystemClockConfig();

  MPU_Config();

  // Enable I-Cache

  SCB_EnableICache();

  // Enable D-Cache

  SCB_EnableDCache();

....

OSPIDriverinit()

....

test_ext_flash_func() // Inside a thread

….

}

Issue

Calling test_ext_flash_func() causes the MCU to reboot continuously. We suspect this is due to executing code from external flash, but need help identifying the root cause and resolving it.

3 REPLIES 3

Please format your code: https://community.st.com/t5/community-guidelines/how-to-write-your-question-to-maximize-your-chances-to-find-a/ta-p/575228

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.
Maxime_MARCHETTO
Community manager
Community manager

Hello @devanshu5,

This post has been escalated to the ST Online Support Team for additional assistance. We'll contact you directly.

Best regards,
Maxime


In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.

Hi Team,

Please help with the analysis of this issue as soon as possible. It is blocking us from moving ahead.

Regards,

Devanshu Agarwal