cancel
Showing results for 
Search instead for 
Did you mean: 

External Memory - Hardfault on startup

mailmail9116
Associate II
Posted on February 19, 2013 at 19:27

Hi,

I am having problem with the external memory.

Not so long ago my program used both the internal memory and the external, but I managed to move both the heap and the stack to the external memory (2 megabyte) ,and for now I am not using the internal memory anymore.

Everything worked great until now, I added a memory pool (taken from the freeRTOS source code). when I define my array (that will be used for the allocations) to 1 mb (or even less than that),I receive a hard-fault on startup, i managed to pin-point the problem :

LoopFillZerobss:

  ldr  r3, = _ebss

  cmp  r2, r3

  bcc  FillZerobss

/* Call static constructors */

  

bl __libc_init_array

// <- Here is the problem

I know that this function initializes the static variables , i also managed to find the exact location in the assembly on where it happens :

0804a490: __libc_init_array+40   b.n 0x804a49a <__libc_init_array+50>

0804a492: __libc_init_array+42   ldr.w r3, [r5],

#4

0804a496: __libc_init_array+46   blx r3

//<- here is the problem

0804a498: __libc_init_array+48   adds r4,

#1

0804a49a: __libc_init_array+50   cmp r4, r6

0804a49c: __libc_init_array+52   bne.n 0x804a492 <__libc_init_array+42>

My guess that it's trying to go to an invalid address, but why does it happens?

Also here is the output from the hard fault trace :

R0 = 0

R1 = 2000032C

R2 = 0

R3 = 64000240

R12 = 31

LR [R14] = 804F36B  subroutine call

return

address //don't thing that it matters but its address of a function called ''wctob''

PC [R15] = 0  program counter

PSR = 60000000

BFAR = E000ED38

CFSR = 20000

HFSR = 40000000

DFSR = 1

AFSR = 0

SCB_SHCSR = 0

The program counter is 0 , so for sure a reset happened .

I also attached my linker script and the startup file for you to look at.

(btw, when I am allocating a really small array for the memory pool (like 100k) ,it works fine.

Any help will be mostly appreciated

Thanks

Michael
4 REPLIES 4
Nickname12657_O
Associate III
Posted on February 19, 2013 at 22:40

Hi michael,

I beleive there is something missing or wrong in the configuration of the external memory thru our FSMC interface at start up and before jumping to the main, can you put a breakpoint in your startup after FSMC configuration and while using your debugger to view the memory location and try to write read to a fixed patern such us 0x5555 up to your 2Mbytes boundary and see if the issue is there?

if you can provide your stm32 exact part number and evaluation board reference this will be very helpfull,  so I can replicate the case at my end.

Cheers,

Moderator

Posted on February 20, 2013 at 00:56

If that is the value of R3 it's calling, then you have linked in some 32-bit ARM code. Maybe look at the .MAP file

Also I wouldn't be putting the stack in the external memory, it's SLOW, the CCM would be better
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
mailmail9116
Associate II
Posted on February 20, 2013 at 06:56

Hi,

I am using STM3240G evaluation board. Clive : ''If that is the value of R3 it's calling, then you have linked in some 32-bit ARM code. Maybe look at the .MAP file '' What do you mean? I did the following in both scenarios ( i.e , when a array of 1 megabyte defined,and when is not defined) ,both worked :

for (uint32_t WriteAddr = 0 ; WriteAddr <0x200000; WriteAddr += 2) 
{
*(uint16_t *) ((uint32_t)0x64000000 + WriteAddr) = 0x5555;
}

Again i have to say,when i worked in my previous configuration ,stack and heap are in the internal RAM ( as by defined by default),and i allocated 1 megabyte of external RAM as a memory pool,nothing crashed ,and it worked fine. Yes i know that using the external RAM is slower,but speed for now is not an issue for me,memory space IS. Here is the init of the external RAM ( also in my previous post i attached the startup file ,the linker file,and the system init file.)

void SystemInit_ExtMemCtl(void)
{
/* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
RCC->AHB1ENR = 0x00000078;
/* Connect PDx pins to FSMC Alternate function */
GPIOD->AFR[0] = 0x00cc00cc;
GPIOD->AFR[1] = 0xcc0ccccc;
/* Configure PDx pins in Alternate function mode */ 
GPIOD->MODER = 0xaaaa0a0a;
/* Configure PDx pins speed to 100 MHz */ 
GPIOD->OSPEEDR = 0xffff0f0f;
/* Configure PDx pins Output type to push-pull */ 
GPIOD->OTYPER = 0x00000000;
/* No pull-up, pull-down for PDx pins */ 
GPIOD->PUPDR = 0x00000000;
/* Connect PEx pins to FSMC Alternate function */
GPIOE->AFR[0] = 0xc00cc0cc;
GPIOE->AFR[1] = 0xcccccccc;
/* Configure PEx pins in Alternate function mode */ 
GPIOE->MODER = 0xaaaa828a;
/* Configure PEx pins speed to 100 MHz */ 
GPIOE->OSPEEDR = 0xffffc3cf;
/* Configure PEx pins Output type to push-pull */ 
GPIOE->OTYPER = 0x00000000;
/* No pull-up, pull-down for PEx pins */ 
GPIOE->PUPDR = 0x00000000;
/* Connect PFx pins to FSMC Alternate function */
GPIOF->AFR[0] = 0x00cccccc;
GPIOF->AFR[1] = 0xcccc0000;
/* Configure PFx pins in Alternate function mode */ 
GPIOF->MODER = 0xaa000aaa;
/* Configure PFx pins speed to 100 MHz */ 
GPIOF->OSPEEDR = 0xff000fff;
/* Configure PFx pins Output type to push-pull */ 
GPIOF->OTYPER = 0x00000000;
/* No pull-up, pull-down for PFx pins */ 
GPIOF->PUPDR = 0x00000000;
/* Connect PGx pins to FSMC Alternate function */
GPIOG->AFR[0] = 0x00cccccc;
GPIOG->AFR[1] = 0x000000c0;
/* Configure PGx pins in Alternate function mode */ 
GPIOG->MODER = 0x00080aaa;
/* Configure PGx pins speed to 100 MHz */ 
GPIOG->OSPEEDR = 0x000c0fff;
/* Configure PGx pins Output type to push-pull */ 
GPIOG->OTYPER = 0x00000000;
/* No pull-up, pull-down for PGx pins */ 
GPIOG->PUPDR = 0x00000000;
/*-- FSMC Configuration ------------------------------------------------------*/
/* Enable the FSMC interface clock */
RCC->AHB3ENR = 0x00000001;
/* Configure and enable Bank1_SRAM2 */
FSMC_Bank1->BTCR[2] = 0x00001015;
FSMC_Bank1->BTCR[3] = 0x00010603;
FSMC_Bank1E->BWTR[2] = 0x0fffffff;
/*
Bank1_SRAM2 is configured as follow:
p.FSMC_AddressSetupTime = 3;
p.FSMC_AddressHoldTime = 0;
p.FSMC_DataSetupTime = 6;
p.FSMC_BusTurnAroundDuration = 1;
p.FSMC_CLKDivision = 0;
p.FSMC_DataLatency = 0;
p.FSMC_AccessMode = FSMC_AccessMode_A;
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; 
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
*/ 
}

Thanks Michael
mailmail9116
Associate II
Posted on February 20, 2013 at 09:58

Thanks all, I managed to fix it.

Probably the FSMC initialization was wrong as you said.

Thanks

Michael