cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7B3 continously resetting when executing code from external flash

devanshu5
Visitor

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

}

  1. MPU Configuration

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();

}

  1. 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();

}

  1. 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.

0 REPLIES 0