当前位置: 首页 > 工具软件 > CCM > 使用案例 >

STM32 CCM内存使用

茅才
2023-12-01

使用 CCM 内存

一些STM32 CPU包括两组存储器:标准SRAM和另一组存储器(又名CCM),它们可能比标准SRAM更快,通常更小。

为此,有几种可能性,具体取决于程序所需的内存量。在所有情况下,您可能需要手动编辑链接器脚本文件(LinkerScript.ld,link.lds 除非由 CubeMX 生成,其名称取决于芯片引用)。

检查是否声明了 CCM

必须首先查找“内存”部分,如果它不存在,请添加一行,如下所示
CCMRAM (rw)      : ORIGIN = 0x10000000, LENGTH = 64K
(当然,您必须检查CCM块的地址;这来自STM32F407芯片)。

在 CCM 中放置完整的数据部分

然后,必须决定哪些部分必须放在 CCM 中。

将所有初始化的数据放在 CCM 中

这很简单可以通过更改读取
} >RAM AT> FLASH
在 .data 部分的末尾
} >CCMRAM AT> FLASH

将所有zero-initialized的数据放在 CCM 中

还可以通过更改读取
} >RAM
在 .bss 部分的末尾
} >CCMRAM

将单个变量放在 CCM 中

可以将单个变量放在 CCRAM 区域中,尽管这可能有点复杂。

未初始化的变量放在 CCM 中

可以非常简单地将未初始化的变量放置在CCM中,方法是在其定义中添加一个部分属性,例如,变量in_ccmram_buffer通过以下方式声明它:
char in_ccram_buffer[1024] __attribute__((section("ccmram")));
(是的,在这种丑陋的语法中有双下划线和双括号,主要是为了确保您不会错误地使用它...)如果它不存在,则必须通过以下方式创建 .ccmram 节:

如果存在,在链接器脚本中要注意不要将ythe变量初始化,即使初始化为零,因为它会占用flash中的空间;(可选)您可以在默认 .ccmram 节定义的末尾禁止显示 AT> FLASH 姿势。

zero-initialized变量放在 CCM 中

默认情况下,按属性放置在 CCMRAM 中的变量无法初始化,甚至无法初始化为zero。

如果需要将它们初始化为zero,zero则必须修改startup_stm32xxxxx.S 文件,用于添加第二个zero-initialization 循环(使用符号 _sccmram 和 _eccmram),方法是复制 bss 的代码,紧跟在其最终的bcc FillZerobs 之后,将其修改为如下所示:
ldr	r2, =_sccmram
	b	 LoopFillZeroCcm
/* Zero fill the ccmram segment. */
FillZeroCcm:
	movs r3, #0
 	str  r3, [r2]
	adds r2, r2, #4

LoopFillZeroCcm:
	ldr	r3, = _eccmram
	cmp	r2, r3
	bcc	FillZeroCcm

将初始化的数据放在 CCM 中

反之,可以通过将初始化的变量放在 .ccmidata 部分中来创建初始化的 ccmram 数据部分。

必须首先通过以下方式在链接器脚本中定义此部分:
_siccmram = LOADADDR(.ccmram); /* May be already present */

  /* Initialized CCM-RAM section 
  * 
  * IMPORTANT NOTE! 
  * If initialized variables will be placed in this section, 
  * the startup code needs to be modified to copy the init-values.  
  */
  .ccmidata : 
  {
    . = ALIGN(4);
    _sccmidata = .;        /* create a global symbol at data start */
    *(.ccmidata)           /* .data sections */
    *(.ccmidata*)          /* .data* sections */

    . = ALIGN(4);
    _eccmidata = .;        /* define a global symbol at data end */
  } >CCMRAM AT> FLASH
必须复制数据部分代码(使用符号_siccmram_sccmidata_eccmidata),紧跟  bcc CopyDataInit 之后:
/* Copy the ccm segment initializers from flash to SRAM */
  movs	r1, #0
  b	LoopCopyCcmInit

CopyCcmInit:
	ldr	r3, =_siccmdata
	ldr	r3, [r3, r1]
	str	r3, [r0, r1]
	adds	r1, r1, #4

LoopCopyCcmInit:
	ldr	r0, =_siccmdata
	ldr	r3, =_eiccmdata
	adds	r2, r0, r1
	cmp	r2, r3
	bcc	CopyCcmInit

将堆和堆栈放置在 CCM 中

最后,要将堆和堆栈放在 CCMRAM 中(可能在其他数据之后),只需要在链接器脚本中执行两个小的修改:

  1. ._user_heap_stack的输出重定向到CCMRAM内存区域而不是RAM。
  2. _estack符号重新定义为 CCMRAM 的末尾,方法是将
    _estack = 0x20020000;    /* end of RAM */
    通过(例如,如果CCM RAM从0x10000000到0x1000FFFF,则特定地址可能会再次更改)
    _estack = 0x10010000;    /* end of CCMRAM */

最后测试CCM内存使用

#define CCMRAM __attribute__((section(".ccmram")))

CCMRAM int test[100];

int main()
{

	for(int i = 0;i<100;i++)
	{
		test[i] = i;
		printf(" %d ",test[i]);
	}

}
 类似资料: