硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1623|回复: 9
收起左侧

[BOOT/IAP] STM32CubeIDE生成的STM32H7工程如何实现将CODE放入RAM执行

[复制链接]

2

主题

9

回帖

15

积分

新手上路

积分
15
发表于 2024-9-20 17:07:50 | 显示全部楼层 |阅读模式
项目开发使用的H743IIT6具有较大的RAM空间,目前想将固件整个拷贝到地址段0x24000000-0x2403FFFF运行以提高代码整体运行速率。参考了很多网上攻略,进行了多种尝试均未成功,不知道这个坑在哪里,因此发帖希望能够得到一点启发。

我的代码分Bootloader和APP两部分,其中Bootloader负责固件更新检查,最后直接到APP的Reset_Handler。

我的操作包括:
1)APP使用的.ld文件如下:


/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1);    /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x3000;      /* required amount of heap  */
_Min_Stack_Size = 0x3000; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
  FLASH (rx)     : ORIGIN = 0x08020000, LENGTH = 1920K
  DTCMRAM (xrw)  : ORIGIN = 0x20000000, LENGTH = 128K
  RAM_EXEC (xrw) : ORIGIN = 0x24000000, LENGTH = 256K
  RAM_D1 (xrw)   : ORIGIN = 0x24040000, LENGTH = 256K
  RAM_D2 (xrw)   : ORIGIN = 0x30000000, LENGTH = 288K
  RAM_D3 (xrw)   : ORIGIN = 0x38000000, LENGTH = 64K
  ITCMRAM (xrw)  : ORIGIN = 0x00000000, LENGTH = 64K
  SDRAM_1 (xrw)  : ORIGIN = 0xD0000000, LENGTH = 32M
}

/* Define output sections */
SECTIONS
{
  /* The startup code goes first into RAM_EXEC */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >RAM_EXEC AT> FLASH

  /* The program code and other data goes into RAM_EXEC */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
  } >RAM_EXEC AT> FLASH

  /* Constant data goes into RAM_EXEC */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  }  >RAM_EXEC AT> FLASH

  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >RAM_EXEC AT> FLASH
  .ARM : {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  }  >RAM_EXEC AT> FLASH

  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } >RAM_EXEC AT> FLASH

  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } >RAM_EXEC AT> FLASH

  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } >RAM_EXEC AT> FLASH

  /* used by the startup to initialize data */  
  _sidata = LOADADDR(.data);

  /* Initialized data sections goes into RAM, load LMA copy after code */
  .data :
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */
    *(.RamFunc)        /* .RamFunc sections */
    *(.RamFunc*)       /* .RamFunc* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } >RAM_D1 AT> FLASH

  /* Uninitialized data section */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM_D1

  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM_D1 /*>DTCMRAM */ /*>RAM_D1*/
  
  .preset_sec (NOLOAD) :
  {
    . = ALIGN(4);

  } >DTCMRAM  

  .dtcmram_sec (NOLOAD):
  {
     
  } >DTCMRAM AT> FLASH
  
  .itcmram_sec (NOLOAD) :
  {
    . = ABSOLUTE(0x00000008);  /*让出地址0x0,防止与NULL指针判断冲突*/
    . = ALIGN(8);
  } >ITCMRAM

  /* ETH_CODE: add placement of DMA descriptors and RX buffers */
  .lwip_sec (NOLOAD) :
  {  
          . = ABSOLUTE(0x30000000);
    KEEP ( *(.RxDecripSection) )
   
    . = ABSOLUTE(0x30000100);
    KEEP ( *(.TxDecripSection) )
   
   . = ABSOLUTE(0x30000200);
   /*KEEP (  *(.Rx_PoolSection)  )  
    . = ABSOLUTE(0x30000000); */
    KEEP ( *(.lwipram) )
   
  } >RAM_D2 AT >FLASH

  .ram3_sec (NOLOAD) :
  {
          . = ABSOLUTE(0x38000000);
          KEEP ( *(.ram3))
  } >RAM_D3  
  
  .sdram1_sec (NOLOAD) :
  {
          . = ABSOLUTE(0xD0000000);
          KEEP ( *(.sdram1) )
  } >SDRAM_1   
  
  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }
}


其中的RAM_EXEC 就是准备用来放置全部code的空间。

固件编译链接后的.list文件中确认已将全部函数及中断向量表都转移到RAM_EXEC中了。

在Bootloader中直接将存放在起始地址为0x08020000的flash空间数据直接拷贝到RAM_EXEC,并修改跳转指针指向RAM_EXEC中的Reset_Handler。

此外,在system_stm32h7xx.c文件中追加了宏定义#define VECT_TAB_SRAM
以确保中断向量表寻址正确。

