2013-02-19 10:27 AM
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 Michael2013-02-19 01:40 PM
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, Moderator2013-02-19 03:56 PM
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 better2013-02-19 09:56 PM
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
2013-02-20 12:58 AM
Thanks all, I managed to fix it.
Probably the FSMC initialization was wrong as you said. Thanks Michael