cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H750, linkerscript internal RAM definition...

pk84
Senior

Hello, 

I'm trying to understand the linkerscript file because I have a RAM overflow error.

As far as I understand the STM32H750 has 1MB internal RAM, why is it only set to 128K in the LTDC_Paint example, see screenshot below?

Thank you

0693W00000Uol9AQAR.png

6 REPLIES 6
pk84
Senior

BTW: which file starts the linkerscript-file?

The linker? LD

Probably shouldn't attribute too much weight to the script content. Check if README for project explains any details/choices, like about which buses or bus matrix functionality play into things, and where specific blocks of memory are placed within the design, and distance from MCU and Peripherals. Check the Reference Manual to understand the topology and sizing. The H7 is a funny beast in that it was originally conceived as a multi-core design, and a lot of peripherals and memory are parked away from the main CM7 core, to where the CM4 one lives, if enabled. For efficiency you need to make choices about which memories are best to use and which cause the least bus contention vs code execution, etc.

The linker is pretty dumb, it was designed for build Linux apps and kernels, not embedded code with sparsely placed memories. It's not going to automatically pick and chose memory regions, or span data/code across multiple regions. These tools tend to parse linearly, and don't do a lot of passes to find the best-fit, or remove all dead code/objects.

Examples are designed to illustrate specific function, not be an end product. They are often put together hastily, along with other work tasks. They are often a check-box item, does the peripheral work, is there a quick example.

These are not validation applications.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
JPeac.1
Senior

An STM32H7 with 1MB SRAM would most likely be an STM32H753 variant, so I'll use it as an example. The linker script line defining flash starting at 0x9000 0000 informs the linker the program storage flash will be the external QUADSPI NOR flash, starting at address 0x9000 0000 to 0x9FFF FFFF, or 0x9001 FFFF for a 128KB component. This looks wrong since none of the generated code will be linked to run in the internal flash. It implies whatever project you are building is an image designed to run (very slowly) from external memory.

Placing code in the QUADSPI would assume your board is jumpered to boot from external QUADSPI flash rather than internal FLASH.

Internal SRAM is divided into several regions, some optimized for code, some for data. The ITCM, fast (zero wait state) executable code RAM starts at 0x0000 0000 to 0x0000 FFFF, or 64KB. This corresponds to the ITCMRAM definition in the linker script. Normally you would build a section of code that is targeted for fast execution from RAM by placing it in this region. This is not ideal if you need more than 64KB for data.

The DTCM fast (again, zero wait state) SRAM region is located at 0x2001 0000 to 0x2001 FFFF, the 128KB region for optimized data access. this is not the large memory array, the reason you are getting RAM overflow errors.

SRAM1, the large SRAM region, is located at 0x3000 0000 to 0x3007 FFFF, the 512KB region you are looking for. SRAM is located at 0x30020000 to 0x3003 FFFF, a 256KB region. SRAM3 is located at 0x3004 0000 to 0x3004 7FFF, a 32KB region. SRAM4 is at 0x3800 0000 to 0x3800 FFFF, the last 64KB area. Each SRAM region has a separate access so that CPU and DMA access can run in parallel if you are clever about placing variables and buffers

You can use SRAM1 through SRAM3 as one contiguous RAM area if you don't require overlapped bus access for DMA. Your RAM linkerscript entry should be changed to ORIGIN = 0x3000 0000, LENGHTH = 800KB (that's 512 + 256 + 32). _estack = 0x3801 0000 will put the stack at the top of this area.

Disclaimer: the memory map can change depending on STM32H7 variant, so check the datasheet on memory map for the version you have. Also, this is grossly simplified. Tuning an app for memory placement takes some experience in order to optimize bus access and non-cache wait states. The bus matrix on the STM32 series is one of the most powerful yet largely ignored benefits over other vendors.

Jack Peacock

Pavel A.
Evangelist III

> STM32H750 has 1MB internal RAM

Anyway, this 1 MB is not contiguous. The area at 0x20000000 is only 128KB, Other RAM pieces are at different addresses.

The largest piece is 512K at 0x24000000.

Where have you found this .ld file? Generate a new project, the Cube should get a better .ld. 

Of course if the chip is not authentic, all bets are off (-_-)

pk84
Senior

0693W00000VO7uTQAT.jpg0693W00000VO7y5QAD.jpg0693W00000VO7xbQAD.jpg 

0693W00000VO7xRQAT.jpgThank you very much for these detailed answers.

I have replaced the two linker scripts with the one generated by CubeMx, and changed FLASH adress/size as below:

/* Specify the memory areas */
MEMORY
{
  FLASH (rx)     : ORIGIN = 0x90000000, LENGTH = 2048K
  DTCMRAM (xrw)  : ORIGIN = 0x20000000, LENGTH = 128K
  RAM_D1 (xrw)   : ORIGIN = 0x24000000, LENGTH = 512K
  RAM_D2 (xrw)   : ORIGIN = 0x30000000, LENGTH = 288K
  RAM_D3 (xrw)   : ORIGIN = 0x38000000, LENGTH = 64K
  ITCMRAM (xrw)  : ORIGIN = 0x00000000, LENGTH = 64K
}

Why I ask, I have two problems:

Basically the LVGL work with all demos except the music demo, here I have quite strange effects as seen in the attached pictures. I would appreciate any advice.

Then I would like to change the LVGL display buffer to the internal RAM, according to the code below, but then the picture freezes, as shown in the picture pic-4 / frozen.jpg

	//int RAM
	static lv_disp_draw_buf_t disp_buf_1;
	static lv_color_t buf1_1[480 * 61];
	static lv_color_t buf1_2[480 * 61];
	lv_disp_draw_buf_init(&disp_buf, buf1_1, buf1_2, Lcd_Ctx[LCD_INSTANCE].XSize * Lcd_Ctx[LCD_INSTANCE].YSize);
 
 
	//ext RAM
	//lv_disp_draw_buf_init(&disp_buf, (void*)LVGL_BUFFER_ADDR_AT_SDRAM,
			//(void*)LVGL_BUFFER_2_ADDR_AT_SDRAM,
			//Lcd_Ctx[LCD_INSTANCE].XSize * Lcd_Ctx[LCD_INSTANCE].YSize); /*Initialize the display buffer*/
 
	//lv_disp_drv_init(&disp_drv);

>You can use SRAM1 through SRAM3 as one contiguous RAM area if you don't require >overlapped bus access for DMA. Your RAM linkerscript entry should be changed to ORIGIN = >0x3000 0000, LENGHTH = 800KB (that's 512 + 256 + 32). _estack = 0x3801 0000 will put the >stack at the top of this area.

@Community member​ 

Are you sure that SRAM1 + SRAM3 can be used contiguous with STM32H750xB for LTDC ...?

It seems that LTDC can only use AXI SRAM (512 k) - see RM RM0433, Table 3. Bus-master-to-bus-slave interconnect. For me it looks SRAM 1-3 cannot be used by LTDC, see also 2.1.6.

Thank you