cancel
Showing results for 
Search instead for 
Did you mean: 

Use external NOR flash to move CPP object file

npatil15
Senior

Hello,

I have STM32F7 controller, using Free RTOS, trying to interface external NOR flash, S29GL128S10TFIV13.

I have one source file say testCode.cpp, which I want to move completely in external NOR flash, but every time I ran then code it give Hardfault.

MEMORY
{
RAM (xrw)           : ORIGIN = 0x20000000, LENGTH = 512K
FLASH (rx)          : ORIGIN = 0x8000000,  LENGTH = 2048K
EXT_FLASH (rx)      : ORIGIN = 0x64000000, LENGTH = 16M
EXT_SRAM_HEAP (xrw) : ORIGIN = 0x60000000, LENGTH = 256K
EXT_SRAM_STACK (rw) : ORIGIN = 0x60040000, LENGTH = 256K
}
  
SECTIONS
{
 .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

.ext_flash_code :
  {
    . = ALIGN(4);
    _sextflash_run = .;
    *(.ext_flash_data*)
    *(.ext_flash_data*)
    . = ALIGN(4);
    _eextflash_run = .;
  } > EXT_FLASH

  /* 2. SECTION FOR MANUAL ATTRIBUTES (For Arrays) */
  .ext_flash_data :
  {
    . = ALIGN(4);
    *(.ext_flash_data)    /* Targets __attribute__((section(".ext_flash_data"))) */
    *(.ext_flash_data*)
    . = ALIGN(4);
  } > EXT_FLASH
}

 

Below function I was trying to call from thread,

main()
{
  testCodeTaskHandle = osThreadNew(testCodeWrapper, NULL, &testCodeTask_attributes);
}

extern "C" 
__attribute__((section(".ext_flash_code")))
void testCodeWrapper(void *argument)
{
  testCode* obj = testCode::getInstance();
  obj->run();
}

Now it gets stuck at first line of this function and then jump to Hardfault.

Note: I have tried to read QRY from flash as test and it PASSED, so flash is integrated correctly.

In .map file it is clearly seen that the function moves to external flash address.

Below init details

  hnor2.Instance = FMC_NORSRAM_DEVICE;
  hnor2.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
  /* hnor2.Init */
  hnor2.Init.NSBank = FMC_NORSRAM_BANK2;
  hnor2.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
  hnor2.Init.MemoryType = FMC_MEMORY_TYPE_NOR;
  hnor2.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
  hnor2.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
  hnor2.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
  hnor2.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
  hnor2.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
  hnor2.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
  hnor2.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
  hnor2.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
  hnor2.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
  hnor2.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
  hnor2.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
  hnor2.Init.PageSize = FMC_PAGE_SIZE_NONE;
  /* Timing */
  Timing.AddressSetupTime = 15;
  Timing.AddressHoldTime = 15;
  Timing.DataSetupTime = 255;
  Timing.BusTurnAroundDuration = 15;
  Timing.CLKDivision = 16;
  Timing.DataLatency = 17;
  Timing.AccessMode = FMC_ACCESS_MODE_A;


Help me to understand what is missing here?
Thanks,

Nitin

 

15 REPLIES 15

The linker neither knows nor cares anything about the physical memory technology - it is only concerned with address ranges.

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Okay, using below test code, I can be able to read/Write the Flash and got success as expected, which explain Flash is integrated and working. 

#define NOR_BANK_ADDR  ((uint32_t)0x64000000) // Change to 0x60000000 if using NE1
#define ADDR_16(offset) ((__IO uint16_t *)(NOR_BANK_ADDR + ((offset) << 1)))

uint16_t q_char = 0, r_char = 0, y_char = 0;
uint16_t cmd;
*ADDR_16(0x000) = 0x00F0;
HAL_Delay(10);

*ADDR_16(0x55) = 0x0098;
HAL_Delay(10);
// 3. Simple Direct Reads (To rule out your NOR_Read function logic)
q_char = *(__IO uint16_t *)(NOR_BANK_ADDR + (0x10 << 1));
r_char = *(__IO uint16_t *)(NOR_BANK_ADDR + (0x11 << 1));
y_char = *(__IO uint16_t *)(NOR_BANK_ADDR + (0x12 << 1));

RESULT = q_char = 'Q', r_char = 'R', y_char = 'Y'

 

But the code I shared on this post, may have some logical issue, which didn't solve yet. External NOR Flash Read address line instead of da... - STMicroelectronics Community

Andrew Neil
Super User

Some GCC Linker resources here.

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

@npatil15 wrote:

Okay, using below test code, I can be able to read/Write the Flash and got success as expected, which explain Flash is integrated and working. 

#define NOR_BANK_ADDR  ((uint32_t)0x64000000) // Change to 0x60000000 if using NE1
#define ADDR_16(offset) ((__IO uint16_t *)(NOR_BANK_ADDR + ((offset) << 1)))

uint16_t q_char = 0, r_char = 0, y_char = 0;
uint16_t cmd;
*ADDR_16(0x000) = 0x00F0;
HAL_Delay(10);

*ADDR_16(0x55) = 0x0098;
HAL_Delay(10);
// 3. Simple Direct Reads (To rule out your NOR_Read function logic)
q_char = *(__IO uint16_t *)(NOR_BANK_ADDR + (0x10 << 1));
r_char = *(__IO uint16_t *)(NOR_BANK_ADDR + (0x11 << 1));
y_char = *(__IO uint16_t *)(NOR_BANK_ADDR + (0x12 << 1));

RESULT = q_char = 'Q', r_char = 'R', y_char = 'Y'

 

But the code I shared on this post, may have some logical issue, which didn't solve yet. External NOR Flash Read address line instead of da... - STMicroelectronics Community


So you need to update that thread with your findings. We need to avoid keeping threads without status as much as possible in this community and avoid such un-usefull exchange (like above).

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.

Okay, I agree. I will focus on the last thread and then will come here.

npatil15
Senior

Hello,

As we decided here, I have worked and resolve these 2 issues

External Flash Read/Write: Solved: Re: External NOR Flash Read address line instead o... - STMicroelectronics Community

Move Object to external SRAM: Solved: Re: Move object (.obj) to external SRAM - STMicroelectronics Community

Now everything has works, but additionally as discussed in above thread, I need to work on external Loader application, found support here (https://github.com/STMicroelectronics/stm32-external-loader.git) which has FMC related Loader examples, make sure you correctly configure the pin of FMC for external Loader application as per you project requirements.

Now you have four things to manage:

1. Create a project with external loader and make sure this works using STM32CubeProgrammer, try to edit, delete, read, multi write/read operations on external Flash.

2. Integrate external Loader program to STM32CubeIDE or vscode in main application project, find the reference you can easily find.

"serverArgs": [
                "-m", "0",
                "-el", "${workspaceFolder}/Loader/testLoader.stldr"
            ],

3. In main application, to access external memory without any limitations (i.e., globally or locally), make sure you initialize FMC and its GPIO inside "SystemInit()" function, that function run at very first stage which make FMC ready for anything.

4. Now, to perform external SRAM operation, you need to copy external/internal FLASH to external SRAM (specifically which execute before main), then make sure you copy external memory to external SRAM and memset to '.bss' sections. And initialize Heap section as mentioned here (Solved: Re: Move object (.obj) to external SRAM - Page 2 - STMicroelectronics Community) So that everything should be ready to run. And that way, it will easily show breakpoint on main(). If you missed anything then you will definitely cause Hard fault before main runs.

Hope my finding helps.

Thanks,

Nitin