CCM(Core Coupled Memory)是给F4内核专用的全速64KB RAM, 它们没有经过总线矩阵,F4内核与之直接相连, 地址空间在0x1000_0000 ~ 0x1000_FFFF.由于其地址空间和常规的SRAM不连续, 加之DMA和外设也无法直接使用它们,就使得一般的用户程序完全视而不见这64KB全速RAM, 罪过啊- 极致发挥STM32F4性能的利器" title="CCM - 极致发挥STM32F4性能的利器" style="box-sizing: border-box; outline: 0px; max-width: 100%; cursor: zoom-in;">...
言归正传, 既然是全速又专用的SRAM, 可以这么使用来充分发挥F4性能:1. 作堆栈. 修改链接脚本, 找到 CCMRAM_region,block CSTACK 和 block HEAP 关键词. 把原先 placein RAM_region {...} 的命令改为如下2句: place in RAM_region { readwrite }; place in CCMRAM_region { block CSTACK, block HEAP }; 搞定!- 极致发挥STM32F4性能的利器" title="CCM - 极致发挥STM32F4性能的利器" style="box-sizing: border-box; outline: 0px; max-width: 100%; cursor: zoom-in;"> 特别是运行RTOS的时候,此类堆栈可以作为特权资源进行管理, 安全和性能得到同步提升.
2. 做高速运算缓冲 对于运算密集型的应用, 同样可以通过定制链接脚本,在CCM中划分出专用的全速运算缓冲区. 比如: FOC模型解耦, 网络SSL,JPEG编码/解码... 这时的F4内核才真正能够发挥出最高的运算性能.- 极致发挥STM32F4性能的利器" title="CCM - 极致发挥STM32F4性能的利器" style="box-sizing: border-box; outline: 0px; max-width: 100%; cursor: zoom-in;">
我们知道STM32F4当中有个CCM内存,如图所示,这个内存是挂在D总线上直接和内核相连,因此除了内核之外谁都不能访问,那么我们怎么将其利用起来呢?网上这个资料还真的很少,今天我就给大家分享一下,献给那些还不知道的人,如有错漏,还请指正。
首先,我们可以使用Keil的设置选项,将IRAM2打勾,让编译器选择什么时候使用这个内存。显然,我们还可以将这两个地址修改一下,将IRAM1改为0x10000000,这样,编译器就会优先分配CCM内存。
我们来看看结果,在MAP文件中,表明确实使用了这段内存,但是因为我们使用的内存较少, 还没有用到CCM。
这种自动分配的方式有什么问题呢?这段内存是内核专有的,除了内核任何其它总线都不能访问,这就意味着,一旦编译器将数据分配到CCM中,而同时使用了DMA访问,显然会出问题。
于是我们就想到了自己分配这段内存,__attribute__((at(address)))这个语句就是专门干这事的,然后我们可以这么做:
[li]int vat[10] __attribute__((at(0x10000000))) = {1,2,3,4,5,6,7,8,9,10};[/li]复制代码
再次编译以后,发现确实如我们所愿,我们将一段数据放在在了CCM内存中:
[li] Execution Region RW_IRAM2 (Base: 0x10000000, Size: 0x00000028, Max: 0x00010000, ABSOLUTE)
[/li][li]
[/li][li] Base Addr Size Type Attr Idx E Section Name Object
[/li][li]
[/li][li] 0x10000000 0x00000028 Data RW 7 .ARM.__AT_0x10000000 main.o
[/li][li][/li]复制代码
太好了,那么我们能不能将FreeRTOS的数据放进CCM中呢?将FreeRTOS要使用的内存全部移到CCM中,使其成为专有内存,显然会提高FreeRTOS的运行速度。
那么怎么放?首先我们想到了heap4.c这个文件当中有这么一段:
[li]/* Allocate the memory for the heap. */
[/li][li]#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
[/li][li] /* The application writer has already defined the array used for the RTOS
[/li][li] heap - probably so it can be placed in a special segment or address. */
[/li][li] extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
[/li][li]#else
[/li][li] static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
[/li][li]#endif /* configAPPLICATION_ALLOCATED_HEAP */[/li]复制代码
这是FreeRTOS中堆内存的分配,我们可以加入__attribute__将其放进CCM中,这样做没有问题,但是去修改FreeRTOS的源代码显然不是明智之举。事到如今,我们只能自己定义链接器的储存器映射了。
修改Keil的Linker选项,我们把Use Memory Layout from Targer Dialog的钩去掉。
然后在Objects的目录中找到一个后缀为sct的文件,打开之后如图所示:
由于我们只需要将RTOS的数据放入CCM中,于是我们可以这样修改,CCM_IRAM的名字是我自己取的,你可以改成任何你喜欢的,比如什么LOVEYOU之类的:
然后在链接器中选择我们自己的文件:
现在,映像文件变成了这样:
是不是很简单呢?系统堆栈仍然在主内存中,而FreeRTOS的堆内存已经移到了CCM中,由于互不影响,这里我分配了50K的空间专门给FreeRTOS使用。我们甚至还可以配置MPU将这段内存配置为特权级,避免一般任务修改等等,怎么使用,那就是你的事了。 |