Hello,
i have the following problem:
I would like to access the external SDRAM on the STM32F429 Discovery. I could access the external SDRAM, that is not the main problem. The problem is, that i have to access the external SDRAM as the following:
/* SDRAM Initialization */ SDRAM_Init(); /* FMC SDRAM GPIOs Configuration */ SDRAM_GPIOConfig(); //Write SDRAM for (counter = 0; counter < TRANSFERS; counter++) { *(__IO uint16_t*) (SDRAM_BANK_ADDR + 2*counter) = (uint16_t)(uhWritedata_16b + counter); }
Here i havé to add the Address "SDRAM_BANK_ADDR" if i would like to write into the external SDRAM. Now i should configure the Scatter - File that i doesn't need that Section. How must be the changes? Is it possible to auto - configure this Section as external SDRAM?
My Scatter File looks like this:
; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_IROM1 0x08000000 0x00200000 { ; load region size_region ER_IROM1 0x08000000 0x00200000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x20000000 0x00030000 { ; RW data .ANY (+RW +ZI) } } ;LR_ERAM1 0xD0000000 0xD0400000 { ;ER_ERAM1 0xD0000000 0xD0400000 { ;.ANY (+RW +ZI) ;} ;}
Thanks for your help.
It's specified in the Scatter File as a SIZE, not by an end address. So 0xD0000000 0x400000
If you use it in the linker, then you'd had better initialize the external memory interface and SDRAM in the SystemInit() routine so the C run time code can copy statics into the SDRAM
You can access the SDRAM with pointers, make absolute declarations, or put the heap there.
unsigned char *FrameBuffer = (unsigned char *)0xD0100000;
's specified in the Scatter File as a SIZE, not by an end address. So 0xD0000000 0x400000
Thanks for your explanation, so i have to change the Scatter File right? How should it looks like?
If you use it in the linker, then you'd had better initialize the external memory interface and SDRAM in the SystemInit() routine so the C run time code can copy statics into the SDRAM Could you make an example? I don't understand it... Here you can see my System Init Function, what kind of changes should be done?
/* FPU settings ------------------------------------------------------------*/ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ #endif /* Reset the RCC clock configuration to the default reset state ------------*/ /* Set HSION bit */ RCC->CR |= (uint32_t)0x00000001; /* Reset CFGR register */ RCC->CFGR = 0x00000000; /* Reset HSEON, CSSON and PLLON bits */ RCC->CR &= (uint32_t)0xFEF6FFFF; /* Reset PLLCFGR register */ RCC->PLLCFGR = 0x24003010; /* Reset HSEBYP bit */ RCC->CR &= (uint32_t)0xFFFBFFFF; /* Disable all interrupts */ RCC->CIR = 0x00000000; #if defined (DATA_IN_ExtSDRAM) SystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSDRAM */ /* Configure the System clock source, PLL Multiplier and Divider factors, AHB/APBx prescalers and Flash settings ----------------------------------*/ SetSysClock(); /* Configure the Vector Table location add offset address ------------------*/ #ifdef VECT_TAB_SRAM SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ #else SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ #endif
unsigned char *FrameBuffer = (unsigned char *)0xD0100000; I understand this example, but i could not use it for my project, becouse i would write in the external SDRAM like in the normal RAM, i will not make defines for the Adress Section. So it means that i would access the external SDRAM like the normal RAM - that is what i need
See that DATA_IN_ExtSDRAM define, and the SystemInit_ExtMemCtl() function it calls? Define it, and make sure the routine initializes your SDRAM
; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_IROM1 0x08000000 0x00200000 { ; load region size_region (2M) ER_IROM1 0x08000000 0x00200000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x20000000 0x00030000 { ; RW data (192K) .ANY (+RW +ZI) } RW_IRAM2 0xD0000000 0x00400000 { ; SDRAM (4M) startup_stm32f429_439xx.o (HEAP) *(.sdram) } }
char buf[256] __attribute__ ((section(".sdram")));
The SDRAM is within regular memory space, but is slower.
Keil project toward the end of this thread. my.st.com/.../Flat.aspx
First Thanks for your Help
Where should be the changes? In which File i should make the #DEFINE DATA_IN_ExtSDRAM and what kind of changes are there? Where should i implement the SystemInit_ExtMemCtl (In the startup_stm32f429_439xx.s - File?) and how should it look?
; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; *************************************************************
LR_IROM1 0x08000000 0x00200000 { ; load region size_region (2M) ER_IROM1 0x08000000 0x00200000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x20000000 0x00030000 { ; RW data (192K) .ANY (+RW +ZI) } RW_IRAM2 0xD0000000 0x00400000 { ; SDRAM (4M) startup_stm32f429_439xx.o (HEAP) *(.sdram) } }
Thanks for this Example
char buf[256] __attribute__ ((section(".sdram"))); This variable i have to define in my main.c - File right?
The SDRAM is within regular memory space, but is slower. I don't want to use the external SDRAM as my regular memory space - i only wanna access it in a flexible and easy way without any functions or something else
The Link doesn't work for me Keil project toward the end of this thread. my.st.com/.../Flat.aspx
Try this http://goo.gl/XDTOdJ or Google "STM32F429DISCO EXTERNAL RAM"
There seems to be a basic lack of comprehension. The Internal SRAM is situated at 0x20000000 and above, the external SDRAM at 0xD0000000, your can access EITHER without functions, they live in the same 4GB/32-bit memory map of the micro-processor. They are not mysteriously different.
The define is within the same system_stm32f4xx.c source as the SystemInit() function, and the external memory configuration routine. Use "Find in File" or "Go to Definition". This is a project specific file, tailored to your hardware. There is a Keil example of this file for the STM32F429I-DISCO board at the end of the cited thread.
The memory needs to get configured prior to use by the C compiler's run time code, as if you describe the available memory in the scatter file and put statics there, they will need to be initialized or zeroed. If the FMC hasn't been configured the system will Hard Fault.
A lot of these concepts should be covered in "Assemblers, Compilers, Linkers, and Loaders" type books and classes.
You want to be selective about what you put in this external memory because it's decidedly slower than internal SRAM. Like I said, you can direct specific variables into specific sections/segments, you can put the HEAP in this memory, and allocate that, or use pointers. This isn't distinctly different from any other C use of memory. You just need to be a little selective about which area of memory you want to use for different purposes. If you put the STACK in SDRAM it will make everything SLOWER.
I don't understand this step - I find the SystemInit() - Function but what kind of changes must be done? If made a define -> #define DATA_IN_ExtSDRAM there, but no changes
void SystemInit(void) { /* FPU settings ------------------------------------------------------------*/ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ #endif /* Reset the RCC clock configuration to the default reset state ------------*/ /* Set HSION bit */ RCC->CR |= (uint32_t)0x00000001; /* Reset CFGR register */ RCC->CFGR = 0x00000000; /* Reset HSEON, CSSON and PLLON bits */ RCC->CR &= (uint32_t)0xFEF6FFFF; /* Reset PLLCFGR register */ RCC->PLLCFGR = 0x24003010; /* Reset HSEBYP bit */ RCC->CR &= (uint32_t)0xFFFBFFFF; /* Disable all interrupts */ RCC->CIR = 0x00000000; #if defined (DATA_IN_ExtSDRAM) SystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSDRAM */ /* Configure the System clock source, PLL Multiplier and Divider factors, AHB/APBx prescalers and Flash settings ----------------------------------*/ SetSysClock(); /* Configure the Vector Table location add offset address ------------------*/ #ifdef VECT_TAB_SRAM SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ #else SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ #endif
My Scatterfile looks like this one:
LR_IROM1 0x08000000 0x00200000 { ; load region size_region ER_IROM1 0x08000000 0x00200000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x20000000 0x00030000 { ; RW data .ANY (+RW +ZI) } ;RW_ERAM1 0xD0000000 0x00400000 { ;startup_stm32f429_439xx.o (HEAP) ;*(.sdram) ;} }
Now i would like to access the Section .sdram like something like this:
uint32_t buf[256] __attribute__ ((section(".sdram")));
What is incorrect in my handling? Can you give me some code examples?
Didn't I provide a thread short cut in my last response? Towards the end of the thread is a message with an attachment containing a Keil example. If the shortened link doesn't work there is also a Google search term to find the thread in question. I've tried very hard to provide multiple ways to get the information you want.
It has a system_stm32f4xx.c file with the right defines and subroutines to enable the SDRAM on the board. It's all been modified to suit the STM32F429I-DISCO board.
You have commented out the portion of the scatter file dealing with the SDRAM. The code to enable the external memory has to deal with your specific board/parts, if you didn't add or adjust the code to suit it probably won't work. The size of the heap is defined in the startup_stm32f4xx.s file.
Didn't I provide a thread short cut in my last response? [...] I've tried very hard to provide multiple ways to get the information you want.
Thanksfull for your help - but sometime it's a little bit hard to understand
It has a system_stm32f4xx.c file [...] board.
I think i did the right defines in system_stm32f4xx.c -> My defines are the following in this file, i think they are correct for the STM32F429 DISCO:
#define DATA_IN_ExtSDRAM /* #define VECT_TAB_SRAM */ #define VECT_TAB_OFFSET 0x00 //#define PLL_SOURCE_HSI // HSI (~16 MHz) used to clock the PLL, and the PLL is used as system clock source #define PLL_SOURCE_HSE // HSE (8MHz) used to clock the PLL, and the PLL is used as system clock source //#define PLL_SOURCE_HSE_BYPASS // HSE bypassed with an external clock (8MHz, coming from ST-Link) used to clock // the PLL, and the PLL is used as system clock source /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ #if defined (PLL_SOURCE_HSI) #define PLL_M 16 #else #define PLL_M 8 #endif #define PLL_N 360 /* SYSCLK = PLL_VCO / PLL_P */ #define PLL_P 2 /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ #define PLL_Q 7
I have no idea what i have to change in my startup file - when i try it like before i could see in the Map-File that the Variable should be accessable. Here is a short piece from my current Map-File. (Here you can see the Variable buf - it should be stored in the external sdram / you also can see the execution region .sdram)
t_buffer 0x2000002c Data 4000 main.o(.bss) r_buffer 0x20000fcc Data 4000 main.o(.bss) __libspace_start 0x20001f6c Data 96 libspace.o(.bss) __temporary_stack_top$libspace 0x20001fcc Data 0 libspace.o(.bss) buf 0xd0000000 Data 1024 main.o(.sdram) Execution Region RW_ERAM1 (Base: 0xd0000000, Size: 0x00000400, Max: 0x00400000, ABSOLUTE, COMPRESSED[0x0000000c]) Base Addr Size Type Attr Idx E Section Name Object 0xd0000000 0x00000400 Data RW 2892 .sdram main.o
I will give you here my startup-file, i hope you can tell me what exactlly should change and how i should change it.
Stack_Size EQU 0x00000400 AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size __initial_sp Heap_Size EQU 0x00000200 AREA HEAP, NOINIT, READWRITE, ALIGN=3 __heap_base Heap_Mem SPACE Heap_Size __heap_limit PRESERVE8 THUMB ; Vector Table Mapped to Address 0 at Reset AREA RESET, DATA, READONLY EXPORT __Vectors EXPORT __Vectors_End EXPORT __Vectors_Size __Vectors DCD WWDG_IRQHandler DCD PVD_IRQHandler DCD TAMP_STAMP_IRQHandler DCD RTC_WKUP_IRQHandler DCD FLASH_IRQHandler DCD RCC_IRQHandler DCD EXTI0_IRQHandler DCD EXTI1_IRQHandler DCD EXTI2_IRQHandler DCD EXTI3_IRQHandler DCD EXTI4_IRQHandler DCD DMA1_Stream0_IRQHandler DCD DMA1_Stream1_IRQHandler DCD DMA1_Stream2_IRQHandler DCD DMA1_Stream3_IRQHandler DCD DMA1_Stream4_IRQHandler DCD DMA1_Stream5_IRQHandler DCD DMA1_Stream6_IRQHandler DCD ADC_IRQHandler DCD CAN1_TX_IRQHandler DCD CAN1_RX0_IRQHandler DCD CAN1_RX1_IRQHandler DCD CAN1_SCE_IRQHandler DCD EXTI9_5_IRQHandler DCD TIM1_BRK_TIM9_IRQHandler DCD TIM1_UP_TIM10_IRQHandler DCD TIM1_TRG_COM_TIM11_IRQHandler DCD TIM1_CC_IRQHandler DCD TIM2_IRQHandler DCD TIM3_IRQHandler DCD TIM4_IRQHandler DCD I2C1_EV_IRQHandler DCD I2C1_ER_IRQHandler DCD I2C2_EV_IRQHandler DCD I2C2_ER_IRQHandler DCD SPI1_IRQHandler DCD SPI2_IRQHandler DCD USART1_IRQHandler DCD USART2_IRQHandler DCD USART3_IRQHandler DCD EXTI15_10_IRQHandler DCD RTC_Alarm_IRQHandler DCD OTG_FS_WKUP_IRQHandler DCD TIM8_BRK_TIM12_IRQHandler DCD TIM8_UP_TIM13_IRQHandler DCD TIM8_TRG_COM_TIM14_IRQHandler DCD TIM8_CC_IRQHandler DCD DMA1_Stream7_IRQHandler DCD FMC_IRQHandler DCD SDIO_IRQHandler DCD TIM5_IRQHandler DCD SPI3_IRQHandler DCD UART4_IRQHandler DCD UART5_IRQHandler DCD TIM6_DAC_IRQHandler DCD TIM7_IRQHandler DCD DMA2_Stream0_IRQHandler DCD DMA2_Stream1_IRQHandler DCD DMA2_Stream2_IRQHandler DCD DMA2_Stream3_IRQHandler DCD DMA2_Stream4_IRQHandler DCD ETH_IRQHandler DCD ETH_WKUP_IRQHandler DCD CAN2_TX_IRQHandler DCD CAN2_RX0_IRQHandler DCD CAN2_RX1_IRQHandler DCD CAN2_SCE_IRQHandler DCD OTG_FS_IRQHandler DCD DMA2_Stream5_IRQHandler DCD DMA2_Stream6_IRQHandler DCD DMA2_Stream7_IRQHandler DCD USART6_IRQHandler DCD I2C3_EV_IRQHandler DCD I2C3_ER_IRQHandler DCD OTG_HS_EP1_OUT_IRQHandler DCD OTG_HS_EP1_IN_IRQHandler DCD OTG_HS_WKUP_IRQHandler DCD OTG_HS_IRQHandler DCD DCMI_IRQHandler DCD CRYP_IRQHandler DCD HASH_RNG_IRQHandler DCD FPU_IRQHandler DCD UART7_IRQHandler DCD UART8_IRQHandler DCD SPI4_IRQHandler DCD SPI5_IRQHandler DCD SPI6_IRQHandler DCD SAI1_IRQHandler DCD LTDC_IRQHandler DCD LTDC_ER_IRQHandler DCD DMA2D_IRQHandler __Vectors_End __Vectors_Size EQU __Vectors_End - __Vectors AREA |.text|, CODE, READONLY ; Reset handler ; Dummy Exception Handlers (infinite loops which can be modified) ;HERE ARE THE DEFAULT_HANDLERS -> DELETED BECOUSE I ONLY CAN POST 7000 Chars B . ENDP ALIGN IF :DEF:__MICROLIB EXPORT __initial_sp EXPORT __heap_base EXPORT __heap_limit ELSE IMPORT __use_two_region_memory EXPORT __user_initial_stackheap __user_initial_stackheap LDR R0, = Heap_Mem LDR R1, =(Stack_Mem + Stack_Size) LDR R2, = (Heap_Mem + Heap_Size) LDR R3, = Stack_Mem BX LR ALIGN ENDIF END
Heap_Size EQU 0x00000200 ; this line will determine the size of the heap allocation
Hello Clive,
i know its irritating - but can you explain how i should change this section?
Thanks / The solution of your Link / google link i can not transfer for me. I'm not so familiar with the SDRAM and Scatterfile / Mappings ...
I just don't understand why it needs to be explained in such painful detail, may be if you're a student, or have no programming experience, perhaps you can provide some context. May be you need to experiment and think a bit, read associated documentation, and CS texts.
So let's recap:
The heap here is set for 512 bytes, as you've got 4MB or so, perhaps you can expand this to a much bigger number of bytes which you can allocate with malloc(), calloc(), etc. Dynamic memory in this context is helpful because it's large, the memory is slow, and it won't eat into the "size" the evaluation copies of Keil limit you too. You have to make decisions on how you best use the resources you have available, and there suitability to specific tasks.
You can direct the HEAP, and specific static allocations into SDRAM using the earlier supplied scatter-file or equivalent. You probably want most static allocations into regular SRAM, along with the STACK, because it's materially faster the SDRAM in the cacheless Cortex-Mx family. Also if your statics have initializers that's going to eat into the FLASH load region which must copy out to SDRAM/SRAM at startup. That initialization is done in __main, before your main() is called, and after you've initialize the external memory and buses in SystemInit().
; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_IROM1 0x08000000 0x00200000 { ; load region size_region (2M) ER_IROM1 0x08000000 0x00200000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x20000000 0x00030000 { ; RW data (192K) .ANY (+RW +ZI) } RW_IRAM2 0xD0000000 0x00400000 { ; SDRAM (4M) the name is arbitrary startup_stm32f429_439xx.o (HEAP) ; Name of Object matching your startup_xxx.s name *(.sdram) ; All sections tagged as .sdram from All objects } }
char buf[256] __attribute__ ((section(".sdram"))); // static allocation from SDRAM
unsigned char *sdrambuf = malloc(1024 * 1024); // dynamic allocation from HEAP in SDRAM
i did the following changes. I changed the value from the HEAP_SIZE to more or less 4MB. My Map-File looks now like the following, it's only a piece from it:
//Buf is the Variable which should be located in SDRAM -> The Adress 0xd000... is correct buf 0xd0000000 Data 256 system_stm32f4xx.o(.sdram) Execution Region RW_IRAM2 (Base: 0xd0000000, Size: 0x00400000, Max: 0x00400000, ABSOLUTE) Base Addr Size Type Attr Idx E Section Name Object 0xd0000000 0x00000100 Data RW 3019 .sdram system_stm32f4xx.o 0xd0000100 0x003fff00 Zero RW 2 HEAP startup_stm32f429_439xx.o
Now Im trying to debug the Project step by step to try to understand the problems like you told me. Im started by the startup file and then i go through the SystemInit Function called in the Startup - File / everything works fine. In this function is the ExtMem_Ctl() called. When im debugging there step by step, the error occures in the following line:
FMX_Bank5_6->SDCR[0] = 0x000029D0
The Error which occures is: Cannot access target. Shutting down debug session.
The SDRAM works fine jet. Thanks for your support clive, but my mistake was a wrong define. One last question, how fast is the external SDRAM?
Is there a big difference between the internal local Storage and the external SDRAM ?
Thanks
Dear Clive,
Can you give me the download link again?
I follow the exactly the same as your suggestion in forum.
But I still don't know how to create SystemInit_ExtMemCtl(); in STM32F769 Discovery board.
Please send me the example project file.
Thanks.
Regards, Thiha Kyaw