Skip to main content
briankaz
Associate III
December 20, 2023
Solved

How to set up IRAM1/IRAM2 in Keil with STM32H742VIT6?

Hello,

I'm having weird problems with code crashing, perhaps related to how I have IRAM1/IRAM2 set up in my project:

briankaz_1-1703032836804.png

Looking in the reference manual, I see that the SRAM starting at 0x2000_0000 is the DTCM_RAM on TCM interface (data RAM?), the SRAM starting at 0x2400_0000 is the D1 domain, AXI SRAM but I don't see any documentation for how big either of these are.  I also can't figure out what is meant in Keil by IRAM1 vs. IRAM2 (Google is not very helpful), although I suspect that question might not be within the scope of the STM forums...

If anyone can help with this I will really appreciate it!
Thanks,
-Brian

This topic has been closed for replies.
briankaz
briankazBest answer
Associate III
December 29, 2023

I edited the stack size in startup_stm32h742xx.s.  It used to be 0x400 and I changed it thus:

Stack_Size		EQU 0x800

Problem solved!

I'm still not sure why this project needs a bigger stack than an equivalent project on an STM32F3* MCU, but I'll take it!

17 replies

lbui
Visitor II
December 20, 2023

 

Simple way is edit your linker file:

 

uint8_t __attribute__(( section(".ram1section") )) buf[1000];

 

.ram1block (NOLOAD) :

  {

    KEEP(*(.ram1section))

  } > RAM_D1

briankaz
briankazAuthor
Associate III
December 20, 2023

Sorry, but I don't understand a single line of the code you wrote... :(

TDK
December 20, 2023

Memory sizes are in the datasheet and reference manual.

TDK_0-1703039099081.png

You have AXI SRAM set to 0x80000 but its size is only 0x60000. Could be the issue, could be issues with the code itself.

 

IRAM = internal RAM. This is Keil terminology.

 

"If you feel a post has answered your question, please click ""Accept as Solution""."
briankaz
briankazAuthor
Associate III
December 21, 2023

Ok wait a minute — isn’t 384kB actually 0x6000 and not 0x60000?

EDIT:  Sorry, I was getting 0000 confused with 000!

Tesla DeLorean
Guru
December 21, 2023

No, that's 24KB

0x20000 is 128KB

0x40000 is 256KB

0x80000 is 512KB

 

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
TDK
December 27, 2023

If global variables are being overwritten, you probably have bad/buggy code resulting in a stack overflow or some other out-of-bounds memory access.

If you know what is being overwritten, you can set a hardware watchpoint at that memory address which will break when the offending code modifies it.

"If you feel a post has answered your question, please click ""Accept as Solution""."
briankaz
briankazAuthor
Associate III
December 27, 2023

I already know one line of code which was causing one of these io_handle structures to be overwritten (I zeroed in on it by setting breakpoints and examining memory).  It was the function get_curr_frmw_info() illustrated here:

 

__NO_RETURN int main(void)
{
 img_header_t img_hdr;
 get_curr_frmw_info(&img_hdr);
}

static void get_curr_frmw_info(img_header_t *header)
{
 memcpy(header, (void *) IMG_INFO_ADDR, sizeof(img_header_t));
}

 

So that memcpy() was the culprit.  But how does this help us understand WHY a static-defined structure that should have been left alone was overwritten?



TDK
December 27, 2023

> But how does this help us understand WHY a static-defined structure that should have been left alone was overwritten?

There is no protection mechanism on global variables that prevents them from being overwritten by bad code (i.e. out of bounds access, stack overflow, etc). Why do you think that shouldn't be possible?

 

> So that memcpy() was the culprit.

Likely nothing wrong with memcpy here. You're passing a value instead of a pointer to that value.

 img_header_t img_hdr;
 get_curr_frmw_info(img_hdr);

...

static void get_curr_frmw_info(img_header_t *header)

Should be:

get_curr_frmw_info(&img_hdr);

 

"If you feel a post has answered your question, please click ""Accept as Solution""."
briankaz
briankazAuthor
Associate III
December 27, 2023

Sorry! I copied the new version of that line of code and forgot to add the ampersand. Of course it was “&img_hdr” in the original code as you suggested.

TDK
December 28, 2023

> static bsp_io_handle_t *io_handle;

The pointer to the structure is static, but the structure itself is dynamically allocated since you call malloc. Note that the "static" keyword here doesn't do a whole lot. If you want statically allocated structure, the proper code would be:

bsp_io_handle_t io_handle;

Tack "static" on the front if you want, but it doesn't do much.

A stack overflow would explain the issue, and that's about it. Look at where the structures are in memory and ensure they don't overlap. You can step through memcpy if you want--unlikely to be any problems with it.

"If you feel a post has answered your question, please click ""Accept as Solution""."
briankaz
briankazAuthor
Associate III
December 28, 2023

OK I think I'm getting somewhere now.

I’ve reverted the code to the original static declarations and removed the malloc()/free() calls.

The IRAM1/IRAM2 settings are as in the screenshot at the top except that I've changed the IRAM2 size to 0x60000.

In debug mode, I noticed that the static structures are being placed in memory around 0x24000230-0x24000400.  Also, the stack pointer is jumping around close to these addresses.  So it seems like the stack memory is overlapping with the memory that should have been reserved for zero-initialized data (static structures).  How does the compiler even allow something like this to happen?  I can't find any settings in Keil controlling where the stack memory should be.

I would have thought the zero-initialized data would be placed at the lower available IRAM address (0x20000000) but that is not what the compiler did...

Ideas welcome!

Thanks!
-Brian