经过上述修改后分别下载Bootloader和APP固件到测试板,上电后程序无法正常运行。
我随后修改.ld文件,将全部存放于FLASH的内容都转移到RAM中,代码下载后是可以正常运行的,说明我对于中断向量表这块的改动是成功的,但在实现代码从FLASH向RAM搬运和跳转控制上存在问题。
哪位大侠对这个有研究啊?

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115490
QQ
发表于 2024-9-20 17:25:42 | 显示全部楼层
之前做了个MDK版的,供参考

制作了一个通过BOOT复制APP程序到AXI SRAM运行的案例,适合H750,H7B0玩
https://www.armbbs.cn/forum.php? ... 2748&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

2

主题

9

回帖

15

积分

新手上路

积分
15
 楼主| 发表于 2024-9-23 09:38:49 | 显示全部楼层
本帖最后由 lorelia 于 2024-9-23 09:41 编辑

链接里那个源码没法下载C:\Users\Administrator\Desktop\捕获.PNG
我的网盘里保存过这个例程(V7-012_串口和PC机通信(驱动支持8串口FIFO)),但是版本不够新,用KEIL打开后没有找到那个CpuRAM的选项。
能再提供一下有效的下载链接吗
捕获.PNG
回复

使用道具 举报

2

主题

9

回帖

15

积分

新手上路

积分
15
 楼主| 发表于 2024-9-23 09:53:36 | 显示全部楼层
eric2013 发表于 2024-9-20 17:25
之前做了个MDK版的,供参考

制作了一个通过BOOT复制APP程序到AXI SRAM运行的案例,适合H750,H7B0玩

链接里的例程源码无法下载。我从置顶贴中的网盘下载链接去下载V7-012_串口和PC机通信(驱动支持8串口FIFO).rar,用KEIL打开,没有CpuRAM这个工程选项,只有FLash。
版主能提供一下新版例程的下载链接吗?
回复

使用道具 举报

4

主题

89

回帖

101

积分

初级会员

积分
101
发表于 2024-9-23 11:44:51 | 显示全部楼层
lorelia 发表于 2024-9-23 09:53
链接里的例程源码无法下载。我从置顶贴中的网盘下载链接去下载V7-012_串口和PC机通信(驱动支持8串口FIFO ...

是下不了
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115490
QQ
发表于 2024-9-24 09:31:31 | 显示全部楼层
lorelia 发表于 2024-9-23 09:38
链接里那个源码没法下载
我的网盘里保存过这个例程(V7-012_串口和PC机通信(驱动支持8串口FIFO)),但是 ...

刚刚测试了二楼提供的链接,可以下载,看看是不是浏览器阻拦了。

如果浏览器阻拦的话,可以获取地址后,复制到迅雷下载


234.png

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115490
QQ
发表于 2024-9-24 09:33:14 | 显示全部楼层

刚刚测试了二楼提供的链接,可以下载,看看是不是浏览器阻拦了。

如果浏览器阻拦的话,可以获取地址后,复制到迅雷下载



回复

使用道具 举报

2

主题

9

回帖

15

积分

新手上路

积分
15
 楼主| 发表于 2024-9-24 16:57:32 | 显示全部楼层
谢谢版主,的确是换了个浏览器就可以下载了。
看了一下BOOT的文件,对照检查了我的bootloader处理方法,确认OK。
现在我面临的问题是无法得到一个直接放入RAM就可以运行的源码,就是main.c中复制到0x24000000地址的数据源_acoutput:
        /* 复制程序到AXI SRAM里面 */
        memcpy((char *)0x24000000, _acoutput, sizeof(_acoutput));
我是在STM32CubeIDE环境下生成整个工程代码,通过修改.ld文件能够将代码直接下载到RAM运行,但不知道应该如何生成基于RAM地址分配的HEX文件,而对应的BIN文件尺寸则非常大。
我应该怎么做呢?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115490
QQ
发表于 2024-9-25 09:18:34 | 显示全部楼层
lorelia 发表于 2024-9-24 16:57
谢谢版主,的确是换了个浏览器就可以下载了。
看了一下BOOT的文件,对照检查了我的bootloader处理方法,确 ...

“而对应的BIN文件尺寸则非常大”

这个把你可以看下你的hex文件地址分配,应该是你通过attribute设置到其它地址范围的RAM了,导致生的bin出现将两个地址连接的情况,这个间隔导致bin非常大。
回复

使用道具 举报

4

主题

89

回帖

101

积分

初级会员

积分
101
发表于 2024-9-25 09:26:49 | 显示全部楼层
eric2013 发表于 2024-9-24 09:33
刚刚测试了二楼提供的链接,可以下载,看看是不是浏览器阻拦了。

如果浏览器阻拦的话,可以获取地址后 ...

可能是网络问题或者拦截了,现在是可以了,谢谢硬汉
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-4-28 22:49 , Processed in 0.476693 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表