cancel
Showing results for 
Search instead for 
Did you mean: 

Using SRAM instead of DTCM on STM32H7?

ASmith
Associate II

Hi All,

I am developing an application for the STM32H753II using IAR toolchain, STM HAL and Micrium OS-II.

Most of the linker script files in the STM32Cube example suite only specify DTCM RAM for data storage (addresses 0x20000000-0x2001FFFF). I have been using the stm32h753xx_flash.icf (with only DTCM region specified) file with no issues up until now. I now need more RAM space.

I have been attempting to use the chip's SRAMs however each time I change the linker to place data there, my application starts crashing somewhere in the init to UsageFault due to a jump to address 0x0...

EDIT: I've narrowed down the instruction that breaks. At the end of an OS function when it's supposed to branch to the calling function, the instruction POP {R0, R4, R5, PC} is executed which is supposed to branch to a location in flash but instead it branches to 0x00000000. It tries to execute code from there and ends up in a UsageFault. Hope this adds useful context.

EDIT 2: Turning off D-Cache seems to solve this problem. As Clive suggests below, this is likely a coherency issue. Need to investigate.

I have also tried using the linker script provided by IAR which comprehensively mapped all of the chip's memory. This lead to the same error.

Here is the working linker file:

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__     = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__       = 0x081FFFFF;
define symbol __ICFEDIT_region_RAM_start__     = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__       = 0x2001FFFF;
define symbol __ICFEDIT_region_ITCMRAM_start__ = 0x00000000;
define symbol __ICFEDIT_region_ITCMRAM_end__   = 0x0000FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__   = 0x200;
/**** End of ICF editor section. ###ICF###*/
 
 
define memory mem with size = 4G;
define region ROM_region      = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region RAM_region      = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];
define region ITCMRAM_region  = mem:[from __ICFEDIT_region_ITCMRAM_start__ to __ICFEDIT_region_ITCMRAM_end__];
 
define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };
 
initialize by copy { readwrite };
do not initialize  { section .noinit };
 
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
 
place in ROM_region   { readonly };
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };

Here is the linker file that creates the issue:

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__     = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__       = 0x081FFFFF;
define symbol __ICFEDIT_region_RAM_start__     = 0x30000000;
define symbol __ICFEDIT_region_RAM_end__       = 0x3001FFFF;
define symbol __ICFEDIT_region_ITCMRAM_start__ = 0x00000000;
define symbol __ICFEDIT_region_ITCMRAM_end__   = 0x0000FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__   = 0x200;
/**** End of ICF editor section. ###ICF###*/
 
 
define memory mem with size = 4G;
define region ROM_region      = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region RAM_region      = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];
define region ITCMRAM_region  = mem:[from __ICFEDIT_region_ITCMRAM_start__ to __ICFEDIT_region_ITCMRAM_end__];
 
define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };
 
initialize by copy { readwrite };
do not initialize  { section .noinit };
 
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
 
place in ROM_region   { readonly };
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };

Notice all I changed was for the RAM_start and RAM_end to be mapped to SRAM1 of the micro. I've also tried calling the following three macros to enable the SRAM clocks to no avail:

    __HAL_RCC_D2SRAM1_CLK_ENABLE();
    __HAL_RCC_D2SRAM2_CLK_ENABLE();
    __HAL_RCC_D2SRAM3_CLK_ENABLE();

Is there something I am missing? Thanks guys!

1 ACCEPTED SOLUTION

Accepted Solutions

The processor shouldn't have an issue keeping the content straight.

I'd probably try to bisect the issue, use the MPU to sub-divide areas where the cache is enabled/disabled, and move selective things into different memories (ie STACK)

Issues with optimization on/off tend to be a bit different, as they usually indicate latent issues with the code, and lack of volatile usage when appropriate.

Perhaps you can run lint or similar static analysis tools to see if those flag up code that's unsafe.

Be careful of code using SCB_InvalidateDCache() functions.

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

View solution in original post

7 REPLIES 7

Probably would not put the initial stack in memory whose clocks I need to enable later.

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

That's fair. I have left the initial stack + heap in DTCM and placed all readwrite in SRAM - my code still exhibits the same behavior. I was under the impression that SRAM clocks should be default on after reset which means I shouldn't have to call the HAL functions to enable them. Is this understanding correct? I have tried all of the SRAMs available and each time my code makes that branch to 0x0 at the same spot.

Thanks for getting back to me on this!

ASmith
Associate II

After disabling D-Cache, the issue is no longer present... I will have to investigate why this is. It seems like this is a recurring issue for me with almost every high-speed micro I use.

That really suggests you've got some coherency issues. Turning off the cache is going to slow stuff down substantially. Are you using DMA into buffers or something?

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

Yeah that's what I am thinking also. Although, I am not sure how to pinpoint it. I am not using DMA.

The processor shouldn't have an issue keeping the content straight.

I'd probably try to bisect the issue, use the MPU to sub-divide areas where the cache is enabled/disabled, and move selective things into different memories (ie STACK)

Issues with optimization on/off tend to be a bit different, as they usually indicate latent issues with the code, and lack of volatile usage when appropriate.

Perhaps you can run lint or similar static analysis tools to see if those flag up code that's unsafe.

Be careful of code using SCB_InvalidateDCache() functions.

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

Thanks for the advice. I am going to investigate and report back after some static analysis.