Skip to main content
Visitor II
December 20, 2023
Solved

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

  • December 20, 2023
  • 5 replies
  • 7173 views

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.
    Best answer by briankaz

    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!

    5 replies

    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

    briankazAuthor
    Visitor II
    December 20, 2023

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

    Super User
    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.

     

    briankazAuthor
    Visitor II
    December 21, 2023

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

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

    Graduate II
    December 21, 2023

    No, that's 24KB

    0x20000 is 128KB

    0x40000 is 256KB

    0x80000 is 512KB

     

    Super User
    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.

    briankazAuthor
    Visitor II
    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?



    Super User
    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);

     

    briankazAuthor
    Visitor II
    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.

    Super User
    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.

    briankazAuthor
    Visitor II
    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