phantomshuttle 博客
CCM SRAM 核心耦合内存使用

一些 STM32 CPU 包含两组内存:标准 SRAM 和另一组核心耦合内存(又名 CCM),它可能比标准 SRAM 更快并且通常更小。

在某些情况下,将数据放置在这个区域可能会很有趣。

对于这一点,有几种可能性,取决于您的程序所需的内存量。在所有情况下,您可能需要手动编辑链接器脚本文件(LinkerScript.ld,除非由 CubeMX 生成,其名称取决于芯片参考)

https://phantomshuttle.com/wp-content/uploads/2024/10/image-6-1024x692.png

以STM32F407VET6举例,

其中192K 的 RAM 分为 112K 的 SRAM1、16K 的 SRAM2、64K 的 CCMRAM

其中的 SRAM1 和 SRAM2 由内核总线经过总线矩阵后进行连接,而CCMRAM则直接与内核总线连接

总线矩阵,用于建立内核指令总线和外部设备总线的传输连接,同时具备仲裁、同时访问等功能,防止访问冲突,提高访问效率

SRAM1 和 2 两块内存,地址上是连续的,从 0x20000000 开始,我们默认使用的便是这块内存段

CCMRAM 和上面的内存地址是分开的,他的起始地址是 0x10000000,关于地址可以在手册中看到

https://phantomshuttle.com/wp-content/uploads/2024/10/image-7.png

因为 CCMRAM 没有经过矩阵总线,直接与内核的数据总线连接,所以只能用于进行数据存取,并且访问操作速度极快。

注意:F4的CCM只连接到D-CODE总线,不能存放指令代码(函数),而F3则可以连接到I-CODE总线,可以存放指令代码

可以用于例如: LVGL图形框架的动态内存,RTOS的任务堆栈,但切勿用于DMA。这个RAM空间不支持DMA操作

CCM下的RAM空间使用方法

方法一:

直接在MDK编译器上面设置:

https://phantomshuttle.com/wp-content/uploads/2024/10/image-8.png

方法二:

直接通过指针变量指向这个空间即可。
uint16_t  *usPtr;
usPtr = (uint16_t *)0x10000000;

方法三:

像使用内部SRAM一样定义使用SDRAM和CCM RAM,可以随意定义到指定的RAM区域且无需具体地址

实现说明:
默认情况下,我们都是通过MDK的option选项设置Flash和RAM

https://phantomshuttle.com/wp-content/uploads/2024/10/image-9.png

这种情况下,所有管理工作都是编译来处理的,不方面用户将变量定义到指定的CCM 或者SDRAM中。而使用attribute指定具体地址又不方便管理。

针对这种情况,使用一个脚本文件即可解决,脚本定义如下:

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00200000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00200000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00030000  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x10000000 0x00010000  {  ; RW data
   *(.CCM_RAM)
  
  }
  RW_IRAM3 0xC0000000 0x01000000  {  ; RW data
   *(.SDRAM)
  
  }
}

同时配置option的链接选项使用此脚本:

https://phantomshuttle.com/wp-content/uploads/2024/10/image-10.png

使用方法:

使用方便很简单,依然是使用attribute,但是不指定具体地址了,指定RAM区,方法如下,仅需加个前缀即可:

/* 定义在CCM RAM里面的变量 */
__attribute__((section (".CCM_RAM"))) uint32_t CCMBuf1[10];
__attribute__((section (".CCM_RAM"))) uint16_t CCMCount;

/* 定义在SDRAM里面的变量 */
__attribute__((section (".SDRAM"))) uint32_t SDRAMBuf1[10];
__attribute__((section (".SDRAM"))) uint32_t SDRAMCount;

然后就可以直接使用变量,不过注意一点,使用SDRAM中的变量前,优先初始化SDRAM.

参考

https://www.st.com/resource/en/application_note/an4296-use-stm32f3stm32g4-ccm-sram-with-iar-embedded-workbench-keil-mdkarm-stmicroelectronics-stm32cubeide-and-other-gnubased-toolchains-stmicroelectronics.pdf

发表回复

textsms
account_circle
email

phantomshuttle 博客

CCM SRAM 核心耦合内存使用
一些 STM32 CPU 包含两组内存:标准 SRAM 和另一组核心耦合内存(又名 CCM),它可能比标准 SRAM 更快并且通常更小。 在某些情况下,将数据放置在这个区域可能会很有趣。 对于这一…
扫描二维码继续阅读
2024-10-17