Question
STM32F7 Heap on External SDRAM
Posted on May 04, 2016 at 23:29
Hello everyone,
I have managed to configure the FMC to read/write on my external SDRAM. Now, I am trying to put the heap on it. Unfortunately, I am unsuccessful. I look up on the forum and I have did change the startup file to use the same size and use a scatter file for place the heap on it. In the map file , the heap seems well placed. The problem occurs when I am trying to do a malloc(). I get a hard fault. Here is the code I am using...int main(void)
{
char* p;
static char AddressString[16] = {0};
//Compatibility call currently not required in version 4.75
//Initialize CMSIS-RTOS
osKernelInitialize();
//Enable I-Cache
SCB_EnableICache();
//Enable D-Cache
SCB_EnableDCache();
//Configure the system clock to 216 MHz
SystemClock_Config();
//Reset of all peripherals, initialize the flash interface and the systick
HAL_Init();
//Compatibility call currently not required in version 4.75
//Start CMSIS-RTOS thread execution
osKernelStart();
p = (char*) malloc(0x2000);
sprintf(AddressString, ''%08x'', (uint32_t) p);
free(p);
}
void InitFMC (void)
{
FMC_SDRAM_TimingTypeDef SdramTiming;
FMC_SDRAM_CommandTypeDef Command;
volatile uint32_t timeout = SDRAM_TIMEOUT;
/** Perform the SDRAM2 memory initialization sequence
*/
hsdram2.Instance = FMC_SDRAM_DEVICE;
/* hsdram2.Init */
hsdram2.Init.SDBank = FMC_SDRAM_BANK1;
hsdram2.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
hsdram2.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13;
hsdram2.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
hsdram2.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
hsdram2.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
hsdram2.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
hsdram2.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
hsdram2.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
hsdram2.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_2;
/* SdramTiming */
// Timing for 143 Mhz so ok for 108MHz(9.25ns)
SdramTiming.LoadToActiveDelay = 2;
SdramTiming.ExitSelfRefreshDelay = 10;
SdramTiming.SelfRefreshTime = 6;
SdramTiming.RowCycleDelay = 9;
SdramTiming.WriteRecoveryTime = 3;
SdramTiming.RPDelay = 3;
SdramTiming.RCDDelay = 3;
HAL_SDRAM_Init(&hsdram2, &SdramTiming);
/* SDRAM Init sequence */
/* Configure a clock configuration enable command */
Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
/* Send command */
HAL_SDRAM_SendCommand(&hsdram2, &Command, SDRAM_TIMEOUT);
//NOP
Command.CommandMode = FMC_SDRAM_CMD_NORMAL_MODE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
/* Send command */
HAL_SDRAM_SendCommand(&hsdram2, &Command, SDRAM_TIMEOUT);
/* Little delay */
timeout = SDRAM_TIMEOUT * 0xF;
while (timeout--);
/* Configure a PALL (precharge all) command */
Command.CommandMode = FMC_SDRAM_CMD_PALL;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 2;
Command.ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(&hsdram2, &Command, SDRAM_TIMEOUT);
/* Configure a Auto-Refresh command */
Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 8;
Command.ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(&hsdram2, &Command, SDRAM_TIMEOUT);
/* Configure a load Mode register command */
Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 2;
Command.ModeRegisterDefinition = (uint32_t)0x230;
/* Wait until the SDRAM controller is ready */
/* Send the command */
HAL_SDRAM_SendCommand(&hsdram2, &Command, SDRAM_TIMEOUT);
/* Step 6: Set the refresh rate counter */
/* Set the device refresh rate */
//64ms for 8192 rows = 7.8125 us.
//(7.8125us * 108 MHz ) - 20 = 875
HAL_SDRAM_ProgramRefreshRate(&hsdram2, 0x337);
//SYSCFG->MEMRMP |= 0x00000400;
}
void HAL_MspInit(void)
{
//Initialize Peripherals
InitFMC();
}
void HAL_SDRAM_MspInit(SDRAM_HandleTypeDef* hsdram)
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_FMC_CLK_ENABLE();
/* GPIOC */
__HAL_RCC_GPIOC_CLK_ENABLE();
//PC0:nWE
//PC2:nCS
//PC3:CKE
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* GPIOD */
__HAL_RCC_GPIOD_CLK_ENABLE();
//PD0:DQ2
//PD1:DQ3
//PD8:DQ13
//PD9:DQ14
//PD10:DQ15
//PD14:DQ0
//PD15:DQ1
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 |
GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* GPIOE */
__HAL_RCC_GPIOE_CLK_ENABLE();
//PE0:DQML
//PE1:DQMH
//PE7:DQ4
//PE8:DQ5
//PE9:DQ6
//PE10:DQ7
//PE11:DQ8
//PE12:DQ9
//PE13:DQ10
//PE14:DQ11
//PE15:DQ12
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7 | GPIO_PIN_8 |
GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 |
GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* GPIOF */
__HAL_RCC_GPIOF_CLK_ENABLE();
//PF0:A0
//PF1:A1
//PF2:A2
//PF3:A3
//PF4:A4
//PF5:A5
//PF11:nRAS
//PF12:A6
//PF13:A7
//PF14:A8
//PF15:A9
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 |
GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_11 | GPIO_PIN_12 |
GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/* GPIOG */
__HAL_RCC_GPIOG_CLK_ENABLE();
// PG0:A10
// PG1:A11
// PG2:A12
// PG4:BA0
// PG5:BA1
// PG8:CLK
// PG15:nCAS
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 |
GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
}
//In startup.s
; <
h
> Heap Configuration
; <
o
> Heap Size (in Bytes) <
0x0-0xFFFFFFFF:8
>
; </
h
>
Heap_Size EQU 0x02000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
//Scatter file
LR_IROM1 0x08040000 0x000C0000 { ; load region size_region
ER_IROM1 0x08040000 0x000C0000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20010000 0x00040000 { ; RW data
.ANY (+RW +ZI)
}
RW_IRAM2 0x20000000 0x00010000 {
CSCH_DTCM_Buffers.o (+ZI +RW)
}
RW_RAM1 0xC0000000 0x02000000 {
*(HEAP)
}
}
Thank you!
#stm32f7 #heap #sdram