[应用相关]

Core Coupled Memory(CCM)内存

[复制链接]
2307|3
手机看帖
扫描二维码
随时随地手机跟帖
nawu|  楼主 | 2021-9-1 16:24 | 显示全部楼层 |阅读模式
基本架构

  废话少说,先看看这块内存特殊在哪里。官方的基本架构说明如下:

The main system consists of 32-bit multilayer AHB bus matrix that interconnects:


Eight masters:

– Cortex® -M4 with FPU core I-bus, D-bus and S-bus

– DMA1 memory bus

– DMA2 memory bus

– DMA2 peripheral bus

– Ethernet DMA bus

– USB OTG HS DMA bus

Seven slaves:

– Internal Flash memory ICode bus

– Internal Flash memory DCode bus

– Main internal SRAM1 (112 KB)

– Auxiliary internal SRAM2 (16 KB)

– AHB1 peripherals including AHB to APB bridges and APB peripherals

– AHB2 peripherals

– FSMC

  The bus matrix provides access from a master to a slave, enabling concurrent access and efficient operation even when several high-speed peripherals work simultaneously. The 64-Kbyte CCM (core coupled memory) data RAM is not part of the bus matrix and can be accessed only through the CPU. This architecture is shown in

11746612f38c176695.png

  其架构和之前的STM32F1x区别还是挺大的。由上可知,CCM共64KB,是直接挂在D-bus上的,除了CPU(即Cortex-M核)之外,谁都无法访问。此外,由于CCM不属于BusMatrix的一部分,所有也就不能被其他组件访问,例如DMA控制器。

  对于CCM,CPU能以最大的系统时钟和最小的等待时间从CCM中读取数据或者代码。官方文档说明了使用CCM的一些优势:比如将频繁读取的数据放到CCM,将中断函数放到CCM,这都能加快程序的执行速度。



使用特权

评论回复
nawu|  楼主 | 2021-9-1 16:26 | 显示全部楼层
如何使用使用方式一

  知道了这块特殊内存,那么我们怎么来使用他呢?常用Keil的人应该知道,在其配置中,有如下选项:

aHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTgwMTI2MjAxODQzNDg4.jpg

 在默认情况下,其中的IRAM2我们不选中,现在我们就可以选中该部分。这样,Keil在生产代码时,就会自动将变量分配到该部分RAM中了。具体的可以打开,Keil生成的.map文件看看。


    Execution Region RW_IRAM2 (Base: 0x10000000, Size: 0x00005ce4, Max: 0x00010000, ABSOLUTE)


    Base Addr    Size         Type   Attr      Idx    E Section Name        Object


    0x10000000   0x00005ce4   Zero   RW        16003    .bss                ram2.o



    Execution Region RW_IRAM1 (Base: 0x20000000, Size: 0x0001b360, Max: 0x00020000, ABSOLUTE, COMPRESSED[0x000000c8])


    Base Addr    Size         Type   Attr      Idx    E Section Name        Object


    0x20000000   0x00000001   Data   RW          264    .data               pbuf.o

    0x20000001   0x00000001   Data   RW          909    .data               api_msg.o



注意:


如果仅仅定义几个变量,可能Keil不会将其放到该RAM中。

我在用的时候,没有选中RAM2,Keil仍然把部分内存放到了RAM2中,不知为啥!

  但是,这样就有一个问题:由于其只能被内核访问,一旦Keil将例如DMA用的内存放到了该部分RAM中,那么DMA将不能工作! 那么怎么使用更合适呢?


使用方式二

  如前所说,直接让编译器自动分配貌似不太合适,所以我们可以自己指定分配的内存。这其中也有两种方式。

  第一种依靠分散加载文件(.sct),更强大,直接定义一个文件(例如,名字为 RAM2.c),将所有要放得变量均放到该文件中,然后如下修改分散加载文件。


LR_IROM1 0x0800C000 0x00100000  {    ; load region size_region

  ER_IROM1 0x0800C000 0x00100000  {  ; load address = execution address

   *.o (RESET, +First)                                ; 中断向量表

    *(InRoot$$Sections)

   .ANY (+RO)

  }


  RW_IRAM1 0x20000000 0x00020000  {  ; RW data

   .ANY (+RW +ZI)

  }

  ; 指定使用CCM

  RW_IRAM2 0x10000000 0x00010000  {

   RAM2.O (RAM2,+RW +ZI)

  }

}



  还有一种方式就是直接使用编译器指令:__attribute__+at。在定义变量时,如下即可:


UINT32 EventNum __attribute__((at(0x10000000))) = 0;



  当然,这种方式也可以稍微变化一下,使用__attribute__+section。给变量指定一个节区名字,然后在分散加载文件中指定节区位置。

  如上处理编译后,可查看map文件对应部分内存中变量的分配了。



使用特权

评论回复
nawu|  楼主 | 2021-9-1 16:27 | 显示全部楼层
关于系统

  我这搞这部分的时候,正好用了FreeRTOS。于是就像既然这部分只能给内核访问,为了内存的合理利用,能不能直接将这部分内存给系统,剩下的给不就是想怎么用就怎么用了么?而且分给FreeRTOS 64KB的内存正好符合我的设计需要!

了解了上面的分散加载文件后,要将FreeRTOS放到RMA2中就非常简单了,根据使用的FreeRTOS的文件,只需要如下的分散加载文件即可。


RW_IRAM2 0x10000000 0x00010000  {

  port.o (+RW +ZI)

  queue.o (+RW +ZI)

  tasks.o (+RW +ZI)

  heap_4.o (+RW +ZI)

  ; 其他的用到的FreeRTOS的.o文件

}




  这样就又有一个问题,如果使用动态申请的内存,则内存还是在RAM2中,如果传递给DMA时,则会出错!


注意:

  1. FreeRTOS中部分文件只有代码,没有数据(RW和ZI),例如:list.c,这样就不能放到上面的分散加载文件中


注意事项

需要了解ARM的分散加载文件。

需要了解个别的编译器指令



使用特权

评论回复
mutable| | 2021-9-2 16:44 | 显示全部楼层
这种高进应用,总让我觉得很高大尚

使用特权

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

本版积分规则

72

主题

3307

帖子

3

粉丝