打印
[DemoCode下载]

如何在STM32上使用CCM存储空间

[复制链接]
1442|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
E-Kaia|  楼主 | 2016-4-21 22:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

有一段时间Kira忙着想办法加速Eieye识别速度,但是限制于F4太小的内存和主频,一直解决不掉,知道某一天他翻看官方文档《STM32F4xx参考手册》中有对CCM的描述,看完大喜,像捡到宝似的来和我们讨论;
    STM32系列芯片的内部SRAM被分为了几块独立的空间,比如说STM32F4有两块独立的的SRAM块,这两个块都分别连接到了芯片的总线矩阵上;其实还有一块儿叫做“核内联存储单元(Core Coupled Memory)”的SRAM空间存在,这就是CCM,CCM没有连接到总线矩阵上,而是直接连在了内核的D-bus(数据bus)上。




这个和内核紧紧相连的存储空间只能被内核访问,且该空间和内核直接相连而没有经过总线矩阵,这就可以使内核访问该空间几乎没有任何等待延时;比如说,如果此时芯片上有某个单元正在通过总线矩阵访问主SRAM空间,此时内核依然可以无需等待直接访问CCM空间;所以CCM空间主要是用来存储堆栈和其他重要的操作系统数据的,即使是有DMA在搬移数据,内核依然可以保证连续不断的使用CCM中的数据;
    有一点需要注意,CCM也可以很容易的当做普通SRAM使用,这时候你可以将你关键费时间的某些数据操作放到CCM中,这样很有可能会节约你的程序执行时间,但这个前提是你读写SRAM在你的程序中占时间比例比较多,否则效果也不明显;
    下面给出两种使用CCM的方法:
<1>先在linker script中定义一个section

.ccm : {
  . = ALIGN(4);
  _sccm = .;
  *(.ccm)
  . = ALIGN(4);      
  _eccm = .;
}>CCM


沙发
E-Kaia|  楼主 | 2016-4-21 22:53 | 只看该作者
本帖最后由 E-Kaia 于 2016-4-21 22:54 编辑


然后在CCM区定义你的变量:

    #define OPENBW_START_ADDR    CCMDATARAM_BASE //定义位图首地址
    volatile uint8_t openbw[sizeof_column][sizeof_line/compression] __attribute__((at(OPENBW_START_ADDR))); //位图定义
<2>在STM32F4官方库文件stm32f4xx.h中定义了CCM段:
#define CCMDATARAM_BASE  ((uint32_t)0x10000000) /*!< CCM(core coupled memory) data RAM(64 KB) base address in the alias region  */
假设我现在将一副8bit位图放入CCM空间的最开始:
#define OPENBW_START_ADDR    CCMDATARAM_BASE //定义位图首地址
volatile uint8_t openbw[sizeof_column][sizeof_line/compression] __attribute__((at(OPENBW_START_ADDR))); //位图定义

好了,就是这样,CCM就可以玩起来了,看文档竟然找出来了一块64Kbyte的SRAM,这可是将近三分之一的片内RAM,并且还是高速的,真的是捡到宝了,哈哈;所以说看官方文档真的是会有好报的,毕竟一个公司的聪明人都想帮助你用好他们设计的芯片,只要我们踏踏实实学,官方文档中就有挖不尽的宝藏;至少我们的Eieye识别指标又和目标近了一步;
    不过,使用CCM也有限制,首先这是一块独立的存储空间且只有64Kbyte这么大,如果你想放一个80Kbyte的变量,还是选择放到主SRAM中比较好;其次,CCM在官方文档中专门强调,这个存储区域只能被内核访问,也就是说必须是内核读内核写,所以说你要是想把CMM给DMA controller用的话应该就是不行的了;最后,我想我们也不能迷信于CCM,毕竟内部存储矩阵的带宽肯定也非常大,读写等待占的内核周期数两种方式差距可能并不会非常大,至少我们Eieye的差距不大,我们怀疑是我们读写等待占内核操作时间的比例较小;如果谁发现CCM对速度的效果提升很大的话请多多分享经验,毕竟这个优化还是比较高级的;

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

100

帖子

0

粉丝